Mercurial > hg > xemacs-beta
changeset 617:af57a77cbc92
[xemacs-hg @ 2001-06-18 07:09:50 by ben]
---------------------------------------------------------------
DOCUMENTATION FIXES:
---------------------------------------------------------------
eval.c: Correct documentation.
elhash.c: Doc correction.
---------------------------------------------------------------
LISP OBJECT CLEANUP:
---------------------------------------------------------------
bytecode.h, buffer.h, casetab.h, chartab.h, console-msw.h, console.h, database.c, device.h, eldap.h, elhash.h, events.h, extents.h, faces.h, file-coding.h, frame.h, glyphs.h, gui-x.h, gui.h, keymap.h, lisp-disunion.h, lisp-union.h, lisp.h, lrecord.h, lstream.h, mule-charset.h, objects.h, opaque.h, postgresql.h, process.h, rangetab.h, specifier.h, toolbar.h, tooltalk.h, ui-gtk.h: Add wrap_* to all objects (it was already there for a few of them)
-- an expression to encapsulate a pointer into a Lisp object,
rather than the inconvenient XSET*. "wrap" was chosen because
"make" as in make_int(), make_char() is not appropriate. (It
implies allocation. The issue does not exist for ints and chars
because they are not allocated.)
Full error checking has been added to these expressions. When
used without error checking, non-union build, use of these
expressions will incur no loss of efficiency. (In fact, XSET* is
now defined in terms of wrap_* in a non-union build.) In a union
build, you will also get no loss of efficiency provided that you
have a decent optimizing compiler, and a compiler that either
understands inlines or automatically inlines those particular
functions. (And since people don't normally do their production
builds on union, it doesn't matter.)
Update the sample Lisp object definition in lrecord.h accordingly.
dumper.c: Fix places in dumper that referenced wrap_object to reference
its new name, wrap_pointer_1.
buffer.c, bufslots.h, conslots.h, console.c, console.h, devslots.h, device.c, device.h, frame.c, frame.h, frameslots.h, window.c, window.h, winslots.h: -- Extract out the Lisp objects of `struct device' into devslots.h,
just like for the other structures.
-- Extract out the remaining (not copied into the window config)
Lisp objects in `struct window' into winslots.h; use different
macros (WINDOW_SLOT vs. WINDOW_SAVED_SLOT) to differentiate them.
-- Eliminate the `dead' flag of `struct frame', since it
duplicates information already available in `framemeths', and fix
FRAME_LIVE_P accordingly. (Devices and consoles already work this
way.)
-- In *slots.h, switch to system where MARKED_SLOT is automatically
undef'd at the end of the file. (Follows what winslots.h already
does.)
-- Update the comments at the beginning of *slots.h to be accurate.
-- When making any of the above objects dead, zero it out entirely
and reset all Lisp object slots to Qnil. (We were already doing
this somewhat, but not consistently.) This (1) Eliminates the
possibility of extra objects hanging around that ought to be
GC'd, (2) Causes an immediate crash if anyone tries to access a
structure in one of these objects, (3) Ensures consistent behavior
wrt dead objects.
dialog-msw.c: Use internal_object_printer, since this object should not escape.
---------------------------------------------------------------
FIXING A CRASH THAT I HIT ONCE (AND A RELATED BAD BEHAVIOR):
---------------------------------------------------------------
eval.c: Fix up some comments about the FSF implementation.
Fix two nasty bugs:
(1) condition_case_unwind frees the conses sitting in the
catch->tag slot too quickly, resulting in a crash that I hit.
(2) catches need to be unwound one at a time when calling
unwind-protect code, rather than all at once at the end; otherwise,
incorrect behavior can result. (A comment shows exactly how.)
backtrace.h: Improve comment about FSF differences in the handler stack.
---------------------------------------------------------------
FIXING A CRASH THAT I REPEATEDLY HIT WHEN USING THE MOUSE WHEEL
UNDER MSWINDOWS:
---------------------------------------------------------------
Basic idea: My crash is due either to a dead, non-marked,
GC-collected frame inside of a window mirror, or a prematurely
freed window mirror. We need to mark the Lisp objects inside of
window mirrors. Tracking the lifespan of window mirrors and
scrollbar instances is extremely hard, and there may well be
lurking bugs where such objects are freed too soon. The only safe
way to fix these problems (and it fixes both problems at once) is
to make both of these structures Lisp objects.
lrecord.h, emacs.c, inline.c, scrollbar-gtk.c, scrollbar-msw.c, scrollbar-x.c, scrollbar.c, scrollbar.h, symsinit.h: Make scrollbar instances actual Lisp objects. Mark the window
mirrors in them. inline.c needs to know about scrollbar.h now.
Record the new type in lrecord.h. Fix up scrollbar-*.c
appropriately. Create a hash table in scrollbar-msw.c so that the
scrollbar instances stored in scrollbar HWND's are properly
GC-protected. Create complex_vars_of_scrollbar_mswindows() to
create the hash table at startup, and call it from emacs.c. Don't
store the scrollbar instance as a property of the GTK scrollbar,
as it's not used and if we did this, we'd have to separately
GC-protect it in a hash table, like in MS Windows.
lrecord.h, frame.h, frame.c, frameslots.h, redisplay.c, window.c, window.h: Move mark_window_mirror from redisplay.c to window.c. Make window
mirrors actual Lisp objects. Tell lrecord.h about them. Change
the window mirror member of struct frame from a pointer to a Lisp
object, and add XWINDOW_MIRROR in appropriate places. Mark the
scrollbar instances in the window mirror.
redisplay.c, redisplay.h, alloc.c: Delete mark_redisplay. Don't call mark_redisplay. We now mark
frame-specific structures in mark_frame.
NOTE: I also deleted an extremely questionable call to
update_frame_window_mirrors(). It was extremely questionable
before, and now totally impossible, since it will create
Lisp objects during redisplay.
frame.c: Mark the scrollbar instances, which are now Lisp objects.
Call mark_gutter() here, not in mark_redisplay().
gutter.c: Update comments about correct marking.
---------------------------------------------------------------
ISSUES BROUGHT UP BY MARTIN:
---------------------------------------------------------------
buffer.h: Put back these macros the way Steve T and I think they ought to be.
I already explained in a previous changelog entry why I think these
macros should be the way I'd defined them. Once again:
We fix these macros so they don't care about the type of their
lvalues. The non-C-string equivalents of these already function
in the same way, and it's correct because it should be OK to pass
in a CBufbyte *, a BufByte *, a Char_Binary *, an UChar_Binary *,
etc. The whole reason for these different types is to work around
errors caused by signed-vs-unsigned non-matching types. Any
possible error that might be caught in a DFC macro would also be
caught wherever the argument is used elsewhere. So creating
multiple macro versions would add no useful error-checking and
just further complicate an already complicated area.
As for Martin's "ANSI aliasing" bug, XEmacs is not ANSI-aliasing
clean and probably never will be. Unless the board agrees to
change XEmacs in this way (and we really don't want to go down
that road), this is not a bug.
sound.h: Undo Martin's type change.
signal.c: Fix problem identified by Martin with Linux and g++ due to
non-standard declaration of setitimer().
systime.h: Update the docs for "qxe_" to point out why making the
encapsulation explicit is always the right way to go. (setitimer()
itself serves as an example.)
For 21.4:
update-elc-2.el: Correct misplaced parentheses, making lisp/mule not get
recompiled.
line wrap: on
line diff
--- a/lisp/ChangeLog Mon Jun 11 07:47:20 2001 +0000 +++ b/lisp/ChangeLog Mon Jun 18 07:10:32 2001 +0000 @@ -1,3 +1,12 @@ +2001-06-17 Ben Wing <ben@xemacs.org> + + For 21.4: + + * update-elc-2.el (do-update-elc-2): + * update-elc-2.el (batch-update-elc-2): + Correct misplaced parentheses, making lisp/mule not get + recompiled. + 2001-06-10 Ben Wing <ben@xemacs.org> * alist.el:
--- a/lisp/update-elc-2.el Mon Jun 11 07:47:20 2001 +0000 +++ b/lisp/update-elc-2.el Mon Jun 18 07:10:32 2001 +0000 @@ -113,7 +113,7 @@ (when (and (file-exists-p file-c) (not (file-exists-p file))) (message "Removing %s; no corresponding .el" file-c) - (delete-file file-c)))) + (delete-file file-c))))) ;; We descend recursively (let ((dirs (directory-files dir t nil t)) @@ -124,8 +124,7 @@ (file-directory-p dir)) (do-update-elc-2 dir compile-stage-p seen)))) - ))) - + )) (defun batch-update-elc-2 () (defvar command-line-args-left)
--- a/src/ChangeLog Mon Jun 11 07:47:20 2001 +0000 +++ b/src/ChangeLog Mon Jun 18 07:10:32 2001 +0000 @@ -1,3 +1,316 @@ +2001-06-17 Ben Wing <ben@xemacs.org> + + --------------------------------------------------------------- + DOCUMENTATION FIXES: + --------------------------------------------------------------- + + * eval.c (Ffunction_min_args): + * eval.c (Ffunction_max_args): + Correct documentation. + + * elhash.c (Fremhash): Doc correction. + + --------------------------------------------------------------- + LISP OBJECT CLEANUP: + --------------------------------------------------------------- + + * bytecode.h (wrap_compiled_function): + * buffer.h (wrap_buffer): + * casetab.h (wrap_case_table): + * chartab.h (wrap_char_table_entry): + * chartab.h (wrap_char_table): + * console-msw.h (wrap_devmode): + * console-msw.h (wrap_mswindows_dialog_id): + * console.h (wrap_console): + * database.c (wrap_database): + * device.h (wrap_device): + * eldap.h (wrap_ldap): + * elhash.h (wrap_hash_table): + * events.h (wrap_timeout): + * events.h (wrap_event): + * extents.h (wrap_extent): + * extents.h (wrap_extent_auxiliary): + * extents.h (wrap_extent_info): + * faces.h (wrap_face): + * file-coding.h (wrap_coding_system): + * frame.h (wrap_frame): + * glyphs.h (wrap_image_instance): + * glyphs.h (wrap_glyph): + * gui-x.h (wrap_popup_data): + * gui.h (wrap_gui_item): + * keymap.h (wrap_keymap): + * lisp-disunion.h (wrap_pointer_1): + * lisp-union.h (wrap_pointer_1): + * lisp.h (wrap_cons): + * lisp.h (wrap_string): + * lisp.h (wrap_vector): + * lisp.h (wrap_bit_vector): + * lisp.h (wrap_symbol): + * lisp.h (wrap_subr): + * lisp.h (wrap_marker): + * lisp.h (wrap_float): + * lisp.h (wrap_weak_list): + * lisp.h (wrap_lcrecord_list): + * lrecord.h (wrap_record_1): + * lstream.h (wrap_lstream): + * mule-charset.h (wrap_charset): + * objects.h (wrap_color_instance): + * objects.h (wrap_font_instance): + * opaque.h (wrap_opaque): + * opaque.h (wrap_opaque_ptr): + * postgresql.h (wrap_pgconn): + * postgresql.h (wrap_pgresult): + * process.h (wrap_process): + * rangetab.h (wrap_range_table): + * specifier.h (wrap_specifier): + * toolbar.h (wrap_toolbar_button): + * tooltalk.h (wrap_tooltalk_message): + * tooltalk.h (wrap_tooltalk_pattern): + * ui-gtk.h (wrap_emacs_ffi): + * ui-gtk.h (wrap_emacs_gtk_object): + * ui-gtk.h (wrap_emacs_gtk_boxed): + * lstream.h (wrap_lstream): + * device.h (wrap_device): New. + * frame.h (wrap_frame): New. + * lisp-disunion.h (wrap_object): + * lisp-disunion.h (XSETOBJ): + * lrecord.h: + Add wrap_* to all objects (it was already there for a few of them) + -- an expression to encapsulate a pointer into a Lisp object, + rather than the inconvenient XSET*. "wrap" was chosen because + "make" as in make_int(), make_char() is not appropriate. (It + implies allocation. The issue does not exist for ints and chars + because they are not allocated.) + + Full error checking has been added to these expressions. When + used without error checking, non-union build, use of these + expressions will incur no loss of efficiency. (In fact, XSET* is + now defined in terms of wrap_* in a non-union build.) In a union + build, you will also get no loss of efficiency provided that you + have a decent optimizing compiler, and a compiler that either + understands inlines or automatically inlines those particular + functions. (And since people don't normally do their production + builds on union, it doesn't matter.) + + Update the sample Lisp object definition in lrecord.h accordingly. + + * dumper.c (pdump_dump_root_objects): + * dumper.c (pdump_load_finish): + Fix places in dumper that referenced wrap_object to reference + its new name, wrap_pointer_1. + + * buffer.c (mark_buffer): + * buffer.c (reset_buffer_local_variables): + * buffer.c (Fbuffer_local_variables): + * buffer.c (nuke_all_buffer_slots): + * buffer.c (complex_vars_of_buffer): + * bufslots.h: + * conslots.h: + * console.c: + * console.c (mark_console): + * console.c (nuke_all_console_slots): + * console.c (delete_console_internal): + * console.c (common_init_complex_vars_of_console): + * console.c (complex_vars_of_console): + * console.h (struct console): + * devslots.h: NEW FILE. + * device.c: + * device.c (MARKED_SLOT): + * device.c (mark_device): + * device.c (nuke_all_device_slots): + * device.c (allocate_device): + * device.c (Fset_device_selected_frame): + * device.c (delete_device_internal): + * device.c (vars_of_device): + * device.h (struct device): + * device.h (MARKED_SLOT): + * frame.c (nuke_all_frame_slots): + * frame.c (allocate_frame_core): + * frame.c (delete_frame_internal): + * frame.h (struct frame): + * frame.h (FRAME_LIVE_P): + * frameslots.h: + * window.c (mark_window): + * window.c (WINDOW_SLOT): + * window.c (allocate_window): + * window.c (mark_window_as_deleted): + * window.c (wrap_window_configuration): + * window.c (Fset_window_configuration): + * window.h: + * window.h (struct window): + * window.h (WINDOW_SLOT): + * winslots.h: + -- Extract out the Lisp objects of `struct device' into devslots.h, + just like for the other structures. + -- Extract out the remaining (not copied into the window config) + Lisp objects in `struct window' into winslots.h; use different + macros (WINDOW_SLOT vs. WINDOW_SAVED_SLOT) to differentiate them. + -- Eliminate the `dead' flag of `struct frame', since it + duplicates information already available in `framemeths', and fix + FRAME_LIVE_P accordingly. (Devices and consoles already work this + way.) + -- In *slots.h, switch to system where MARKED_SLOT is automatically + undef'd at the end of the file. (Follows what winslots.h already + does.) + -- Update the comments at the beginning of *slots.h to be accurate. + -- When making any of the above objects dead, zero it out entirely + and reset all Lisp object slots to Qnil. (We were already doing + this somewhat, but not consistently.) This (1) Eliminates the + possibility of extra objects hanging around that ought to be + GC'd, (2) Causes an immediate crash if anyone tries to access a + structure in one of these objects, (3) Ensures consistent behavior + wrt dead objects. + + * dialog-msw.c: + Use internal_object_printer, since this object should not escape. + + --------------------------------------------------------------- + FIXING A CRASH THAT I HIT ONCE (AND A RELATED BAD BEHAVIOR): + --------------------------------------------------------------- + + * eval.c (unwind_to_catch): + * eval.c (condition_bind_unwind): + * eval.c (condition_case_unwind): + * eval.c (condition_case_1): + Fix up some comments about the FSF implementation. + Fix two nasty bugs: + + (1) condition_case_unwind frees the conses sitting in the + catch->tag slot too quickly, resulting in a crash that I hit. + (2) catches need to be unwound one at a time when calling + unwind-protect code, rather than all at once at the end; otherwise, + incorrect behavior can result. (A comment shows exactly how.) + + * backtrace.h: + Improve comment about FSF differences in the handler stack. + + --------------------------------------------------------------- + FIXING A CRASH THAT I REPEATEDLY HIT WHEN USING THE MOUSE WHEEL + UNDER MSWINDOWS: + --------------------------------------------------------------- + + Basic idea: My crash is due either to a dead, non-marked, + GC-collected frame inside of a window mirror, or a prematurely + freed window mirror. We need to mark the Lisp objects inside of + window mirrors. Tracking the lifespan of window mirrors and + scrollbar instances is extremely hard, and there may well be + lurking bugs where such objects are freed too soon. The only safe + way to fix these problems (and it fixes both problems at once) is + to make both of these structures Lisp objects. + + * lrecord.h (lrecord_type): + * emacs.c (main_1): + * inline.c: + * scrollbar-gtk.c (gtk_create_scrollbar_instance): + * scrollbar-gtk.c (find_scrollbar_window_mirror): + * scrollbar-gtk.c (scrollbar_cb): + * scrollbar-gtk.c (gtk_scrollbar_pointer_changed_in_window): + * scrollbar-gtk.c (gtk_update_frame_scrollbars): + * scrollbar-msw.c: + * scrollbar-msw.c (mswindows_create_scrollbar_instance): + * scrollbar-msw.c (mswindows_free_scrollbar_instance): + * scrollbar-msw.c (mswindows_update_scrollbar_instance_values): + * scrollbar-msw.c (mswindows_handle_scrollbar_event): + * scrollbar-msw.c (syms_of_scrollbar_mswindows): + * scrollbar-msw.c (vars_of_scrollbar_mswindows): + * scrollbar-msw.c (complex_vars_of_scrollbar_mswindows): + * scrollbar-x.c (find_scrollbar_window_mirror): + * scrollbar-x.c (x_update_frame_scrollbars): + * scrollbar.c: + * scrollbar.c (mark_scrollbar_instance): + * scrollbar.c (free_scrollbar_instance): + * scrollbar.c (free_frame_scrollbars): + * scrollbar.c (create_scrollbar_instance): + * scrollbar.c (syms_of_scrollbar): + * scrollbar.h: + * scrollbar.h (struct scrollbar_instance): + * symsinit.h: + Make scrollbar instances actual Lisp objects. Mark the window + mirrors in them. inline.c needs to know about scrollbar.h now. + Record the new type in lrecord.h. Fix up scrollbar-*.c + appropriately. Create a hash table in scrollbar-msw.c so that the + scrollbar instances stored in scrollbar HWND's are properly + GC-protected. Create complex_vars_of_scrollbar_mswindows() to + create the hash table at startup, and call it from emacs.c. Don't + store the scrollbar instance as a property of the GTK scrollbar, + as it's not used and if we did this, we'd have to separately + GC-protect it in a hash table, like in MS Windows. + + * lrecord.h (lrecord_type): + * frame.h (struct frame): + * frame.c (delete_frame_internal): + * frameslots.h: + * redisplay.c: + * window.c: + * window.c (mark_window_mirror): + * window.c (new_window_mirror): + * window.c (update_frame_window_mirror): + * window.c (free_window_mirror): + * window.c (find_window_mirror): + * window.c (syms_of_window): + * window.c (real_window): + * window.h (struct window_mirror): + Move mark_window_mirror from redisplay.c to window.c. Make window + mirrors actual Lisp objects. Tell lrecord.h about them. Change + the window mirror member of struct frame from a pointer to a Lisp + object, and add XWINDOW_MIRROR in appropriate places. Mark the + scrollbar instances in the window mirror. + + * redisplay.c: + * redisplay.h: + * alloc.c (garbage_collect_1): + Delete mark_redisplay. Don't call mark_redisplay. We now mark + frame-specific structures in mark_frame. + + NOTE: I also deleted an extremely questionable call to + update_frame_window_mirrors(). It was extremely questionable + before, and now totally impossible, since it will create + Lisp objects during redisplay. + + * frame.c (mark_frame): + Mark the scrollbar instances, which are now Lisp objects. + Call mark_gutter() here, not in mark_redisplay(). + + * gutter.c: + Update comments about correct marking. + + --------------------------------------------------------------- + ISSUES BROUGHT UP BY MARTIN: + --------------------------------------------------------------- + + * buffer.h (DFC_C_STRING_ALLOCA_USE_CONVERTED_DATA): + Put back these macros the way Steve T and I think they ought to be. + I already explained in a previous changelog entry why I think these + macros should be the way I'd defined them. Once again: + + We fix these macros so they don't care about the type of their + lvalues. The non-C-string equivalents of these already function + in the same way, and it's correct because it should be OK to pass + in a CBufbyte *, a BufByte *, a Char_Binary *, an UChar_Binary *, + etc. The whole reason for these different types is to work around + errors caused by signed-vs-unsigned non-matching types. Any + possible error that might be caught in a DFC macro would also be + caught wherever the argument is used elsewhere. So creating + multiple macro versions would add no useful error-checking and + just further complicate an already complicated area. + + As for Martin's "ANSI aliasing" bug, XEmacs is not ANSI-aliasing + clean and probably never will be. Unless the board agrees to + change XEmacs in this way (and we really don't want to go down + that road), this is not a bug. + + * sound.h (sound_perror): + Undo Martin's type change. + + * signal.c (qxe_setitimer): + Fix problem identified by Martin with Linux and g++ due to + non-standard declaration of setitimer(). + + * systime.h: + Update the docs for "qxe_" to point out why making the + encapsulation explicit is always the right way to go. (setitimer() + itself serves as an example.) + 2001-06-11 Martin Buchholz <martin@xemacs.org> * buffer.h (DFC_C_STRING_ALLOCA_USE_CONVERTED_DATA): @@ -1406,7 +1719,6 @@ * lread.c (syms_of_lread): * lread.c (vars_of_lread): * lstream.c (Lstream_internal_error): - * lstream.h (wrap_lstream): * macros.c (Fstart_kbd_macro): * macros.c (Fend_kbd_macro): * macros.c (pop_kbd_macro_event): @@ -5921,7 +6233,6 @@ [6]. [7]. - * device.h (wrap_device): New. First of its kind; meant to replace XSETDEVICE. * dialog-msw.c: Many file-dialog symbols. @@ -6164,7 +6475,6 @@ * frame.c: * frame.c (Fmouse_pixel_position): Minor doc fixes. - * frame.h (wrap_frame): New. Macro like wrap_device. * general.c: @@ -6238,7 +6548,6 @@ * keymap.h: Support new button modifiers. - * lisp-disunion.h (wrap_object): * lisp-disunion.h (XSETOBJ): Rename make_obj to wrap_object.
--- a/src/alloc.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/alloc.c Mon Jun 18 07:10:32 2001 +0000 @@ -3476,7 +3476,6 @@ } } - mark_redisplay (); mark_profiling_info (); /* OK, now do the after-mark stuff. This is for things that
--- a/src/backtrace.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/backtrace.h Mon Jun 18 07:10:32 2001 +0000 @@ -79,7 +79,11 @@ JMP_BUF jmp; struct backtrace *backlist; #if 0 /* FSFmacs */ - /* #### */ + /* FSF uses a separate handler stack to hold condition-cases, + where we use Vcondition_handlers. We should switch to their + system becaue it avoids the need to mess around with consing + up stuff and then dangerously freeing it. See comment in + condition_case_unwind(). */ struct handler *handlerlist; #endif int lisp_eval_depth;
--- a/src/buffer.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/buffer.c Mon Jun 18 07:10:32 2001 +0000 @@ -238,7 +238,6 @@ #define MARKED_SLOT(x) mark_object (buf->x) #include "bufslots.h" -#undef MARKED_SLOT mark_object (buf->extent_info); if (buf->text) @@ -697,7 +696,6 @@ b->slot = def->slot; \ } #include "bufslots.h" -#undef MARKED_SLOT } @@ -846,7 +844,6 @@ result = Fcons (Fcons (syms->slot, buf->slot), result); \ } #include "bufslots.h" -#undef MARKED_SLOT } return result; } @@ -2383,7 +2380,6 @@ #define MARKED_SLOT(x) b->x = zap #include "bufslots.h" -#undef MARKED_SLOT } static void @@ -3028,7 +3024,6 @@ != !(NILP (XBUFFER (Vbuffer_local_symbols)->slot))) \ abort () #include "bufslots.h" -#undef MARKED_SLOT { Lisp_Object scratch = Fget_buffer_create (QSscratch);
--- a/src/buffer.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/buffer.h Mon Jun 18 07:10:32 2001 +0000 @@ -224,6 +224,7 @@ DECLARE_LRECORD (buffer, struct buffer); #define XBUFFER(x) XRECORD (x, buffer, struct buffer) #define XSETBUFFER(x, p) XSETRECORD (x, p, buffer) +#define wrap_buffer(p) wrap_record (p, buffer) #define BUFFERP(x) RECORDP (x, buffer) #define CHECK_BUFFER(x) CHECK_RECORD (x, buffer) #define CONCHECK_BUFFER(x) CONCHECK_RECORD (x, buffer) @@ -1284,12 +1285,12 @@ #define DFC_C_STRING_ALLOCA_USE_CONVERTED_DATA(sink) do { \ void * dfc_sink_ret = alloca (dfc_sink.data.len + 1); \ memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 1); \ - sink = (char *) dfc_sink_ret; \ + ((dfc_aliasing_voidpp) &(sink))->p = dfc_sink_ret; \ } while (0) #define DFC_C_STRING_MALLOC_USE_CONVERTED_DATA(sink) do { \ void * dfc_sink_ret = xmalloc (dfc_sink.data.len + 1); \ memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 1); \ - sink = (char *) dfc_sink_ret; \ + ((dfc_aliasing_voidpp) &(sink))->p = dfc_sink_ret; \ } while (0) #define DFC_LISP_STRING_USE_CONVERTED_DATA(sink) \ sink = make_string ((Bufbyte *) dfc_sink.data.ptr, dfc_sink.data.len)
--- a/src/bufslots.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/bufslots.h Mon Jun 18 07:10:32 2001 +0000 @@ -27,10 +27,13 @@ XEmacs: a few other changes. */ -/* In the declaration of the buffer structure, this file is included - after defining MARKED_SLOT(x) to be Lisp_Object x; i.e. just a slot - definition. In the garbage collector this file is included after - defining MARKED_SLOT(x) to be mark_object(buffer->x). */ +/* We define the Lisp_Objects in the buffer structure in a separate file + because there are numerous places we want to iterate over them, such + as when defining them in the structure, initializing them, or marking + them. + + To use, define MARKED_SLOT before including this file. No need to + undefine; that happens automatically. */ #ifndef BUFFER_SLOTS_FIRST_NAME #define BUFFER_SLOTS_FIRST_NAME name @@ -222,9 +225,4 @@ #define BUFFER_SLOTS_LAST_NAME modeline_extent_table #endif -#if 0 /* FSFmacs */ - /* This is silly and stupid */ - /* These are so we don't have to recompile everything - the next few times we add a new slot. */ - MARKED_SLOT (extra1, extra2, extra3); -#endif +#undef MARKED_SLOT
--- a/src/bytecode.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/bytecode.h Mon Jun 18 07:10:32 2001 +0000 @@ -92,6 +92,7 @@ #define XCOMPILED_FUNCTION(x) XRECORD (x, compiled_function, \ Lisp_Compiled_Function) #define XSETCOMPILED_FUNCTION(x, p) XSETRECORD (x, p, compiled_function) +#define wrap_compiled_function(p) wrap_record (p, compiled_function) #define COMPILED_FUNCTIONP(x) RECORDP (x, compiled_function) #define CHECK_COMPILED_FUNCTION(x) CHECK_RECORD (x, compiled_function) #define CONCHECK_COMPILED_FUNCTION(x) CONCHECK_RECORD (x, compiled_function)
--- a/src/casetab.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/casetab.h Mon Jun 18 07:10:32 2001 +0000 @@ -35,6 +35,7 @@ DECLARE_LRECORD (case_table, Lisp_Case_Table); #define XCASE_TABLE(x) XRECORD (x, case_table, Lisp_Case_Table) #define XSETCASE_TABLE(x, p) XSETRECORD (x, p, case_table) +#define wrap_case_table(p) wrap_record (p, case_table) #define CASE_TABLEP(x) RECORDP (x, case_table) #define CHECK_CASE_TABLE(x) CHECK_RECORD (x, case_table) #define CONCHECK_CASE_TABLE(x) CONCHECK_RECORD (x, case_table)
--- a/src/chartab.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/chartab.h Mon Jun 18 07:10:32 2001 +0000 @@ -52,6 +52,7 @@ #define XCHAR_TABLE_ENTRY(x) \ XRECORD (x, char_table_entry, Lisp_Char_Table_Entry) #define XSETCHAR_TABLE_ENTRY(x, p) XSETRECORD (x, p, char_table_entry) +#define wrap_char_table_entry(p) wrap_record (p, char_table_entry) #define CHAR_TABLE_ENTRYP(x) RECORDP (x, char_table_entry) /* #define CHECK_CHAR_TABLE_ENTRY(x) CHECK_RECORD (x, char_table_entry) char table entries should never escape to Lisp */ @@ -122,6 +123,7 @@ DECLARE_LRECORD (char_table, Lisp_Char_Table); #define XCHAR_TABLE(x) XRECORD (x, char_table, Lisp_Char_Table) #define XSETCHAR_TABLE(x, p) XSETRECORD (x, p, char_table) +#define wrap_char_table(p) wrap_record (p, char_table) #define CHAR_TABLEP(x) RECORDP (x, char_table) #define CHECK_CHAR_TABLE(x) CHECK_RECORD (x, char_table) #define CONCHECK_CHAR_TABLE(x) CONCHECK_RECORD (x, char_table)
--- a/src/conslots.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/conslots.h Mon Jun 18 07:10:32 2001 +0000 @@ -20,10 +20,13 @@ /* Synched up with: Mule 2.0, FSF 19.30. (see FSF keyboard.h.) */ -/* In the declaration of the console structure, this file is included - after defining MARKED_SLOT(x) to be Lisp_Object x; i.e. just a slot - definition. In the garbage collector this file is included after - defining MARKED_SLOT(x) to be mark_object(console->x). */ +/* We define the Lisp_Objects in the console structure in a separate file + because there are numerous places we want to iterate over them, such + as when defining them in the structure, initializing them, or marking + them. + + To use, define MARKED_SLOT before including this file. No need to + undefine; that happens automatically. */ #ifndef CONSOLE_SLOTS_FIRST_NAME #define CONSOLE_SLOTS_FIRST_NAME name @@ -101,3 +104,4 @@ #define CONSOLE_SLOTS_LAST_NAME function_key_map #endif +#undef MARKED_SLOT
--- a/src/console-msw.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/console-msw.h Mon Jun 18 07:10:32 2001 +0000 @@ -83,6 +83,7 @@ DECLARE_LRECORD (devmode, Lisp_Devmode); #define XDEVMODE(x) XRECORD (x, devmode, Lisp_Devmode) #define XSETDEVMODE(x, p) XSETRECORD (x, p, devmode) +#define wrap_devmode(p) wrap_record (p, devmode) #define DEVMODEP(x) RECORDP (x, devmode) #define CHECK_DEVMODE(x) CHECK_RECORD (x, devmode) #define CONCHECK_DEVMODE(x) CONCHECK_RECORD (x, devmode) @@ -403,6 +404,7 @@ DECLARE_LRECORD (mswindows_dialog_id, struct mswindows_dialog_id); #define XMSWINDOWS_DIALOG_ID(x) XRECORD (x, mswindows_dialog_id, struct mswindows_dialog_id) #define XSETMSWINDOWS_DIALOG_ID(x, p) XSETRECORD (x, p, mswindows_dialog_id) +#define wrap_mswindows_dialog_id(p) wrap_record (p, mswindows_dialog_id) #define MSWINDOWS_DIALOG_IDP(x) RECORDP (x, mswindows_dialog_id) #define CHECK_MSWINDOWS_DIALOG_ID(x) CHECK_RECORD (x, mswindows_dialog_id) #define CONCHECK_MSWINDOWS_DIALOG_ID(x) CONCHECK_RECORD (x, mswindows_dialog_id)
--- a/src/console.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/console.c Mon Jun 18 07:10:32 2001 +0000 @@ -104,7 +104,6 @@ #define MARKED_SLOT(x) mark_object (con->x) #include "conslots.h" -#undef MARKED_SLOT /* Can be zero for Vconsole_defaults, Vconsole_local_symbols */ if (con->conmeths) @@ -580,6 +579,15 @@ LISP_TO_VOID (console)); } +static void +nuke_all_console_slots (struct console *con, Lisp_Object zap) +{ + zero_lcrecord (con); + +#define MARKED_SLOT(x) con->x = zap +#include "conslots.h" +} + /* Delete console CON. If FORCE is non-zero, allow deletion of the only frame. @@ -719,7 +727,15 @@ MAYBE_CONMETH (con, delete_console, (con)); Vconsole_list = delq_no_quit (console, Vconsole_list); + RESET_CHANGED_SET_FLAGS; + + /* Nobody should be accessing anything in this object any more, and + making all Lisp_Objects Qnil allows for better GC'ing in case a + pointer to the dead console continues to hang around. Zero all + other structs in case someone tries to access something through + them. */ + nuke_all_console_slots (con, Qnil); con->conmeths = dead_console_methods; UNGCPRO; @@ -1203,37 +1219,38 @@ #endif } -/* The docstrings for DEFVAR_* are recorded externally by make-docfile. */ -#define DEFVAR_CONSOLE_LOCAL_1(lname, field_name, forward_type, magicfun) do { \ - static const struct symbol_value_forward I_hate_C = \ - { /* struct symbol_value_forward */ \ - { /* struct symbol_value_magic */ \ - { /* struct lcrecord_header */ \ - { /* struct lrecord_header */ \ - lrecord_type_symbol_value_forward, /* lrecord_type_index */ \ - 1, /* mark bit */ \ - 1, /* c_readonly bit */ \ - 1 /* lisp_readonly bit */ \ - }, \ - 0, /* next */ \ - 0, /* uid */ \ - 0 /* free */ \ - }, \ - &(console_local_flags.field_name), \ - forward_type \ - }, \ - magicfun \ - }; \ - \ - { \ - int offset = ((char *)symbol_value_forward_forward (&I_hate_C) \ - - (char *)&console_local_flags); \ - \ - defvar_magic (lname, &I_hate_C); \ - \ - *((Lisp_Object *)(offset + (char *)XCONSOLE (Vconsole_local_symbols))) \ - = intern (lname); \ - } \ +/* The docstrings for DEFVAR_* are recorded externally by make-docfile. */ \ +#define DEFVAR_CONSOLE_LOCAL_1(lname, field_name, forward_type, magicfun) \ +do { \ + static const struct symbol_value_forward I_hate_C = \ + { /* struct symbol_value_forward */ \ + { /* struct symbol_value_magic */ \ + { /* struct lcrecord_header */ \ + { /* struct lrecord_header */ \ + lrecord_type_symbol_value_forward, /* lrecord_type_index */ \ + 1, /* mark bit */ \ + 1, /* c_readonly bit */ \ + 1 /* lisp_readonly bit */ \ + }, \ + 0, /* next */ \ + 0, /* uid */ \ + 0 /* free */ \ + }, \ + &(console_local_flags.field_name), \ + forward_type \ + }, \ + magicfun \ + }; \ + \ + { \ + int offset = ((char *)symbol_value_forward_forward (&I_hate_C) \ + - (char *)&console_local_flags); \ + \ + defvar_magic (lname, &I_hate_C); \ + \ + *((Lisp_Object *)(offset + (char *)XCONSOLE (Vconsole_local_symbols))) \ + = intern (lname); \ + } \ } while (0) #define DEFVAR_CONSOLE_LOCAL_MAGIC(lname, field_name, magicfun) \ @@ -1254,16 +1271,6 @@ DEFVAR_CONSOLE_DEFAULTS_MAGIC (lname, field_name, 0) static void -nuke_all_console_slots (struct console *con, Lisp_Object zap) -{ - zero_lcrecord (con); - -#define MARKED_SLOT(x) con->x = zap -#include "conslots.h" -#undef MARKED_SLOT -} - -static void common_init_complex_vars_of_console (void) { /* Make sure all markable slots in console_defaults @@ -1467,5 +1474,4 @@ != !(NILP (XCONSOLE (Vconsole_local_symbols)->slot))) \ abort () #include "conslots.h" -#undef MARKED_SLOT }
--- a/src/console.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/console.h Mon Jun 18 07:10:32 2001 +0000 @@ -443,7 +443,6 @@ #define MARKED_SLOT(x) Lisp_Object x #include "conslots.h" -#undef MARKED_SLOT /* Where to store the next keystroke of the macro. Index into con->kbd_macro_builder. */ @@ -464,6 +463,7 @@ DECLARE_LRECORD (console, struct console); #define XCONSOLE(x) XRECORD (x, console, struct console) #define XSETCONSOLE(x, p) XSETRECORD (x, p, console) +#define wrap_console(p) wrap_record (p, console) #define CONSOLEP(x) RECORDP (x, console) #define CHECK_CONSOLE(x) CHECK_RECORD (x, console) #define CONCHECK_CONSOLE(x) CONCHECK_RECORD (x, console)
--- a/src/database.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/database.c Mon Jun 18 07:10:32 2001 +0000 @@ -111,6 +111,7 @@ #define XDATABASE(x) XRECORD (x, database, Lisp_Database) #define XSETDATABASE(x, p) XSETRECORD (x, p, database) +#define wrap_database(p) wrap_record (p, database) #define DATABASEP(x) RECORDP (x, database) #define CHECK_DATABASE(x) CHECK_RECORD (x, database) #define CONCHECK_DATABASE(x) CONCHECK_RECORD (x, database)
--- a/src/device.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/device.c Mon Jun 18 07:10:32 2001 +0000 @@ -83,25 +83,8 @@ { struct device *d = XDEVICE (obj); - mark_object (d->name); - mark_object (d->connection); - mark_object (d->canon_connection); - mark_object (d->console); - mark_object (d->selected_frame); - mark_object (d->frame_with_focus_real); - mark_object (d->frame_with_focus_for_hooks); - mark_object (d->frame_that_ought_to_have_focus); - mark_object (d->device_class); - mark_object (d->user_defined_tags); - mark_object (d->pixel_to_glyph_cache.obj1); - mark_object (d->pixel_to_glyph_cache.obj2); - - mark_object (d->color_instance_cache); - mark_object (d->font_instance_cache); -#ifdef MULE - mark_object (d->charset_font_cache); -#endif - mark_object (d->image_instance_cache); +#define MARKED_SLOT(x) mark_object (d->x) +#include "devslots.h" if (d->devmeths) { @@ -161,6 +144,15 @@ return Fcopy_sequence (Vdevice_class_list); } +static void +nuke_all_device_slots (struct device *d, Lisp_Object zap) +{ + zero_lcrecord (d); + +#define MARKED_SLOT(x) d->x = zap +#include "devslots.h" +} + static struct device * allocate_device (Lisp_Object console) { @@ -168,25 +160,12 @@ struct device *d = alloc_lcrecord_type (struct device, &lrecord_device); struct gcpro gcpro1; - zero_lcrecord (d); - XSETDEVICE (device, d); GCPRO1 (device); - d->name = Qnil; + nuke_all_device_slots (d, Qnil); + d->console = console; - d->connection = Qnil; - d->canon_connection = Qnil; - d->frame_list = Qnil; - d->selected_frame = Qnil; - d->frame_with_focus_real = Qnil; - d->frame_with_focus_for_hooks = Qnil; - d->frame_that_ought_to_have_focus = Qnil; - d->device_class = Qnil; - d->user_defined_tags = Qnil; - d->pixel_to_glyph_cache.obj1 = Qnil; - d->pixel_to_glyph_cache.obj2 = Qnil; - d->infd = d->outfd = -1; /* #### is 20 reasonable? */ @@ -302,7 +281,8 @@ CHECK_LIVE_FRAME (frame); if (! EQ (device, FRAME_DEVICE (XFRAME (frame)))) - invalid_argument ("In `set-device-selected-frame', FRAME is not on DEVICE", Qunbound); + invalid_argument ("In `set-device-selected-frame', FRAME is not on DEVICE", + Qunbound); if (EQ (device, Fselected_device (Qnil))) return Fselect_frame (frame); @@ -823,8 +803,17 @@ MAYBE_DEVMETH (d, delete_device, (d)); CONSOLE_DEVICE_LIST (c) = delq_no_quit (device, CONSOLE_DEVICE_LIST (c)); + RESET_CHANGED_SET_FLAGS; + + /* Nobody should be accessing anything in this object any more, and + making all Lisp_Objects Qnil allows for better GC'ing in case a + pointer to the dead device continues to hang around. Zero all + other structs in case someone tries to access something through + them. */ + nuke_all_device_slots (d, Qnil); d->devmeths = dead_console_methods; + UNGCPRO; } @@ -1362,5 +1351,5 @@ staticpro (&Vdevice_class_list); /* Death to devices.el !!! */ - Fprovide(intern("devices")); + Fprovide (intern ("devices")); }
--- a/src/device.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/device.h Mon Jun 18 07:10:32 2001 +0000 @@ -72,90 +72,6 @@ through device->console, but it's faster this way. */ struct console_methods *devmeths; - /* Name of this device, for resourcing and printing purposes. - If not explicitly given, it's initialized in a device-specific - manner. */ - Lisp_Object name; - - /* What this device is connected to */ - Lisp_Object connection; - - /* A canonical name for the connection that is used to determine - whether `make-device' is being called on an existing device. */ - Lisp_Object canon_connection; - - /* List of frames on this device. */ - Lisp_Object frame_list; - - /* The console this device is on. */ - Lisp_Object console; - - /* Frame which is "currently selected". This is what `selected-frame' - returns and is the default frame for many operations. This may - not be the same as frame_with_focus; `select-frame' changes the - selected_frame but not the frame_with_focus. However, eventually - either the two values will be the same, or frame_with_focus will - be nil: right before waiting for an event, the focus is changed - to point to the selected_frame if XEmacs currently has the focus - on this device. Note that frame_with_focus may be nil (none of the - frames on this device have the window-system focus), but - selected_frame will never be nil if there are any frames on - the device. */ - Lisp_Object selected_frame; - /* Frame that currently contains the window-manager focus, or none. - Note that we've split frame_with_focus into two variables. - frame_with_focus_real is the value we use most of the time, - but frame_with_focus_for_hooks is used for running the select-frame-hook - and deselect-frame-hook. We do this because we split the focus handling - into two parts: one part (deals with drawing the solid/box cursor) - runs as soon as a focus event is received; the other (running the - hooks) runs after any pending sit-for/sleep-for/accept-process-output - calls are done. */ - Lisp_Object frame_with_focus_real; - Lisp_Object frame_with_focus_for_hooks; - /* If we have recently issued a request to change the focus as a - result of select-frame having been called, the following variable - records the frame we are trying to focus on. The reason for this - is that the window manager may not grant our request to change - the focus (so we can't just change frame_with_focus), and we don't - want to keep sending requests again and again to the window manager. - This variable is reset whenever a focus-change event is seen. */ - Lisp_Object frame_that_ought_to_have_focus; - - /* Color class of this device. */ - Lisp_Object device_class; - - /* Alist of values for user-defined tags in this device. */ - Lisp_Object user_defined_tags; - - /* Hash tables for device-specific objects (fonts, colors, etc). - These are key-weak hash tables (or hash tables containing key-weak - hash tables) so that they disappear when the key goes away. */ - - /* This is a simple key-weak hash table hashing color names to - instances. */ - Lisp_Object color_instance_cache; - - /* This is a simple key-weak hash table hashing font names to - instances. */ - Lisp_Object font_instance_cache; - -#ifdef MULE - /* This is a bi-level cache, where the hash table in this slot here - indexes charset objects to key-weak hash tables, which in turn - index font names to more specific font names that match the - given charset's registry. This speeds up the horrendously - slow XListFonts() operation that needs to be done in order - to determine an appropriate font. */ - Lisp_Object charset_font_cache; -#endif - - /* This is a bi-level cache, where the hash table in this slot here - indexes image-instance-type masks (there are currently 6 - image-instance types and thus 64 possible masks) to key-weak hash - tables like the one for colors. */ - Lisp_Object image_instance_cache; - /* A structure of auxiliary data specific to the device type. struct x_device is used for X window frames; defined in console-x.h struct tty_device is used to TTY's; defined in console-tty.h */ @@ -196,6 +112,8 @@ unsigned int on_console_p :1; unsigned int connected_to_nas_p :1; +#define MARKED_SLOT(x) Lisp_Object x +#include "devslots.h" /* File descriptors for input and output. Much of the time (but not always) these will be the same. For an X device, @@ -221,7 +139,7 @@ DECLARE_LRECORD (device, struct device); #define XDEVICE(x) XRECORD (x, device, struct device) #define XSETDEVICE(x, p) XSETRECORD (x, p, device) -#define wrap_device(p) wrap_object (p) +#define wrap_device(p) wrap_record (p, device) #define DEVICEP(x) RECORDP (x, device) #define CHECK_DEVICE(x) CHECK_RECORD (x, device) #define CONCHECK_DEVICE(x) CONCHECK_RECORD (x, device)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/devslots.h Mon Jun 18 07:10:32 2001 +0000 @@ -0,0 +1,116 @@ +/* Definitions of marked slots in consoles + Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc. + +This file is part of XEmacs. + +XEmacs is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +XEmacs is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with XEmacs; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Synched up with: Not in FSF. */ + +/* We define the Lisp_Objects in the device structure in a separate file + because there are numerous places we want to iterate over them, such + as when defining them in the structure, initializing them, or marking + them. + + To use, define MARKED_SLOT before including this file. In the structure + definition, you also need to define FRAME_SLOT_DECLARATION. No need to + undefine either value; that happens automatically. */ + + /* Name of this device, for resourcing and printing purposes. + If not explicitly given, it's initialized in a device-specific + manner. */ + MARKED_SLOT (name); + + /* What this device is connected to */ + MARKED_SLOT (connection); + + /* A canonical name for the connection that is used to determine + whether `make-device' is being called on an existing device. */ + MARKED_SLOT (canon_connection); + + /* List of frames on this device. */ + MARKED_SLOT (frame_list); + + /* The console this device is on. */ + MARKED_SLOT (console); + + /* Frame which is "currently selected". This is what `selected-frame' + returns and is the default frame for many operations. This may + not be the same as frame_with_focus; `select-frame' changes the + selected_frame but not the frame_with_focus. However, eventually + either the two values will be the same, or frame_with_focus will + be nil: right before waiting for an event, the focus is changed + to point to the selected_frame if XEmacs currently has the focus + on this device. Note that frame_with_focus may be nil (none of the + frames on this device have the window-system focus), but + selected_frame will never be nil if there are any frames on + the device. */ + MARKED_SLOT (selected_frame); + /* Frame that currently contains the window-manager focus, or none. + Note that we've split frame_with_focus into two variables. + frame_with_focus_real is the value we use most of the time, + but frame_with_focus_for_hooks is used for running the select-frame-hook + and deselect-frame-hook. We do this because we split the focus handling + into two parts: one part (deals with drawing the solid/box cursor) + runs as soon as a focus event is received; the other (running the + hooks) runs after any pending sit-for/sleep-for/accept-process-output + calls are done. */ + MARKED_SLOT (frame_with_focus_real); + MARKED_SLOT (frame_with_focus_for_hooks); + /* If we have recently issued a request to change the focus as a + result of select-frame having been called, the following variable + records the frame we are trying to focus on. The reason for this + is that the window manager may not grant our request to change + the focus (so we can't just change frame_with_focus), and we don't + want to keep sending requests again and again to the window manager. + This variable is reset whenever a focus-change event is seen. */ + MARKED_SLOT (frame_that_ought_to_have_focus); + + /* Color class of this device. */ + MARKED_SLOT (device_class); + + /* Alist of values for user-defined tags in this device. */ + MARKED_SLOT (user_defined_tags); + + /* Hash tables for device-specific objects (fonts, colors, etc). + These are key-weak hash tables (or hash tables containing key-weak + hash tables) so that they disappear when the key goes away. */ + + /* This is a simple key-weak hash table hashing color names to + instances. */ + MARKED_SLOT (color_instance_cache); + + /* This is a simple key-weak hash table hashing font names to + instances. */ + MARKED_SLOT (font_instance_cache); + +#ifdef MULE + /* This is a bi-level cache, where the hash table in this slot here + indexes charset objects to key-weak hash tables, which in turn + index font names to more specific font names that match the + given charset's registry. This speeds up the horrendously + slow XListFonts() operation that needs to be done in order + to determine an appropriate font. */ + MARKED_SLOT (charset_font_cache); +#endif + + /* This is a bi-level cache, where the hash table in this slot here + indexes image-instance-type masks (there are currently 6 + image-instance types and thus 64 possible masks) to key-weak hash + tables like the one for colors. */ + MARKED_SLOT (image_instance_cache); + +#undef MARKED_SLOT
--- a/src/dialog-msw.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/dialog-msw.c Mon Jun 18 07:10:32 2001 +0000 @@ -175,7 +175,8 @@ } DEFINE_LRECORD_IMPLEMENTATION ("mswindows-dialog-id", mswindows_dialog_id, - mark_mswindows_dialog_id, 0, 0, 0, 0, 0, + mark_mswindows_dialog_id, + internal_object_printer, 0, 0, 0, 0, struct mswindows_dialog_id); /* Dialog procedure */
--- a/src/dumper.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/dumper.c Mon Jun 18 07:10:32 2001 +0000 @@ -934,7 +934,9 @@ obj.value = * obj.address; if (POINTER_TYPE_P (XTYPE (obj.value))) - obj.value = wrap_object ((void *) pdump_get_entry (XRECORD_LHEADER (obj.value))->save_offset); + obj.value = wrap_record_1 ((void *) + pdump_get_entry (XRECORD_LHEADER + (obj.value))->save_offset); PDUMP_WRITE (pdump_static_Lisp_Object, obj); } @@ -960,7 +962,7 @@ obj.value = *(Lisp_Object *)(desc[pos].offset + (char *)(XRECORD_LHEADER (obj.value))); } - obj.value = wrap_object ((void *) elt->save_offset); + obj.value = wrap_record_1 ((void *) elt->save_offset); PDUMP_WRITE (pdump_static_Lisp_Object, obj); } @@ -1147,7 +1149,7 @@ pdump_static_Lisp_Object obj = PDUMP_READ (p, pdump_static_Lisp_Object); if (POINTER_TYPE_P (XTYPE (obj.value))) - obj.value = wrap_object ((char *) XPNTR (obj.value) + delta); + obj.value = wrap_record_1 ((char *) XPNTR (obj.value) + delta); (* obj.address) = obj.value; }
--- a/src/eldap.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/eldap.h Mon Jun 18 07:10:32 2001 +0000 @@ -44,6 +44,7 @@ DECLARE_LRECORD (ldap, Lisp_LDAP); #define XLDAP(x) XRECORD (x, ldap, Lisp_LDAP) #define XSETLDAP(x, p) XSETRECORD (x, p, ldap) +#define wrap_ldap(p) wrap_record (p, ldap) #define LDAPP(x) RECORDP (x, ldap) #define CHECK_LDAP(x) CHECK_RECORD (x, ldap) #define CONCHECK_LDAP(x) CONCHECK_RECORD (x, ldap)
--- a/src/elhash.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/elhash.c Mon Jun 18 07:10:32 2001 +0000 @@ -1092,6 +1092,7 @@ DEFUN ("remhash", Fremhash, 2, 2, 0, /* Remove the entry for KEY from HASH-TABLE. Do nothing if there is no entry for KEY in HASH-TABLE. +Return non-nil if an entry was removed. */ (key, hash_table)) {
--- a/src/elhash.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/elhash.h Mon Jun 18 07:10:32 2001 +0000 @@ -29,6 +29,7 @@ #define XHASH_TABLE(x) XRECORD (x, hash_table, Lisp_Hash_Table) #define XSETHASH_TABLE(x, p) XSETRECORD (x, p, hash_table) +#define wrap_hash_table(p) wrap_record (p, hash_table) #define HASH_TABLEP(x) RECORDP (x, hash_table) #define CHECK_HASH_TABLE(x) CHECK_RECORD (x, hash_table) #define CONCHECK_HASH_TABLE(x) CONCHECK_RECORD (x, hash_table)
--- a/src/emacs.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/emacs.c Mon Jun 18 07:10:32 2001 +0000 @@ -2016,9 +2016,13 @@ complex_vars_of_menubar (); #endif +#ifdef HAVE_SCROLLBARS /* This calls Fmake_glyph_internal(). */ -#ifdef HAVE_SCROLLBARS complex_vars_of_scrollbar (); +#ifdef HAVE_MS_WINDOWS + /* Calls make_lisp_hash_table(). */ + complex_vars_of_scrollbar_mswindows (); +#endif #endif /* This calls allocate_glyph(). */ @@ -2181,7 +2185,7 @@ #endif #endif /* HAVE_X_WINDOWS */ -#if defined(MULE) && defined(HAVE_WNN) +#if defined (MULE) && defined (HAVE_WNN) reinit_vars_of_mule_wnn (); #endif
--- a/src/eval.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/eval.c Mon Jun 18 07:10:32 2001 +0000 @@ -1343,10 +1343,7 @@ static void unwind_to_catch (struct catchtag *c, Lisp_Object val) { -#if 0 /* FSFmacs */ - /* #### */ REGISTER int last_time; -#endif /* Unwind the specbind, catch, and handler stacks back to CATCH Before each catch is discarded, unbind all special bindings @@ -1365,8 +1362,7 @@ set_poll_suppress_count (catch->poll_suppress_count); #endif -#if 0 /* FSFmacs */ - /* #### FSFmacs has the following loop. Is it more correct? */ +#if 1 do { last_time = catchlist == c; @@ -1374,21 +1370,40 @@ /* Unwind the specpdl stack, and then restore the proper set of handlers. */ unbind_to (catchlist->pdlcount, Qnil); - handlerlist = catchlist->handlerlist; catchlist = catchlist->next; #ifdef ERROR_CHECK_TYPECHECK check_error_state_sanity (); #endif } while (! last_time); -#else /* Actual XEmacs code */ +#else + /* Former XEmacs code. This is definitely not as correct because + there may be a number of catches we're unwinding, and a number + of unwind-protects in the process. By not undoing the catches till + the end, there may be invalid catches still current. (This would + be a particular problem with code like this: + + (catch 'foo + (call-some-code-which-does... + (catch 'bar + (unwind-protect + (call-some-code-which-does... + (catch 'bar + (call-some-code-which-does... + (throw 'foo nil)))) + (throw 'bar nil))))) + + This would try to throw to the inner (catch 'bar)! + + --ben + */ /* Unwind the specpdl stack */ unbind_to (c->pdlcount, Qnil); catchlist = c->next; #ifdef ERROR_CHECK_TYPECHECK check_error_state_sanity (); #endif -#endif +#endif /* Former code */ gcprolist = c->gcpro; backtrace_list = c->backlist; @@ -1504,6 +1519,9 @@ static Lisp_Object condition_bind_unwind (Lisp_Object loser) { + /* There is no problem freeing stuff here like there is in + condition_case_unwind(), because there are no outside pointers + (like the tag below in the catchlist) pointing to the objects. */ Lisp_Cons *victim; /* ((handler-fun . handler-args) ... other handlers) */ Lisp_Object tem = XCAR (loser); @@ -1526,17 +1544,32 @@ static Lisp_Object condition_case_unwind (Lisp_Object loser) { - Lisp_Cons *victim; - /* ((<unbound> . clauses) ... other handlers */ - victim = XCONS (XCAR (loser)); - free_cons (victim); - - victim = XCONS (loser); + /* NO! Doing this now leaves the tag deleted in a still-active + catch. With the recent changes to unwind_to_catch(), the + evil situation might not happen any more; it certainly could + happen before because it did. But it's very precarious to rely + on something like this. #### Instead we should rewrite, adopting + the FSF's mechanism with a struct handler instead of + Vcondition_handlers; then we have NO Lisp-object structures used + to hold all of the values, and there's no possibility either of + crashes from freeing objects too quickly, or objects not getting + freed and hanging around till the next GC. + + In practice, the extra consing here should not matter because + it only happens when we throw past the condition-case, which almost + always is the result of an error. Most of the time, there will be + no error, and we will free the objects below in the main function. + + --ben + + DO NOT DO: free_cons (XCAR (loser)); + */ + if (EQ (loser, Vcondition_handlers)) /* may have been rebound to some tail */ - Vcondition_handlers = victim->cdr; - - free_cons (victim); + Vcondition_handlers = XCDR (loser); + + /* DO NOT DO: free_cons (loser); */ return Qnil; } @@ -1599,7 +1632,7 @@ { int speccount = specpdl_depth(); struct catchtag c; - struct gcpro gcpro1; + struct gcpro gcpro1, gcpro2, gcpro3; #if 0 /* FSFmacs */ c.tag = Qnil; @@ -1607,9 +1640,18 @@ /* Do consing now so out-of-memory error happens up front */ /* (unbound . stuff) is a special condition-case kludge marker which is known specially by Fsignal. - This is an abomination, but to fix it would require either + [[ This is an abomination, but to fix it would require either making condition_case cons (a union of the conditions of the clauses) - or changing the byte-compiler output (no thanks). */ + or changing the byte-compiler output (no thanks).]] + + The above comment is clearly wrong. FSF does not do it this way + and did not change the byte-compiler output. Instead they use a + `struct handler' to hold the various values (in place of our + Vcondition_handlers) and chain them together, with pointers from + the `struct catchtag' to the `struct handler'. We should perhaps + consider moving to something similar, but not before I merge my + stderr-proc workspace, which contains changes to these + functions. --ben */ c.tag = noseeum_cons (noseeum_cons (Qunbound, handlers), Vcondition_handlers); #endif @@ -1647,22 +1689,27 @@ Vcondition_handlers = c.tag; #endif GCPRO1 (harg); /* Somebody has to gc-protect */ - c.val = ((*bfun) (barg)); - - /* The following is *not* true: (ben) - - ungcpro, restoring catchlist and condition_handlers are actually - redundant since unbind_to now restores them. But it looks funny not to - have this code here, and it doesn't cost anything, so I'm leaving it.*/ UNGCPRO; + + /* Once we change `catchlist' below, the stuff in c will not be GCPRO'd. */ + GCPRO3 (harg, c.val, c.tag); + catchlist = c.next; #ifdef ERROR_CHECK_TYPECHECK check_error_state_sanity (); #endif + /* Note: The unbind also resets Vcondition_handlers. Maybe we should + delete this here. */ Vcondition_handlers = XCDR (c.tag); - - return unbind_to (speccount, c.val); + unbind_to (speccount, Qnil); + + UNGCPRO; + /* free the conses *after* the unbind, because the unbind will run + condition_case_unwind above. */ + free_cons (XCONS (XCAR (c.tag))); + free_cons (XCONS (c.tag)); + return c.val; } static Lisp_Object @@ -3603,7 +3650,7 @@ } DEFUN ("function-min-args", Ffunction_min_args, 1, 1, 0, /* -Return the number of arguments a function may be called with. +Return the minimum number of arguments a function may be called with. The function may be any form that can be passed to `funcall', any special form, or any macro. */ @@ -3613,7 +3660,7 @@ } DEFUN ("function-max-args", Ffunction_max_args, 1, 1, 0, /* -Return the number of arguments a function may be called with. +Return the maximum number of arguments a function may be called with. The function may be any form that can be passed to `funcall', any special form, or any macro. If the function takes an arbitrary number of arguments or is
--- a/src/events.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/events.h Mon Jun 18 07:10:32 2001 +0000 @@ -462,6 +462,7 @@ DECLARE_LRECORD (timeout, Lisp_Timeout); #define XTIMEOUT(x) XRECORD (x, timeout, Lisp_Timeout) #define XSETTIMEOUT(x, p) XSETRECORD (x, p, timeout) +#define wrap_timeout(p) wrap_record (p, timeout) #define TIMEOUTP(x) RECORDP (x, timeout) #define CHECK_TIMEOUT(x) CHECK_RECORD (x, timeout) #define CONCHECK_TIMEOUT(x) CONCHECK_RECORD (x, timeout) @@ -496,6 +497,7 @@ DECLARE_LRECORD (event, Lisp_Event); #define XEVENT(x) XRECORD (x, event, Lisp_Event) #define XSETEVENT(x, p) XSETRECORD (x, p, event) +#define wrap_event(p) wrap_record (p, event) #define EVENTP(x) RECORDP (x, event) #define CHECK_EVENT(x) CHECK_RECORD (x, event) #define CONCHECK_EVENT(x) CONCHECK_RECORD (x, event)
--- a/src/extents.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/extents.h Mon Jun 18 07:10:32 2001 +0000 @@ -26,6 +26,7 @@ DECLARE_LRECORD (extent, struct extent); #define XEXTENT(x) XRECORD (x, extent, struct extent) #define XSETEXTENT(x, p) XSETRECORD (x, p, extent) +#define wrap_extent(p) wrap_record (p, extent) #define EXTENTP(x) RECORDP (x, extent) #define CHECK_EXTENT(x) CHECK_RECORD (x, extent) #define CONCHECK_EXTENT(x) CONCHECK_RECORD (x, extent) @@ -145,6 +146,7 @@ #define XEXTENT_AUXILIARY(x) \ XRECORD (x, extent_auxiliary, struct extent_auxiliary) #define XSETEXTENT_AUXILIARY(x, p) XSETRECORD (x, p, extent_auxiliary) +#define wrap_extent_auxiliary(p) wrap_record (p, extent_auxiliary) #define EXTENT_AUXILIARYP(x) RECORDP (x, extent_auxiliary) #define CHECK_EXTENT_AUXILIARY(x) CHECK_RECORD (x, extent_auxiliary) #define CONCHECK_EXTENT_AUXILIARY(x) CONCHECK_RECORD (x, extent_auxiliary) @@ -160,6 +162,7 @@ DECLARE_LRECORD (extent_info, struct extent_info); #define XEXTENT_INFO(x) XRECORD (x, extent_info, struct extent_info) #define XSETEXTENT_INFO(x, p) XSETRECORD (x, p, extent_info) +#define wrap_extent_info(p) wrap_record (p, extent_info) #define EXTENT_INFOP(x) RECORDP (x, extent_info) #define CHECK_EXTENT_INFO(x) CHECK_RECORD (x, extent_info) #define CONCHECK_EXTENT_INFO(x) CONCHECK_RECORD (x, extent_info)
--- a/src/faces.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/faces.h Mon Jun 18 07:10:32 2001 +0000 @@ -225,6 +225,7 @@ DECLARE_LRECORD (face, Lisp_Face); #define XFACE(x) XRECORD (x, face, Lisp_Face) #define XSETFACE(x, p) XSETRECORD (x, p, face) +#define wrap_face(p) wrap_record (p, face) #define FACEP(x) RECORDP (x, face) #define CHECK_FACE(x) CHECK_RECORD (x, face)
--- a/src/file-coding.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/file-coding.h Mon Jun 18 07:10:32 2001 +0000 @@ -144,6 +144,7 @@ DECLARE_LRECORD (coding_system, Lisp_Coding_System); #define XCODING_SYSTEM(x) XRECORD (x, coding_system, Lisp_Coding_System) #define XSETCODING_SYSTEM(x, p) XSETRECORD (x, p, coding_system) +#define wrap_coding_system(p) wrap_record (p, coding_system) #define CODING_SYSTEMP(x) RECORDP (x, coding_system) #define CHECK_CODING_SYSTEM(x) CHECK_RECORD (x, coding_system) #define CONCHECK_CODING_SYSTEM(x) CONCHECK_RECORD (x, coding_system)
--- a/src/frame.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/frame.c Mon Jun 18 07:10:32 2001 +0000 @@ -133,6 +133,15 @@ if (FRAME_LIVE_P (f)) /* device is nil for a dead frame */ MAYBE_FRAMEMETH (f, mark_frame, (f)); +#ifdef HAVE_SCROLLBARS + if (f->sb_vcache) + mark_object (wrap_scrollbar_instance (f->sb_vcache)); + if (f->sb_hcache) + mark_object (wrap_scrollbar_instance (f->sb_hcache)); +#endif + + mark_gutters (f); + return Qnil; } @@ -161,6 +170,8 @@ static void nuke_all_frame_slots (struct frame *f) { + zero_lcrecord (f); + #define MARKED_SLOT(x) f->x = Qnil #include "frameslots.h" } @@ -177,7 +188,6 @@ Lisp_Object root_window; struct frame *f = alloc_lcrecord_type (struct frame, &lrecord_frame); - zero_lcrecord (f); nuke_all_frame_slots (f); XSETFRAME (frame, f); @@ -1570,10 +1580,9 @@ d->frame_list = delq_no_quit (frame, d->frame_list); RESET_CHANGED_SET_FLAGS; - f->dead = 1; f->visible = 0; - free_window_mirror (f->root_mirror); + free_window_mirror (XWINDOW_MIRROR (f->root_mirror)); /* free_line_insertion_deletion_costs (f); */ /* If we've deleted the last non-minibuf frame, then try to find @@ -1660,12 +1669,15 @@ con->default_minibuffer_frame = Qnil; } - nuke_all_frame_slots (f); /* nobody should be accessing the device - or anything else any more, and making - them Qnil allows for better GC'ing - in case a pointer to the dead frame - continues to hang around. */ + /* Nobody should be accessing anything in this object any more, and + making all Lisp_Objects Qnil allows for better GC'ing in case a + pointer to the dead frame continues to hang around. Zero all + other structs in case someone tries to access something through + them. */ + + nuke_all_frame_slots (f); f->framemeths = dead_console_methods; + UNGCPRO; }
--- a/src/frame.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/frame.h Mon Jun 18 07:10:32 2001 +0000 @@ -87,15 +87,10 @@ dependencies. */ int internal_border_width; - /* This frame's root window mirror. This structure exactly mirrors - the frame's window structure but contains only pointers to the - display structures. */ - struct window_mirror *root_mirror; - int modiff; - struct expose_ignore* subwindow_exposures; - struct expose_ignore* subwindow_exposures_tail; + struct expose_ignore *subwindow_exposures; + struct expose_ignore *subwindow_exposures_tail; #ifdef HAVE_SCROLLBARS /* frame-local scrollbar information. See scrollbar.c. */ @@ -151,9 +146,6 @@ /* Is frame marked for deletion? This is used in XSetErrorHandler(). */ unsigned int being_deleted :1; - /* Nonzero if this frame has been destroyed. */ - unsigned int dead :1; - /* Nonzero if last attempt at redisplay on this frame was preempted. */ unsigned int display_preempted :1; @@ -245,7 +237,7 @@ DECLARE_LRECORD (frame, struct frame); #define XFRAME(x) XRECORD (x, frame, struct frame) #define XSETFRAME(x, p) XSETRECORD (x, p, frame) -#define wrap_frame(p) wrap_object (p) +#define wrap_frame(p) wrap_record (p, frame) #define FRAMEP(x) RECORDP (x, frame) #define CHECK_FRAME(x) CHECK_RECORD (x, frame) #define CONCHECK_FRAME(x) CONCHECK_RECORD (x, frame) @@ -505,7 +497,7 @@ #define SET_FRAME_CLEAR(f) MARK_FRAME_CHANGED (f); (f)->clear = 1 #define FRAME_DEVICE(f) ((f)->device) #define FRAME_CONSOLE(f) DEVICE_CONSOLE (XDEVICE (FRAME_DEVICE (f))) -#define FRAME_LIVE_P(f) (!(f)->dead) +#define FRAME_LIVE_P(f) (!EQ (FRAME_TYPE (f), Qdead)) #define FRAME_MINIBUF_ONLY_P(f) \ EQ (FRAME_ROOT_WINDOW (f), FRAME_MINIBUF_WINDOW (f))
--- a/src/frameslots.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/frameslots.h Mon Jun 18 07:10:32 2001 +0000 @@ -21,6 +21,15 @@ /* Synched up with: FSF 19.30. Split out of frame.h. */ +/* We define the Lisp_Objects in the frame structure in a separate file + because there are numerous places we want to iterate over them, such + as when defining them in the structure, initializing them, or marking + them. + + To use, define MARKED_SLOT before including this file. In the structure + definition, you also need to define FRAME_SLOT_DECLARATION. No need to + undefine either value; that happens automatically. */ + #ifdef FRAME_SLOT_DECLARATION #define MARKED_SLOT_ARRAY(slot, size) MARKED_SLOT(slot[size]) #else @@ -81,6 +90,11 @@ frame. */ MARKED_SLOT (last_nonminibuf_window); + /* This frame's root window mirror. This structure exactly mirrors + the frame's window structure but contains only pointers to the + display structures. */ + MARKED_SLOT (root_mirror); + /* frame property list */ MARKED_SLOT (plist);
--- a/src/glyphs.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/glyphs.h Mon Jun 18 07:10:32 2001 +0000 @@ -429,6 +429,7 @@ DECLARE_LRECORD (image_instance, Lisp_Image_Instance); #define XIMAGE_INSTANCE(x) XRECORD (x, image_instance, Lisp_Image_Instance) #define XSETIMAGE_INSTANCE(x, p) XSETRECORD (x, p, image_instance) +#define wrap_image_instance(p) wrap_record (p, image_instance) #define IMAGE_INSTANCEP(x) RECORDP (x, image_instance) #define CHECK_IMAGE_INSTANCE(x) CHECK_RECORD (x, image_instance) #define CONCHECK_IMAGE_INSTANCE(x) CONCHECK_RECORD (x, image_instance) @@ -938,6 +939,7 @@ DECLARE_LRECORD (glyph, Lisp_Glyph); #define XGLYPH(x) XRECORD (x, glyph, Lisp_Glyph) #define XSETGLYPH(x, p) XSETRECORD (x, p, glyph) +#define wrap_glyph(p) wrap_record (p, glyph) #define GLYPHP(x) RECORDP (x, glyph) #define CHECK_GLYPH(x) CHECK_RECORD (x, glyph) #define CONCHECK_GLYPH(x) CONCHECK_RECORD (x, glyph)
--- a/src/gui-x.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/gui-x.h Mon Jun 18 07:10:32 2001 +0000 @@ -61,6 +61,7 @@ DECLARE_LRECORD (popup_data, struct popup_data); #define XPOPUP_DATA(x) XRECORD (x, popup_data, struct popup_data) #define XSETPOPUP_DATA(x, p) XSETRECORD (x, p, popup_data) +#define wrap_popup_data(p) wrap_record (p, popup_data) #define POPUP_DATAP(x) RECORDP (x, popup_data) #define CHECK_POPUP_DATA(x) CHECK_RECORD (x, popup_data)
--- a/src/gui.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/gui.h Mon Jun 18 07:10:32 2001 +0000 @@ -63,6 +63,7 @@ DECLARE_LRECORD (gui_item, Lisp_Gui_Item); #define XGUI_ITEM(x) XRECORD (x, gui_item, Lisp_Gui_Item) #define XSETGUI_ITEM(x, p) XSETRECORD (x, p, gui_item) +#define wrap_gui_item(p) wrap_record (p, gui_item) #define GUI_ITEMP(x) RECORDP (x, gui_item) #define CHECK_GUI_ITEM(x) CHECK_RECORD (x, gui_item) #define CONCHECK_GUI_ITEM(x) CONCHECK_RECORD (x, gui_item)
--- a/src/gutter.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/gutter.c Mon Jun 18 07:10:32 2001 +0000 @@ -521,22 +521,25 @@ redisplay_clear_region (window, findex, x, y, width, height); } -/* #### I don't currently believe that redisplay needs to mark the +/* [[#### I don't currently believe that redisplay needs to mark the glyphs in its structures since these will always be referenced from somewhere else. However, I'm not sure enough to stake my life on it - at this point, so we do the safe thing. */ + at this point, so we do the safe thing.]] + + ALWAYS mark everything. --ben */ /* See the comment in image_instantiate_cache_result as to why marking the glyph will also mark the image_instance. */ void -mark_gutters (struct frame* f) +mark_gutters (struct frame *f) { enum gutter_pos pos; GUTTER_POS_LOOP (pos) { if (f->current_display_lines[pos]) mark_redisplay_structs (f->current_display_lines[pos]); - /* #### Do we really need to mark the desired lines? */ + /* [[#### Do we really need to mark the desired lines?]] + ALWAYS mark everything. --ben */ if (f->desired_display_lines[pos]) mark_redisplay_structs (f->desired_display_lines[pos]); }
--- a/src/inline.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/inline.c Mon Jun 18 07:10:32 2001 +0000 @@ -77,6 +77,10 @@ #include "toolbar.h" #endif +#ifdef HAVE_SCROLLBARS +#include "scrollbar.h" +#endif + #ifdef HAVE_DATABASE #include "database.h" #endif
--- a/src/keymap.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/keymap.h Mon Jun 18 07:10:32 2001 +0000 @@ -29,6 +29,7 @@ DECLARE_LRECORD (keymap, Lisp_Keymap); #define XKEYMAP(x) XRECORD (x, keymap, Lisp_Keymap) #define XSETKEYMAP(x, p) XSETRECORD (x, p, keymap) +#define wrap_keymap(p) wrap_record (p, keymap) #define KEYMAPP(x) RECORDP (x, keymap) #define CHECK_KEYMAP(x) CHECK_RECORD (x, keymap) #define CONCHECK_KEYMAP(x) CONCHECK_RECORD (x, keymap)
--- a/src/lisp-disunion.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/lisp-disunion.h Mon Jun 18 07:10:32 2001 +0000 @@ -78,7 +78,7 @@ typedef EMACS_INT Lisp_Object; #define Lisp_Type_Int_Bit (Lisp_Type_Int_Even & Lisp_Type_Int_Odd) -#define wrap_object(ptr) ((Lisp_Object) (ptr)) +#define wrap_pointer_1(ptr) ((Lisp_Object) (ptr)) #define make_int(x) ((Lisp_Object) (((x) << INT_GCBITS) | Lisp_Type_Int_Bit)) #define make_char(x) ((Lisp_Object) (((x) << GCBITS) | Lisp_Type_Char)) #define VALMASK (((1UL << VALBITS) - 1UL) << GCTYPEBITS) @@ -98,7 +98,7 @@ #define EQ(x,y) ((x) == (y)) #define XSETINT(var, value) ((void) ((var) = make_int (value))) #define XSETCHAR(var, value) ((void) ((var) = make_char (value))) -#define XSETOBJ(var, value) ((void) ((var) = wrap_object (value))) +#define XSETOBJ(var, value) ((void) ((var) = wrap_pointer_1 (value))) /* Convert between a (void *) and a Lisp_Object, as when the Lisp_Object is passed to a toolkit callback function */
--- a/src/lisp-union.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/lisp-union.h Mon Jun 18 07:10:32 2001 +0000 @@ -118,9 +118,9 @@ return obj; } -INLINE_HEADER Lisp_Object wrap_object (void *ptr); +INLINE_HEADER Lisp_Object wrap_pointer_1 (void *ptr); INLINE_HEADER Lisp_Object -wrap_object (void *ptr) +wrap_pointer_1 (void *ptr) { Lisp_Object obj; XSETOBJ (obj, ptr);
--- a/src/lisp.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/lisp.h Mon Jun 18 07:10:32 2001 +0000 @@ -676,6 +676,7 @@ DECLARE_LRECORD (cons, Lisp_Cons); #define XCONS(x) XRECORD (x, cons, Lisp_Cons) #define XSETCONS(x, p) XSETRECORD (x, p, cons) +#define wrap_cons(p) wrap_record (p, cons) #define CONSP(x) RECORDP (x, cons) #define CHECK_CONS(x) CHECK_RECORD (x, cons) #define CONCHECK_CONS(x) CONCHECK_RECORD (x, cons) @@ -1163,6 +1164,7 @@ DECLARE_LRECORD (string, Lisp_String); #define XSTRING(x) XRECORD (x, string, Lisp_String) #define XSETSTRING(x, p) XSETRECORD (x, p, string) +#define wrap_string(p) wrap_record (p, string) #define STRINGP(x) RECORDP (x, string) #define CHECK_STRING(x) CHECK_RECORD (x, string) #define CONCHECK_STRING(x) CONCHECK_RECORD (x, string) @@ -1254,6 +1256,7 @@ DECLARE_LRECORD (vector, Lisp_Vector); #define XVECTOR(x) XRECORD (x, vector, Lisp_Vector) #define XSETVECTOR(x, p) XSETRECORD (x, p, vector) +#define wrap_vector(p) wrap_record (p, vector) #define VECTORP(x) RECORDP (x, vector) #define CHECK_VECTOR(x) CHECK_RECORD (x, vector) #define CONCHECK_VECTOR(x) CONCHECK_RECORD (x, vector) @@ -1292,6 +1295,7 @@ DECLARE_LRECORD (bit_vector, Lisp_Bit_Vector); #define XBIT_VECTOR(x) XRECORD (x, bit_vector, Lisp_Bit_Vector) #define XSETBIT_VECTOR(x, p) XSETRECORD (x, p, bit_vector) +#define wrap_bit_vector(p) wrap_record (p, bit_vector) #define BIT_VECTORP(x) RECORDP (x, bit_vector) #define CHECK_BIT_VECTOR(x) CHECK_RECORD (x, bit_vector) #define CONCHECK_BIT_VECTOR(x) CONCHECK_RECORD (x, bit_vector) @@ -1357,6 +1361,7 @@ DECLARE_LRECORD (symbol, Lisp_Symbol); #define XSYMBOL(x) XRECORD (x, symbol, Lisp_Symbol) #define XSETSYMBOL(x, p) XSETRECORD (x, p, symbol) +#define wrap_symbol(p) wrap_record (p, symbol) #define SYMBOLP(x) RECORDP (x, symbol) #define CHECK_SYMBOL(x) CHECK_RECORD (x, symbol) #define CONCHECK_SYMBOL(x) CONCHECK_RECORD (x, symbol) @@ -1386,6 +1391,7 @@ DECLARE_LRECORD (subr, Lisp_Subr); #define XSUBR(x) XRECORD (x, subr, Lisp_Subr) #define XSETSUBR(x, p) XSETRECORD (x, p, subr) +#define wrap_subr(p) wrap_record (p, subr) #define SUBRP(x) RECORDP (x, subr) #define CHECK_SUBR(x) CHECK_RECORD (x, subr) #define CONCHECK_SUBR(x) CONCHECK_RECORD (x, subr) @@ -1412,6 +1418,7 @@ DECLARE_LRECORD (marker, Lisp_Marker); #define XMARKER(x) XRECORD (x, marker, Lisp_Marker) #define XSETMARKER(x, p) XSETRECORD (x, p, marker) +#define wrap_marker(p) wrap_record (p, marker) #define MARKERP(x) RECORDP (x, marker) #define CHECK_MARKER(x) CHECK_RECORD (x, marker) #define CONCHECK_MARKER(x) CONCHECK_RECORD (x, marker) @@ -1465,6 +1472,7 @@ DECLARE_LRECORD (float, Lisp_Float); #define XFLOAT(x) XRECORD (x, float, Lisp_Float) #define XSETFLOAT(x, p) XSETRECORD (x, p, float) +#define wrap_float(p) wrap_record (p, float) #define FLOATP(x) RECORDP (x, float) #define CHECK_FLOAT(x) CHECK_RECORD (x, float) #define CONCHECK_FLOAT(x) CONCHECK_RECORD (x, float) @@ -1664,6 +1672,7 @@ DECLARE_LRECORD (weak_list, struct weak_list); #define XWEAK_LIST(x) XRECORD (x, weak_list, struct weak_list) #define XSETWEAK_LIST(x, p) XSETRECORD (x, p, weak_list) +#define wrap_weak_list(p) wrap_record (p, weak_list) #define WEAK_LISTP(x) RECORDP (x, weak_list) #define CHECK_WEAK_LIST(x) CHECK_RECORD (x, weak_list) #define CONCHECK_WEAK_LIST(x) CONCHECK_RECORD (x, weak_list) @@ -1689,6 +1698,7 @@ DECLARE_LRECORD (lcrecord_list, struct lcrecord_list); #define XLCRECORD_LIST(x) XRECORD (x, lcrecord_list, struct lcrecord_list) #define XSETLCRECORD_LIST(x, p) XSETRECORD (x, p, lcrecord_list) +#define wrap_lcrecord_list(p) wrap_record (p, lcrecord_list) #define LCRECORD_LISTP(x) RECORDP (x, lcrecord_list) /* #define CHECK_LCRECORD_LIST(x) CHECK_RECORD (x, lcrecord_list) Lcrecord lists should never escape to the Lisp level, so
--- a/src/lrecord.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/lrecord.h Mon Jun 18 07:10:32 2001 +0000 @@ -171,10 +171,12 @@ lrecord_type_device, lrecord_type_frame, lrecord_type_window, + lrecord_type_window_mirror, lrecord_type_window_configuration, lrecord_type_gui_item, lrecord_type_popup_data, lrecord_type_toolbar_button, + lrecord_type_scrollbar_instance, lrecord_type_color_instance, lrecord_type_font_instance, lrecord_type_image_instance, @@ -268,7 +270,7 @@ unsigned int basic_p :1; }; -/* All the built-in lisp object types are enumerated in `enum record_type'. +/* All the built-in lisp object types are enumerated in `enum lrecord_type'. Additional ones may be defined by a module (none yet). We leave some room in `lrecord_implementations_table' for such new lisp object types. */ #define MODULE_DEFINABLE_TYPE_COUNT 32 @@ -512,8 +514,8 @@ struct lcrecord_header header; - 2. Put a DECLARE_LRECORD() for the object below the struct definition, - along with the standard XFOO/XSETFOO junk. + 2. Put the "standard junk" (DECLARE_RECORD()/XFOO/XSETFOO/etc.) below the + struct definition -- see below. 3. Add this header file to inline.c. @@ -566,9 +568,12 @@ int border_width; }; +[[ the standard junk: ]] + DECLARE_LRECORD (toolbar_button, struct toolbar_button); #define XTOOLBAR_BUTTON(x) XRECORD (x, toolbar_button, struct toolbar_button) #define XSETTOOLBAR_BUTTON(x, p) XSETRECORD (x, p, toolbar_button) +#define wrap_toolbar_button(p) wrap_record (p, toolbar_button) #define TOOLBAR_BUTTONP(x) RECORDP (x, toolbar_button) #define CHECK_TOOLBAR_BUTTON(x) CHECK_RECORD (x, toolbar_button) #define CONCHECK_TOOLBAR_BUTTON(x) CONCHECK_RECORD (x, toolbar_button) @@ -596,9 +601,12 @@ return data->help_string; } +[[ If your object should never escape to Lisp, declare its print method + as internal_object_printer instead of 0. ]] + DEFINE_LRECORD_IMPLEMENTATION ("toolbar-button", toolbar_button, - mark_toolbar_button, 0, 0, 0, 0, 0, - struct toolbar_button); + mark_toolbar_button, 0, + 0, 0, 0, 0, struct toolbar_button); ... @@ -684,6 +692,18 @@ assert (RECORD_TYPEP (var, lrecord_type_##c_name)); \ } while (0) +INLINE_HEADER Lisp_Object wrap_record_1 (void *ptr, enum lrecord_type ty); +INLINE_HEADER Lisp_Object +wrap_record_1 (void *ptr, enum lrecord_type ty) +{ + Lisp_Object obj; + XSETOBJ (obj, ptr); + assert (RECORD_TYPEP (obj, ty)); + return obj; +} + +#define wrap_record(ptr, ty) wrap_record_1 (ptr, lrecord_type_##ty) + #else /* not ERROR_CHECK_TYPECHECK */ # define DECLARE_LRECORD(c_name, structtype) \ @@ -699,6 +719,9 @@ # define XNONRECORD(x, c_name, type_enum, structtype) \ ((structtype *) XPNTR (x)) # define XSETRECORD(var, p, c_name) XSETOBJ (var, p) +/* wrap_pointer_1 is so named as a suggestion not to use it unless you + know what you're doing. */ +#define wrap_record(ptr, ty) wrap_pointer_1 (ptr) #endif /* not ERROR_CHECK_TYPECHECK */
--- a/src/lstream.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/lstream.h Mon Jun 18 07:10:32 2001 +0000 @@ -33,7 +33,7 @@ DECLARE_LRECORD (lstream, struct lstream); #define XLSTREAM(x) XRECORD (x, lstream, struct lstream) #define XSETLSTREAM(x, p) XSETRECORD (x, p, lstream) -#define wrap_lstream(p) wrap_object (p) +#define wrap_lstream(p) wrap_record (p, lstream) #define LSTREAMP(x) RECORDP (x, lstream) /* #define CHECK_LSTREAM(x) CHECK_RECORD (x, lstream) Lstream pointers should never escape to the Lisp level, so
--- a/src/mule-charset.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/mule-charset.h Mon Jun 18 07:10:32 2001 +0000 @@ -496,6 +496,7 @@ DECLARE_LRECORD (charset, Lisp_Charset); #define XCHARSET(x) XRECORD (x, charset, Lisp_Charset) #define XSETCHARSET(x, p) XSETRECORD (x, p, charset) +#define wrap_charset(p) wrap_record (p, charset) #define CHARSETP(x) RECORDP (x, charset) #define CHECK_CHARSET(x) CHECK_RECORD (x, charset) #define CONCHECK_CHARSET(x) CONCHECK_RECORD (x, charset)
--- a/src/objects.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/objects.h Mon Jun 18 07:10:32 2001 +0000 @@ -128,6 +128,7 @@ DECLARE_LRECORD (color_instance, Lisp_Color_Instance); #define XCOLOR_INSTANCE(x) XRECORD (x, color_instance, Lisp_Color_Instance) #define XSETCOLOR_INSTANCE(x, p) XSETRECORD (x, p, color_instance) +#define wrap_color_instance(p) wrap_record (p, color_instance) #define COLOR_INSTANCEP(x) RECORDP (x, color_instance) #define CHECK_COLOR_INSTANCE(x) CHECK_RECORD (x, color_instance) #define CONCHECK_COLOR_INSTANCE(x) CONCHECK_RECORD (x, color_instance) @@ -142,6 +143,7 @@ DECLARE_LRECORD (font_instance, Lisp_Font_Instance); #define XFONT_INSTANCE(x) XRECORD (x, font_instance, Lisp_Font_Instance) #define XSETFONT_INSTANCE(x, p) XSETRECORD (x, p, font_instance) +#define wrap_font_instance(p) wrap_record (p, font_instance) #define FONT_INSTANCEP(x) RECORDP (x, font_instance) #define CHECK_FONT_INSTANCE(x) CHECK_RECORD (x, font_instance) #define CONCHECK_FONT_INSTANCE(x) CONCHECK_RECORD (x, font_instance)
--- a/src/opaque.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/opaque.h Mon Jun 18 07:10:32 2001 +0000 @@ -36,6 +36,7 @@ DECLARE_LRECORD (opaque, Lisp_Opaque); #define XOPAQUE(x) XRECORD (x, opaque, Lisp_Opaque) #define XSETOPAQUE(x, p) XSETRECORD (x, p, opaque) +#define wrap_opaque(p) wrap_record (p, opaque) #define OPAQUEP(x) RECORDP (x, opaque) /* #define CHECK_OPAQUE(x) CHECK_RECORD (x, opaque) Opaque pointers should never escape to the Lisp level, so @@ -63,6 +64,7 @@ DECLARE_LRECORD (opaque_ptr, Lisp_Opaque_Ptr); #define XOPAQUE_PTR(x) XRECORD (x, opaque_ptr, Lisp_Opaque_Ptr) #define XSETOPAQUE_PTR(x, p) XSETRECORD (x, p, opaque_ptr) +#define wrap_opaque_ptr(p) wrap_record (p, opaque_ptr) #define OPAQUE_PTRP(x) RECORDP (x, opaque_ptr) Lisp_Object make_opaque_ptr (void *val);
--- a/src/postgresql.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/postgresql.h Mon Jun 18 07:10:32 2001 +0000 @@ -35,6 +35,7 @@ #define XPGCONN(x) XRECORD (x, pgconn, Lisp_PGconn) #define XSETPGCONN(x, p) XSETRECORD (x, p, pgconn) +#define wrap_pgconn(p) wrap_record (p, pgconn) #define PGCONNP(x) RECORDP (x, pgconn) #define CHECK_PGCONN(x) CHECK_RECORD (x, pgconn) #define CONCHECK_PGCONN(x) CONCHECK_RECORD (x, pgconn) @@ -55,6 +56,7 @@ #define XPGRESULT(x) XRECORD (x, pgresult, Lisp_PGresult) #define XSETPGRESULT(x, p) XSETRECORD (x, p, pgresult) +#define wrap_pgresult(p) wrap_record (p, pgresult) #define PGRESULTP(x) RECORDP (x, pgresult) #define CHECK_PGRESULT(x) CHECK_RECORD (x, pgresult) #define CONCHECK_PGRESULT(x) CONCHECK_RECORD (x, pgresult)
--- a/src/process.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/process.h Mon Jun 18 07:10:32 2001 +0000 @@ -43,6 +43,7 @@ DECLARE_LRECORD (process, Lisp_Process); #define XPROCESS(x) XRECORD (x, process, Lisp_Process) #define XSETPROCESS(x, p) XSETRECORD (x, p, process) +#define wrap_process(p) wrap_record (p, process) #define PROCESSP(x) RECORDP (x, process) #define CHECK_PROCESS(x) CHECK_RECORD (x, process) #define PROCESS_LIVE_P(x) (!NILP ((x)->pipe_instream))
--- a/src/rangetab.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/rangetab.h Mon Jun 18 07:10:32 2001 +0000 @@ -49,6 +49,7 @@ DECLARE_LRECORD (range_table, Lisp_Range_Table); #define XRANGE_TABLE(x) XRECORD (x, range_table, Lisp_Range_Table) #define XSETRANGE_TABLE(x, p) XSETRECORD (x, p, range_table) +#define wrap_range_table(p) wrap_record (p, range_table) #define RANGE_TABLEP(x) RECORDP (x, range_table) #define CHECK_RANGE_TABLE(x) CHECK_RECORD (x, range_table)
--- a/src/redisplay.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/redisplay.c Mon Jun 18 07:10:32 2001 +0000 @@ -7079,38 +7079,6 @@ } } -static void -mark_window_mirror (struct window_mirror *mir) -{ - mark_redisplay_structs (mir->current_display_lines); - mark_redisplay_structs (mir->desired_display_lines); - - if (mir->next) - mark_window_mirror (mir->next); - - if (mir->hchild) - mark_window_mirror (mir->hchild); - else if (mir->vchild) - mark_window_mirror (mir->vchild); -} - -void -mark_redisplay (void) -{ - Lisp_Object frmcons, devcons, concons; - - FRAME_LOOP_NO_BREAK (frmcons, devcons, concons) - { - struct frame *f = XFRAME (XCAR (frmcons)); - /* #### urk! this does tons o' crap, such as creating lots of - structs, doing window system actions, etc. we DO NOT want to - be doing this -- marking should never change any state. - i think we can just delete this. --ben */ - update_frame_window_mirror (f); - mark_window_mirror (f->root_mirror); - mark_gutters (f); - } -} /***************************************************************************** Line Start Cache Description and Rationale
--- a/src/redisplay.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/redisplay.h Mon Jun 18 07:10:32 2001 +0000 @@ -252,7 +252,7 @@ } glyph_block_dynarr; /*************************************************************************/ -/* display lines */ +/* display lines */ /*************************************************************************/ /* Modeline commentary: IMO the modeline is handled very badly, we @@ -723,7 +723,6 @@ Lisp_Object *obj1, Lisp_Object *obj2); void glyph_to_pixel_translation (struct window *w, int char_x, int char_y, int *pix_x, int *pix_y); -void mark_redisplay (void); int point_in_line_start_cache (struct window *w, Bufpos point, int min_past); int point_would_be_visible (struct window *w, Bufpos startp, @@ -753,22 +752,30 @@ int *next_start); void redisplay_output_layout (Lisp_Object domain, Lisp_Object image_instance, - struct display_box* db, struct display_glyph_area* dga, - face_index findex, int cursor_start, int cursor_width, + struct display_box* db, + struct display_glyph_area* dga, + face_index findex, int cursor_start, + int cursor_width, int cursor_height); void redisplay_output_subwindow (struct window *w, Lisp_Object image_instance, - struct display_box* db, struct display_glyph_area* dga, - face_index findex, int cursor_start, int cursor_width, + struct display_box* db, + struct display_glyph_area* dga, + face_index findex, int cursor_start, + int cursor_width, int cursor_height); -void redisplay_unmap_subwindows_maybe (struct frame* f, int x, int y, int width, int height); +void redisplay_unmap_subwindows_maybe (struct frame* f, int x, int y, + int width, int height); void redisplay_output_pixmap (struct window *w, Lisp_Object image_instance, - struct display_box* db, struct display_glyph_area* dga, - face_index findex, int cursor_start, int cursor_width, + struct display_box* db, + struct display_glyph_area* dga, + face_index findex, int cursor_start, + int cursor_width, int cursor_height, int offset_bitmap); int redisplay_calculate_display_boxes (struct display_line *dl, int xpos, - int xoffset, int start_pixpos, int width, + int xoffset, int start_pixpos, + int width, struct display_box* dest, struct display_glyph_area* src); int redisplay_normalize_glyph_area (struct display_box* dest,
--- a/src/scrollbar-gtk.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/scrollbar-gtk.c Mon Jun 18 07:10:32 2001 +0000 @@ -100,7 +100,6 @@ gtk_object_set_data (GTK_OBJECT (adj), "xemacs::gui_id", (void *) SCROLLBAR_GTK_ID (instance)); gtk_object_set_data (GTK_OBJECT (adj), "xemacs::frame", f); - gtk_object_set_data (GTK_OBJECT (adj), "xemacs::sb_instance", instance); sb = GTK_SCROLLBAR (vertical ? gtk_vscrollbar_new (adj) : gtk_hscrollbar_new (adj)); SCROLLBAR_GTK_WIDGET (instance) = GTK_WIDGET (sb); @@ -357,7 +356,8 @@ if (f->mirror_dirty) update_frame_window_mirror (f); return gtk_scrollbar_loop (GTK_FIND_SCROLLBAR_WINDOW_MIRROR, f->root_window, - f->root_mirror, id, (GdkWindow *) NULL); + XWINDOW_MIRROR (f->root_mirror), id, + (GdkWindow *) NULL); } static gboolean @@ -366,7 +366,7 @@ /* This function can GC */ int vertical = (int) user_data; struct frame *f = gtk_object_get_data (GTK_OBJECT (adj), "xemacs::frame"); - struct scrollbar_instance *instance = gtk_object_get_data (GTK_OBJECT (adj), "xemacs::sb_instance"); + struct scrollbar_instance *instance; GUI_ID id = (GUI_ID) gtk_object_get_data (GTK_OBJECT (adj), "xemacs::gui_id"); Lisp_Object win, frame; struct window_mirror *mirror; @@ -427,8 +427,8 @@ Lisp_Object window; XSETWINDOW (window, w); - gtk_scrollbar_loop (GTK_SET_SCROLLBAR_POINTER, window, find_window_mirror (w), - 0, (GdkWindow *) NULL); + gtk_scrollbar_loop (GTK_SET_SCROLLBAR_POINTER, window, + find_window_mirror (w), 0, (GdkWindow *) NULL); } /* #### BILL!!! This comment is not true for Gtk - should it be? */ @@ -440,7 +440,8 @@ /* Consider this code to be "in_display" so that we abort() if Fsignal() gets called. */ in_display++; - gtk_scrollbar_loop (GTK_UPDATE_FRAME_SCROLLBARS, f->root_window, f->root_mirror, + gtk_scrollbar_loop (GTK_UPDATE_FRAME_SCROLLBARS, f->root_window, + XWINDOW_MIRROR (f->root_mirror), 0, (GdkWindow *) NULL); in_display--; if (in_display < 0) abort ();
--- a/src/scrollbar-msw.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/scrollbar-msw.c Mon Jun 18 07:10:32 2001 +0000 @@ -27,8 +27,10 @@ #include "lisp.h" #include "console-msw.h" +#include "elhash.h" #include "events.h" #include "frame.h" +#include "opaque.h" #include "scrollbar-msw.h" #include "scrollbar.h" #include "specifier.h" @@ -42,11 +44,17 @@ static int vertical_drag_in_progress = 0; +/* As long as the HWND is around, the scrollbar instance must be GC-protected. + We have gotten crashes, apparently from trying to access a dead, freed + frame inside of a window mirror pointed to by the scrollbar structure. */ +static Lisp_Object Vmswindows_scrollbar_instance_table; + static void mswindows_create_scrollbar_instance (struct frame *f, int vertical, struct scrollbar_instance *sb) { int orientation; + Lisp_Object ptr; sb->scrollbar_data = xnew_and_zero (struct mswindows_scrollbar_data); @@ -63,26 +71,26 @@ NULL, NULL, NULL); SCROLLBAR_MSW_INFO (sb).cbSize = sizeof (SCROLLINFO); SCROLLBAR_MSW_INFO (sb).fMask = SIF_ALL; - GetScrollInfo(SCROLLBAR_MSW_HANDLE (sb), SB_CTL, - &SCROLLBAR_MSW_INFO (sb)); - SetWindowLong (SCROLLBAR_MSW_HANDLE (sb), GWL_USERDATA, (LONG) sb); - -#if 0 - { - HWND h = SCROLLBAR_MSW_HANDLE (sb); - int x = SetWindowLong (SCROLLBAR_MSW_HANDLE(sb), GWL_USERDATA, (LONG)sb); - int y = GetLastError(); - struct scrollbar_instance *z = - (struct scrollbar_instance *)GetWindowLong (SCROLLBAR_MSW_HANDLE(sb), - GWL_USERDATA); - *z = *z; - } -#endif + GetScrollInfo (SCROLLBAR_MSW_HANDLE (sb), SB_CTL, + &SCROLLBAR_MSW_INFO (sb)); + ptr = make_opaque_ptr (SCROLLBAR_MSW_HANDLE (sb)); + Fputhash (ptr, wrap_scrollbar_instance (sb), + Vmswindows_scrollbar_instance_table); + SetWindowLong (SCROLLBAR_MSW_HANDLE (sb), GWL_USERDATA, + (LONG) LISP_TO_VOID (ptr)); } static void mswindows_free_scrollbar_instance (struct scrollbar_instance *sb) { + void *opaque = + (void *) GetWindowLong (SCROLLBAR_MSW_HANDLE (sb), GWL_USERDATA); + Lisp_Object ptr; + + VOID_TO_LISP (ptr, opaque); + assert (OPAQUE_PTRP (ptr)); + ptr = Fremhash (ptr, Vmswindows_scrollbar_instance_table); + assert (!NILP (ptr)); DestroyWindow (SCROLLBAR_MSW_HANDLE (sb)); if (sb->scrollbar_data) xfree (sb->scrollbar_data); @@ -161,10 +169,10 @@ if (pos_changed) { - MoveWindow(SCROLLBAR_MSW_HANDLE (sb), - new_scrollbar_x, new_scrollbar_y, - new_scrollbar_width, new_scrollbar_height, - TRUE); + MoveWindow (SCROLLBAR_MSW_HANDLE (sb), + new_scrollbar_x, new_scrollbar_y, + new_scrollbar_width, new_scrollbar_height, + TRUE); } } @@ -188,28 +196,36 @@ { struct frame *f; Lisp_Object win, frame; - struct scrollbar_instance *sb; + struct scrollbar_instance *sb = 0; + void *v; SCROLLINFO scrollinfo; int vert = GetWindowLong (hwnd, GWL_STYLE) & SBS_VERT; int value; - sb = (struct scrollbar_instance *) GetWindowLong (hwnd, GWL_USERDATA); - if (!sb) + v = (void *) GetWindowLong (hwnd, GWL_USERDATA); + if (!v) { + /* apparently this can happen, as it was definitely necessary + to put the check in for sb below (VERTICAL_SCROLLBAR_DRAG_HACK) */ frame = mswindows_find_frame (hwnd); f = XFRAME (frame); win = FRAME_SELECTED_WINDOW (f); } else { + Lisp_Object ptr; + VOID_TO_LISP (ptr, v); + assert (OPAQUE_PTRP (ptr)); + ptr = Fgethash (ptr, Vmswindows_scrollbar_instance_table, Qnil); + sb = XSCROLLBAR_INSTANCE (ptr); win = real_window (sb->mirror, 0); - frame = XWINDOW (win)->frame; + frame = WINDOW_FRAME (XWINDOW (win)); f = XFRAME (frame); } - /* SB_LINEDOWN == SB_CHARLEFT etc. This is the way they will - always be - any Windows is binary compatible backward with - old programs */ + /* SB_LINEDOWN == SB_CHARLEFT etc. This is the way they will + always be -- any Windows is binary compatible backward with + old programs. */ switch (code) { @@ -407,7 +423,8 @@ /* Device-specific ghost specifiers initialization */ /************************************************************************/ -DEFUN ("mswindows-init-scrollbar-metrics", Fmswindows_init_scrollbar_metrics, 1, 1, 0, /* +DEFUN ("mswindows-init-scrollbar-metrics", Fmswindows_init_scrollbar_metrics, + 1, 1, 0, /* */ (locale)) { @@ -443,14 +460,21 @@ } void -syms_of_scrollbar_mswindows(void) +syms_of_scrollbar_mswindows (void) { DEFSUBR (Fmswindows_init_scrollbar_metrics); } void -vars_of_scrollbar_mswindows(void) +vars_of_scrollbar_mswindows (void) { Fprovide (intern ("mswindows-scrollbars")); } +void +complex_vars_of_scrollbar_mswindows (void) +{ + staticpro (&Vmswindows_scrollbar_instance_table); + Vmswindows_scrollbar_instance_table = + make_lisp_hash_table (100, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ); +}
--- a/src/scrollbar-x.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/scrollbar-x.c Mon Jun 18 07:10:32 2001 +0000 @@ -384,7 +384,7 @@ if (f->mirror_dirty) update_frame_window_mirror (f); return x_scrollbar_loop (X_FIND_SCROLLBAR_WINDOW_MIRROR, f->root_window, - f->root_mirror, id, (Window) NULL); + XWINDOW_MIRROR (f->root_mirror), id, (Window) NULL); } /* @@ -688,8 +688,8 @@ /* Consider this code to be "in_display" so that we abort() if Fsignal() gets called. */ in_display++; - x_scrollbar_loop (X_UPDATE_FRAME_SCROLLBARS, f->root_window, f->root_mirror, - 0, (Window) NULL); + x_scrollbar_loop (X_UPDATE_FRAME_SCROLLBARS, f->root_window, + XWINDOW_MIRROR (f->root_mirror), 0, (Window) NULL); in_display--; if (in_display < 0) abort (); }
--- a/src/scrollbar.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/scrollbar.c Mon Jun 18 07:10:32 2001 +0000 @@ -78,6 +78,22 @@ struct scrollbar_instance *instance); +static Lisp_Object +mark_scrollbar_instance (Lisp_Object obj) +{ + struct scrollbar_instance *data = XSCROLLBAR_INSTANCE (obj); + mark_object (wrap_window_mirror (data->mirror)); + if (data->next) + return wrap_scrollbar_instance (data->next); + else + return Qnil; +} + +DEFINE_LRECORD_IMPLEMENTATION ("scrollbar-instance", scrollbar_instance, + mark_scrollbar_instance, + internal_object_printer, 0, 0, 0, 0, + struct scrollbar_instance); + static void free_scrollbar_instance (struct scrollbar_instance *instance, struct frame *frame) @@ -89,7 +105,8 @@ struct device *d = XDEVICE (frame->device); MAYBE_DEVMETH (d, free_scrollbar_instance, (instance)); - xfree (instance); + /* not worth calling free_managed_lcrecord() -- scrollbar instances + are not created that frequently and it's dangerous. */ } } @@ -148,7 +165,7 @@ if (f->mirror_dirty) update_frame_window_mirror (f); - free_scrollbars_loop (f->root_window, f->root_mirror); + free_scrollbars_loop (f->root_window, XWINDOW_MIRROR (f->root_mirror)); while (FRAME_SB_VCACHE (f)) { @@ -173,8 +190,10 @@ { struct device *d = XDEVICE (f->device); struct scrollbar_instance *instance = - xnew_and_zero (struct scrollbar_instance); + alloc_lcrecord_type (struct scrollbar_instance, + &lrecord_scrollbar_instance); + zero_lcrecord (instance); MAYBE_DEVMETH (d, create_scrollbar_instance, (f, vertical, instance)); return instance; @@ -894,6 +913,8 @@ void syms_of_scrollbar (void) { + INIT_LRECORD_IMPLEMENTATION (scrollbar_instance); + DEFSYMBOL (Qscrollbar_line_up); DEFSYMBOL (Qscrollbar_line_down); DEFSYMBOL (Qscrollbar_page_up);
--- a/src/scrollbar.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/scrollbar.h Mon Jun 18 07:10:32 2001 +0000 @@ -27,6 +27,8 @@ struct scrollbar_instance { + struct lcrecord_header header; + /* Used by the frame caches. */ struct scrollbar_instance *next; @@ -45,6 +47,14 @@ void *scrollbar_data; }; +DECLARE_LRECORD (scrollbar_instance, struct scrollbar_instance); +#define XSCROLLBAR_INSTANCE(x) XRECORD (x, scrollbar_instance, struct scrollbar_instance) +#define XSETSCROLLBAR_INSTANCE(x, p) XSETRECORD (x, p, scrollbar_instance) +#define wrap_scrollbar_instance(p) wrap_record (p, scrollbar_instance) +#define SCROLLBAR_INSTANCEP(x) RECORDP (x, scrollbar_instance) +#define CHECK_SCROLLBAR_INSTANCE(x) CHECK_RECORD (x, scrollbar_instance) +#define CONCHECK_SCROLLBAR_INSTANCE(x) CONCHECK_RECORD (x, scrollbar_instance) + #define SCROLLBAR_INSTANCE_FRAME(inst) (inst->mirror->frame) void init_frame_scrollbars (struct frame *f);
--- a/src/signal.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/signal.c Mon Jun 18 07:10:32 2001 +0000 @@ -287,10 +287,25 @@ { #if defined (WIN32_NATIVE) || defined (CYGWIN) /* setitimer() does not exist on native MS Windows, and appears broken - on Cygwin. See win32.c. */ + on Cygwin. See win32.c. + + We are emulating the Unix98 setitimer() function, as found in its + incarnations on modern versions of Unix. Note however that in + the win32.c version, ITNEW and ITOLD must be equal if both are + non-zero, due to limitations in the underlying multimedia-timer + API. */ return mswindows_setitimer (kind, itnew, itold); #else - return setitimer (kind, itnew, itold); + /* YUCK! glibc defines setitimer's first argument as + enum __itimer_which, not int, which causes compile errors if + we call setitimer() in the obvious way. */ + switch (kind) + { + case ITIMER_REAL: return setitimer (ITIMER_REAL, itnew, itold); + case ITIMER_VIRTUAL: return setitimer (ITIMER_VIRTUAL, itnew, itold); + case ITIMER_PROF: return setitimer (ITIMER_PROF, itnew, itold); + default: abort (); return 0; + } #endif }
--- a/src/sound.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/sound.h Mon Jun 18 07:10:32 2001 +0000 @@ -29,18 +29,18 @@ void play_sound_file (Extbyte *name, int volume); int play_sound_data (UChar_Binary *data, int length, int volume); -# define sound_perror(string) \ -do { \ - CBufbyte *errmess; \ - CBufbyte *string_int; \ - /* #### fix this to GET_STRERROR in my mule ws */ \ - EXTERNAL_TO_C_STRING (strerror (errno), errmess, Qnative); \ - EXTERNAL_TO_C_STRING (string, string_int, Qnative); \ - warn_when_safe (Qsound, Qerror, "audio: %s, %s", string_int, errmess); \ +# define sound_perror(string) \ +do { \ + Bufbyte *errmess; \ + Bufbyte *string_int; \ + /* #### fix this to GET_STRERROR in my mule ws */ \ + EXTERNAL_TO_C_STRING (strerror (errno), errmess, Qnative); \ + EXTERNAL_TO_C_STRING (string, string_int, Qnative); \ + warn_when_safe (Qsound, Qerror, "audio: %s, %s", string_int, errmess); \ } while (0) # define sound_warn(string) \ do { \ - CBufbyte *string_int; \ + Bufbyte *string_int; \ EXTERNAL_TO_C_STRING (GETTEXT (string), string_int, Qnative); \ warn_when_safe (Qsound, Qwarning, "audio: %s", string_int); \ } while (0)
--- a/src/specifier.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/specifier.h Mon Jun 18 07:10:32 2001 +0000 @@ -242,6 +242,7 @@ DECLARE_LRECORD (specifier, Lisp_Specifier); #define XSPECIFIER(x) XRECORD (x, specifier, Lisp_Specifier) #define XSETSPECIFIER(x, p) XSETRECORD (x, p, specifier) +#define wrap_specifier(p) wrap_record (p, specifier) #define SPECIFIERP(x) RECORDP (x, specifier) #define CHECK_SPECIFIER(x) CHECK_RECORD (x, specifier) #define CONCHECK_SPECIFIER(x) CONCHECK_RECORD (x, specifier)
--- a/src/symsinit.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/symsinit.h Mon Jun 18 07:10:32 2001 +0000 @@ -411,6 +411,7 @@ void complex_vars_of_alloc (void); void complex_vars_of_menubar (void); void complex_vars_of_scrollbar (void); +void complex_vars_of_scrollbar_mswindows (void); void complex_vars_of_frame (void); void complex_vars_of_casetab (void); void complex_vars_of_syntax (void);
--- a/src/systime.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/systime.h Mon Jun 18 07:10:32 2001 +0000 @@ -273,6 +273,11 @@ somewhere else. This is doubly true when the redefinition occurs in out-of-the way s+m files and only on certainly systems. + The name "qxe" was chosen because it is a unique string that is not + going to be found anywhere else in the sources (unlike, for example, + the prefixes "xemacs" or "sys") and is easy to type. Alternative + names are certainly possible, and suggestions are welcome. + By making the encapsulation explicit we might be making the code that uses is slightly less pretty, but this is more than compensated for by the huge increase in clarity. @@ -288,6 +293,22 @@ function; but be aware that the reimplementation may be incomplete or differ in important respects. This is especially the case when attempts are made to implement Unix functions on MS Windows. + + (The comment on the particular encapsulation should describe what + standard function is being emulated, if this is not obvious, and + what the differences, if any, from that standard function are.) + + An example of this is the qxe_setitimer() function. This attempts + to emulate the POSIX (Unix98?) standard setitimer(), as found on + all modern versions of Unix. Normally, we just call the system- + provided setitimer() function. When emulated on MS Windows and + Cygwin, however, the ITNEW and ITOLD values cannot be different + from each other if both are non-zero, due to limitations in the + underlying multimedia-timer API. By simply using setitimer() with + preprocessor tricks, a programmer would almost have to be a + mind-reader to figure this out. With the explicit encapsulation, a + programmer need only look at the definition of qxe_setitimer() to + see what its semantics are. */ int qxe_setitimer (int kind, const struct itimerval *itnew,
--- a/src/toolbar.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/toolbar.h Mon Jun 18 07:10:32 2001 +0000 @@ -72,6 +72,7 @@ DECLARE_LRECORD (toolbar_button, struct toolbar_button); #define XTOOLBAR_BUTTON(x) XRECORD (x, toolbar_button, struct toolbar_button) #define XSETTOOLBAR_BUTTON(x, p) XSETRECORD (x, p, toolbar_button) +#define wrap_toolbar_button(p) wrap_record (p, toolbar_button) #define TOOLBAR_BUTTONP(x) RECORDP (x, toolbar_button) #define CHECK_TOOLBAR_BUTTON(x) CHECK_RECORD (x, toolbar_button) #define CONCHECK_TOOLBAR_BUTTON(x) CONCHECK_RECORD (x, toolbar_button)
--- a/src/tooltalk.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/tooltalk.h Mon Jun 18 07:10:32 2001 +0000 @@ -30,6 +30,7 @@ DECLARE_LRECORD (tooltalk_message, Lisp_Tooltalk_Message); #define XTOOLTALK_MESSAGE(x) XRECORD (x, tooltalk_message, Lisp_Tooltalk_Message) #define XSETTOOLTALK_MESSAGE(x, p) XSETRECORD (x, p, tooltalk_message) +#define wrap_tooltalk_message(p) wrap_record (p, tooltalk_message) #define TOOLTALK_MESSAGEP(x) RECORDP (x, tooltalk_message) #define CHECK_TOOLTALK_MESSAGE(x) CHECK_RECORD (x, tooltalk_message) @@ -37,6 +38,7 @@ DECLARE_LRECORD (tooltalk_pattern, Lisp_Tooltalk_Pattern); #define XTOOLTALK_PATTERN(x) XRECORD (x, tooltalk_pattern, Lisp_Tooltalk_Pattern) #define XSETTOOLTALK_PATTERN(x, p) XSETRECORD (x, p, tooltalk_pattern) +#define wrap_tooltalk_pattern(p) wrap_record (p, tooltalk_pattern) #define TOOLTALK_PATTERNP(x) RECORDP (x, tooltalk_pattern) #define CHECK_TOOLTALK_PATTERN(x) CHECK_RECORD (x, tooltalk_pattern)
--- a/src/ui-gtk.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/ui-gtk.h Mon Jun 18 07:10:32 2001 +0000 @@ -34,6 +34,7 @@ #define XFFI(x) XRECORD (x, emacs_ffi, emacs_ffi_data) #define XSETFFI(x,p) XSETRECORD (x, p, emacs_ffi) +#define wrap_emacs_ffi(p) wrap_record (p, emacs_ffi) #define FFIP(x) RECORDP (x, emacs_ffi) #define CHECK_FFI(x) CHECK_RECORD (x, emacs_ffi) @@ -49,6 +50,7 @@ #define XGTK_OBJECT(x) XRECORD (x, emacs_gtk_object, emacs_gtk_object_data) #define XSETGTK_OBJECT(x,p) XSETRECORD (x, p, emacs_gtk_object) +#define wrap_emacs_gtk_object(p) wrap_record (p, emacs_gtk_object) #define GTK_OBJECTP(x) RECORDP (x, emacs_gtk_object) #define CHECK_GTK_OBJECT(x) CHECK_RECORD (x, emacs_gtk_object) @@ -65,6 +67,7 @@ #define XGTK_BOXED(x) XRECORD (x, emacs_gtk_boxed, emacs_gtk_boxed_data) #define XSETGTK_BOXED(x,p) XSETRECORD (x, p, emacs_gtk_boxed) +#define wrap_emacs_gtk_boxed(p) wrap_record (p, emacs_gtk_boxed) #define GTK_BOXEDP(x) RECORDP (x, emacs_gtk_boxed) #define CHECK_GTK_BOXED(x) CHECK_RECORD (x, emacs_gtk_boxed)
--- a/src/window.c Mon Jun 11 07:47:20 2001 +0000 +++ b/src/window.c Mon Jun 18 07:10:32 2001 +0000 @@ -149,30 +149,11 @@ mark_window (Lisp_Object obj) { struct window *window = XWINDOW (obj); - mark_object (window->frame); - mark_object (window->mini_p); - mark_object (window->next); - mark_object (window->prev); - mark_object (window->hchild); - mark_object (window->vchild); - mark_object (window->parent); - mark_object (window->buffer); - MARK_DISP_VARIABLE (start); - MARK_DISP_VARIABLE (pointm); - mark_object (window->sb_point); /* #### move to scrollbar.c? */ - mark_object (window->use_time); - MARK_DISP_VARIABLE (last_modified); - MARK_DISP_VARIABLE (last_point); - MARK_DISP_VARIABLE (last_start); - MARK_DISP_VARIABLE (last_facechange); - mark_object (window->line_cache_last_updated); - mark_object (window->redisplay_end_trigger); - mark_object (window->subwindow_instance_cache); mark_face_cachels (window->face_cachels); mark_glyph_cachels (window->glyph_cachels); -#define WINDOW_SLOT(slot, compare) mark_object (window->slot) +#define WINDOW_SLOT(slot) mark_object (window->slot); #include "winslots.h" return Qnil; @@ -261,14 +242,10 @@ XSETWINDOW (val, p); p->dead = 0; - p->frame = Qnil; - p->mini_p = Qnil; - p->next = Qnil; - p->prev = Qnil; - p->hchild = Qnil; - p->vchild = Qnil; - p->parent = Qnil; - p->buffer = Qnil; + +#define WINDOW_SLOT(slot) p->slot = Qnil; +#include "winslots.h" + INIT_DISP_VARIABLE (start, Fmake_marker ()); INIT_DISP_VARIABLE (pointm, Fmake_marker ()); p->sb_point = Fmake_marker (); @@ -286,16 +263,12 @@ INIT_DISP_VARIABLE (last_point_x, 0); INIT_DISP_VARIABLE (last_point_y, 0); INIT_DISP_VARIABLE (window_end_pos, 0); - p->redisplay_end_trigger = Qnil; p->gutter_extent_modiff[0] = 0; p->gutter_extent_modiff[1] = 0; p->gutter_extent_modiff[2] = 0; p->gutter_extent_modiff[3] = 0; -#define WINDOW_SLOT(slot, compare) p->slot = Qnil -#include "winslots.h" - p->windows_changed = 1; p->shadow_thickness_changed = 1; @@ -303,6 +276,10 @@ } #undef INIT_DISP_VARIABLE +/************************************************************************/ +/* Window mirror structure */ +/************************************************************************/ + /* * The redisplay structures used to be stored with each window. While * they are logically something associated with frames they can't be @@ -322,23 +299,71 @@ * the display structures. */ +/* NOTE: The window-mirror structure formerly was not a Lisp object, and + marking was handled specially. I've gotten recurring crashes, however, + using the mouse wheel under Windows, where either the window mirror + accessed through a scrollbar instance, or the frame pointed to by that + window mirror, gets garbaged. Things are tricky under windows because + the scrollbar instances are stored in HWND-specific data. Furthermore, + we have scrollbar-instance caches to complicate things. Both of these + make it very difficult (for me at least, not being intimately familiar + with the redisplay code) to track exactly when and where a particular + window mirror or scrollbar instance has pointers to it, or whether a + window mirror might have a dead frame or buffer in it (i.e. not + necessarily gc-protected by being on a global list). By far the safest + thing, then, is to make both structures Lisp objects and not explicitly + xfree() them. This should make no practical difference in memory usage + because neither structure is created very often (only when windows are + created or deleted). --ben */ + +static Lisp_Object +mark_window_mirror (Lisp_Object obj) +{ + struct window_mirror *mir = XWINDOW_MIRROR (obj); + + if (mir->current_display_lines) + mark_redisplay_structs (mir->current_display_lines); + if (mir->desired_display_lines) + mark_redisplay_structs (mir->desired_display_lines); + + if (mir->hchild) + mark_object (wrap_window_mirror (mir->hchild)); + if (mir->vchild) + mark_object (wrap_window_mirror (mir->vchild)); + + if (mir->frame) + mark_object (wrap_frame (mir->frame)); + if (mir->buffer) + mark_object (wrap_buffer (mir->buffer)); + +#ifdef HAVE_SCROLLBARS + if (mir->scrollbar_vertical_instance) + mark_object (wrap_scrollbar_instance (mir->scrollbar_vertical_instance)); + if (mir->scrollbar_horizontal_instance) + mark_object (wrap_scrollbar_instance (mir->scrollbar_horizontal_instance)); +#endif /* HAVE_SCROLLBARS */ + if (mir->next) + return wrap_window_mirror (mir->next); + else + return Qnil; +} + +DEFINE_LRECORD_IMPLEMENTATION ("window-mirror", window_mirror, + mark_window_mirror, internal_object_printer, + 0, 0, 0, 0, struct window_mirror); + /* Create a new window mirror structure and associated redisplay structs. */ static struct window_mirror * new_window_mirror (struct frame *f) { - struct window_mirror *t = xnew_and_zero (struct window_mirror); + struct window_mirror *t = + alloc_lcrecord_type (struct window_mirror, &lrecord_window_mirror); + zero_lcrecord (t); t->frame = f; - t->current_display_lines = Dynarr_new (display_line); t->desired_display_lines = Dynarr_new (display_line); - t->buffer = NULL; - -#ifdef HAVE_SCROLLBARS - t->scrollbar_vertical_instance = NULL; - t->scrollbar_horizontal_instance = NULL; -#endif return t; } @@ -456,7 +481,11 @@ void update_frame_window_mirror (struct frame *f) { - f->root_mirror = update_mirror_internal (f->root_window, f->root_mirror); + f->root_mirror = + wrap_window_mirror (update_mirror_internal + (f->root_window, + NILP (f->root_mirror) ? 0 : + XWINDOW_MIRROR (f->root_mirror))); f->mirror_dirty = 0; } @@ -467,7 +496,6 @@ { while (mir) { - struct window_mirror *prev = mir; if (mir->hchild) free_window_mirror (mir->hchild); if (mir->vchild) free_window_mirror (mir->vchild); #ifdef HAVE_SCROLLBARS @@ -475,7 +503,10 @@ #endif free_display_structs (mir); mir = mir->next; - xfree (prev); + /* not worth calling free_managed_lcrecord() -- window mirrors + are not created that frequently and it's dangerous. we don't + know for sure that there aren't other pointers around -- e.g. + in a scrollbar instance. */ } } @@ -484,8 +515,9 @@ Lisp_Object real_window (struct window_mirror *mir, int no_abort) { - Lisp_Object retval = real_window_internal (mir->frame->root_window, - mir->frame->root_mirror, mir); + Lisp_Object retval = + real_window_internal (mir->frame->root_window, + XWINDOW_MIRROR (mir->frame->root_mirror), mir); if (NILP (retval) && !no_abort) abort (); @@ -500,7 +532,8 @@ struct frame *f = XFRAME (w->frame); if (f->mirror_dirty) update_frame_window_mirror (f); - return find_window_mirror_internal (f->root_window, f->root_mirror, w); + return find_window_mirror_internal (f->root_window, + XWINDOW_MIRROR (f->root_mirror), w); } /***************************************************************************** @@ -1904,7 +1937,20 @@ ERROR_CHECK_SUBWINDOW_CACHE (w); window_unmap_subwindows (w); - /* In the loop + /* Free the extra data structures attached to windows immediately so + they don't sit around consuming excess space. They will be + reinitialized by the window-configuration code as necessary. */ + finalize_window ((void *) w, 0); + + /* Nobody should be accessing anything in this object any more, and + making them Qnil allows for better GC'ing in case a pointer to + the dead window continues to hang around. Zero all other structs + in case someone tries to access something through them. + + As an example of why setting the values to Qnil is good, here + is an old comment: + + In the loop (while t (split-window) (delete-window)) we end up with a tree of deleted windows which are all connected through the `next' slot. This might not seem so bad, as they're @@ -1916,19 +1962,13 @@ pointers to other windows (they are all recreated from the window-config data), we set them all to nil so that we are able to collect more actual garbage. */ - w->next = Qnil; - w->prev = Qnil; - w->hchild = Qnil; - w->vchild = Qnil; - w->parent = Qnil; - w->subwindow_instance_cache = Qnil; + + zero_lcrecord (w); + +#define WINDOW_SLOT(slot) w->slot = Qnil; +#include "winslots.h" w->dead = 1; - - /* Free the extra data structures attached to windows immediately so - they don't sit around consuming excess space. They will be - reinitialized by the window-configuration code as necessary. */ - finalize_window ((void *) w, 0); } DEFUN ("delete-window", Fdelete_window, 0, 2, "", /* @@ -5002,7 +5042,8 @@ char start_at_line_beg; /* boolean */ #define WINDOW_SLOT_DECLARATION -#define WINDOW_SLOT(slot, compare) Lisp_Object slot +#define WINDOW_SLOT(slot) +#define WINDOW_SAVED_SLOT(slot, compare) Lisp_Object slot; #include "winslots.h" }; @@ -5032,6 +5073,7 @@ #define SAVED_WINDOW_N(conf, n) (&((conf)->saved_windows[(n)])) #define XWINDOW_CONFIGURATION(x) XRECORD (x, window_configuration, struct window_config) #define XSETWINDOW_CONFIGURATION(x, p) XSETRECORD (x, p, window_configuration) +#define wrap_window_configuration(p) wrap_record (p, window_configuration) #define WINDOW_CONFIGURATIONP(x) RECORDP (x, window_configuration) #define CHECK_WINDOW_CONFIGURATION(x) CHECK_RECORD (x, window_configuration) @@ -5061,7 +5103,8 @@ aren't they? -- kkm */ mark_object (s->dedicated); #else -#define WINDOW_SLOT(slot, compare) mark_object (s->slot) +#define WINDOW_SLOT(slot) +#define WINDOW_SAVED_SLOT(slot, compare) mark_object (s->slot); #include "winslots.h" #endif } @@ -5108,7 +5151,8 @@ static int saved_window_equal (struct saved_window *win1, struct saved_window *win2) { -#define WINDOW_SLOT(slot, compare) \ +#define WINDOW_SLOT(slot) +#define WINDOW_SAVED_SLOT(slot, compare) \ if (!compare (win1->slot, win2->slot)) \ return 0; #include "winslots.h" @@ -5498,8 +5542,9 @@ SET_LAST_FACECHANGE (w); w->config_mark = 0; - /* #### Consider making the instance cache a winslot. */ -#define WINDOW_SLOT(slot, compare) w->slot = p->slot + /* #### Consider making the instance cache a WINDOW_SAVED_SLOT. */ +#define WINDOW_SLOT(slot) +#define WINDOW_SAVED_SLOT(slot, compare) w->slot = p->slot; #include "winslots.h" /* Reinstall the saved buffer and pointers into it. */ @@ -5784,7 +5829,8 @@ p->hscroll = w->hscroll; p->modeline_hscroll = w->modeline_hscroll; -#define WINDOW_SLOT(slot, compare) p->slot = w->slot +#define WINDOW_SLOT(slot) +#define WINDOW_SAVED_SLOT(slot, compare) p->slot = w->slot; #include "winslots.h" if (!NILP (w->buffer)) @@ -6063,6 +6109,7 @@ { INIT_LRECORD_IMPLEMENTATION (window); INIT_LRECORD_IMPLEMENTATION (window_configuration); + INIT_LRECORD_IMPLEMENTATION (window_mirror); DEFSYMBOL (Qwindowp); DEFSYMBOL (Qwindow_live_p);
--- a/src/window.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/window.h Mon Jun 18 07:10:32 2001 +0000 @@ -89,21 +89,6 @@ { struct lcrecord_header header; - /* The frame this window is on. */ - Lisp_Object frame; - /* t if this window is a minibuffer window. */ - Lisp_Object mini_p; - /* Following child (to right or down) at same level of tree */ - Lisp_Object next; - /* Preceding child (to left or up) at same level of tree */ - Lisp_Object prev; - /* First child of this window. */ - /* vchild is used if this is a vertical combination, - hchild if this is a horizontal combination. */ - Lisp_Object hchild, vchild; - /* The window this one is a child of. */ - Lisp_Object parent; - /* The upper left corner coordinates of this window, as integers (pixels) relative to upper left corner of frame = 0, 0 */ int pixel_left; @@ -112,20 +97,6 @@ int pixel_height; int pixel_width; - /* The buffer displayed in this window */ - /* Of the fields vchild, hchild and buffer, only one is non-nil. */ - Lisp_Object buffer; - /* A marker pointing to where in the text to start displaying */ - /* need one for each set of display structures */ - Lisp_Object start[3]; - /* A marker pointing to where in the text point is in this window, - used only when the window is not selected. - This exists so that when multiple windows show one buffer - each one can have its own value of point. */ - /* need one for each set of display structures */ - Lisp_Object pointm[3]; - /* A marker pointing to where in the text the scrollbar is pointing */ - Lisp_Object sb_point; /* Number of columns display within the window is scrolled to the left. */ int hscroll; /* Idem for the window's modeline */ @@ -138,33 +109,14 @@ scrolling. Hscroll will remain constant but this will be incremented to incrementally shift lines left.*/ int left_xoffset; - /* Number saying how recently window was selected */ - Lisp_Object use_time; - /* text.modified of displayed buffer as of last time display completed */ - Lisp_Object last_modified[3]; - /* Value of point at that time */ - Lisp_Object last_point[3]; - /* Value of start at that time */ - Lisp_Object last_start[3]; - /* buf.face_change as of last time display completed */ - Lisp_Object last_facechange[3]; /* face cache elements correct for this window and its current buffer */ face_cachel_dynarr *face_cachels; /* glyph cache elements correct for this window and its current buffer */ glyph_cachel_dynarr *glyph_cachels; - /* we cannot have a per-device cache of widgets / subwindows because - each visible instance needs to be a separate instance. The lowest - level of granularity we can get easily is the window that the - subwindow is in. This will fail if we attach the same subwindow - twice to a buffer. However, we are quite unlikely to do this, - especially with buttons which will need individual callbacks. The - proper solution is probably not worth the effort. */ - Lisp_Object subwindow_instance_cache; /* List of starting positions for display lines. Only valid if buffer has not changed. */ line_start_cache_dynarr *line_start_cache; - Lisp_Object line_cache_last_updated; int line_cache_validation_override; /* Length of longest line currently displayed. Used to control the @@ -180,10 +132,6 @@ /* need one for each set of display structures */ int window_end_pos[3]; - /* If redisplay in this window goes beyond this buffer position, - must run the redisplay-end-trigger-functions. */ - Lisp_Object redisplay_end_trigger; - /* Set by the extent code when extents in the gutter are changed. */ int gutter_extent_modiff[4]; @@ -192,7 +140,7 @@ Bufpos last_redisplay_pos; #define WINDOW_SLOT_DECLARATION -#define WINDOW_SLOT(slot, compare) Lisp_Object slot +#define WINDOW_SLOT(slot) Lisp_Object slot; #include "winslots.h" /* one-bit flags: */ @@ -217,12 +165,22 @@ unsigned int need_vertical_divider_valid_p :1; }; +DECLARE_LRECORD (window, struct window); +#define XWINDOW(x) XRECORD (x, window, struct window) +#define XSETWINDOW(x, p) XSETRECORD (x, p, window) +#define wrap_window(p) wrap_record (p, window) +#define WINDOWP(x) RECORDP (x, window) +#define CHECK_WINDOW(x) CHECK_RECORD (x, window) +#define CONCHECK_WINDOW(x) CONCHECK_RECORD (x, window) + #define CURRENT_DISP 0 #define DESIRED_DISP 1 #define CMOTION_DISP 2 struct window_mirror { + struct lcrecord_header header; + /* Frame this mirror is on. */ struct frame *frame; @@ -259,14 +217,13 @@ unsigned int truncate_win :1; }; -#ifdef emacs /* some things other than emacs want the structs */ - -DECLARE_LRECORD (window, struct window); -#define XWINDOW(x) XRECORD (x, window, struct window) -#define XSETWINDOW(x, p) XSETRECORD (x, p, window) -#define WINDOWP(x) RECORDP (x, window) -#define CHECK_WINDOW(x) CHECK_RECORD (x, window) -#define CONCHECK_WINDOW(x) CONCHECK_RECORD (x, window) +DECLARE_LRECORD (window_mirror, struct window_mirror); +#define XWINDOW_MIRROR(x) XRECORD (x, window_mirror, struct window_mirror) +#define XSETWINDOW_MIRROR(x, p) XSETRECORD (x, p, window_mirror) +#define wrap_window_mirror(p) wrap_record (p, window_mirror) +#define WINDOW_MIRRORP(x) RECORDP (x, window_mirror) +#define CHECK_WINDOW_MIRROR(x) CHECK_RECORD (x, window_mirror) +#define CONCHECK_WINDOW_MIRROR(x) CONCHECK_RECORD (x, window_mirror) #define WINDOW_LIVE_P(x) (!(x)->dead) #define CHECK_LIVE_WINDOW(x) do { \ @@ -375,7 +332,6 @@ struct window *decode_window (Lisp_Object window); struct window *find_window_by_pixel_pos (int pix_x, int pix_y, Lisp_Object win); -/* new functions to handle the window mirror */ void free_window_mirror (struct window_mirror *mir); Lisp_Object real_window (struct window_mirror *mir, int no_abort); struct window_mirror *find_window_mirror (struct window *w); @@ -439,6 +395,4 @@ ? 10 \ : MODELINE_OFF_SHADOW_THICKNESS_ADJUSTED (win)) -#endif /* emacs */ - #endif /* INCLUDED_window_h_ */
--- a/src/winslots.h Mon Jun 11 07:47:20 2001 +0000 +++ b/src/winslots.h Mon Jun 18 07:10:32 2001 +0000 @@ -1,7 +1,7 @@ /* Definitions of marked slots in windows and window configs Copyright (C) 1985, 1986, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. - Copyright (C) 1995, 1996 Ben Wing. + Copyright (C) 1995, 1996, 2001 Ben Wing. Copyright (C) 1996 Chuck Thompson. This file is part of XEmacs. @@ -24,120 +24,221 @@ /* Split out of window.h and window.c by Kirill Katsnelson <kkm@kis.ru>, May 1998 */ -#ifdef WINDOW_SLOT_DECLARATION -#define WINDOW_SLOT_ARRAY(slot, size, compare) WINDOW_SLOT (slot[size], compare) -#else -#define WINDOW_SLOT_ARRAY(slot, size, compare) do { \ - int wsaidx; \ - for (wsaidx = 0; wsaidx < size; wsaidx++) \ - { \ - WINDOW_SLOT (slot[wsaidx], compare); \ - } \ -} while (0); +/* Separation into WINDOW_SLOT / WINDOW_SAVED_SLOT by Ben Wing, June 2001. + + NOTE: No semicolons after slot declarations in this file! The + definitions of WINDOW_SLOT (and possibly WINDOW_SAVED_SLOT) need + to include a semicolon. + + WINDOW_SLOT declares a Lisp_Object that is not copied into the + saved_window struct of a window configuration, or is handled in + a special way in window configurations. + WINDOW_SLOT_ARRAY is the same for an array of Lisp_Objects. + WINDOW_SAVED_SLOT declares a Lisp_Object that is copied with no + special handling into the saved_window struct of a window + configuration. You must also declare the comparison function, + either EQ or EQUAL_WRAPPED (i.e. Feq() or Fequal()). + WINDOW_SAVED_SLOT_ARRAY is the same for an array of Lisp_Objects. + + Callers should define WINDOW_SLOT (with a terminating semicolon if + not blank), and WINDOW_SAVED_SLOT if different; otherwise the + latter will be defined using WINDOW_SLOT. Callers do not define + the _ARRAY versions. Instead, they either do or do not define + WINDOW_SLOT_DECLARATION. It should be defined in the definition of + a struct and not elsewhere. + + Callers do not need to undefine these definitions; it is done + automatically. +*/ + +#ifndef WINDOW_SAVED_SLOT +#define WINDOW_SAVED_SLOT(slot, compare) WINDOW_SLOT (slot) #endif +#ifdef WINDOW_SLOT_DECLARATION +#define WINDOW_SLOT_ARRAY(slot, size) WINDOW_SLOT (slot[size]) +#define WINDOW_SAVED_SLOT_ARRAY(slot, size, compare) \ + WINDOW_SAVED_SLOT (slot[size], compare) +#else +#define WINDOW_SLOT_ARRAY(slot, size) do { \ + int wsaidx; \ + for (wsaidx = 0; wsaidx < size; wsaidx++) \ + { \ + WINDOW_SLOT (slot[wsaidx]); \ + } \ +} while (0); +#define WINDOW_SAVED_SLOT_ARRAY(slot, size, compare) do { \ + int wsaidx; \ + for (wsaidx = 0; wsaidx < size; wsaidx++) \ + { \ + WINDOW_SAVED_SLOT (slot[wsaidx], compare); \ + } \ +} while (0); +#endif /* WINDOW_SLOT_DECLARATION */ + #define EQUAL_WRAPPED(x,y) internal_equal ((x), (y), 0) + + /* The frame this window is on. */ + WINDOW_SLOT (frame) + /* t if this window is a minibuffer window. */ + WINDOW_SLOT (mini_p) + /* Following child (to right or down) at same level of tree */ + WINDOW_SLOT (next) + /* Preceding child (to left or up) at same level of tree */ + WINDOW_SLOT (prev) + /* First child of this window. */ + /* vchild is used if this is a vertical combination, + hchild if this is a horizontal combination. */ + WINDOW_SLOT (hchild) + WINDOW_SLOT (vchild) + /* The window this one is a child of. */ + WINDOW_SLOT (parent) + + /* The buffer displayed in this window */ + /* Of the fields vchild, hchild and buffer, only one is non-nil. */ + WINDOW_SLOT (buffer) + /* A marker pointing to where in the text to start displaying */ + /* need one for each set of display structures */ + WINDOW_SLOT_ARRAY (start, 3) + /* A marker pointing to where in the text point is in this window, + used only when the window is not selected. + This exists so that when multiple windows show one buffer + each one can have its own value of point. */ + /* need one for each set of display structures */ + WINDOW_SLOT_ARRAY (pointm, 3) + /* A marker pointing to where in the text the scrollbar is pointing; + #### moved to scrollbar.c? */ + WINDOW_SLOT (sb_point) + + /* Number saying how recently window was selected */ + WINDOW_SLOT (use_time) + /* text.modified of displayed buffer as of last time display completed */ + WINDOW_SLOT_ARRAY (last_modified, 3) + /* Value of point at that time */ + WINDOW_SLOT_ARRAY (last_point, 3) + /* Value of start at that time */ + WINDOW_SLOT_ARRAY (last_start, 3) + /* buf.face_change as of last time display completed */ + WINDOW_SLOT_ARRAY (last_facechange, 3) + + /* we cannot have a per-device cache of widgets / subwindows because + each visible instance needs to be a separate instance. The lowest + level of granularity we can get easily is the window that the + subwindow is in. This will fail if we attach the same subwindow + twice to a buffer. However, we are quite unlikely to do this, + especially with buttons which will need individual callbacks. The + proper solution is probably not worth the effort. */ + WINDOW_SLOT (subwindow_instance_cache) + + WINDOW_SLOT (line_cache_last_updated) + + /* If redisplay in this window goes beyond this buffer position, + must run the redisplay-end-trigger-functions. */ + WINDOW_SLOT (redisplay_end_trigger) + /*** Non-specifier vars of window and window config ***/ /* Non-nil means window is marked as dedicated. */ - WINDOW_SLOT (dedicated, EQ); + WINDOW_SAVED_SLOT (dedicated, EQ) /*** specifier values cached in the struct window ***/ /* Display-table to use for displaying chars in this window. */ - WINDOW_SLOT (display_table, EQUAL_WRAPPED); + WINDOW_SAVED_SLOT (display_table, EQUAL_WRAPPED) /* Thickness of modeline shadow, in pixels. If negative, draw as recessed. */ - WINDOW_SLOT (modeline_shadow_thickness, EQ); + WINDOW_SAVED_SLOT (modeline_shadow_thickness, EQ) /* Non-nil means to display a modeline for the buffer. */ - WINDOW_SLOT (has_modeline_p, EQ); + WINDOW_SAVED_SLOT (has_modeline_p, EQ) /* Thickness of vertical divider shadow, in pixels. If negative, draw as recessed. */ - WINDOW_SLOT (vertical_divider_shadow_thickness, EQ); + WINDOW_SAVED_SLOT (vertical_divider_shadow_thickness, EQ) /* Divider surface width (not counting 3-d borders) */ - WINDOW_SLOT (vertical_divider_line_width, EQ); + WINDOW_SAVED_SLOT (vertical_divider_line_width, EQ) /* Spacing between outer edge of divider border and window edge */ - WINDOW_SLOT (vertical_divider_spacing, EQ); + WINDOW_SAVED_SLOT (vertical_divider_spacing, EQ) /* Whether vertical dividers are always displayed */ - WINDOW_SLOT (vertical_divider_always_visible_p, EQ); + WINDOW_SAVED_SLOT (vertical_divider_always_visible_p, EQ) #ifdef HAVE_SCROLLBARS /* Width of vertical scrollbars. */ - WINDOW_SLOT (scrollbar_width, EQ); + WINDOW_SAVED_SLOT (scrollbar_width, EQ) /* Height of horizontal scrollbars. */ - WINDOW_SLOT (scrollbar_height, EQ); + WINDOW_SAVED_SLOT (scrollbar_height, EQ) /* Whether the scrollbars are visible */ - WINDOW_SLOT (horizontal_scrollbar_visible_p, EQ); - WINDOW_SLOT (vertical_scrollbar_visible_p, EQ); + WINDOW_SAVED_SLOT (horizontal_scrollbar_visible_p, EQ) + WINDOW_SAVED_SLOT (vertical_scrollbar_visible_p, EQ) /* Scrollbar positions */ - WINDOW_SLOT (scrollbar_on_left_p, EQ); - WINDOW_SLOT (scrollbar_on_top_p, EQ); + WINDOW_SAVED_SLOT (scrollbar_on_left_p, EQ) + WINDOW_SAVED_SLOT (scrollbar_on_top_p, EQ) /* Pointer to use for vertical and horizontal scrollbars. */ - WINDOW_SLOT (scrollbar_pointer, EQ); + WINDOW_SAVED_SLOT (scrollbar_pointer, EQ) #endif /* HAVE_SCROLLBARS */ #ifdef HAVE_TOOLBARS /* Toolbar specification for each of the four positions. This is not a size hog because the value here is not copied, and will be shared with the specs in the specifier. */ - WINDOW_SLOT_ARRAY (toolbar, 4, EQUAL_WRAPPED); + WINDOW_SAVED_SLOT_ARRAY (toolbar, 4, EQUAL_WRAPPED) /* Toolbar size for each of the four positions. */ - WINDOW_SLOT_ARRAY (toolbar_size, 4, EQUAL_WRAPPED); + WINDOW_SAVED_SLOT_ARRAY (toolbar_size, 4, EQUAL_WRAPPED) /* Toolbar border width for each of the four positions. */ - WINDOW_SLOT_ARRAY (toolbar_border_width, 4, EQUAL_WRAPPED); + WINDOW_SAVED_SLOT_ARRAY (toolbar_border_width, 4, EQUAL_WRAPPED) /* Toolbar visibility status for each of the four positions. */ - WINDOW_SLOT_ARRAY (toolbar_visible_p, 4, EQUAL_WRAPPED); + WINDOW_SAVED_SLOT_ARRAY (toolbar_visible_p, 4, EQUAL_WRAPPED) /* Caption status of toolbar. */ - WINDOW_SLOT (toolbar_buttons_captioned_p, EQ); + WINDOW_SAVED_SLOT (toolbar_buttons_captioned_p, EQ) /* The following five don't really need to be cached except that we need to know when they've changed. */ - WINDOW_SLOT (default_toolbar, EQUAL_WRAPPED); - WINDOW_SLOT (default_toolbar_width, EQ); - WINDOW_SLOT (default_toolbar_height, EQ); - WINDOW_SLOT (default_toolbar_visible_p, EQ); - WINDOW_SLOT (default_toolbar_border_width, EQ); + WINDOW_SAVED_SLOT (default_toolbar, EQUAL_WRAPPED) + WINDOW_SAVED_SLOT (default_toolbar_width, EQ) + WINDOW_SAVED_SLOT (default_toolbar_height, EQ) + WINDOW_SAVED_SLOT (default_toolbar_visible_p, EQ) + WINDOW_SAVED_SLOT (default_toolbar_border_width, EQ) #endif /* HAVE_TOOLBARS */ /* Gutter specification for each of the four positions. This is not a size hog because the value here is not copied, and will be shared with the specs in the specifier. */ - WINDOW_SLOT_ARRAY (gutter, 4, EQUAL_WRAPPED); + WINDOW_SAVED_SLOT_ARRAY (gutter, 4, EQUAL_WRAPPED) /* Real (pre-calculated) gutter specification for each of the four positions. This is not a specifier, it is calculated by the specifier change functions. */ - WINDOW_SLOT_ARRAY (real_gutter, 4, EQUAL_WRAPPED); + WINDOW_SAVED_SLOT_ARRAY (real_gutter, 4, EQUAL_WRAPPED) /* Gutter size for each of the four positions. */ - WINDOW_SLOT_ARRAY (gutter_size, 4, EQUAL_WRAPPED); + WINDOW_SAVED_SLOT_ARRAY (gutter_size, 4, EQUAL_WRAPPED) /* Real (pre-calculated) gutter size for each of the four positions. This is not a specifier, it is calculated by the specifier change functions. */ - WINDOW_SLOT_ARRAY (real_gutter_size, 4, EQUAL_WRAPPED); + WINDOW_SAVED_SLOT_ARRAY (real_gutter_size, 4, EQUAL_WRAPPED) /* Gutter border width for each of the four positions. */ - WINDOW_SLOT_ARRAY (gutter_border_width, 4, EQUAL_WRAPPED); + WINDOW_SAVED_SLOT_ARRAY (gutter_border_width, 4, EQUAL_WRAPPED) /* Gutter visibility status for each of the four positions. */ - WINDOW_SLOT_ARRAY (gutter_visible_p, 4, EQUAL_WRAPPED); + WINDOW_SAVED_SLOT_ARRAY (gutter_visible_p, 4, EQUAL_WRAPPED) /* The following five don't really need to be cached except that we need to know when they've changed. */ - WINDOW_SLOT (default_gutter, EQUAL_WRAPPED); - WINDOW_SLOT (default_gutter_width, EQ); - WINDOW_SLOT (default_gutter_height, EQ); - WINDOW_SLOT (default_gutter_visible_p, EQ); - WINDOW_SLOT (default_gutter_border_width, EQ); + WINDOW_SAVED_SLOT (default_gutter, EQUAL_WRAPPED) + WINDOW_SAVED_SLOT (default_gutter_width, EQ) + WINDOW_SAVED_SLOT (default_gutter_height, EQ) + WINDOW_SAVED_SLOT (default_gutter_visible_p, EQ) + WINDOW_SAVED_SLOT (default_gutter_border_width, EQ) /* margins */ - WINDOW_SLOT (left_margin_width, EQ); - WINDOW_SLOT (right_margin_width, EQ); - WINDOW_SLOT (minimum_line_ascent, EQ); - WINDOW_SLOT (minimum_line_descent, EQ); - WINDOW_SLOT (use_left_overflow, EQ); - WINDOW_SLOT (use_right_overflow, EQ); + WINDOW_SAVED_SLOT (left_margin_width, EQ) + WINDOW_SAVED_SLOT (right_margin_width, EQ) + WINDOW_SAVED_SLOT (minimum_line_ascent, EQ) + WINDOW_SAVED_SLOT (minimum_line_descent, EQ) + WINDOW_SAVED_SLOT (use_left_overflow, EQ) + WINDOW_SAVED_SLOT (use_right_overflow, EQ) #ifdef HAVE_MENUBARS /* Visibility of menubar. */ - WINDOW_SLOT (menubar_visible_p, EQ); + WINDOW_SAVED_SLOT (menubar_visible_p, EQ) #endif /* HAVE_MENUBARS */ - WINDOW_SLOT (text_cursor_visible_p, EQ); + WINDOW_SAVED_SLOT (text_cursor_visible_p, EQ) /* Hara-kiri */ #undef EQUAL_WRAPPED #undef WINDOW_SLOT_DECLARATION #undef WINDOW_SLOT #undef WINDOW_SLOT_ARRAY +#undef WINDOW_SAVED_SLOT +#undef WINDOW_SAVED_SLOT_ARRAY