XEmacs 21.2-b2
authortomo <tomo>
Mon, 17 May 1999 09:41:34 +0000 (09:41 +0000)
committertomo <tomo>
Mon, 17 May 1999 09:41:34 +0000 (09:41 +0000)
56 files changed:
src/ChangeLog
src/buffer.c
src/buffer.h
src/bufslots.h
src/callint.c
src/casefiddle.c
src/config.h.in
src/console-msw.h
src/console-x.h
src/device-msw.c
src/device-x.c
src/device.c
src/dired.c
src/emacs.c
src/event-Xt.c
src/event-msw.c
src/extents.c
src/extents.h
src/faces.c
src/fileio.c
src/filelock.c
src/fns.c
src/frame-x.c
src/gif_io.c [new file with mode: 0644]
src/gifrlib.h [new file with mode: 0644]
src/glyphs-eimage.c
src/glyphs-msw.c
src/glyphs-x.c
src/glyphs.c
src/gui-x.c
src/insdel.c
src/insdel.h
src/keymap.c
src/line-number.c
src/lisp.h
src/lread.c
src/macros.c
src/marker.c
src/menubar-msw.c
src/menubar-x.c
src/mule-canna.c
src/ntproc.c
src/objects-msw.c
src/process-nt.c
src/process-unix.c
src/ralloc.c
src/redisplay-x.c
src/redisplay.c
src/regex.c
src/s/cygwin32.h
src/s/decosf4-0.h
src/s/freebsd.h
src/undo.c
src/unexalpha.c
src/unexelf.c
src/window.c

index 72e9ef4..35afafe 100644 (file)
@@ -1,3 +1,432 @@
+1998-09-29  SL Baur  <steve@altair.xemacs.org>
+
+       * XEmacs 21.2-beta2 is released.
+
+1998-09-27  P. E. Jareth Hein  <jareth@camelot.co.jp>
+
+       * regex.c (re_match_2_internal): Add in code to reset lowest_active_reg
+       to prevent memory corruption in the case of jumping out of a series of
+       nested match patterns. This is a rather brute force approach, though.
+
+1998-09-02  Andy Piper  <andyp@parallax.co.uk>
+
+       * config.h.in: ditto.
+
+       * s/cygwin32.h: rearrange declarations to cope with cygwin
+       b20. Include cygwin32/version.h if it exists.
+
+1998-09-20  Jonathan Harris  <jhar@tardis.ed.ac.uk>
+
+       * device-msw.c (mswindows_init_device): Call new
+         mswindows_enumerate_fonts() function in objects-msw.c instead
+         of font_enum_callback_1() to enumerate fonts.
+
+         font_enum_callback_1() and _2() moved to objects-msw.c. 
+
+       * faces.c (complex_vars_of_faces): Make the mswindows default 
+         face font fully specified and provide some fallbacks.
+
+       * objects-msw.c: font_enum_callback_1() and _2() moved here
+         from objects-msw.c. Obtain the enumerated font's character
+         sets by table lookup instead of using the locale-specific
+         string provided by Windows.
+
+         New public non-method mswindows_enumerate_fonts() that fills
+         in the supplied mswindows device's font list.
+
+         mswindows_initialize_font_instance: Use the supplied name
+         variable instead of f->name when signalling errors. Match font
+         weights and character sets using lookup tables which handle
+         spaces instead of by frobbing.
+
+1998-09-20  Jonathan Harris  <jhar@tardis.ed.ac.uk>
+
+       * process-nt.c: Define an arbitrary limit, FRAGMENT_CODE_SIZE,
+         on the size of code fragments passed to run_in_other_process.
+
+         run_in_other_process(): Use FRAGMENT_CODE_SIZE to determine
+         the amount of memory to allocate in the other process.
+
+         Removed sigkill_code_end(), sigint_code_end() and
+         sig_enable_code_end() since they are now redundant.
+
+         send_signal() and enable_child_signals(): Don't try to work
+         out the end of the code fragments passed to 
+         run_in_other_process()
+
+1998-09-10  Kazuyuki IENAGA  <ienaga@jsys.co.jp>
+
+       * src/s/freebsd.h: Added __ELF__ and compiler/liker flags for
+       FreeBSD-current.
+
+       * src/unexelf.c: Partially synched with FSF's 20.3.
+
+1998-09-10  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * insdel.c (signal_after_change): Map across indirect buffers
+       here, and not in the upper-level functions.
+       (signal_first_change): Don't check for Armageddon.
+       (signal_before_change): Map across indirect buffers here.
+       (prepare_to_modify_buffer): ...and here.
+
+1998-09-09  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * insdel.c (signal_after_change): Add return value.
+       (buffer_insert_string_1): Use it.
+       (buffer_delete_range): Ditto.
+       (buffer_replace_char): Ditto.
+       (cancel_multiple_change): Map the indirect buffers.
+
+1998-09-06  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * insdel.c (init_buffer_text): Remove INDIRECT_P parameter.
+       (uninit_buffer_text): Ditto.
+
+       * buffer.c (Fmake_indirect_buffer): Implement stricter
+       error-checking.
+
+1998-09-04  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * insdel.c (change_function_restore): Reverse order of
+       function-call and assignment.
+       (first_change_hook_restore): Ditto.
+
+       * extents.c (mark_extent_auxiliary): Mark them.
+       (Fset_extent_property): Set them.
+       (Fextent_property): Get them.
+       (Fextent_properties): Ditto.
+       (vars_of_extents): Set their default.
+
+       * extents.h (struct extent_auxiliary): Add before_change_functions
+       and after_change_functions.
+
+       * insdel.c (signal_before_change): Use it.
+       (signal_after_change): Ditto.
+
+       * extents.c (report_extent_modification): New function.
+
+       * insdel.c (signal_before_change): Don't check for Armageddon.
+       (signal_after_change): Ditto.
+
+1998-09-11  Gunnar Evermann  <Gunnar.Evermann@nats.informatik.uni-hamburg.de>
+
+       * redisplay.c (redisplay_window): make sure a new starting point
+       is chosen if it somehow got moved from the beginning of the line
+       -- this can happen because Fwiden was called recently.
+
+       * window.c (Fset_window_start): set start_at_line_beg correctly
+       (Fset_window_buffer): Ditto
+
+1998-09-06  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * insdel.c (init_buffer_text): Remove INDIRECT_P parameter.
+       (uninit_buffer_text): Ditto.
+
+       * buffer.c (Fmake_indirect_buffer): Implement stricter
+       error-checking.
+
+1998-05-14  Jan Vroonhof  <vroonhof@math.ethz.ch>
+
+       * emacs.c (main_1): Removed references to *vars_of_filelock.
+
+       * lisp.h: Added Fsystem_name.
+
+       * filelock.c: Replaced by version from FSF 20.2. Now implements
+       locking by using symlinks which is NFS safe. However keep the
+       GCPRO's in lock_file and the calls to callx_in_buffer like our old 
+       version (and of course use ansi C, acessor macros, etc).
+
+1998-09-06  Jan Vroonhof  <vroonhof@math.ethz.ch>
+
+       * process-unix.c (unix_create_process): Reset SIGHUP handler to
+       SIG_DFL. We now try to conserve any inherted SIG_IGN settings
+       in init_signals_very_early. However these should not be passed 
+       on to children attached to the new pty.
+
+1998-08-28  Andy Piper  <andyp@parallax.co.uk>
+
+       * glyphs-eimage.c (png_instantiate_unwind): clean up eimage after use.
+
+1998-09-07  Jonathan Harris  <jhar@tardis.ed.ac.uk>
+
+       * fileio.c (file-name-directory, file_name_as_directory):
+         Don't call CORRECT_DIR_SEPS, even when #defined WINDOWSNT. 
+
+1998-09-02  Andy Piper  <andyp@parallax.co.uk>
+
+       * emacs.c (main_1): init_ralloc() if initialised and we have REL_ALLOC
+
+       * ralloc.c: uncomment __morecore.
+
+1998-09-92  Jonathan Harris  <jhar@tardis.ed.ac.uk>
+
+       * event-msw.c(winsock_writer): Supply a dummy 4th argument to
+         WriteFile() to fix a winsock 1.x bug on Win95.
+
+1998-08-28  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * event-Xt.c (emacs_Xt_mapping_action): Check for device being
+       deleted.
+       (x_event_to_emacs_event): Ditto.
+       (emacs_Xt_handle_focus_event): Ditto.
+       (emacs_Xt_handle_magic_event): Ditto.
+
+       * console-x.h (struct x_device): New flag being_deleted.
+       (DEVICE_X_BEING_DELETED): New macro.
+
+       * device-x.c (x_IO_error_handler): Throw to top-level instead of
+       returning.  Before doing that, set the being_deleted flag on the
+       device.
+
+1998-08-27  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * device-x.c (x-seppuku-on-epipe): Removed.
+
+1998-08-26  Gunnar Evermann  <Gunnar.Evermann@nats.informatik.uni-hamburg.de>
+
+       * frame-x.c (x_delete_frame): Flush the X output buffer after
+       calling XtDestroyWidget to ensure that the windows are really
+       killed right now. 
+
+1998-08-26  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * menubar-x.c (my_run_hook): New unused function.
+       (pre_activate_callback): Use run_hook for Qactivate_menubar_hook,
+       since we ignore the results of the contained functions anyway.
+
+1998-08-26  P. E. Jareth Hein  <jareth@camelot.co.jp>
+
+       * glyphs-eimage.c (gif_instantiate): Fix a crash in handling
+       interlaced GIF files that are smaller than 4 lines high...
+
+1998-08-31  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * buffer.c (map_over_sharing_buffers): Deleted.
+
+       * insdel.c (MAP_INDIRECT_BUFFERS): Move to buffer.h.
+
+       * buffer.c (Fkill_buffer): Keep indirect_children updated while
+       killing them.
+
+1998-08-31  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * insdel.c (buffer_insert_string_1): Advance the point bytind in
+       all the buffers.
+       (buffer_delete_range): Ditto.
+
+       * marker.c (init_buffer_markers): Set point-marker to the value of 
+       point in an indirect buffer.
+
+1998-08-30  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * undo.c (undo_prelude): Test last-undo-buffer against base
+       buffer.
+
+       * insdel.c (MAP_INDIRECT_BUFFERS): Use it.
+
+       * buffer.h (BUFFER_BASE_BUFFER): New macro.
+
+1998-08-30  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * insdel.c (init_buffer_text): Initialize it here.
+
+       * line-number.c: Address line_number_cache through buffer->text.
+
+       * buffer.c (mark_buffer): Mark line number cache.
+
+       * bufslots.h (line_number_cache): Move to struct buffer_text.
+
+       * insdel.c (buffer_insert_string_1): Propagate signals and changes
+       across the children buffers.
+       (buffer_delete_range): Ditto.
+       (buffer_replace_char): Ditto.
+       (gap_left): Ditto.
+       (gap_right): Ditto.
+
+       * insdel.c (MAP_INDIRECT_BUFFERS): New macro.
+
+       * buffer.c (Fmake_indirect_buffer): Uncomment.
+
+1998-08-31  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * macros.c (Fend_kbd_macro): Remove trailing period from error
+       message.
+       (Fexecute_kbd_macro): Ditto.
+
+1998-08-21  Greg Klanderman  <greg@alphatech.com>
+
+       * dired.c (Fuser_name_completion): remove optional 2nd argument.
+       (Fuser_name_completion_1): new function to return uniqueness
+       indication in addition to the user name completion.
+       (user_name_completion): change type of `uniq' argument.
+
+1998-08-19  Michael Sperber [Mr. Preprocessor]  <sperber@informatik.uni-tuebingen.de>
+
+       * lread.c (vars_of_lread): Removed `source-directory' variable.
+
+1998-08-22  Hrvoje Niksic  <hniksic@srce.hr>
+
+       * fileio.c (Ffile_readable_p): Apply the DOS/Windows logic to
+       Cygwin.
+
+1998-08-19  SL Baur  <steve@altair.xemacs.org>
+
+       * dired.c (vars_of_dired): Fix misapplied patch.
+
+1998-08-16  Martin Buchholz  <martin@xemacs.org>
+
+       * fns.c (Fremrassq, remrassq_no_quit):
+       A XCAR that should have been an XCDR turned Fremrassq into Fremassq
+
+1998-07-17  Didier Verna  <verna@inf.enst.fr>
+
+       * redisplay-x.c (x_get_gc): returns a GC with a FillStipple fill
+       style as foreground GC for faces that have the `dim' property.
+       (x_output_string): when the `dim' face property is set,
+       ensure the gray pixmap has been created, and get a proper
+       foreground GC to draw the text.
+
+1998-08-09  Jonathan Harris  <jhar@tardis.ed.ac.uk>
+
+       * event-msw.c (mswindows_wnd_proc): Workaround for a Win95 bug:
+         Manually track the state of the left and right Ctrl and Alt
+         modifiers.
+
+1998-08-07 Matt Stupple <matts@tibco.com>
+
+        * ntproc.c: don't wait on char_consumed at thread entry. 
+       Additionally, to get the 'process' marked as finished, ensure
+       that the CHILD_ACTIVE macro returns false, so before exiting
+       close char_avail and set it to NULL, and close other handles
+       to reduce handle leak problems.
+
+1998-08-09  Jonathan Harris  <jhar@tardis.ed.ac.uk>
+
+       * menubar-msw.c (displayable_menu_item): take account of menu
+         depth when deciding whether to try to display accelerators.
+
+1998-08-04  Andy Piper  <andyp@parallax.co.uk>
+
+       * event-msw.c: use MsgWaitForMultipleObjects if there are no
+       subprocesses.
+
+       * glyphs-msw.c: fix a couple of potential handle leaks.
+
+1998-08-04  P. E. Jareth Hein  <jareth@camelot.co.jp>
+
+       * dgif_lib.c gif_io.c gifrlib.h: New files to put GIF
+         *decoding ONLY* back into the core.
+       * glyphs-eimage.c: Change referenced header file for GIF
+         reading to point to the incore version.
+
+1998-07-20  Martin Buchholz  <martin@xemacs.org>
+
+       * casefiddle.c (casify_object): 
+       Change algorithm from O(N**2) to O(N).
+       Code cleanup.
+       Doc string cleanup.
+
+1998-07-22  Greg Klanderman  <greg@alphatech.com>
+
+       * dired.c (file_name_completion_unwind): don't leak the cons.
+
+1998-07-20  Greg Klanderman  <greg@alphatech.com>
+
+       * dired.c (Fuser_name_completion): new function.
+       (Fuser_name_all_completions): new function.
+       (user_name_completion): new function.
+       (syms_of_dired): 2 new DEFSUBRs.
+       (vars_of_dired): initialize user name cache vars.
+
+1998-07-29  P. E. Jareth Hein  <jareth@camelot.co.jp>
+
+       * glyphs-eimage.c (png_instantiate): Add proper handling for background
+       colors taken from the default face.  Also correct a thinko in
+       transparency (not alpha) handling.
+
+1998-07-23  Martin Buchholz  <martin@xemacs.org>
+
+       * s/decosf4-0.h:  Use a perfectly ordinary link.  Nuke BSD crap.
+       * unexalpha.c: ANSI C-ize.  Clean compiler warnings.
+       * lread.c (Fload_internal):  Be very careful with printfs of
+       size_t's
+       * gui-x.c (menu_name_to_accelerator): tolower wants an `int'
+       argument.
+
+1998-07-27  Gunnar Evermann  <Gunnar.Evermann@nats.informatik.uni-hamburg.de>
+
+       * callint.c (Fcall_interactively): GCPRO prompt string before
+       passing it to Fread_key_sequence
+
+1998-07-27  SL Baur  <steve@altair.xemacs.org>
+
+       * keymap.c (vars_of_keymap): Initialize Vkey_translation_map and
+       Vvertical_divider_map.
+
+       * mule-canna.c (vars_of_mule_canna): Initialize every symbol to
+       Qnil or 0, none were initialized prior to this change.
+
+       Rename misnamed `V' prefixed integer variables:
+       Vcanna_empty_info, Vcanna_through_info, Vcanna_underline,
+       Vcanna_inhibit_hankakukana, Vcanna_henkan_length, Vcanna_henkan_revPos,
+       Vcanna_henkan_revLen, Vcanna_ichiran_length, Vcanna_ichiran_revPos,
+       Vcanna_ichiran_revLen.
+
+       Rename misnamed `V' prefixed integer variables and initialize
+       properly in the vars_of routine.
+       Vcanna_mode_AlphaMode, Vcanna_mode_EmptyMode, Vcanna_mode_KigoMode,
+       Vcanna_mode_YomiMode, Vcanna_mode_JishuMode, Vcanna_mode_TankouhoMode,
+       Vcanna_mode_IchiranMode, Vcanna_mode_YesNoMode, Vcanna_mode_OnOffMode,
+       Vcanna_mode_AdjustBunsetsuMode, Vcanna_mode_ChikujiYomiMode,
+       Vcanna_mode_ChikujiTanMode, Vcanna_mode_HenkanMode,
+       Vcanna_mode_HenkanNyuryokuMode, Vcanna_mode_ZenHiraHenkanMode,
+       Vcanna_mode_HanHiraHenkanMode, Vcanna_mode_ZenKataHenkanMode,
+       Vcanna_mode_HanKataHenkanMode, Vcanna_mode_HanKataHenkanMode,
+       Vcanna_mode_ZenAlphaHenkanMode, Vcanna_mode_HanAlphaHenkanMode,
+       Vcanna_mode_ZenHiraKakuteiMode, Vcanna_mode_HanHiraKakuteiMode,
+       Vcanna_mode_ZenKataKakuteiMode, Vcanna_mode_HanKataKakuteiMode,
+       Vcanna_mode_ZenAlphaKakuteiMode, Vcanna_mode_HanAlphaKakuteiMode,
+       Vcanna_mode_HexMode, Vcanna_mode_BushuMode, Vcanna_mode_ExtendMode,
+       Vcanna_mode_RussianMode, Vcanna_mode_GreekMode, Vcanna_mode_LineMode,
+       Vcanna_mode_ChangingServerMode, Vcanna_mode_HenkanMethodMode,
+       Vcanna_mode_DeleteDicMode, Vcanna_mode_TourokuMode,
+       Vcanna_mode_TourokuEmptyMode, Vcanna_mode_TourokuHinshiMode,
+       Vcanna_mode_TourokuDicMode, Vcanna_mode_QuotedInsertMode,
+       Vcanna_mode_BubunMuhenkanMode, Vcanna_mode_MountDicMode,
+       Vcanna_fn_SelfInsert, Vcanna_fn_FunctionalInsert,
+       Vcanna_fn_QuotedInsert, Vcanna_fn_JapaneseMode, Vcanna_fn_AlphaMode,
+       Vcanna_fn_HenkanNyuryokuMode, Vcanna_fn_Forward, Vcanna_fn_Backward,
+       Vcanna_fn_Next, Vcanna_fn_Prev, Vcanna_fn_BeginningOfLine,
+       Vcanna_fn_EndOfLine, Vcanna_fn_DeleteNext, Vcanna_fn_DeletePrevious,
+       Vcanna_fn_KillToEndOfLine, Vcanna_fn_Henkan, Vcanna_fn_Kakutei,
+       Vcanna_fn_Extend, Vcanna_fn_Shrink, Vcanna_fn_AdjustBunsetsu,
+       Vcanna_fn_Quit, Vcanna_fn_ConvertAsHex, Vcanna_fn_ConvertAsBushu,
+       Vcanna_fn_KouhoIchiran, Vcanna_fn_BubunMuhenkan, Vcanna_fn_Zenkaku,
+       Vcanna_fn_Hankaku, Vcanna_fn_ExtendMode, Vcanna_fn_ToUpper,
+       Vcanna_fn_Capitalize, Vcanna_fn_ToLower, Vcanna_fn_Hiragana,
+       Vcanna_fn_Katakana, Vcanna_fn_Romaji, Vcanna_fn_BaseHiragana,
+       Vcanna_fn_BaseKatakana, Vcanna_fn_BaseEisu, Vcanna_fn_BaseZenkaku,
+       Vcanna_fn_BaseHankaku, Vcanna_fn_BaseKana, Vcanna_fn_BaseKakutei,
+       Vcanna_fn_BaseHenkan, Vcanna_fn_BaseHiraKataToggle,
+       Vcanna_fn_BaseZenHanToggle, Vcanna_fn_BaseKanaEisuToggle,
+       Vcanna_fn_BaseKakuteiHenkanToggle, Vcanna_fn_BaseRotateForward,
+       Vcanna_fn_BaseRotateBackward, Vcanna_fn_Touroku, Vcanna_fn_HexMode,
+       Vcanna_fn_BushuMode, Vcanna_fn_KigouMode, Vcanna_fn_Mark,
+       Vcanna_fn_TemporalMode, Vcanna_key_Nfer, Vcanna_key_Xfer,
+       Vcanna_key_Up, Vcanna_key_Left, Vcanna_key_Right, Vcanna_key_Down,
+       Vcanna_key_Insert, Vcanna_key_Rollup, Vcanna_key_Rolldown,
+       Vcanna_key_Home, Vcanna_key_Help, Vcanna_key_KP_Key,
+       Vcanna_key_Shift_Nfer, Vcanna_key_Shift_Xfer, Vcanna_key_Shift_Up,
+       Vcanna_key_Shift_Left, Vcanna_key_Shift_Right, Vcanna_key_Shift_Down,
+       Vcanna_key_Cntrl_Nfer, Vcanna_key_Cntrl_Xfer, Vcanna_key_Cntrl_Up,
+       Vcanna_key_Cntrl_Left, Vcanna_key_Cntrl_Right, Vcanna_key_Cntrl_Down
+
+1998-07-16  Jan Vroonhof  <vroonhof@math.ethz.ch>
+
+       * event-Xt.c (x_to_emacs_keysym): Return nil for modifier keysyms.
+       (x_event_to_emacs_event): Let x_to_emacs_keysym check for modifier 
+       keys thus no longer considering all keysyms on a key.
+
 1998-07-19  SL Baur  <steve@altair.xemacs.org>
 
        * XEmacs 21.2-beta1 is released.
index 81acfbc..7b88d68 100644 (file)
@@ -232,6 +232,8 @@ mark_buffer (Lisp_Object obj, void (*markobj) (Lisp_Object))
 #undef MARKED_SLOT
 
   ((markobj) (buf->extent_info));
+  if (buf->text)
+    ((markobj) (buf->text->line_number_cache));
 
   /* Don't mark normally through the children slot.
      (Actually, in this case, it doesn't matter.)  */
@@ -614,12 +616,11 @@ The value is never nil.
   b->text = &b->own_text;
   b->base_buffer = 0;
   b->indirect_children = Qnil;
-  init_buffer_text (b, 0);
+  init_buffer_text (b);
 
   return finish_init_buffer (b, name);
 }
 
-#if 0 /* #### implement this!  Need various changes in insdel.c */
 DEFUN ("make-indirect-buffer", Fmake_indirect_buffer, 2, 2,
        "bMake indirect buffer (to buffer): \nBName of indirect buffer: ", /*
 Create and return an indirect buffer for buffer BASE, named NAME.
@@ -631,44 +632,40 @@ If BASE is an indirect buffer itself, the base buffer for that buffer
 */
        (base_buffer, name))
 {
-  Lisp_Object buf;
-  REGISTER struct buffer *b;
+  /* This function can GC */
+
+  /* #### The above interactive specification is totally bogus,
+     because it offers an existing buffer as default answer to the
+     second question.  However, the second argument may not BE an
+     existing buffer!  */
+  struct buffer *b;
+
+  base_buffer = get_buffer (base_buffer, 1);
 
 #ifdef I18N3
   /* #### Doc string should indicate that the buffer name will get
      translated. */
 #endif
-
+  CHECK_STRING (name);
   name = LISP_GETTEXT (name);
-  buf = Fget_buffer (name);
-  if (!NILP (buf))
-    error ("Buffer name `%s' is in use", XSTRING_DATA (name));
-
-  base_buffer = Fget_buffer (base_buffer);
-  if (NILP (base_buffer))
-    error ("No such buffer: `%s'", XSTRING_DATA (XBUFFER (base_buffer)->name));
-
+  if (!NILP (Fget_buffer (name)))
+    signal_simple_error ("Buffer name already in use", name);
   if (XSTRING_LENGTH (name) == 0)
     error ("Empty string for buffer name is not allowed");
 
   b = allocate_buffer ();
 
-  if (XBUFFER (base_buffer)->base_buffer)
-    b->base_buffer = XBUFFER (base_buffer)->base_buffer;
-  else
-    b->base_buffer = XBUFFER (base_buffer);
+  b->base_buffer = BUFFER_BASE_BUFFER (XBUFFER (base_buffer));
 
   /* Use the base buffer's text object.  */
   b->text = b->base_buffer->text;
   b->indirect_children = Qnil;
-  XSETBUFFER (buf, b);
   b->base_buffer->indirect_children =
-    Fcons (buf, b->base_buffer->indirect_children);
-  init_buffer_text (b, 1);
+    Fcons (make_buffer (b), b->base_buffer->indirect_children);
+  init_buffer_text (b);
 
   return finish_init_buffer (b, name);
 }
-#endif /* 0 */
 
 
 \f
@@ -814,41 +811,6 @@ If BUFFER is indirect, the return value will always be nil; see
   return Fcopy_sequence (buf->indirect_children);
 }
 
-/* Map MAPFUN over all buffers that share the same text as BUF
-   (this includes BUF).  Pass two arguments to MAPFUN: a buffer,
-   and CLOSURE.  If any invocation of MAPFUN returns non-zero,
-   halt immediately and return that value.  Otherwise, continue
-   the mapping to the end and return 0. */
-
-int
-map_over_sharing_buffers (struct buffer *buf,
-                         int (*mapfun) (struct buffer *buf, void *closure),
-                         void *closure)
-{
-  int result;
-  Lisp_Object tail;
-
-  if (buf->base_buffer)
-    {
-      buf = buf->base_buffer;
-      assert (!buf->base_buffer);
-    }
-
-  result = (mapfun) (buf, closure);
-  if (result)
-    return result;
-
-  LIST_LOOP (tail, buf->indirect_children)
-    {
-      Lisp_Object buffer = XCAR (tail);
-      result = (mapfun) (XBUFFER (buffer), closure);
-      if (result)
-       return result;
-    }
-
-  return 0;
-}
-
 DEFUN ("buffer-local-variables", Fbuffer_local_variables, 0, 1, 0, /*
 Return an alist of variables that are buffer-local in BUFFER.
 Most elements look like (SYMBOL . VALUE), describing one variable.
@@ -1287,7 +1249,12 @@ with `delete-process'.
       GCPRO1 (buf);
 
       LIST_LOOP (rest, b->indirect_children)
-       Fkill_buffer (XCAR (rest));
+       {
+         Fkill_buffer (XCAR (rest));
+         /* Keep indirect_children updated in case a
+             query-function/hook throws.  */
+         b->indirect_children = XCDR (rest);
+       }
 
       UNGCPRO;
     }
@@ -1372,7 +1339,7 @@ with `delete-process'.
     kill_buffer_local_variables (b);
 
     b->name = Qnil;
-    uninit_buffer_text (b, !!b->base_buffer);
+    uninit_buffer_text (b);
     b->undo_list = Qnil;
     uninit_buffer_extents (b);
     if (b->base_buffer)
@@ -1869,9 +1836,7 @@ syms_of_buffer (void)
   DEFSUBR (Fget_buffer);
   DEFSUBR (Fget_file_buffer);
   DEFSUBR (Fget_buffer_create);
-#if 0
   DEFSUBR (Fmake_indirect_buffer);
-#endif
 
   DEFSUBR (Fgenerate_new_buffer_name);
   DEFSUBR (Fbuffer_name);
index 7e0ce23..0a7b634 100644 (file)
@@ -102,6 +102,10 @@ struct buffer_text
   Bytind mule_bytind_cache[16];
 #endif
 
+  /* Similar to the above, we keep track of positions for which line
+     number has last been calculated.  See line-number.c. */
+  Lisp_Object line_number_cache;
+
   /* Change data that goes with the text. */
   struct buffer_text_change_data *changes;
 
@@ -233,6 +237,23 @@ DECLARE_LRECORD (buffer, struct buffer);
     x = wrong_type_argument (Qbuffer_live_p, (x));     \
 } while (0)
 
+#define BUFFER_BASE_BUFFER(b) ((b)->base_buffer ? (b)->base_buffer : (b))
+
+/* Map over buffers sharing the same text as MPS_BUF.  MPS_BUFVAR is a
+   variable that gets the buffer values (beginning with the base
+   buffer, then the children), and MPS_BUFCONS should be a temporary
+   Lisp_Object variable.  */
+#define MAP_INDIRECT_BUFFERS(mps_buf, mps_bufvar, mps_bufcons)                 \
+for (mps_bufcons = Qunbound,                                                   \
+     mps_bufvar = BUFFER_BASE_BUFFER (mps_buf);                                        \
+     UNBOUNDP (mps_bufcons) ?                                                  \
+       (mps_bufcons = mps_bufvar->indirect_children,                           \
+       1)                                                                      \
+       : (!NILP (mps_bufcons)                                                  \
+         && (mps_bufvar = XBUFFER (XCAR (mps_bufcons)), 1)                     \
+         && (mps_bufcons = XCDR (mps_bufcons), 1));                            \
+     )
+
 \f
 /* NOTE: In all the following macros, we follow these rules concerning
    multiple evaluation of the arguments:
index 000a943..e3e4b16 100644 (file)
@@ -241,7 +241,3 @@ Boston, MA 02111-1307, USA.  */
        the next few times we add a new slot.  */
     MARKED_SLOT (extra1, extra2, extra3);
 #endif
-  /* The cache of positions for whilch line number has last been
-     calculated.  See line-number.c. */
-    MARKED_SLOT (line_number_cache);
-
index d1cd907..dac2dfb 100644 (file)
@@ -715,7 +715,14 @@ when reading the arguments.
             }
          case 'k':             /* Key sequence (vector of events) */
            {
-             Lisp_Object tem = Fread_key_sequence (PROMPT (), Qnil, Qnil);
+             struct gcpro ngcpro1;
+             Lisp_Object tem;
+             Lisp_Object key_prompt = PROMPT ();
+
+             NGCPRO1(key_prompt);
+             tem = Fread_key_sequence (key_prompt, Qnil, Qnil);
+             NUNGCPRO;
+
              visargs[argnum] = Fkey_description (tem);
              /* The following makes `describe-key' not work with
                 extent-local keymaps and such; and anyway, it's
@@ -728,7 +735,14 @@ when reading the arguments.
          case 'K':             /* Key sequence (vector of events),
                                   no automatic downcasing */
            {
-             Lisp_Object tem = Fread_key_sequence (PROMPT (), Qnil, Qt);
+             struct gcpro ngcpro1;
+             Lisp_Object tem;
+             Lisp_Object key_prompt = PROMPT ();
+
+             NGCPRO1(key_prompt);
+             tem = Fread_key_sequence (key_prompt, Qnil, Qt);
+             NUNGCPRO;
+
              visargs[argnum] = Fkey_description (tem);
              /* The following makes `describe-key' not work with
                 extent-local keymaps and such; and anyway, it's
index cb21d57..78f3789 100644 (file)
@@ -1,5 +1,5 @@
 /* XEmacs case conversion functions.
-   Copyright (C) 1985, 1992, 1993, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
 
 This file is part of XEmacs.
 
@@ -18,13 +18,12 @@ 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: FSF 19.34. */
+/* Synched up with: FSF 19.34, but substantially rewritten by Martin. */
 
 #include <config.h>
 #include "lisp.h"
 
 #include "buffer.h"
-#include "commands.h"
 #include "insdel.h"
 #include "syntax.h"
 
@@ -34,100 +33,117 @@ static Lisp_Object
 casify_object (enum case_action flag, Lisp_Object obj, Lisp_Object buffer)
 {
   struct buffer *buf = decode_buffer (buffer, 0);
-  REGISTER int inword = (flag == CASE_DOWN);
-  struct Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
 
-  while (1)
+ retry:
+
+  if (CHAR_OR_CHAR_INTP (obj))
     {
-      if (CHAR_OR_CHAR_INTP (obj))
-       {
-         Emchar c;
-         CHECK_CHAR_COERCE_INT (obj);
-         c = XCHAR (obj);
-         if (IN_TRT_TABLE_DOMAIN (c))
-           {
-             if (inword)
-               obj = make_char (DOWNCASE (buf, c));
-             else if (!UPPERCASEP (buf, c))
-               obj = make_char (UPCASE1 (buf, c));
-           }
-         return obj;
-       }
-      if (STRINGP (obj))
+      Emchar c;
+      CHECK_CHAR_COERCE_INT (obj);
+      c = XCHAR (obj);
+      c = (flag == CASE_DOWN) ? DOWNCASE (buf, c) : UPCASE (buf, c);
+      return make_char (c);
+    }
+
+  if (STRINGP (obj))
+    {
+      struct Lisp_Char_Table *syntax_table =
+       XCHAR_TABLE (buf->mirror_syntax_table);
+      Bufbyte *storage =
+       alloca_array (Bufbyte, XSTRING_LENGTH (obj) * MAX_EMCHAR_LEN);
+      Bufbyte *newp = storage;
+      Bufbyte *oldp = XSTRING_DATA (obj);
+      int wordp = 0, wordp_prev;
+
+      while (*oldp)
        {
-         Charcount i;
-         Charcount len = XSTRING_CHAR_LENGTH (obj);
-         obj = Fcopy_sequence (obj);
-         for (i = 0; i < len; i++)
+         Emchar c = charptr_emchar (oldp);
+         switch (flag)
            {
-             Emchar c = string_char (XSTRING (obj), i);
-             if (inword && flag != CASE_CAPITALIZE_UP)
-               c = DOWNCASE (buf, c);
-             else if (!UPPERCASEP (buf, c)
-                      && (!inword || flag != CASE_CAPITALIZE_UP))
-               c = UPCASE1 (buf, c);
-             set_string_char (XSTRING (obj), i, c);
-             if ((int) flag >= (int) CASE_CAPITALIZE)
-               inword = WORD_SYNTAX_P (syntax_table, c);
+           case CASE_UP:
+             c = UPCASE (buf, c);
+             break;
+           case CASE_DOWN:
+             c = DOWNCASE (buf, c);
+             break;
+           case CASE_CAPITALIZE:
+           case CASE_CAPITALIZE_UP:
+             wordp_prev = wordp;
+             wordp = WORD_SYNTAX_P (syntax_table, c);
+             if (!wordp) break;
+             if (wordp_prev)
+               {
+                 if (flag == CASE_CAPITALIZE)
+                   c = DOWNCASE (buf, c);
+               }
+             else
+               c = UPCASE (buf, c);
+             break;
            }
-         return obj;
+
+         newp += set_charptr_emchar (newp, c);
+         INC_CHARPTR (oldp);
        }
-      obj = wrong_type_argument (Qchar_or_string_p, obj);
+
+      return make_string (storage, newp - storage);
     }
+
+  obj = wrong_type_argument (Qchar_or_string_p, obj);
+  goto retry;
 }
 
 DEFUN ("upcase", Fupcase, 1, 2, 0, /*
-Convert argument to upper case and return that.
-The argument may be a character or string.  The result has the same type.
-The argument object is not altered--the value is a copy.
+Convert OBJECT to upper case and return that.
+OBJECT may be a character or string.  The result has the same type.
+OBJECT is not altered--the value is a copy.
 See also `capitalize', `downcase' and `upcase-initials'.
 Optional second arg BUFFER specifies which buffer's case tables to use,
  and defaults to the current buffer.
 */
-       (obj, buffer))
+       (object, buffer))
 {
-  return casify_object (CASE_UP, obj, buffer);
+  return casify_object (CASE_UP, object, buffer);
 }
 
 DEFUN ("downcase", Fdowncase, 1, 2, 0, /*
-Convert argument to lower case and return that.
-The argument may be a character or string.  The result has the same type.
-The argument object is not altered--the value is a copy.
+Convert OBJECT to lower case and return that.
+OBJECT may be a character or string.  The result has the same type.
+OBJECT is not altered--the value is a copy.
 Optional second arg BUFFER specifies which buffer's case tables to use,
  and defaults to the current buffer.
 */
-       (obj, buffer))
+       (object, buffer))
 {
-  return casify_object (CASE_DOWN, obj, buffer);
+  return casify_object (CASE_DOWN, object, buffer);
 }
 
 DEFUN ("capitalize", Fcapitalize, 1, 2, 0, /*
-Convert argument to capitalized form and return that.
+Convert OBJECT to capitalized form and return that.
 This means that each word's first character is upper case
 and the rest is lower case.
-The argument may be a character or string.  The result has the same type.
-The argument object is not altered--the value is a copy.
+OBJECT may be a character or string.  The result has the same type.
+OBJECT is not altered--the value is a copy.
 Optional second arg BUFFER specifies which buffer's case tables to use,
  and defaults to the current buffer.
 */
-       (obj, buffer))
+       (object, buffer))
 {
-  return casify_object (CASE_CAPITALIZE, obj, buffer);
+  return casify_object (CASE_CAPITALIZE, object, buffer);
 }
 
-/* Like Fcapitalize but change only the initials.  */
+/* Like Fcapitalize but change only the initial characters.  */
 
 DEFUN ("upcase-initials", Fupcase_initials, 1, 2, 0, /*
-Convert the initial of each word in the argument to upper case.
+Convert the initial of each word in OBJECT to upper case.
 Do not change the other letters of each word.
-The argument may be a character or string.  The result has the same type.
-The argument object is not altered--the value is a copy.
+OBJECT may be a character or string.  The result has the same type.
+OBJECT is not altered--the value is a copy.
 Optional second arg BUFFER specifies which buffer's case tables to use,
  and defaults to the current buffer.
 */
-       (obj, buffer))
+       (object, buffer))
 {
-  return casify_object (CASE_CAPITALIZE_UP, obj, buffer);
+  return casify_object (CASE_CAPITALIZE_UP, object, buffer);
 }
 \f
 /* flag is CASE_UP, CASE_DOWN or CASE_CAPITALIZE or CASE_CAPITALIZE_UP.
@@ -140,9 +156,10 @@ casify_region_internal (enum case_action flag, Lisp_Object b, Lisp_Object e,
   /* This function can GC */
   REGISTER Bufpos i;
   Bufpos start, end;
-  REGISTER int inword = (flag == CASE_DOWN);
   struct Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
   int mccount;
+  Emchar oldc, c;
+  int wordp = 0, wordp_prev;
 
   if (EQ (b, e))
     /* Not modifying because nothing marked */
@@ -155,25 +172,38 @@ casify_region_internal (enum case_action flag, Lisp_Object b, Lisp_Object e,
 
   for (i = start; i < end; i++)
     {
-      Emchar c = BUF_FETCH_CHAR (buf, i);
-      Emchar oldc = c;
+      c = oldc = BUF_FETCH_CHAR (buf, i);
 
-      if (inword && flag != CASE_CAPITALIZE_UP)
-       c = DOWNCASE (buf, c);
-      else if (!UPPERCASEP (buf, c)
-              && (!inword || flag != CASE_CAPITALIZE_UP))
-       c = UPCASE1 (buf, c);
-
-      if (oldc != c)
+      switch (flag)
        {
-         buffer_replace_char (buf, i, c, 1, (i == start));
-         BUF_MODIFF (buf)++;
+       case CASE_UP:
+         c = UPCASE (buf, oldc);
+         break;
+       case CASE_DOWN:
+         c = DOWNCASE (buf, oldc);
+         break;
+       case CASE_CAPITALIZE:
+       case CASE_CAPITALIZE_UP:
+         /* !!#### need to revalidate the start and end pointers in case
+            the buffer was changed */
+         wordp_prev = wordp;
+         wordp = WORD_SYNTAX_P (syntax_table, c);
+         if (!wordp) continue;
+         if (wordp_prev)
+           {
+             if (flag == CASE_CAPITALIZE)
+               c = DOWNCASE (buf, c);
+           }
+         else
+           c = UPCASE (buf, c);
+         break;
        }
-      /* !!#### need to revalidate the start and end pointers in case
-        the buffer was changed */
-      if ((int) flag >= (int) CASE_CAPITALIZE)
-       inword = WORD_SYNTAX_P (syntax_table, c);
+
+      if (oldc == c) continue;
+      buffer_replace_char (buf, i, c, 1, (i == start));
+      BUF_MODIFF (buf)++;
     }
+
   end_multiple_change (buf, mccount);
 }
 
index d8508cc..b78318e 100644 (file)
@@ -194,6 +194,7 @@ char *alloca();
 #undef HAVE_ULIMIT_H
 #undef HAVE_X11_XLOCALE_H
 #undef HAVE_LINUX_VERSION_H
+#undef HAVE_CYGWIN32_VERSION_H
 #undef HAVE_INTTYPES_H
 #undef HAVE_SYS_UN_H
 #undef HAVE_A_OUT_H
index c78792e..45e2561 100644 (file)
@@ -251,4 +251,6 @@ HANDLE get_nt_process_handle (struct Lisp_Process *p);
 extern Lisp_Object Vmswindows_frame_being_created;
 extern Lisp_Object mswindows_frame_being_created;
 
+void mswindows_enumerate_fonts (struct device *d);
+
 #endif /* _XEMACS_CONSOLE_MSW_H_ */
index 91f91db..aa1f594 100644 (file)
@@ -70,6 +70,9 @@ struct x_device
   /* The X connection of this device. */
   Display *display;
 
+  /* Set by x_IO_error_handler(). */
+  int being_deleted;
+
   /* Xt application info. */
   Widget Xt_app_shell;
 
@@ -184,6 +187,7 @@ struct x_device
 
 #define FRAME_X_DISPLAY(f) (DEVICE_X_DISPLAY (XDEVICE (f->device)))
 #define DEVICE_X_DISPLAY(d)    (DEVICE_X_DATA (d)->display)
+#define DEVICE_X_BEING_DELETED(d) (DEVICE_X_DATA (d)->being_deleted)
 #define DEVICE_X_VISUAL(d)     (DEVICE_X_DATA (d)->visual)
 #define DEVICE_X_DEPTH(d)      (DEVICE_X_DATA (d)->depth)
 #define DEVICE_X_COLORMAP(d)   (DEVICE_X_DATA (d)->device_cmap)
index 266c014..2b8e28e 100644 (file)
@@ -39,13 +39,6 @@ Boston, MA 02111-1307, USA.  */
 #include "frame.h"
 #include "sysdep.h"
 
-#ifndef __CYGWIN32__
-#include <commctrl.h>
-#else
-#define FONTENUMPROC FONTENUMEXPROC
-#define ntmTm ntmentm
-#endif
-
 /* win32 DDE management library globals */
 #ifdef HAVE_DRAGNDROP
 DWORD mswindows_dde_mlid;
@@ -65,77 +58,11 @@ Lisp_Object Vmswindows_get_true_file_attributes;
 
 Lisp_Object Qinit_pre_mswindows_win, Qinit_post_mswindows_win;
 
-struct font_enum_t
-{
-  HDC hdc;
-  struct device *d;
-};
-
 
 /************************************************************************/
 /*                               helpers                                */
 /************************************************************************/
 
-static int CALLBACK
-font_enum_callback_2 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, 
-                     int FontType, struct font_enum_t *font_enum)
-{
-  struct mswindows_font_enum *fontlist, **fonthead;
-  char fontname[MSW_FONTSIZE];
-
-  /* The enumerated font weights are not to be trusted because:
-   *  a) lpelfe->elfStyle is only filled in for TrueType fonts.
-   *  b) Not all Bold and Italic styles of all fonts (inluding some Vector,
-   *     Truetype and Raster fonts) are enumerated.
-   * I guess that fonts for which Bold and Italic styles are generated
-   * 'on-the-fly' are not enumerated. It would be overly restrictive to
-   * disallow Bold And Italic weights for these fonts, so we just leave
-   * weights unspecified. This means that we have to weed out duplicates of
-   * those fonts that do get enumerated with different weights. */
-
-  if (FontType == 0 /*vector*/ || FontType == TRUETYPE_FONTTYPE)
-    /* Scalable, so leave pointsize blank */
-    sprintf (fontname, "%s::::%s", lpelfe->elfLogFont.lfFaceName,
-            lpelfe->elfScript);
-  else
-    /* Formula for pointsize->height from LOGFONT docs in Platform SDK */
-    sprintf (fontname, "%s::%d::%s", lpelfe->elfLogFont.lfFaceName,
-            MulDiv (lpntme->ntmTm.tmHeight - lpntme->ntmTm.tmInternalLeading,
-                    72, DEVICE_MSWINDOWS_LOGPIXELSY (font_enum->d)),
-             lpelfe->elfScript);
-
-  fonthead = &DEVICE_MSWINDOWS_FONTLIST (font_enum->d);
-  fontlist = *fonthead;
-  while (fontlist)
-    if (!strcmp (fontname, fontlist->fontname))
-      return 1;                /* found a duplicate */
-    else
-      fontlist = fontlist->next;
-
-  /* Insert entry at head */
-  fontlist = *fonthead;
-  *fonthead = xmalloc (sizeof (struct mswindows_font_enum));
-  if (*fonthead == NULL)
-    {
-      *fonthead = fontlist;
-      return 0;
-    }
-  strcpy ((*fonthead)->fontname, fontname);
-  (*fonthead)->next = fontlist;
-  return 1;
-}
-
-static int CALLBACK
-font_enum_callback_1 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, 
-                     int FontType, struct font_enum_t *font_enum)
-{
-  /* This function gets called once per facename per character set.
-   * We call a second callback to enumerate the fonts in each facename */
-  return EnumFontFamiliesEx (font_enum->hdc, &lpelfe->elfLogFont,
-                            (FONTENUMPROC) font_enum_callback_2,
-                            (LPARAM) font_enum, 0);
-}
-
 static Lisp_Object
 build_syscolor_string (int index)
 {
@@ -182,8 +109,6 @@ mswindows_init_device (struct device *d, Lisp_Object props)
 {
   WNDCLASSEX wc;
   HDC hdc;
-  LOGFONT logfont;
-  struct font_enum_t font_enum;
 
   DEVICE_CLASS (d) = Qcolor;
   DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1;
@@ -204,17 +129,10 @@ mswindows_init_device (struct device *d, Lisp_Object props)
   DEVICE_MSWINDOWS_HORZSIZE(d) = GetDeviceCaps(hdc, HORZSIZE);
   DEVICE_MSWINDOWS_VERTSIZE(d) = GetDeviceCaps(hdc, VERTSIZE);
   DEVICE_MSWINDOWS_BITSPIXEL(d) = GetDeviceCaps(hdc, BITSPIXEL);
-
-  DEVICE_MSWINDOWS_FONTLIST (d) = NULL;
-  logfont.lfCharSet = DEFAULT_CHARSET;
-  logfont.lfFaceName[0] = '\0';
-  logfont.lfPitchAndFamily = DEFAULT_PITCH;
-  font_enum.hdc = hdc;
-  font_enum.d = d;
-  EnumFontFamiliesEx (hdc, &logfont, (FONTENUMPROC) font_enum_callback_1,
-                     (LPARAM) (&font_enum), 0);
   DeleteDC (hdc);
 
+  mswindows_enumerate_fonts (d);
+
   /* Register the main window class */
   wc.cbSize = sizeof (WNDCLASSEX);
   wc.style = CS_OWNDC; /* One DC per window */
index 6a9c7b9..b0cad36 100644 (file)
@@ -62,9 +62,6 @@ Lisp_Object Vx_app_defaults_directory;
 Lisp_Object Qx_error;
 Lisp_Object Qinit_pre_x_win, Qinit_post_x_win;
 
-/* \e$B@ZJ"\e(B, n.  Japanese ritual suicide. */
-int x_seppuku_on_epipe;
-
 /* The application class of Emacs. */
 Lisp_Object Vx_emacs_application_class;
 
@@ -880,10 +877,8 @@ x_IO_error_handler (Display *disp)
   Lisp_Object dev;
   struct device *d = get_device_from_display_1 (disp);
 
-  if (d)
-    XSETDEVICE (dev, d);
-  else
-    dev = Qnil;
+  assert (d != NULL);
+  XSETDEVICE (dev, d);
 
   if (NILP (find_nonminibuffer_frame_not_on_device (dev)))
     {
@@ -903,31 +898,24 @@ x_IO_error_handler (Display *disp)
     {
       warn_when_safe
        (Qx, Qcritical,
-        "I/O Error %d (%s) on display connection \"%s\"\n"
-        "  after %lu requests (%lu known processed) with "
-        "%d events remaining.\n",
+        "I/O Error %d (%s) on display connection\n"
+        "  \"%s\" after after %lu requests (%lu known processed)\n"
+        "  with %d events remaining.\n"
+        "  Throwing to top level.\n",
         errno, strerror (errno), DisplayString (disp),
          NextRequest (disp) - 1, LastKnownRequestProcessed (disp),
          QLength (disp));
     }
 
+  /* According to X specs, we should not return from this function, or
+     Xlib might just decide to exit().  So we mark the offending
+     console for deletion and throw to top level.  */
   if (d)
     enqueue_magic_eval_event (io_error_delete_device, dev);
+  DEVICE_X_BEING_DELETED (d) = 1;
+  Fthrow (Qtop_level, Qnil);
 
-  /* CvE, July 16, 1996, XEmacs 19.14 */
-  /* Test for broken pipe error, which indicates X-server has gone down */
-  if (errno == EPIPE && x_seppuku_on_epipe)
-    {
-      /* Most probably X-server has gone down: Avoid infinite loop by just */
-      /* exiting */
-      /* slb:  This sounds really, really dangerous to do by default, so */
-      /* I'm adding a guard to avoid doing this as default behavior */
-      stderr_out( "\n\nXEmacs exiting on broken pipe (errno %d, %s)\n",
-                 errno, strerror(errno));
-      exit(errno);
-    }
-
-  return 0;
+  RETURN_NOT_REACHED (0);
 }
 
 DEFUN ("x-debug-mode", Fx_debug_mode, 1, 2, 0, /*
@@ -1734,14 +1722,6 @@ just reside in C.
 */ );
   Vx_initial_argv_list = Qnil;
 
-  DEFVAR_BOOL ("x-seppuku-on-epipe", &x_seppuku_on_epipe /*
-When non-nil, terminate XEmacs immediately on SIGPIPE from the X server.
-XEmacs doesn't terminate properly on some systems.
-When this variable is non-nil, XEmacs will commit immediate suicide
-when it gets a sigpipe from the X Server.
-*/ );
-  x_seppuku_on_epipe = 0;
-
 #if defined(MULE) && (defined(LWLIB_MENUBARS_MOTIF) || defined(HAVE_XIM) || defined (USE_XFONTSET))
   DEFVAR_LISP ("x-app-defaults-directory", &Vx_app_defaults_directory /*
 Used by the Lisp code to communicate to the low level X initialization
index e96ff39..44d69ba 100644 (file)
@@ -817,6 +817,9 @@ delete_device_internal (struct device *d, int force,
 void
 io_error_delete_device (Lisp_Object device)
 {
+  /* Note: it's the console that should get deleted, but
+     delete_device_internal() contains a hack that also deletes the
+     console when called from this function.  */
   delete_device_internal (XDEVICE (device), 1, 0, 1);
 }
 
index b8c35f2..076e339 100644 (file)
@@ -30,6 +30,8 @@ Boston, MA 02111-1307, USA.  */
 #include "opaque.h"
 #include "sysfile.h"
 #include "sysdir.h"
+#include "systime.h"
+#include "syspwd.h"
 
 Lisp_Object Vcompletion_ignored_extensions;
 Lisp_Object Qdirectory_files;
@@ -294,11 +296,12 @@ file_name_completion_unwind (Lisp_Object locative)
   DIR *d;
   Lisp_Object obj = XCAR (locative);
 
-  if (NILP (obj))
-    return Qnil;
-  d = (DIR *)get_opaque_ptr (obj);
-  closedir (d);
-  free_opaque_ptr (obj);
+  if (!NILP (obj))
+    {
+      d = (DIR *)get_opaque_ptr (obj);
+      closedir (d);
+      free_opaque_ptr (obj);
+    }
   free_cons (XCONS (locative));
   return Qnil;
 }
@@ -528,6 +531,252 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag,
 }
 
 \f
+static Lisp_Object user_name_completion (Lisp_Object user,
+                                         int all_flag,
+                                         int *uniq);
+
+DEFUN ("user-name-completion", Fuser_name_completion, 1, 1, 0, /*
+Complete user name USER.
+
+Returns the longest string common to all user names that start
+with USER.  If there is only one and USER matches it exactly,
+returns t.  Returns nil if there is no user name starting with USER.
+*/
+       (user))
+{
+  return user_name_completion (user, 0, NULL);
+}
+
+DEFUN ("user-name-completion-1", Fuser_name_completion_1, 1, 1, 0, /*
+Complete user name USER.
+
+This function is identical to `user-name-completion', except that
+the cons of the completion and an indication of whether the
+completion was unique is returned.
+
+The car of the returned value is the longest string common to all
+user names that start with USER.  If there is only one and USER
+matches it exactly, the car is t.  The car is nil if there is no
+user name starting with USER.  The cdr of the result is non-nil
+if and only if the completion returned in the car was unique.
+*/
+       (user))
+{
+  int uniq;
+  Lisp_Object completed;
+
+  completed = user_name_completion (user, 0, &uniq);
+  return Fcons (completed, uniq ? Qt : Qnil);
+}
+
+DEFUN ("user-name-all-completions", Fuser_name_all_completions, 1, 1, 0, /*
+Return a list of all completions of user name USER.
+These are all user names which begin with USER.
+*/
+       (user))
+{
+  return user_name_completion (user, 1, NULL);
+}
+
+static Lisp_Object
+user_name_completion_unwind (Lisp_Object locative)
+{
+  Lisp_Object obj1 = XCAR (locative);
+  Lisp_Object obj2 = XCDR (locative);
+  char **cache;
+  int clen, i;
+
+
+  if (!NILP (obj1) && !NILP (obj2))
+    {
+      /* clean up if interrupted building cache */
+      cache = *(char ***)get_opaque_ptr (obj1);
+      clen  = *(int *)get_opaque_ptr (obj2);
+      free_opaque_ptr (obj1);
+      free_opaque_ptr (obj2);
+      for (i = 0; i < clen; i++)
+        free (cache[i]);
+      free (cache);
+    }
+
+  free_cons (XCONS (locative));
+  endpwent ();
+
+  return Qnil;
+}
+
+static char **user_cache;
+static int user_cache_len;
+static int user_cache_max;
+static long user_cache_time;
+
+#define  USER_CACHE_REBUILD  (24*60*60)  /* 1 day, in seconds */
+
+static Lisp_Object
+user_name_completion (Lisp_Object user, int all_flag, int *uniq)
+{
+  /* This function can GC */
+  struct passwd *pw;
+  int matchcount = 0;
+  Lisp_Object bestmatch = Qnil;
+  Charcount bestmatchsize = 0;
+  int speccount = specpdl_depth ();
+  int i, cmax, clen;
+  char **cache;
+  Charcount user_name_length;
+  Lisp_Object locative;
+  EMACS_TIME t;
+  struct gcpro gcpro1, gcpro2;
+
+  GCPRO2 (user, bestmatch);
+
+  CHECK_STRING (user);
+
+  user_name_length = XSTRING_CHAR_LENGTH (user);
+
+  /* Cache user name lookups because it tends to be quite slow.
+   * Rebuild the cache occasionally to catch changes */
+  EMACS_GET_TIME (t);
+  if (user_cache  &&
+      EMACS_SECS (t) - user_cache_time > USER_CACHE_REBUILD)
+    {
+      for (i = 0; i < user_cache_len; i++)
+        free (user_cache[i]);
+      free (user_cache);
+      user_cache = NULL;
+      user_cache_len = 0;
+      user_cache_max = 0;
+    }
+
+  if (user_cache == NULL || user_cache_max <= 0)
+    {
+      cmax  = 200;
+      clen  = 0;
+      cache = (char **) malloc (cmax*sizeof (char *));
+
+      setpwent ();
+      locative = noseeum_cons (Qnil, Qnil);
+      XCAR (locative) = make_opaque_ptr ((void *) &cache);
+      XCDR (locative) = make_opaque_ptr ((void *) &clen);
+      record_unwind_protect (user_name_completion_unwind, locative);
+      /* #### may need to slow down interrupts around call to getpwent
+       * below.  at least the call to getpwnam in Fuser_full_name
+       * is documented as needing it on irix. */
+      while ((pw = getpwent ()))
+        {
+          if (clen >= cmax)
+            {
+              cmax *= 2;
+              cache = (char **) realloc (cache, cmax*sizeof (char *));
+            }
+
+          QUIT;
+
+          cache[clen++] = strdup (pw->pw_name);
+        }
+      free_opaque_ptr (XCAR (locative));
+      free_opaque_ptr (XCDR (locative));
+      XCAR (locative) = Qnil;
+      XCDR (locative) = Qnil;
+
+      unbind_to (speccount, Qnil); /* free locative cons, endpwent() */
+
+      user_cache_max = cmax;
+      user_cache_len = clen;
+      user_cache = cache;
+      user_cache_time = EMACS_SECS (t);
+    }
+
+  for (i = 0; i < user_cache_len; i++)
+    {
+      Bytecount len;
+      /* scmp() works in chars, not bytes, so we have to compute this: */
+      Charcount cclen;
+      Bufbyte *d_name;
+
+      d_name = (Bufbyte *) user_cache[i];
+      len = strlen (d_name);
+      cclen = bytecount_to_charcount (d_name, len);
+
+      QUIT;
+
+      if (cclen < user_name_length   ||
+          0 <= scmp (d_name, XSTRING_DATA (user), user_name_length))
+        continue;
+
+      matchcount++;    /* count matching completions */
+
+      if (all_flag || NILP (bestmatch))
+        {
+          Lisp_Object name = Qnil;
+          struct gcpro ngcpro1;
+          NGCPRO1 (name);
+          /* This is a possible completion */
+          name = make_string (d_name, len);
+          if (all_flag)
+            {
+              bestmatch = Fcons (name, bestmatch);
+            }
+          else
+            {
+              bestmatch = name;
+              bestmatchsize = XSTRING_CHAR_LENGTH (name);
+            }
+          NUNGCPRO;
+        }
+      else
+        {
+          Charcount compare = min (bestmatchsize, cclen);
+          Bufbyte *p1 = XSTRING_DATA (bestmatch);
+          Bufbyte *p2 = d_name;
+          Charcount matchsize = scmp (p1, p2, compare);
+
+          if (matchsize < 0)
+            matchsize = compare;
+          if (completion_ignore_case)
+            {
+              /* If this is an exact match except for case,
+                 use it as the best match rather than one that is not
+                 an exact match.  This way, we get the case pattern
+                 of the actual match.  */
+              if ((matchsize == cclen
+                   && matchsize < XSTRING_CHAR_LENGTH (bestmatch))
+                  ||
+                  /* If there is no exact match ignoring case,
+                     prefer a match that does not change the case
+                     of the input.  */
+                  (((matchsize == cclen)
+                    ==
+                    (matchsize == XSTRING_CHAR_LENGTH (bestmatch)))
+                   /* If there is more than one exact match aside from
+                      case, and one of them is exact including case,
+                      prefer that one.  */
+                   && 0 > scmp_1 (p2, XSTRING_DATA (user),
+                                  user_name_length, 0)
+                   && 0 <= scmp_1 (p1, XSTRING_DATA (user),
+                                   user_name_length, 0)))
+                {
+                  bestmatch = make_string (d_name, len);
+                }
+            }
+
+          bestmatchsize = matchsize;
+        }
+    }
+
+  UNGCPRO;
+
+  if (uniq)
+    *uniq = (matchcount == 1);
+
+  if (all_flag || NILP (bestmatch))
+    return bestmatch;
+  if (matchcount == 1 && bestmatchsize == user_name_length)
+    return Qt;
+  return Fsubstring (bestmatch, Qzero, make_int (bestmatchsize));
+}
+
+\f
 Lisp_Object
 make_directory_hash_table (CONST char *path)
 {
@@ -689,6 +938,9 @@ syms_of_dired (void)
   DEFSUBR (Fdirectory_files);
   DEFSUBR (Ffile_name_completion);
   DEFSUBR (Ffile_name_all_completions);
+  DEFSUBR (Fuser_name_completion);
+  DEFSUBR (Fuser_name_completion_1);
+  DEFSUBR (Fuser_name_all_completions);
   DEFSUBR (Ffile_attributes);
 }
 
@@ -703,4 +955,8 @@ It is used by the functions `file-name-completion' and
 `file-name-all-completions'.
 */ );
   Vcompletion_ignored_extensions = Qnil;
+
+  user_cache = NULL;
+  user_cache_len = 0;
+  user_cache_max = 0;
 }
index 5114354..edad0fc 100644 (file)
@@ -612,6 +612,9 @@ main_1 (int argc, char **argv, char **envp, int restart)
 #if defined (HAVE_MMAP) && defined (REL_ALLOC)
   /* ralloc can only be used if using the GNU memory allocator. */
   init_ralloc ();
+#elif defined (REL_ALLOC) && !defined(DOUG_LEA_MALLOC)
+  if (initialized)
+    init_ralloc();
 #endif
 
 #ifdef HAVE_SOCKS
@@ -1278,9 +1281,6 @@ main_1 (int argc, char **argv, char **envp, int restart)
       vars_of_extents ();
       vars_of_faces ();
       vars_of_fileio ();
-#ifdef CLASH_DETECTION
-      vars_of_filelock ();
-#endif
       vars_of_floatfns ();
       vars_of_font_lock ();
       vars_of_frame ();
@@ -1535,10 +1535,6 @@ main_1 (int argc, char **argv, char **envp, int restart)
         might depend on all sorts of things; I'm not sure. */
       complex_vars_of_emacs ();
 
-#ifdef CLASH_DETECTION
-      complex_vars_of_filelock ();
-#endif /* CLASH_DETECTION */
-
       /* This creates a couple of basic keymaps and depends on Lisp
         hashtables and Ffset() (both of which depend on some variables
         initialized in the vars_of_*() section) and possibly other
index e852322..5052edd 100644 (file)
@@ -658,6 +658,9 @@ void
 emacs_Xt_mapping_action (Widget w, XEvent* event)
 {
   struct device *d = get_device_from_display (event->xany.display);
+
+  if (DEVICE_X_BEING_DELETED (d))
+    return;
 #if 0
   /* nyet.  Now this is handled by Xt. */
   XRefreshKeyboardMapping (&event->xmapping);
@@ -769,7 +772,7 @@ x_to_emacs_keysym (XKeyPressedEvent *event, int simple_p)
      /* simple_p means don't try too hard (ASCII only) */
 {
   KeySym keysym = 0;
-
+  
 #ifdef HAVE_XIM
   int len;
   char buffer[64];
@@ -794,7 +797,8 @@ x_to_emacs_keysym (XKeyPressedEvent *event, int simple_p)
          than passing in 0) to avoid crashes on German IRIX */
       char dummy[256];
       XLookupString (event, dummy, 200, &keysym, 0);
-      return x_keysym_to_emacs_keysym (keysym, simple_p);
+      return (IsModifierKey (keysym) || keysym == XK_Mode_switch )
+       ? Qnil : x_keysym_to_emacs_keysym (keysym, simple_p);
     }
 #endif /* ! XIM_MOTIF */
 
@@ -843,7 +847,8 @@ x_to_emacs_keysym (XKeyPressedEvent *event, int simple_p)
     {
     case XLookupKeySym:
     case XLookupBoth:
-      return x_keysym_to_emacs_keysym (keysym, simple_p);
+      return (IsModifierKey (keysym) || keysym == XK_Mode_switch )
+       ? Qnil : x_keysym_to_emacs_keysym (keysym, simple_p);
 
     case XLookupChars:
       {
@@ -921,6 +926,10 @@ x_event_to_emacs_event (XEvent *x_event, struct Lisp_Event *emacs_event)
   struct device *d    = get_device_from_display (display);
   struct x_device *xd = DEVICE_X_DATA (d);
 
+  if (DEVICE_X_BEING_DELETED (d))
+     /* #### Uh, is this 0 correct? */
+     return 0;
+
   set_last_server_timestamp (d, x_event);
 
   switch (x_event->type)
@@ -983,20 +992,16 @@ x_event_to_emacs_event (XEvent *x_event, struct Lisp_Event *emacs_event)
          {
            Lisp_Object keysym;
            XKeyEvent *ev = &x_event->xkey;
-           KeyCode keycode = ev->keycode;
-
-           if (x_key_is_modifier_p (keycode, d)) /* it's a modifier key */
-             return 0;
-
            /* This used to compute the frame from the given X window and
               store it here, but we really don't care about the frame. */
            emacs_event->channel = DEVICE_CONSOLE (d);
            keysym = x_to_emacs_keysym (&x_event->xkey, 0);
 
-           /* If the emacs keysym is nil, then that means that the
-              X keysym was NoSymbol, which probably means that
-              we're in the midst of reading a Multi_key sequence,
-              or a "dead" key prefix, or XIM input.  Ignore it. */
+           /* If the emacs keysym is nil, then that means that the X
+              keysym was either a Modifier or NoSymbol, which
+              probably means that we're in the midst of reading a
+              Multi_key sequence, or a "dead" key prefix, or XIM
+              input. Ignore it. */
            if (NILP (keysym))
              return 0;
 
@@ -1337,14 +1342,17 @@ void emacs_Xt_handle_focus_event (XEvent *event);
 void
 emacs_Xt_handle_focus_event (XEvent *event)
 {
+  struct device *d = get_device_from_display (event->xany.display);
+  struct frame *f;
+
+  if (DEVICE_X_BEING_DELETED (d))
+    return;
+
   /*
    * It's curious that we're using x_any_window_to_frame() instead
    * of x_window_to_frame().  I don't know what the impact of this is.
    */
-
-  struct frame *f =
-    x_any_window_to_frame (get_device_from_display (event->xany.display),
-                          event->xfocus.window);
+  f = x_any_window_to_frame (d, event->xfocus.window);
   if (!f)
     /* focus events are sometimes generated just before
        a frame is destroyed. */
@@ -1511,7 +1519,7 @@ emacs_Xt_handle_magic_event (struct Lisp_Event *emacs_event)
   XEvent *event = &emacs_event->event.magic.underlying_x_event;
   struct frame *f = XFRAME (EVENT_CHANNEL (emacs_event));
 
-  if (!FRAME_LIVE_P (f))
+  if (!FRAME_LIVE_P (f) || DEVICE_X_BEING_DELETED (XDEVICE (FRAME_DEVICE (f))))
     return;
 
   switch (event->type)
index 09054fd..f31da31 100644 (file)
@@ -98,6 +98,7 @@ static struct event_stream *mswindows_event_stream;
 #ifdef HAVE_MSG_SELECT
 extern SELECT_TYPE input_wait_mask, non_fake_input_wait_mask;
 extern SELECT_TYPE process_only_mask, tty_only_mask;
+SELECT_TYPE zero_mask;
 extern int signal_event_pipe_initialized;
 int windows_fd;
 #endif
@@ -727,8 +728,11 @@ winsock_writer (Lstream *stream, CONST unsigned char *data, size_t size)
   
   {
     ResetEvent (str->ov.hEvent);
-    
-    if (WriteFile ((HANDLE)str->s, data, size, NULL, &str->ov)
+
+    /* Docs indicate that 4th parameter to WriteFile can be NULL since this is
+     * an overlapped operation. This fails on Win95 with winsock 1.x so we
+     * supply a spare address which is ignored by Win95 anyway. Sheesh. */
+    if (WriteFile ((HANDLE)str->s, data, size, (LPDWORD)&str->buffer, &str->ov)
        || GetLastError() == ERROR_IO_PENDING)
       str->pending_p = 1;
     else
@@ -1294,6 +1298,29 @@ mswindows_need_event (int badly_p)
          EMACS_TIME_TO_SELECT_TIME (sometime, select_time_to_block);
          pointer_to_this = &select_time_to_block;
        }
+
+      /* select() is slow and buggy so if we don't have any processes
+         just wait as normal */
+      if (memcmp (&process_only_mask, &zero_mask, sizeof(SELECT_TYPE))==0)
+       {
+         /* Now try getting a message or process event */
+         active = MsgWaitForMultipleObjects (0, mswindows_waitable_handles,
+                                             FALSE, badly_p ? INFINITE : 0,
+                                             QS_ALLINPUT);
+         
+         if (active == WAIT_TIMEOUT)
+           {
+             /* No luck trying - just return what we've already got */
+             return;
+           }
+         else if (active == WAIT_OBJECT_0)
+           {
+             /* Got your message, thanks */
+             mswindows_drain_windows_queue ();
+             continue;
+           }
+       }
+
       active = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this);
       
       if (active == 0)
@@ -1572,8 +1599,37 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     mswindows_enqueue_misc_user_event (fobj, Qeval, list3 (Qdelete_frame, fobj, Qt));
     break;
 
+  case WM_KEYUP:
+  case WM_SYSKEYUP:
+    /* See Win95 comment under WM_KEYDOWN */
+    {
+      BYTE keymap[256];
+
+      if (wParam == VK_CONTROL)
+        {
+         GetKeyboardState (keymap);
+         keymap [(lParam & 0x1000000) ? VK_RCONTROL : VK_LCONTROL] &= ~0x80;
+         SetKeyboardState (keymap);
+       }
+      else if (wParam == VK_MENU)
+       {
+         GetKeyboardState (keymap);
+         keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] &= ~0x80;
+         SetKeyboardState (keymap);
+       }
+    };
+    goto defproc;
+
   case WM_KEYDOWN:
   case WM_SYSKEYDOWN:
+    /* In some locales the right-hand Alt key is labelled AltGr. This key
+     * should produce alternative charcaters when combined with another key.
+     * eg on a German keyboard pressing AltGr+q should produce '@'.
+     * AltGr generates exactly the same keystrokes as LCtrl+RAlt. But if
+     * TranslateMessage() is called with *any* combination of Ctrl+Alt down,
+     * it translates as if AltGr were down.
+     * We get round this by removing all modifiers from the keymap before
+     * calling TranslateMessage() unless AltGr is *really* down. */
     {
       BYTE keymap[256];
       int has_AltGr = mswindows_current_layout_has_AltGr ();
@@ -1583,7 +1639,7 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       GetKeyboardState (keymap);
       mods = mswindows_modifier_state (keymap, has_AltGr);
 
-      /* Handle those keys that TranslateMessage won't generate a WM_CHAR for */
+      /* Handle those keys for which TranslateMessage won't generate a WM_CHAR */
       if (!NILP (keysym = mswindows_key_to_emacs_keysym(wParam, mods)))
        mswindows_enqueue_keypress_event (hwnd, keysym, mods);
       else
@@ -1591,12 +1647,21 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
          int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd)));
          BYTE keymap_orig[256];
          MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), (GetMessagePos()) };
+
+         /* GetKeyboardState() does not work as documented on Win95. We have
+          * to loosely track Left and Right modifiers on behalf of the OS,
+          * without screwing up Windows NT which tracks them properly. */
+         if (wParam == VK_CONTROL)
+           keymap [(lParam & 0x1000000) ? VK_RCONTROL : VK_LCONTROL] |= 0x80;
+         else if (wParam == VK_MENU)
+           keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] |= 0x80;
+
          memcpy (keymap_orig, keymap, 256);
 
          /* Remove shift modifier from an ascii character */
          mods &= ~MOD_SHIFT;
 
-         /* Clear control and alt modifiers out of the keymap */
+         /* Clear control and alt modifiers unless AltGr is pressed */
          keymap [VK_RCONTROL] = 0;
          keymap [VK_LMENU] = 0;
          if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) || !(keymap [VK_RMENU] & 0x80))
@@ -1608,7 +1673,7 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
            }
          SetKeyboardState (keymap);
 
-         /* Have some WM_[SYS]CHARS in the queue */
+         /* Maybe generate some WM_[SYS]CHARs in the queue */
          TranslateMessage (&msg);
 
          while (PeekMessage (&msg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE)
@@ -2778,9 +2843,7 @@ init_event_mswindows_late (void)
   windows_fd = open("/dev/windows", O_RDONLY | O_NONBLOCK, 0);
   assert (windows_fd>=0);
   FD_SET (windows_fd, &input_wait_mask);
-  /* for some reason I get blocks on the signal event pipe, which is
-     bad... 
-     signal_event_pipe_initialized = 0; */
+  FD_ZERO(&zero_mask);
 #endif
 
   event_stream = mswindows_event_stream;
index da6bde7..aa0f4fc 100644 (file)
@@ -921,6 +921,8 @@ mark_extent_auxiliary (Lisp_Object obj, void (*markobj) (Lisp_Object))
   ((markobj) (data->read_only));
   ((markobj) (data->mouse_face));
   ((markobj) (data->initial_redisplay_function));
+  ((markobj) (data->before_change_functions));
+  ((markobj) (data->after_change_functions));
   return data->parent;
 }
 
@@ -3156,6 +3158,8 @@ extent_remprop (Lisp_Object obj, Lisp_Object prop)
       || EQ (prop, Qpriority)
       || EQ (prop, Qface)
       || EQ (prop, Qinitial_redisplay_function)
+      || EQ (prop, Qafter_change_functions)
+      || EQ (prop, Qbefore_change_functions)
       || EQ (prop, Qmouse_face)
       || EQ (prop, Qhighlight)
       || EQ (prop, Qbegin_glyph_layout)
@@ -4602,6 +4606,105 @@ process_extents_for_deletion (Lisp_Object object, Bytind from,
                      ME_END_CLOSED | ME_MIGHT_MODIFY_EXTENTS);
 }
 
+/* ------------------------------- */
+/*   report_extent_modification()  */
+/* ------------------------------- */
+struct report_extent_modification_closure {
+  Lisp_Object buffer;
+  Bufpos start, end;
+  int afterp;
+  int speccount;
+};
+
+/* This juggling with the pointer to another file's global variable is
+   kind of yucky.  Perhaps I should just export the variable.  */
+static int *inside_change_hook_pointer;
+
+static Lisp_Object
+report_extent_modification_restore (Lisp_Object buffer)
+{
+  *inside_change_hook_pointer = 0;
+  if (current_buffer != XBUFFER (buffer))
+    Fset_buffer (buffer);
+  return Qnil;
+}
+
+static int
+report_extent_modification_mapper (EXTENT extent, void *arg)
+{
+  struct report_extent_modification_closure *closure =
+    (struct report_extent_modification_closure *)arg;
+  Lisp_Object exobj, startobj, endobj;
+  Lisp_Object hook = (closure->afterp
+                     ? extent_after_change_functions (extent)
+                     : extent_before_change_functions (extent));
+  if (NILP (hook))
+    return 0;
+
+  XSETEXTENT (exobj, extent);
+  XSETINT (startobj, closure->start);
+  XSETINT (endobj, closure->end);
+
+  /* Now that we are sure to call elisp, set up an unwind-protect so
+     inside_change_hook gets restored in case we throw.  Also record
+     the current buffer, in case we change it.  Do the recording only
+     once.  */
+  if (closure->speccount == -1)
+    {
+      closure->speccount = specpdl_depth ();
+      record_unwind_protect (report_extent_modification_restore,
+                            Fcurrent_buffer ());
+    }
+
+  /* The functions will expect closure->buffer to be the current
+     buffer, so change it if it isn't.  */
+  if (current_buffer != XBUFFER (closure->buffer))
+    Fset_buffer (closure->buffer);
+
+  /* #### It's a shame that we can't use any of the existing run_hook*
+     functions here.  This is so because all of them work with
+     symbols, to be able to retrieve default values of local hooks.
+     <sigh> */
+
+  if (!CONSP (hook) || EQ (XCAR (hook), Qlambda))
+    call3 (hook, exobj, startobj, endobj);
+  else
+    {
+      Lisp_Object tail;
+      EXTERNAL_LIST_LOOP (tail, hook)
+       call3 (XCAR (tail), exobj, startobj, endobj);
+    }
+  return 0;
+}
+
+void
+report_extent_modification (Lisp_Object buffer, Bufpos start, Bufpos end,
+                           int *inside, int afterp)
+{
+  struct report_extent_modification_closure closure;
+
+  closure.buffer = buffer;
+  closure.start = start;
+  closure.end = end;
+  closure.afterp = afterp;
+  closure.speccount = -1;
+
+  inside_change_hook_pointer = inside;
+  *inside = 1;
+
+  map_extents (start, end, report_extent_modification_mapper, (void *)&closure,
+              buffer, NULL, ME_MIGHT_CALL_ELISP);
+
+  if (closure.speccount == -1)
+    *inside = 0;
+  else
+    {
+      /* We mustn't unbind when closure.speccount != -1 because
+        map_extents_bytind has already done that.  */
+      assert (*inside == 0);
+    }
+}
+
 \f
 /************************************************************************/
 /*                     extent properties                               */
@@ -5201,6 +5304,10 @@ The following symbols have predefined meanings:
     Fset_extent_face (extent, value);
   else if (EQ (property, Qinitial_redisplay_function))
     Fset_extent_initial_redisplay_function (extent, value);
+  else if (EQ (property, Qbefore_change_functions))
+    set_extent_before_change_functions (e, value);
+  else if (EQ (property, Qafter_change_functions))
+    set_extent_after_change_functions (e, value);
   else if (EQ (property, Qmouse_face))
     Fset_extent_mouse_face (extent, value);
   /* Obsolete: */
@@ -5306,6 +5413,10 @@ See `set-extent-property' for the built-in property names.
     return Fextent_face (extent);
   else if (EQ (property, Qinitial_redisplay_function))
     return extent_initial_redisplay_function (e);
+  else if (EQ (property, Qbefore_change_functions))
+    return extent_before_change_functions (e);
+  else if (EQ (property, Qafter_change_functions))
+    return extent_after_change_functions (e);
   else if (EQ (property, Qmouse_face))
     return Fextent_mouse_face (extent);
   /* Obsolete: */
@@ -5382,6 +5493,14 @@ Do not modify this list; use `set-extent-property' instead.
     result = cons3 (Qinitial_redisplay_function,
                    extent_initial_redisplay_function (anc), result);
 
+  if (!NILP (extent_before_change_functions (anc)))
+    result = cons3 (Qbefore_change_functions,
+                   extent_before_change_functions (anc), result);
+
+  if (!NILP (extent_after_change_functions (anc)))
+    result = cons3 (Qafter_change_functions,
+                   extent_after_change_functions (anc), result);
+
   if (!NILP (extent_invisible (anc)))
     result = cons3 (Qinvisible, extent_invisible (anc), result);
 
@@ -6723,6 +6842,8 @@ functions `get-text-property' or `get-char-property' are called.
   extent_auxiliary_defaults.read_only = Qnil;
   extent_auxiliary_defaults.mouse_face = Qnil;
   extent_auxiliary_defaults.initial_redisplay_function = Qnil;
+  extent_auxiliary_defaults.before_change_functions = Qnil;
+  extent_auxiliary_defaults.after_change_functions = Qnil;
 }
 
 void
index e9f1dff..be0d6e4 100644 (file)
@@ -82,17 +82,14 @@ struct extent
     unsigned int has_aux           :1; /*  6 extent has an aux. structure */
     unsigned int start_open        :1; /*  7 insertion behavior at start  */
     unsigned int end_open          :1; /*  8 insertion behavior at end    */
-    unsigned int unused9           :1; /*  9 unused                       */
-    unsigned int unique                    :1; /* 10 there may be only one attached  */
-    unsigned int duplicable        :1; /* 11 copied to strings by kill/undo  */
-    unsigned int REPLICATING       :1; /* 12 invoke old extent-replica behav.*/
-                                       /*    Not used any more */
-    unsigned int detachable        :1; /* 13 extent detaches if text deleted */
-    unsigned int internal          :1; /* 14 used by map-extents etc.        */
-    unsigned int in_red_event       :1; /* 15 An event has been spawned for
+    unsigned int unique                    :1; /*  9 there may be only one attached  */
+    unsigned int duplicable        :1; /* 10 copied to strings by kill/undo  */
+    unsigned int detachable        :1; /* 11 extent detaches if text deleted */
+    unsigned int internal          :1; /* 12 used by map-extents etc.        */
+    unsigned int in_red_event       :1; /* 13 An event has been spawned for
                                              initial redisplay.
-                                             Not exported to the lisp level */
-    unsigned int unused16          :1;  /* 16 unused                        */
+                                             (not exported to lisp) */
+    unsigned int unused16          :1;  /* 16 unused bits                   */
     /* --- Adding more flags will cause the extent struct to grow by another
        word.  It's not clear that this would make a difference, however,
        because on 32-bit machines things tend to get allocated in chunks
@@ -139,6 +136,7 @@ struct extent_auxiliary
   Lisp_Object read_only;
   Lisp_Object mouse_face;
   Lisp_Object initial_redisplay_function;
+  Lisp_Object before_change_functions, after_change_functions;
   int priority;
 };
 
@@ -230,6 +228,8 @@ extent_aux_or_default (EXTENT e)
 #define extent_read_only(e)    extent_aux_field (e, read_only)
 #define extent_mouse_face(e)   extent_aux_field (e, mouse_face)
 #define extent_initial_redisplay_function(e)   extent_aux_field (e, initial_redisplay_function)
+#define extent_before_change_functions(e) extent_aux_field (e, before_change_functions)
+#define extent_after_change_functions(e)  extent_aux_field (e, after_change_functions)
 
 #define set_extent_begin_glyph(e, value)       \
   set_extent_aux_field (e, begin_glyph, value)
@@ -246,6 +246,10 @@ extent_aux_or_default (EXTENT e)
 /* Use Fset_extent_initial_redisplay_function unless you know what you're doing */
 #define set_extent_initial_redisplay_function(e, value) \
   set_extent_aux_field (e, initial_redisplay_function, value)
+#define set_extent_before_change_functions(e, value)   \
+  set_extent_aux_field (e, before_change_functions, value)
+#define set_extent_after_change_functions(e, value)    \
+  set_extent_aux_field (e, after_change_functions, value)
 
 #define extent_face(e)              extent_normal_field (e, face)
 #define extent_begin_glyph_layout(e) extent_normal_field (e, begin_glyph_layout)
@@ -366,6 +370,7 @@ void process_extents_for_insertion (Lisp_Object object,
                                    Bytind opoint, Bytecount length);
 void process_extents_for_deletion (Lisp_Object object, Bytind from,
                                   Bytind to, int destroy_them);
+void report_extent_modification (Lisp_Object, Bufpos, Bufpos, int *, int);
 
 void set_extent_glyph (EXTENT extent, Lisp_Object glyph, int endp,
                       glyph_layout layout);
index 750055c..dc694dd 100644 (file)
@@ -1919,8 +1919,12 @@ complex_vars_of_faces (void)
                       inst_list);
 #endif /* HAVE_TTY */
 #ifdef HAVE_MS_WINDOWS
-    inst_list = Fcons (Fcons (list1 (Qmswindows), build_string ("Courier New")),
-                      inst_list);
+    inst_list = Fcons (Fcons (list1 (Qmswindows),
+                      build_string ("Fixedsys:Regular:9::Western")), inst_list);
+    inst_list = Fcons (Fcons (list1 (Qmswindows),
+                      build_string ("Courier:Regular:10::Western")), inst_list);
+    inst_list = Fcons (Fcons (list1 (Qmswindows),
+                      build_string ("Courier New:Regular:10::Western")), inst_list);
 #endif /* HAVE_MS_WINDOWS */
     set_specifier_fallback (Fget (Vdefault_face, Qfont, Qnil), inst_list);
   }
index 0f21f16..4893391 100644 (file)
@@ -454,13 +454,16 @@ Given a Unix syntax file name, returns a string ending in slash.
       Bufbyte *res = alloca (MAXPATHLEN + 1);
       if (getdefdir (toupper (*beg) - 'A' + 1, res))
        {
-         if (!IS_DIRECTORY_SEP (res[strlen ((char *) res) - 1]))
-           strcat ((char *) res, "/");
+         char *c=((char *) res) + strlen ((char *) res);
+         if (!IS_DIRECTORY_SEP (*c))
+           {
+             *c++ = DIRECTORY_SEP;
+             *c = '\0';
+           }
          beg = res;
          p = beg + strlen ((char *) beg);
        }
     }
-  CORRECT_DIR_SEPS (beg);
 #endif /* WINDOWSNT */
   return make_string (beg, p - beg);
 }
@@ -544,9 +547,6 @@ file_name_as_directory (char *out, char *in)
          out[size + 1] = '\0';
        }
     }
-#ifdef WINDOWSNT
-  CORRECT_DIR_SEPS (out);
-#endif
   return out;
 }
 
@@ -608,9 +608,6 @@ directory_file_name (CONST char *src, char *dst)
       )
     dst[slen - 1] = 0;
 #endif /* APOLLO */
-#ifdef WINDOWSNT
-  CORRECT_DIR_SEPS (dst);
-#endif /* WINDOWSNT */
   return 1;
 }
 
@@ -2288,7 +2285,7 @@ See also `file-exists-p' and `file-attributes'.
   if (!NILP (handler))
     RETURN_UNGCPRO (call2 (handler, Qfile_readable_p, abspath));
 
-#ifdef WINDOWSNT
+#if defined(WINDOWSNT) || defined(__CYGWIN32__)
   /* Under MS-DOS and Windows, open does not work for directories.  */
   UNGCPRO;
   if (access (XSTRING_DATA (abspath), 0) == 0)
index d216ab8..96ee76d 100644 (file)
@@ -1,24 +1,23 @@
-/* Copyright (C) 1985, 1986, 1987, 1992, 1993, 1994
-   Free Software Foundation, Inc.
+/* Copyright (C) 1985, 86, 87, 93, 94, 96 Free Software Foundation, Inc.
 
-This file is part of XEmacs.
+This file is part of GNU Emacs.
 
-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.
+GNU Emacs 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.
+GNU Emacs 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
+along with GNU Emacs; 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: FSF 19.30. */
+/* Synced with FSF 20.2 */
 
 #include <config.h>
 #include "lisp.h"
@@ -31,169 +30,271 @@ Boston, MA 02111-1307, USA.  */
 #include "syspwd.h"
 #include "syssignal.h" /* for kill */
 
-#ifndef CLASH_DETECTION
-#error  CLASH_DETECTION is not defined??
-#endif
-
-/* FSFmacs uses char *lock_dir and char *superlock_file instead of
-   the Lisp variables we use. */
-
-/* The name of the directory in which we keep lock files, with a '/'
-   appended.  */
-Lisp_Object Vlock_directory;
-
-#if 0 /* FSFmacs */
-/* Look in startup.el */
-/* The name of the file in the lock directory which is used to
-   arbitrate access to the entire directory.  */
-#define SUPERLOCK_NAME "!!!SuperLock!!!"
-#endif
-
-/* The name of the superlock file.  This is SUPERLOCK_NAME appended to
-   Vlock_directory.  */
-Lisp_Object Vsuperlock_file, Vconfigure_superlock_file;
-
 Lisp_Object Qask_user_about_supersession_threat;
 Lisp_Object Qask_user_about_lock;
 
-static void lock_superlock (CONST char *lfname);
-static int lock_file_1 (CONST char *lfname, int mode);
-static int lock_if_free (CONST char *lfname);
-static int current_lock_owner (CONST char *);
-static int current_lock_owner_1 (CONST char *);
-
-/* Set LOCK to the name of the lock file for the filename FILE.
-   char *LOCK; Lisp_Object FILE;
+#ifdef CLASH_DETECTION
+  
+/* The strategy: to lock a file FN, create a symlink .#FN in FN's
+   directory, with link data `user@host.pid'.  This avoids a single
+   mount (== failure) point for lock files.
+
+   When the host in the lock data is the current host, we can check if
+   the pid is valid with kill.
+   
+   Otherwise, we could look at a separate file that maps hostnames to
+   reboot times to see if the remote pid can possibly be valid, since we
+   don't want Emacs to have to communicate via pipes or sockets or
+   whatever to other processes, either locally or remotely; rms says
+   that's too unreliable.  Hence the separate file, which could
+   theoretically be updated by daemons running separately -- but this
+   whole idea is unimplemented; in practice, at least in our
+   environment, it seems such stale locks arise fairly infrequently, and
+   Emacs' standard methods of dealing with clashes suffice.
+
+   We use symlinks instead of normal files because (1) they can be
+   stored more efficiently on the filesystem, since the kernel knows
+   they will be small, and (2) all the info about the lock can be read
+   in a single system call (readlink).  Although we could use regular
+   files to be useful on old systems lacking symlinks, nowadays
+   virtually all such systems are probably single-user anyway, so it
+   didn't seem worth the complication.
+
+   Similarly, we don't worry about a possible 14-character limit on
+   file names, because those are all the same systems that don't have
+   symlinks.
+   
+   This is compatible with the locking scheme used by Interleaf (which
+   has contributed this implementation for Emacs), and was designed by
+   Ethan Jacobson, Kimbo Mundy, and others.
+   
+   --karl@cs.umb.edu/karl@hq.ileaf.com.  */
 
-   MAKE_LOCK_NAME assumes you have already verified that Vlock_directory
-   is a string. */
-
-#ifndef HAVE_LONG_FILE_NAMES
+\f
+/* Here is the structure that stores information about a lock.  */
 
-#define MAKE_LOCK_NAME(lock, file)                                     \
-  (lock = (char *) alloca (14 + XSTRING_LENGTH (Vlock_directory) + 1), \
-   fill_in_lock_short_file_name (lock, (file)))
+typedef struct
+{
+  char *user;
+  char *host;
+  unsigned long pid;
+} lock_info_type;
+
+/* When we read the info back, we might need this much more,
+   enough for decimal representation plus null.  */
+#define LOCK_PID_MAX (4 * sizeof (unsigned long))
+
+/* Free the two dynamically-allocated pieces in PTR.  */
+#define FREE_LOCK_INFO(i) do { xfree ((i).user); xfree ((i).host); } while (0)
+
+/* Write the name of the lock file for FN into LFNAME.  Length will be
+   that of FN plus two more for the leading `.#' plus one for the null.  */
+#define MAKE_LOCK_NAME(lock, file) \
+  (lock = (char *) alloca (XSTRING_LENGTH(file) + 2 + 1), \
+   fill_in_lock_file_name (lock, (file)))
 
 static void
-fill_in_lock_short_file_name (REGISTER char *lockfile, REGISTER Lisp_Object fn)
+fill_in_lock_file_name (lockfile, fn)
+     register char *lockfile;
+     register Lisp_Object fn;
 {
-  REGISTER union
-    {
-      unsigned int  word [2];
-      unsigned char byte [8];
-    } crc;
-  REGISTER unsigned char *p, new;
+  register char *p;
 
-  CHECK_STRING (Vlock_directory);
+  strcpy (lockfile, XSTRING_DATA(fn));
 
-  /* 7-bytes cyclic code for burst correction on byte-by-byte basis.
-     the used polynomial is D^7 + D^6 + D^3 +1. pot@cnuce.cnr.it */
+  /* Shift the nondirectory part of the file name (including the null)
+     right two characters.  Here is one of the places where we'd have to
+     do something to support 14-character-max file names.  */
+  for (p = lockfile + strlen (lockfile); p != lockfile && *p != '/'; p--)
+    p[2] = *p;
 
-  crc.word[0] = crc.word[1] = 0;
-
-  for (p = XSTRING_DATA (fn); new = *p++; )
-    {
-      new += crc.byte[6];
-      crc.byte[6] = crc.byte[5] + new;
-      crc.byte[5] = crc.byte[4];
-      crc.byte[4] = crc.byte[3];
-      crc.byte[3] = crc.byte[2] + new;
-      crc.byte[2] = crc.byte[1];
-      crc.byte[1] = crc.byte[0];
-      crc.byte[0] = new;
-    }
-
-  {
-    int need_slash = 0;
-
-    /* in case lock-directory doesn't end in / */
-    if (XSTRING_BYTE (Vlock_directory,
-                    XSTRING_LENGTH (Vlock_directory) - 1) != '/')
-      need_slash = 1;
-
-    sprintf (lockfile, "%s%s%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
-            (char *) XSTRING_DATA (Vlock_directory),
-            need_slash ? "/" : "",
-            crc.byte[0], crc.byte[1], crc.byte[2], crc.byte[3],
-            crc.byte[4], crc.byte[5], crc.byte[6]);
-  }
+  /* Insert the `.#'.  */
+  p[1] = '.';
+  p[2] = '#';
 }
 
-#else /* defined HAVE_LONG_FILE_NAMES */
-
-/* +2 for terminating null and possible extra slash */
-#define MAKE_LOCK_NAME(lock, file)                                     \
-  (lock = (char *) alloca (XSTRING_LENGTH (file) +                     \
-                          XSTRING_LENGTH (Vlock_directory) + 2),       \
-   fill_in_lock_file_name (lock, (file)))
+/* Lock the lock file named LFNAME.
+   If FORCE is nonzero, we do so even if it is already locked.
+   Return 1 if successful, 0 if not.  */
 
-static void
-fill_in_lock_file_name (REGISTER char *lockfile, REGISTER Lisp_Object fn)
-     /* fn must be a Lisp_String! */
+static int
+lock_file_1 (char *lfname,int force)
 {
-  REGISTER char *p;
-
-  CHECK_STRING (Vlock_directory);
+  register int err;
+  char *user_name;
+  char *host_name;
+  char *lock_info_str;
 
-  strcpy (lockfile, (char *) XSTRING_DATA (Vlock_directory));
+  if (STRINGP (Fuser_login_name (Qnil)))
+    user_name = (char *)XSTRING_DATA((Fuser_login_name (Qnil)));
+  else
+    user_name = "";
+  if (STRINGP (Fsystem_name ()))
+    host_name = (char *)XSTRING_DATA((Fsystem_name ()));
+  else
+    host_name = "";
+  lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name)
+                         + LOCK_PID_MAX + 5);
 
-  p = lockfile + strlen (lockfile);
+  sprintf (lock_info_str, "%s@%s.%lu", user_name, host_name,
+           (unsigned long) getpid ());
 
-  if (p == lockfile /* lock-directory is empty?? */
-      || *(p - 1) != '/')  /* in case lock-directory doesn't end in / */
+  err = symlink (lock_info_str, lfname);
+  if (errno == EEXIST && force)
     {
-      *p = '/';
-      p++;
+      unlink (lfname);
+      err = symlink (lock_info_str, lfname);
     }
 
-  strcpy (p, (char *) XSTRING_DATA (fn));
+  return err == 0;
+}
+\f
+/* Return 0 if nobody owns the lock file LFNAME or the lock is obsolete,
+   1 if another process owns it (and set OWNER (if non-null) to info),
+   2 if the current process owns it,
+   or -1 if something is wrong with the locking mechanism.  */
 
-  for (; *p; p++)
+static int
+current_lock_owner (lock_info_type *owner, char *lfname)
+{
+#ifndef index
+  extern char *rindex (), *index ();
+#endif
+  int o, p, len, ret;
+  int local_owner = 0;
+  char *at, *dot;
+  char *lfinfo = 0;
+  int bufsize = 50;
+  /* Read arbitrarily-long contents of symlink.  Similar code in
+     file-symlink-p in fileio.c.  */
+  do
+    {
+      bufsize *= 2;
+      lfinfo = (char *) xrealloc (lfinfo, bufsize);
+      len = readlink (lfname, lfinfo, bufsize);
+    }
+  while (len >= bufsize);
+  
+  /* If nonexistent lock file, all is well; otherwise, got strange error. */
+  if (len == -1)
     {
-      if (*p == '/')
-       *p = '!';
+      xfree (lfinfo);
+      return errno == ENOENT ? 0 : -1;
     }
+
+  /* Link info exists, so `len' is its length.  Null terminate.  */
+  lfinfo[len] = 0;
+  
+  /* Even if the caller doesn't want the owner info, we still have to
+     read it to determine return value, so allocate it.  */
+  if (!owner)
+    {
+      owner = (lock_info_type *) alloca (sizeof (lock_info_type));
+      local_owner = 1;
+    }
+  
+  /* Parse USER@HOST.PID.  If can't parse, return -1.  */
+  /* The USER is everything before the first @.  */
+  at = index (lfinfo, '@');
+  dot = rindex (lfinfo, '.');
+  if (!at || !dot) {
+    xfree (lfinfo);
+    return -1;
+  }
+  len = at - lfinfo;
+  owner->user = (char *) xmalloc (len + 1);
+  strncpy (owner->user, lfinfo, len);
+  owner->user[len] = 0;
+  
+  /* The PID is everything after the last `.'.  */
+  owner->pid = atoi (dot + 1);
+
+  /* The host is everything in between.  */
+  len = dot - at - 1;
+  owner->host = (char *) xmalloc (len + 1);
+  strncpy (owner->host, at + 1, len);
+  owner->host[len] = 0;
+
+  /* We're done looking at the link info.  */
+  xfree (lfinfo);
+  
+  /* On current host?  */
+  if (STRINGP (Fsystem_name ()) 
+      && strcmp (owner->host, XSTRING_DATA(Fsystem_name ())) == 0)
+    {
+      if (owner->pid == getpid ())
+        ret = 2; /* We own it.  */
+      else if (owner->pid > 0
+               && (kill (owner->pid, 0) >= 0 || errno == EPERM))
+        ret = 1; /* An existing process on this machine owns it.  */
+      /* The owner process is dead or has a strange pid (<=0), so try to
+         zap the lockfile.  */
+      else if (unlink (lfname) < 0)
+        ret = -1;
+      else
+       ret = 0;
+    }
+  else
+    { /* If we wanted to support the check for stale locks on remote machines,
+         here's where we'd do it.  */
+      ret = 1;
+    }
+  
+  /* Avoid garbage.  */
+  if (local_owner || ret <= 0)
+    {
+      FREE_LOCK_INFO (*owner);
+    }
+  return ret;
 }
-#endif /* !defined HAVE_LONG_FILE_NAMES */
+\f
+/* Lock the lock named LFNAME if possible.
+   Return 0 in that case.
+   Return positive if some other process owns the lock, and info about
+     that process in CLASHER.
+   Return -1 if cannot lock for any other reason.  */
 
-static Lisp_Object
-lock_file_owner_name (CONST char *lfname)
+static int
+lock_if_free (lock_info_type *clasher, char *lfname)
 {
-  struct stat s;
-  struct passwd *the_pw = 0;
+  if (lock_file_1 (lfname, 0) == 0)
+    {
+      int locker;
 
-  if (lstat (lfname, &s) == 0)
-    the_pw = getpwuid (s.st_uid);
-  return (the_pw == 0 ? Qnil : build_string (the_pw->pw_name));
+      if (errno != EEXIST)
+       return -1;
+      
+      locker = current_lock_owner (clasher, lfname);
+      if (locker == 2)
+        {
+          FREE_LOCK_INFO (*clasher);
+          return 0;   /* We ourselves locked it.  */
+        }
+      else if (locker == 1)
+        return 1;  /* Someone else has it.  */
+
+      return -1; /* Something's wrong.  */
+    }
+  return 0;
 }
 
-
-/* lock_file locks file fn,
+/* lock_file locks file FN,
    meaning it serves notice on the world that you intend to edit that file.
    This should be done only when about to modify a file-visiting
    buffer previously unmodified.
-   Do not (normally) call lock_buffer for a buffer already modified,
+   Do not (normally) call this for a buffer already modified,
    as either the file is already locked, or the user has already
    decided to go ahead without locking.
 
-   When lock_buffer returns, either the lock is locked for us,
+   When this returns, either the lock is locked for us,
    or the user has said to go ahead without locking.
 
-   If the file is locked by someone else, lock_buffer calls
+   If the file is locked by someone else, this calls
    ask-user-about-lock (a Lisp function) with two arguments,
-   the file name and the name of the user who did the locking.
+   the file name and info about the user who did the locking.
    This function can signal an error, or return t meaning
    take away the lock, or return nil meaning ignore the lock.  */
 
-/* The lock file name is the file name with "/" replaced by "!"
-   and put in the Emacs lock directory.  */
-/* (ie., /ka/king/junk.tex -> /!/!ka!king!junk.tex). */
-
-/* If HAVE_LONG_FILE_NAMES is not defined, the lock file name is the hex
-   representation of a 14-bytes CRC generated from the file name
-   and put in the Emacs lock directory (not very nice, but it works).
-   (ie., /ka/king/junk.tex -> /!/12a82c62f1c6da). */
-
 void
 lock_file (Lisp_Object fn)
 {
@@ -201,16 +302,14 @@ lock_file (Lisp_Object fn)
   /* dmoore - and can destroy current_buffer and all sorts of other
      mean nasty things with pointy teeth.  If you call this make sure
      you protect things right. */
+  /* Somebody updated the code in this function and removed the previous 
+     comment.  -slb */
 
-  REGISTER Lisp_Object attack, orig_fn;
-  REGISTER char *lfname;
-  struct gcpro gcpro1, gcpro2;
-  Lisp_Object subject_buf = Qnil;
-
-  if (NILP (Vlock_directory) || NILP (Vsuperlock_file))
-    return;
-  CHECK_STRING (fn);
-  CHECK_STRING (Vlock_directory);
+  register Lisp_Object attack, orig_fn;
+  register char *lfname, *locker;
+  lock_info_type lock_info;
+  struct gcpro gcpro1,gcpro2;
+  Lisp_Object subject_buf;
 
   GCPRO2 (fn, subject_buf);
   orig_fn = fn;
@@ -221,29 +320,34 @@ lock_file (Lisp_Object fn)
 
   /* See if this file is visited and has changed on disk since it was
      visited.  */
-  subject_buf = Fget_file_buffer (fn);
-  if (!NILP (subject_buf)
-      && NILP (Fverify_visited_file_modtime (subject_buf))
-      && !NILP (Ffile_exists_p (fn)))
-    call1_in_buffer (XBUFFER (subject_buf),
-                    Qask_user_about_supersession_threat, fn);
+  {
+    subject_buf = get_truename_buffer (orig_fn);
+    if (!NILP (subject_buf)
+       && NILP (Fverify_visited_file_modtime (subject_buf))
+       && !NILP (Ffile_exists_p (fn)))
+      call1_in_buffer (XBUFFER(subject_buf),
+                       Qask_user_about_supersession_threat, fn);
+  }
 
   /* Try to lock the lock. */
-  if (lock_if_free (lfname) <= 0)
-    /* Return now if we have locked it, or if lock dir does not exist */
+  if (lock_if_free (&lock_info, lfname) <= 0)
+    /* Return now if we have locked it, or if lock creation failed */
     goto done;
 
   /* Else consider breaking the lock */
+  locker = (char *) alloca (strlen (lock_info.user) + strlen (lock_info.host)
+                           + LOCK_PID_MAX + 9);
+  sprintf (locker, "%s@%s (pid %lu)", lock_info.user, lock_info.host,
+           lock_info.pid);
+  FREE_LOCK_INFO (lock_info);
+  
   attack = call2_in_buffer (BUFFERP (subject_buf) ? XBUFFER (subject_buf) :
-                           current_buffer, Qask_user_about_lock, fn,
-                           lock_file_owner_name (lfname));
+                           current_buffer, Qask_user_about_lock , fn,
+                           build_string (locker));
   if (!NILP (attack))
     /* User says take the lock */
     {
-      CHECK_STRING (Vsuperlock_file);
-      lock_superlock (lfname);
-      lock_file_1 (lfname, O_WRONLY);
-      unlink ((char *) XSTRING_DATA (Vsuperlock_file));
+      lock_file_1 (lfname, 1);
       goto done;
     }
   /* User says ignore the lock */
@@ -251,197 +355,46 @@ lock_file (Lisp_Object fn)
   UNGCPRO;
 }
 
-
-/* Lock the lock file named LFNAME.
-   If MODE is O_WRONLY, we do so even if it is already locked.
-   If MODE is O_WRONLY | O_EXCL | O_CREAT, we do so only if it is free.
-   Return 1 if successful, 0 if not.  */
-
-static int
-lock_file_1 (CONST char *lfname, int mode)
-{
-  REGISTER int fd;
-  char buf[20];
-
-  if ((fd = open (lfname, mode, 0666)) >= 0)
-    {
-#if defined(WINDOWSNT)
-      chmod(lfname, _S_IREAD|_S_IWRITE);
-#elif defined(USG)
-      chmod (lfname, 0666);
-#else
-      fchmod (fd, 0666);
-#endif
-      sprintf (buf, "%ld ", (long) getpid ());
-      write (fd, buf, strlen (buf));
-      close (fd);
-      return 1;
-    }
-  else
-    return 0;
-}
-
-/* Lock the lock named LFNAME if possible.
-   Return 0 in that case.
-   Return positive if lock is really locked by someone else.
-   Return -1 if cannot lock for any other reason.  */
-
-static int
-lock_if_free (CONST char *lfname)
-{
-  REGISTER int clasher;
-
-  while (lock_file_1 (lfname, O_WRONLY | O_EXCL | O_CREAT) == 0)
-    {
-      if (errno != EEXIST)
-       return -1;
-      clasher = current_lock_owner (lfname);
-      if (clasher != 0)
-       if (clasher != getpid ())
-         return (clasher);
-       else return (0);
-      /* Try again to lock it */
-    }
-  return 0;
-}
-
-/* Return the pid of the process that claims to own the lock file LFNAME,
-   or 0 if nobody does or the lock is obsolete,
-   or -1 if something is wrong with the locking mechanism.  */
-
-static int
-current_lock_owner (CONST char *lfname)
-{
-  int owner = current_lock_owner_1 (lfname);
-  if (owner == 0 && errno == ENOENT)
-    return (0);
-  /* Is it locked by a process that exists?  */
-  if (owner != 0 && (kill (owner, 0) >= 0 || errno == EPERM))
-    return (owner);
-  if (unlink (lfname) < 0)
-    return (-1);
-  return (0);
-}
-
-static int
-current_lock_owner_1 (CONST char *lfname)
-{
-  REGISTER int fd;
-  char buf[20];
-  int tem;
-
-  fd = open (lfname, O_RDONLY, 0666);
-  if (fd < 0)
-    return 0;
-  tem = read (fd, buf, sizeof buf);
-  close (fd);
-  return (tem <= 0 ? 0 : atoi (buf));
-}
-
-\f
 void
 unlock_file (Lisp_Object fn)
 {
-  /* This function can GC. */
-  /* dmoore - and can destroy current_buffer and all sorts of other
-     mean nasty things with pointy teeth.  If you call this make sure
-     you protect things right. */
-
-  REGISTER char *lfname;
-  if (NILP (Vlock_directory) || NILP (Vsuperlock_file)) return;
-  CHECK_STRING (fn);
-  CHECK_STRING (Vlock_directory);
-  CHECK_STRING (Vsuperlock_file);
+  register char *lfname;
 
   fn = Fexpand_file_name (fn, Qnil);
 
   MAKE_LOCK_NAME (lfname, fn);
 
-  lock_superlock (lfname);
-
-  if (current_lock_owner_1 (lfname) == getpid ())
+  if (current_lock_owner (0, lfname) == 2)
     unlink (lfname);
-
-  unlink ((char *) XSTRING_DATA (Vsuperlock_file));
-}
-
-static void
-lock_superlock (CONST char *lfname)
-{
-  REGISTER int i, fd;
-  DIR *lockdir;
-
-  for (i = -20; i < 0 &&
-       (fd = open ((char *) XSTRING_DATA (Vsuperlock_file),
-                  O_WRONLY | O_EXCL | O_CREAT, 0666)) < 0;
-       i++)
-    {
-      if (errno != EEXIST)
-       return;
-
-      /* This seems to be necessary to prevent Emacs from hanging when the
-        competing process has already deleted the superlock, but it's still
-        in the NFS cache.  So we force NFS to synchronize the cache.  */
-      lockdir = opendir ((char *) XSTRING_DATA (Vlock_directory));
-      if (lockdir)
-       closedir (lockdir);
-
-      emacs_sleep (1);
-    }
-  if (fd >= 0)
-    {
-#if defined(WINDOWSNT)
-      chmod(lfname, _S_IREAD|_S_IWRITE);
-#elif defined(USG)
-      chmod ((char *) XSTRING_DATA (Vsuperlock_file), 0666);
-#else
-      fchmod (fd, 0666);
-#endif
-      write (fd, lfname, strlen (lfname));
-      close (fd);
-    }
 }
 
 void
-unlock_all_files (void)
+unlock_all_files ()
 {
-  /* This function can GC. */
-
-  Lisp_Object tail;
-  REGISTER struct buffer *b;
-  struct gcpro gcpro1;
+  register Lisp_Object tail;
+  register struct buffer *b;
 
-  GCPRO1 (tail);
-  for (tail = Vbuffer_alist; GC_CONSP (tail);
-       tail = XCDR (tail))
+  for (tail = Vbuffer_alist; GC_CONSP (tail); tail = XCDR (tail))
     {
       b = XBUFFER (XCDR (XCAR (tail)));
-      if (STRINGP (b->file_truename) &&
-         BUF_SAVE_MODIFF (b) < BUF_MODIFF (b))
+      if (STRINGP (b->file_truename) && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b))
        unlock_file (b->file_truename);
     }
-  UNGCPRO;
 }
-
 \f
-DEFUN ("lock-buffer", Flock_buffer, 0, 1, 0, /*
-Lock FILE, if current buffer is modified.
-FILE defaults to current buffer's visited file,
+DEFUN ("lock-buffer", Flock_buffer,   0, 1, 0, /*
+  Lock FILE, if current buffer is modified.\n\
+FILE defaults to current buffer's visited file,\n\
 or else nothing is done if current buffer isn't visiting a file.
 */
-       (fn))
+  (file))
 {
-  /* This function can GC */
-  /* dmoore - and can destroy current_buffer and all sorts of other
-     mean nasty things with pointy teeth.  If you call this make sure
-     you protect things right. */
-
-  if (NILP (fn))
-    fn = current_buffer->file_truename;
-  CHECK_STRING (fn);
+  if (NILP (file))
+    file = current_buffer->file_truename;
+  CHECK_STRING (file);
   if (BUF_SAVE_MODIFF (current_buffer) < BUF_MODIFF (current_buffer)
-      && !NILP (fn))
-    lock_file (fn);
+      && !NILP (file))
+    lock_file (file);
   return Qnil;
 }
 
@@ -462,9 +415,9 @@ if it should normally be locked.
   return Qnil;
 }
 
-\f
 /* Unlock the file visited in buffer BUFFER.  */
 
+
 void
 unlock_buffer (struct buffer *buffer)
 {
@@ -478,32 +431,37 @@ unlock_buffer (struct buffer *buffer)
 }
 
 DEFUN ("file-locked-p", Ffile_locked_p, 0, 1, 0, /*
-Return nil if the FILENAME is not locked,
+  Return nil if the FILENAME is not locked,\n\
 t if it is locked by you, else a string of the name of the locker.
 */
-       (fn))
+  (filename)) 
 {
-  /* This function can GC */
-  REGISTER char *lfname;
+  Lisp_Object ret;
+  register char *lfname;
   int owner;
+  lock_info_type locker;
 
-  if (NILP (Vlock_directory) || NILP (Vsuperlock_file))
-    return Qnil;
-  CHECK_STRING (Vlock_directory);
+  filename = Fexpand_file_name (filename, Qnil);
 
-  fn = Fexpand_file_name (fn, Qnil);
+  MAKE_LOCK_NAME (lfname, filename);
 
-  MAKE_LOCK_NAME (lfname, fn);
-
-  owner = current_lock_owner (lfname);
+  owner = current_lock_owner (&locker, lfname);
   if (owner <= 0)
-    return Qnil;
-  else if (owner == getpid ())
-    return Qt;
+    ret = Qnil;
+  else if (owner == 2)
+    ret = Qt;
+  else
+    ret = build_string (locker.user);
+
+  if (owner > 0)
+    FREE_LOCK_INFO (locker);
 
-  return lock_file_owner_name (lfname);
+  return ret;
 }
 
+\f
+/* Initialization functions.  */
+
 void
 syms_of_filelock (void)
 {
@@ -517,30 +475,5 @@ syms_of_filelock (void)
   defsymbol (&Qask_user_about_lock, "ask-user-about-lock");
 }
 
-void
-vars_of_filelock (void)
-{
-  DEFVAR_LISP ("lock-directory", &Vlock_directory /*
-Don't change this
-*/ );
-  Vlock_directory = Qnil;
-  DEFVAR_LISP ("superlock-file", &Vsuperlock_file /*
-Don't change this
-*/ );
-  Vsuperlock_file = Qnil;
-}
 
-void
-complex_vars_of_filelock (void)
-{
-  DEFVAR_LISP ("configure-superlock-file", &Vconfigure_superlock_file /*
-For internal use by the build procedure only.
-configure's idea of what SUPERLOCK-FILE will be.
-*/ );
-#ifdef PATH_SUPERLOCK
-  Vconfigure_superlock_file = build_string (PATH_SUPERLOCK);
-#else
-  Vconfigure_superlock_file = Qnil;
-#endif
-  /* All the rest done dynamically by startup.el */
-}
+#endif /* CLASH_DETECTION */
index 22cba39..bc4cc9e 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -1688,7 +1688,7 @@ the value of `foo'.
       REGISTER Lisp_Object elt, tem;
       CONCHECK_CONS (tail);
       elt = XCAR (tail);
-      if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (value, tem)))
+      if (CONSP (elt) && (tem = XCDR (elt), EQ_WITH_EBOLA_NOTICE (value, tem)))
        {
          if (NILP (prev))
            list = XCDR (tail);
@@ -1715,7 +1715,7 @@ remrassq_no_quit (Lisp_Object value, Lisp_Object list)
     {
       REGISTER Lisp_Object elt, tem;
       elt = XCAR (tail);
-      if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (value, tem)))
+      if (CONSP (elt) && (tem = XCDR (elt), EQ_WITH_EBOLA_NOTICE (value, tem)))
        {
          if (NILP (prev))
            list = XCDR (tail);
index 2fddbae..3c538f0 100644 (file)
@@ -2651,6 +2651,7 @@ x_delete_frame (struct frame *f)
   }
 #else
   XtDestroyWidget (w);
+  XFlush (XtDisplay(w));   /* make sure the windows are really gone! */
 #endif /* EXTERNAL_WIDGET */
 
   if (FRAME_X_GEOM_FREE_ME_PLEASE (f))
diff --git a/src/gif_io.c b/src/gif_io.c
new file mode 100644 (file)
index 0000000..ddbfb16
--- /dev/null
@@ -0,0 +1,259 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "gifrlib.h"
+
+/******************************************************************************
+* Set up the GifFileType structure for use.  This must be called first in any *
+* client program.  Then, if custom IO or Error functions are desired, call    *
+* GifSetIOFunc/GifSetErrorFunc, then call EGifInitWrite.  Else call           *
+* EGifOpenFileName or EGifOpenFileHandle for standard IO functions.           *
+* If setup fails, a NULL pointer is returned.                                 *
+******************************************************************************/
+GifFileType *GifSetup(void)
+{
+    GifIODataType *GifIO;
+    GifFileType *GifFile;
+
+    if ((GifFile = (GifFileType *) malloc(sizeof(GifFileType))) == NULL)
+       return NULL;
+    memset(GifFile, '\0', sizeof(GifFileType));
+    if ((GifIO = (GifIODataType *) malloc(sizeof(GifIODataType))) == NULL) {
+       free((char *) GifFile);
+       return NULL;
+    }
+    memset(GifIO, '\0', sizeof(GifIODataType));
+    GifFile->GifIO = GifIO;    
+    return GifFile;
+}
+
+void GifFree(GifFileType *GifFile)
+{
+    GifFilePrivateType *Private;
+
+    if (GifFile == NULL) return;
+
+    Private = (GifFilePrivateType *) GifFile->Private;
+
+    if (GifFile->SavedImages)
+       FreeSavedImages(GifFile);
+    if (GifFile->Image.ColorMap)
+       FreeMapObject(GifFile->Image.ColorMap);
+    if (GifFile->SColorMap)
+       FreeMapObject(GifFile->SColorMap);
+    if (Private)
+    {
+       free(Private);
+    }
+    if (GifFile->GifIO)
+       free(GifFile->GifIO);
+    free(GifFile);
+}
+
+/****************************************************************************
+* Install the specified ReadFunction into the GifFile specified.            *
+****************************************************************************/
+void GifSetReadFunc(GifFileType *GifFile, Gif_rw_func ReadFunc, VoidPtr data)
+{
+    GifIODataType *GifIO = (GifIODataType *)GifFile->GifIO;
+    GifIO->ReadFunc = ReadFunc;
+    GifIO->ReadFunc_data = data;
+}
+
+/****************************************************************************
+* Install the specified WriteFunction into the GifFile specified.           *
+****************************************************************************/
+void GifSetWriteFunc(GifFileType *GifFile, Gif_rw_func WriteFunc, VoidPtr data)
+{
+    GifIODataType *GifIO = (GifIODataType *)GifFile->GifIO;
+    GifIO->WriteFunc = WriteFunc;
+    GifIO->WriteFunc_data = data;
+}
+
+/****************************************************************************
+* Install the specified CloseFunction into the GifFile specified.           *
+****************************************************************************/
+void GifSetCloseFunc(GifFileType *GifFile, Gif_close_func CloseFunc, VoidPtr data)
+{
+    GifIODataType *GifIO = (GifIODataType *)GifFile->GifIO;
+    GifIO->CloseFunc = CloseFunc;
+    GifIO->CloseFunc_data = data;
+}
+
+/****************************************************************************
+* Install the standard IO funcs into the GifFile, including the FILE info   *
+****************************************************************************/
+void GifStdIOInit(GifFileType *GifFile, FILE *file, int filehandle)
+{
+    GifStdIODataType *IOData;
+    
+    if ((IOData = (GifStdIODataType*)malloc(sizeof(GifStdIODataType))) == NULL)
+       GifInternError(GifFile, GIF_ERR_NOT_ENOUGH_MEM);
+    IOData->File = file;
+    IOData->FileHandle = filehandle;
+    GifSetReadFunc(GifFile, GifStdRead, IOData);
+    GifSetWriteFunc(GifFile, GifStdWrite, IOData);
+    GifSetCloseFunc(GifFile, GifStdFileClose, IOData);
+}
+
+size_t GifStdRead(GifByteType *buf, size_t size, VoidPtr method_data)
+{
+  GifStdIODataType *IOtype = (GifStdIODataType*)method_data;
+  return (fread(buf, 1, size, IOtype->File));
+}
+
+size_t GifStdWrite(GifByteType *buf, size_t size, VoidPtr method_data)
+{
+  GifStdIODataType *IOtype = (GifStdIODataType*)method_data;
+  return (fwrite(buf, 1, size, IOtype->File));  
+}
+
+int GifStdFileClose(VoidPtr method_data)
+{
+  int ret;
+  GifStdIODataType *IOtype = (GifStdIODataType*)method_data;
+  ret = fclose(IOtype->File);
+  if (ret == 0 && IOtype->FileHandle != -1)
+    ret = close(IOtype->FileHandle);
+  return ret;
+}
+
+void GifRead(GifByteType *buf, size_t size, GifFileType *GifFile)
+{
+  GifIODataType *GifIO = (GifIODataType*)GifFile->GifIO;
+  if ((*(GifIO->ReadFunc))(buf, size, GifIO->ReadFunc_data) != size)
+    GifError(GifFile, "Read error!");
+}
+
+void GifWrite(GifByteType *buf, size_t size, GifFileType *GifFile)
+{
+  GifIODataType *GifIO = (GifIODataType*)GifFile->GifIO;
+  if ((*(GifIO->WriteFunc))(buf, size, GifIO->WriteFunc_data) != size)
+    GifError(GifFile, "Write error!");
+}
+
+int GifClose(GifFileType *GifFile) 
+{
+  GifIODataType *GifIO = (GifIODataType*)GifFile->GifIO;
+  return ((*(GifIO->CloseFunc))(GifIO->CloseFunc_data));
+}
+
+static char *GifErrorString[14] = {
+  "Failed to open given file",                 /* D_GIF_ERR_OPEN_FAILED */
+  "Failed to read from given file",            /* D_GIF_ERR_READ_FAILED */
+  "Given file is NOT a GIF file",              /* D_GIF_ERR_NOT_GIF_FILE */
+  "No Screen Descriptor detected",             /* D_GIF_ERR_NO_SCRN_DSCR */
+  "No Image Descriptor detected",              /* D_GIF_ERR_NO_IMAG_DSCR */
+  "No global or local color map",              /* D_GIF_ERR_NO_COLOR_MAP */
+  "Wrong record type detected",                        /* D_GIF_ERR_WRONG_RECORD */
+  "#Pixels bigger than Width * Height",                /* D_GIF_ERR_DATA_TOO_BIG */
+  "Fail to allocate required memory",          /* D_GIF_ERR_NOT_ENOUGH_MEM */
+  "Failed to close given file",                        /* D_GIF_ERR_CLOSE_FAILED */
+  "Given file was not opened for read",                /* D_GIF_ERR_CLOSE_FAILED */
+  "Image is defective, decoding aborted",      /* D_GIF_ERR_IMAGE_DEFECT */
+  "Image EOF detected before image complete",  /* D_GIF_ERR_EOF_TOO_SOON */
+  "Undefined error!",
+};
+
+const char *GetGifError(int error);
+
+/*****************************************************************************
+* Get the last GIF error in human-readable form.                            *
+*****************************************************************************/
+const char *GetGifError(int error)
+{
+    char *Err;
+
+    switch(error) {
+       case D_GIF_ERR_OPEN_FAILED:
+           Err = GifErrorString[0];
+           break;
+       case D_GIF_ERR_READ_FAILED:
+           Err = GifErrorString[1];
+           break;
+       case D_GIF_ERR_NOT_GIF_FILE:
+           Err = GifErrorString[2];
+           break;
+       case D_GIF_ERR_NO_SCRN_DSCR:
+           Err = GifErrorString[3];
+           break;
+       case D_GIF_ERR_NO_IMAG_DSCR:
+           Err = GifErrorString[4];
+           break;
+       case D_GIF_ERR_NO_COLOR_MAP:
+           Err = GifErrorString[5];
+           break;
+       case D_GIF_ERR_WRONG_RECORD:
+           Err = GifErrorString[6];
+           break;
+       case D_GIF_ERR_DATA_TOO_BIG:
+           Err = GifErrorString[7];
+           break;
+       case D_GIF_ERR_NOT_ENOUGH_MEM:
+           Err = GifErrorString[8];
+           break;
+       case D_GIF_ERR_CLOSE_FAILED:
+           Err = GifErrorString[9];
+           break;
+       case D_GIF_ERR_NOT_READABLE:
+           Err = GifErrorString[10];
+           break;
+       case D_GIF_ERR_IMAGE_DEFECT:
+           Err = GifErrorString[11];
+           break;
+       case D_GIF_ERR_EOF_TOO_SOON:
+           Err = GifErrorString[12];
+           break;
+       default:
+           Err = GifErrorString[13];
+           break;
+    }
+    return Err;
+}
+
+/******************************
+* These are called internally *        
+******************************/
+void GifError(GifFileType *GifFile, const char *err_str)
+{
+  GifIODataType *GifIO = (GifIODataType*)GifFile->GifIO;
+  if (GifIO->ErrorFunc)
+    (*(GifIO->ErrorFunc))(err_str, GifIO->ErrorFunc_data);
+  else
+    fprintf(stderr, "GIF FATAL ERROR: %s", err_str);
+  exit(-10);
+}
+
+void GifWarning(GifFileType *GifFile, const char *err_str)
+{
+  GifIODataType *GifIO = (GifIODataType*)GifFile->GifIO;
+  if (GifIO->WarningFunc) 
+    (*(GifIO->WarningFunc))(err_str, GifIO->WarningFunc_data);
+}
+
+void GifInternError(GifFileType *GifFile, int error_num)
+{
+  const char *ErrStr = GetGifError(error_num);
+  GifError(GifFile, ErrStr);
+}
+
+void GifInternWarning(GifFileType *GifFile, int error_num)
+{
+  const char *ErrStr = GetGifError(error_num);
+  GifWarning(GifFile, ErrStr);
+}
+
+void GifSetErrorFunc(GifFileType *GifFile, Gif_error_func ErrorFunc, VoidPtr data)
+{
+    GifIODataType *GifIO = (GifIODataType *)GifFile->GifIO;
+    GifIO->ErrorFunc = ErrorFunc;
+    GifIO->ErrorFunc_data = data;  
+}
+
+void GifSetWarningFunc(GifFileType *GifFile, Gif_error_func WarningFunc, VoidPtr data)
+{
+    GifIODataType *GifIO = (GifIODataType *)GifFile->GifIO;
+    GifIO->WarningFunc = WarningFunc;
+    GifIO->WarningFunc_data = data;
+}
diff --git a/src/gifrlib.h b/src/gifrlib.h
new file mode 100644 (file)
index 0000000..5b185d7
--- /dev/null
@@ -0,0 +1,272 @@
+/******************************************************************************
+* In order to make life a little bit easier when using the GIF file format,   *
+* this library was written, and which does all the dirty work...             *
+*                                                                            *
+*                                      Written by Gershon Elber,  Jun. 1989  *
+*                                      Hacks by Eric S. Raymond,  Sep. 1992  *
+*                                             and Jareth Hein,     Jan. 1998  *
+*******************************************************************************
+* History:                                                                   *
+* 14 Jun 89 - Version 1.0 by Gershon Elber.                                  *
+*  3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names). *
+* 15 Sep 90 - Version 2.0 by Eric S. Raymond (Changes to suoport GIF slurp)   *
+* 26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support)             *
+* 19 Jan 98 - Version 3.1 by Jareth Hein (Support for user-defined I/O).      *
+******************************************************************************/
+
+#ifndef GIF_LIB_H
+#define GIF_LIB_H
+
+#define        GIF_ERROR       0
+#define GIF_OK         1
+
+#ifndef TRUE
+#define TRUE           1
+#define FALSE          0
+#endif
+
+#ifndef NULL
+#define NULL           0
+#endif /* NULL */
+
+#define GIF_FILE_BUFFER_SIZE 16384  /* Files uses bigger buffers than usual. */
+
+typedef        int             GifBooleanType;
+typedef        unsigned char   GifPixelType;
+typedef unsigned char *        GifRowType;
+typedef unsigned char  GifByteType;
+
+#ifdef SYSV
+#define VoidPtr char *
+#else
+#define VoidPtr void *
+#endif /* SYSV */
+
+typedef struct GifColorType {
+    GifByteType Red, Green, Blue;
+} GifColorType;
+
+typedef struct ColorMapObject
+{
+    int        ColorCount;
+    int BitsPerPixel;
+    GifColorType *Colors;              /* on malloc(3) heap */
+}
+ColorMapObject;
+
+typedef struct GifImageDesc {
+    int Left, Top, Width, Height,      /* Current image dimensions. */
+       Interlace;                      /* Sequential/Interlaced lines. */
+    ColorMapObject *ColorMap;          /* The local color map */
+} GifImageDesc;
+
+/* I/O operations.  If you roll your own, they need to be semantically equivilent to
+   fread/fwrite, with an additional paramater to hold data local to your method. */
+typedef size_t (*Gif_rw_func)(GifByteType *buffer, size_t size, VoidPtr method_data);
+/* Finish up stream. Non-zero return indicates failure */
+typedef int (*Gif_close_func)(VoidPtr close_data);
+/* Error handling function */
+typedef void (*Gif_error_func)(const char *string, VoidPtr error_data);
+
+typedef struct GifFileType {
+    int SWidth, SHeight,               /* Screen dimensions. */
+       SColorResolution,               /* How many colors can we generate? */
+       SBackGroundColor;               /* I hope you understand this one... */
+    ColorMapObject *SColorMap;         /* NULL if it doesn't exist. */
+    int ImageCount;                    /* Number of current image */
+    GifImageDesc Image;                        /* Block describing current image */
+    struct SavedImage *SavedImages;    /* Use this to accumulate file state */
+    VoidPtr Private;                   /* Don't mess with this! */
+    VoidPtr GifIO;                     /* Contains all information for I/O */
+} GifFileType;
+
+typedef enum {
+    UNDEFINED_RECORD_TYPE,
+    SCREEN_DESC_RECORD_TYPE,
+    IMAGE_DESC_RECORD_TYPE,            /* Begin with ',' */
+    EXTENSION_RECORD_TYPE,             /* Begin with '!' */
+    TERMINATE_RECORD_TYPE              /* Begin with ';' */
+} GifRecordType;
+
+/******************************************************************************
+*  GIF89 extension function codes                                             *
+******************************************************************************/
+
+#define COMMENT_EXT_FUNC_CODE          0xfe    /* comment */
+#define GRAPHICS_EXT_FUNC_CODE         0xf9    /* graphics control */
+#define PLAINTEXT_EXT_FUNC_CODE                0x01    /* plaintext */
+#define APPLICATION_EXT_FUNC_CODE      0xff    /* application block */
+
+/******************************************************************************
+* IO related routines.  Defined in gif_io.c                                   *
+******************************************************************************/
+GifFileType *GifSetup(void);
+void GifFree(GifFileType *GifFile);
+void GifSetReadFunc (GifFileType *GifFile, Gif_rw_func func, VoidPtr data);
+void GifSetWriteFunc(GifFileType *GifFile, Gif_rw_func func, VoidPtr data);
+void GifSetCloseFunc(GifFileType *GifFile, Gif_close_func func, VoidPtr data);
+
+/******************************************************************************
+* O.K., here are the routines one can access in order to decode GIF file:     *
+******************************************************************************/
+
+void DGifOpenFileName(GifFileType *GifFile, const char *GifFileName);
+void DGifOpenFileHandle(GifFileType *GifFile, int GifFileHandle);
+void DGifInitRead(GifFileType *GifFile);
+void DGifSlurp(GifFileType *GifFile);
+void DGifGetScreenDesc(GifFileType *GifFile);
+void DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType);
+void DGifGetImageDesc(GifFileType *GifFile);
+void DGifGetLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
+void DGifGetPixel(GifFileType *GifFile, GifPixelType GifPixel);
+void DGifGetComment(GifFileType *GifFile, char *GifComment);
+void DGifGetExtension(GifFileType *GifFile, int *GifExtCode,
+                                               GifByteType **GifExtension);
+void DGifGetExtensionNext(GifFileType *GifFile, GifByteType **GifExtension);
+void DGifGetCode(GifFileType *GifFile, int *GifCodeSize,
+                                               GifByteType **GifCodeBlock);
+void DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock);
+void DGifGetLZCodes(GifFileType *GifFile, int *GifCode);
+int DGifCloseFile(GifFileType *GifFile);
+
+#define        D_GIF_ERR_OPEN_FAILED   101             /* And DGif possible errors. */
+#define        D_GIF_ERR_READ_FAILED   102
+#define        D_GIF_ERR_NOT_GIF_FILE  103
+#define D_GIF_ERR_NO_SCRN_DSCR 104
+#define D_GIF_ERR_NO_IMAG_DSCR 105
+#define D_GIF_ERR_NO_COLOR_MAP 106
+#define D_GIF_ERR_WRONG_RECORD 107
+#define D_GIF_ERR_DATA_TOO_BIG 108
+#define GIF_ERR_NOT_ENOUGH_MEM 109
+#define D_GIF_ERR_NOT_ENOUGH_MEM 109
+#define D_GIF_ERR_CLOSE_FAILED 110
+#define D_GIF_ERR_NOT_READABLE 111
+#define D_GIF_ERR_IMAGE_DEFECT 112
+#define D_GIF_ERR_EOF_TOO_SOON 113
+
+/******************************************************************************
+* O.K., here are the error routines                                          *
+******************************************************************************/
+extern void GifSetErrorFunc(GifFileType *GifFile, Gif_error_func func, VoidPtr data);
+extern void GifSetWarningFunc(GifFileType *GifFile, Gif_error_func func, VoidPtr data);
+extern void GifInternError(GifFileType *GifFile, int errnum);
+extern void GifInternWarning(GifFileType *GifFile, int errnum);
+extern void GifError(GifFileType *GifFile, const char *err_str);
+extern void GifWarning(GifFileType *GifFile, const char *err_str);
+
+/*****************************************************************************
+ *
+ * Everything below this point is new after version 1.2, supporting `slurp
+ * mode' for doing I/O in two big belts with all the image-bashing in core.
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+* Support for the in-core structures allocation (slurp mode).                *
+******************************************************************************/
+
+/* This is the in-core version of an extension record */
+typedef struct {
+    int                ByteCount;
+    char       *Bytes;         /* on malloc(3) heap */
+} ExtensionBlock;
+
+/* This holds an image header, its unpacked raster bits, and extensions */
+typedef struct SavedImage {
+    GifImageDesc       ImageDesc;
+
+    char               *RasterBits;            /* on malloc(3) heap */
+
+    int                        Function;
+    int                        ExtensionBlockCount;
+    ExtensionBlock     *ExtensionBlocks;       /* on malloc(3) heap */
+} SavedImage;
+
+extern void ApplyTranslation(SavedImage *Image, GifPixelType Translation[]);
+
+extern void MakeExtension(SavedImage *New, int Function);
+extern int AddExtensionBlock(SavedImage *New, int Length, GifByteType *data);
+extern void FreeExtension(SavedImage *Image);
+
+extern SavedImage *MakeSavedImage(GifFileType *GifFile, SavedImage *CopyFrom);
+extern void FreeSavedImages(GifFileType *GifFile);
+
+/*   Common defines used by encode/decode functions */
+
+#define COMMENT_EXT_FUNC_CODE  0xfe /* Extension function code for comment. */
+#define GIF_STAMP      "GIFVER"         /* First chars in file - GIF stamp. */
+#define GIF_STAMP_LEN  sizeof(GIF_STAMP) - 1
+#define GIF_VERSION_POS        3               /* Version first character in stamp. */
+#define GIF87_STAMP    "GIF87a"         /* First chars in file - GIF stamp. */
+#define GIF89_STAMP    "GIF89a"         /* First chars in file - GIF stamp. */
+
+#define LZ_MAX_CODE    4095            /* Biggest code possible in 12 bits. */
+#define LZ_BITS                12
+
+#define FILE_STATE_READ                0x01
+#define FILE_STATE_WRITE       0x01
+#define FILE_STATE_SCREEN      0x02
+#define FILE_STATE_IMAGE       0x04
+
+#define FLUSH_OUTPUT           4096    /* Impossible code, to signal flush. */
+#define FIRST_CODE             4097    /* Impossible code, to signal first. */
+#define NO_SUCH_CODE           4098    /* Impossible code, to signal empty. */
+
+#define IS_READABLE(Private)   (!(Private->FileState & FILE_STATE_READ))
+#define IS_WRITEABLE(Private)  (Private->FileState & FILE_STATE_WRITE)
+
+typedef struct GifFilePrivateType {
+    int FileState,
+       BitsPerPixel,       /* Bits per pixel (Codes uses at list this + 1). */
+       ClearCode,                                     /* The CLEAR LZ code. */
+       EOFCode,                                         /* The EOF LZ code. */
+       RunningCode,                /* The next code algorithm can generate. */
+       RunningBits,/* The number of bits required to represent RunningCode. */
+       MaxCode1,  /* 1 bigger than max. possible code, in RunningBits bits. */
+       LastCode,                       /* The code before the current code. */
+       CrntCode,                                 /* Current algorithm code. */
+       StackPtr,                        /* For character stack (see below). */
+       CrntShiftState;                 /* Number of bits in CrntShiftDWord. */
+    unsigned long CrntShiftDWord;     /* For bytes decomposition into codes. */
+    unsigned long PixelCount;                 /* Number of pixels in image. */
+    GifByteType Buf[256];             /* Compressed input is buffered here. */
+    GifByteType Stack[LZ_MAX_CODE];     /* Decoded pixels are stacked here. */
+    GifByteType Suffix[LZ_MAX_CODE+1];        /* So we can trace the codes. */
+    unsigned int Prefix[LZ_MAX_CODE+1];
+} GifFilePrivateType;
+
+typedef struct GifIODataType {
+    Gif_rw_func ReadFunc, WriteFunc;   /* Pointers to the functions that will do the I/O */
+    Gif_close_func CloseFunc;    
+    VoidPtr ReadFunc_data;             /* data to be passed to the read function */
+    VoidPtr WriteFunc_data;            /* data to be passed to the write function */
+    VoidPtr CloseFunc_data;            /* data to be passed to the close function */
+    Gif_error_func ErrorFunc;  /* MUST NOT RETURN (use lng_jmp or exit)!  */
+    Gif_error_func WarningFunc;        /* For warning messages (can be ignored) */
+    VoidPtr ErrorFunc_data;
+    VoidPtr WarningFunc_data;
+} GifIODataType;
+
+typedef struct GifStdIODataType {
+  FILE *File;
+  int FileHandle;
+} GifStdIODataType;
+
+/* Install StdIO funcs on FILE into GifFile */
+void GifStdIOInit(GifFileType *GifFile, FILE *file, int filehandle);
+
+/* Error checking reads, writes and closes */
+void GifRead(GifByteType *buf, size_t size, GifFileType *GifFile);
+void GifWrite(GifByteType *buf, size_t size, GifFileType *GifFile);
+int GifClose(GifFileType *GifFile);
+
+/* The default Read and Write functions for files */
+size_t GifStdRead(GifByteType *buf, size_t size, VoidPtr method_data);
+size_t GifStdWrite(GifByteType *buf, size_t size, VoidPtr method_data);
+int GifStdFileClose(VoidPtr method_data);
+
+ColorMapObject *MakeMapObject(int ColorCount, GifColorType *ColorMap);
+void FreeMapObject(ColorMapObject *Object);
+
+
+#endif /* GIF_LIB_H */
index c4daa12..bd1fcd7 100644 (file)
@@ -49,6 +49,7 @@ Boston, MA 02111-1307, USA.  */
 #include "lstream.h"
 #include "console.h"
 #include "device.h"
+#include "faces.h"
 #include "glyphs.h"
 #include "objects.h"
 
@@ -516,7 +517,7 @@ jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
  *                               GIF                                  *
  **********************************************************************/
 
-#include <gifrlib.h>
+#include "gifrlib.h"
 
 static void
 gif_validate (Lisp_Object instantiator)
@@ -697,8 +698,12 @@ gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
     eip = unwind.eimage;
     for (i = 0; i < height; i++)
       {
-       if (interlace && row >= height)
-         row = InterlacedOffset[++pass];
+       if (interlace)
+         if (row >= height) {
+           row = InterlacedOffset[++pass];
+           while (row > height) 
+             row = InterlacedOffset[++pass];
+         }
        eip = unwind.eimage + (row * width * 3);
        for (j = 0; j < width; j++)
          {
@@ -812,6 +817,8 @@ png_instantiate_unwind (Lisp_Object unwind_obj)
   if (data->instream)
     fclose (data->instream);
 
+  if (data->eimage) xfree(data->eimage);
+
   return Qnil;
 }
 
@@ -902,6 +909,42 @@ png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
     for (y = 0; y < height; y++)
       row_pointers[y] = unwind.eimage + (width * 3 * y);
 
+    {
+      /* if the png specifies a background chunk, go ahead and
+        use it, else use what we can get from the default face. */
+      png_color_16 my_background, *image_background;
+      Lisp_Object bkgd = Qnil;
+
+      my_background.red   = 0x7fff;
+      my_background.green = 0x7fff;
+      my_background.blue  = 0x7fff;
+      bkgd = FACE_BACKGROUND (Vdefault_face, domain);
+      if (!COLOR_INSTANCEP (bkgd))
+       {
+         warn_when_safe (Qpng, Qinfo, "Couldn't get background color!");
+       }
+      else
+       {
+         struct Lisp_Color_Instance *c;
+         Lisp_Object rgblist;
+
+         c = XCOLOR_INSTANCE (bkgd);
+         rgblist = MAYBE_LISP_DEVMETH (XDEVICE (c->device),
+                                       color_instance_rgb_components,
+                                       (c));
+         my_background.red = XINT (XCAR (rgblist));
+         my_background.green = XINT (XCAR (XCDR (rgblist)));
+         my_background.blue = XINT (XCAR (XCDR (XCDR (rgblist))));
+       }
+      
+      if (png_get_bKGD (png_ptr, info_ptr, &image_background))
+       png_set_background (png_ptr, image_background,
+                           PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+      else 
+       png_set_background (png_ptr, &my_background,
+                           PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+    }
+
     /* Now that we're using EImage, ask for 8bit RGB triples for any type
        of image*/
     /* convert palatte images to full RGB */
@@ -914,12 +957,6 @@ png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
     /* we can't handle alpha values */
     if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
       png_set_strip_alpha (png_ptr);
-    /* rip out any transparancy layers/colors */
-    if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
-      {
-        png_set_expand (png_ptr);
-       png_set_strip_alpha (png_ptr);
-      }
     /* tell libpng to strip 16 bit depth files down to 8 bits */
     if (info_ptr->bit_depth == 16)
       png_set_strip_16 (png_ptr);
@@ -932,25 +969,6 @@ png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
          png_set_packing (png_ptr);
       }
 
-#if 1 /* tests? or permanent? */
-    {
-      /* if the png specifies a background chunk, go ahead and
-        use it */
-      png_color_16 my_background, *image_background;
-    
-      /* ### how do I get the background of the current frame? */
-      my_background.red   = 0x7fff;
-      my_background.green = 0x7fff;
-      my_background.blue  = 0x7fff;
-
-      if (png_get_bKGD (png_ptr, info_ptr, &image_background))
-       png_set_background (png_ptr, image_background,
-                           PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
-      else 
-       png_set_background (png_ptr, &my_background,
-                           PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
-    }
-#endif
     png_read_image (png_ptr, row_pointers);
     png_read_end (png_ptr, info_ptr);
     
index 6ee899e..ddb16d4 100644 (file)
@@ -521,6 +521,8 @@ mswindows_create_resized_bitmap (struct Lisp_Image_Instance* ii,
                   IMAGE_INSTANCE_PIXMAP_HEIGHT (ii), 
                   SRCCOPY))
     {
+      DeleteObject (newbmp);
+      DeleteDC (hdcDst);
       return 0;
     }
 
@@ -553,6 +555,8 @@ mswindows_create_resized_mask (struct Lisp_Image_Instance* ii,
                      IMAGE_INSTANCE_PIXMAP_HEIGHT (ii), 
                      SRCCOPY))
        {
+         DeleteObject (newmask);
+         DeleteDC (hdcDst);
          return NULL;
        }
       
index 5b35f11..70b15e0 100644 (file)
@@ -39,6 +39,7 @@ Boston, MA 02111-1307, USA.  */
    Many changes for color work and optimizations by Jareth Hein for 21.0
    Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0
    TIFF code by Jareth Hein for 21.0
+   GIF/JPEG/PNG/TIFF code moved to new glyph-eimage.c for 21.0
 
    TODO:
    Convert images.el to C and stick it in here?
index b481ce8..86f2cb1 100644 (file)
@@ -2366,15 +2366,17 @@ pairs.  FORMAT should be one of
   instanced as `mono-pixmap', `color-pixmap', or `pointer'.)
 'gif
   (A GIF87 or GIF89 image; only if GIF support was compiled into this
-   XEmacs.  Can be instanced as `color-pixmap'.)
+   XEmacs.  NOTE: only the first frame of animated gifs will be displayed.
+   Can be instanced as `color-pixmap'.)
 'jpeg
   (A JPEG image; only if JPEG support was compiled into this XEmacs.
    Can be instanced as `color-pixmap'.)
 'png
-  (A PNG/GIF24 image; only if PNG support was compiled into this XEmacs.
+  (A PNG image; only if PNG support was compiled into this XEmacs.
    Can be instanced as `color-pixmap'.)
 'tiff
-  (A TIFF image; not currently implemented.)
+  (A TIFF image; only if TIFF support was compiled into this XEmacs.
+   Can be instanced as `color-pixmap'.)
 'cursor-font
   (One of the standard cursor-font names, such as "watch" or
    "right_ptr" under X.  Under X, this is, more specifically, any
index 0b917a7..ac6f2dc 100644 (file)
@@ -324,8 +324,11 @@ menu_name_to_accelerator (char *name)
       ++name;
       if (!(*name))
        return Qnil;
-      if (*name=='_'&&*(name+1))
-       return make_char (tolower(*(name+1)));
+      if (*name=='_' && *(name+1))
+       {
+         int accelerator = (int) (unsigned char) (*(name+1));
+         return make_char (tolower (accelerator));
+       }
     }
     ++name;
   }
index 01484b7..f516263 100644 (file)
@@ -1657,6 +1657,8 @@ gap_left (struct buffer *buf, Bytind pos)
   Bufbyte *to, *from;
   Bytecount i;
   Bytind new_s1;
+  struct buffer *mbuf;
+  Lisp_Object bufcons;
 
   from = BUF_GPT_ADDR (buf);
   to = from + BUF_GAP_SIZE (buf);
@@ -1708,13 +1710,22 @@ gap_left (struct buffer *buf, Bytind pos)
   /* Adjust markers, and buffer data structure, to put the gap at POS.
      POS is where the loop above stopped, which may be what was specified
      or may be where a quit was detected.  */
-  adjust_markers (buf, pos, BI_BUF_GPT (buf), BUF_GAP_SIZE (buf));
-  adjust_extents (make_buffer (buf), pos, BI_BUF_GPT (buf),
-                 BUF_GAP_SIZE (buf));
+  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+    {
+      adjust_markers (mbuf, pos, BI_BUF_GPT (mbuf), BUF_GAP_SIZE (mbuf));
+    }
+  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+    {
+      adjust_extents (make_buffer (mbuf), pos, BI_BUF_GPT (mbuf),
+                     BUF_GAP_SIZE (mbuf));
+    }
   SET_BI_BUF_GPT (buf, pos);
   SET_GAP_SENTINEL (buf);
 #ifdef ERROR_CHECK_EXTENTS
-  sledgehammer_extent_check (make_buffer (buf));
+  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+    {
+      sledgehammer_extent_check (make_buffer (mbuf));
+    }
 #endif
   QUIT;
 }
@@ -1725,6 +1736,8 @@ gap_right (struct buffer *buf, Bytind pos)
   Bufbyte *to, *from;
   Bytecount i;
   Bytind new_s1;
+  struct buffer *mbuf;
+  Lisp_Object bufcons;
 
   to = BUF_GPT_ADDR (buf);
   from = to + BUF_GAP_SIZE (buf);
@@ -1775,13 +1788,22 @@ gap_right (struct buffer *buf, Bytind pos)
 
   {
     int gsize = BUF_GAP_SIZE (buf);
-    adjust_markers (buf, BI_BUF_GPT (buf) + gsize, pos + gsize, - gsize);
-    adjust_extents (make_buffer (buf), BI_BUF_GPT (buf) + gsize, pos + gsize,
-                   - gsize);
+    MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+      {
+       adjust_markers (mbuf, BI_BUF_GPT (mbuf) + gsize, pos + gsize, - gsize);
+      }
+    MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+      {
+       adjust_extents (make_buffer (mbuf), BI_BUF_GPT (mbuf) + gsize,
+                       pos + gsize, - gsize);
+      }
     SET_BI_BUF_GPT (buf, pos);
     SET_GAP_SENTINEL (buf);
 #ifdef ERROR_CHECK_EXTENTS
-    sledgehammer_extent_check (make_buffer (buf));
+    MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+      {
+       sledgehammer_extent_check (make_buffer (mbuf));
+      }
 #endif
   }
   if (pos == BI_BUF_Z (buf))
@@ -2080,8 +2102,10 @@ static int inside_change_hook;
 static Lisp_Object
 change_function_restore (Lisp_Object buffer)
 {
-  Fset_buffer (buffer);
+  /* We should first reset the variable and then change the buffer,
+     because Fset_buffer() can throw.  */
   inside_change_hook = 0;
+  Fset_buffer (buffer);
   return Qnil;
 }
 
@@ -2090,8 +2114,8 @@ static int in_first_change;
 static Lisp_Object
 first_change_hook_restore (Lisp_Object buffer)
 {
-  Fset_buffer (buffer);
   in_first_change = 0;
+  Fset_buffer (buffer);
   return Qnil;
 }
 
@@ -2106,8 +2130,7 @@ signal_first_change (struct buffer *buf)
 
   if (!in_first_change)
     {
-      if (!preparing_for_armageddon &&
-         !NILP (symbol_value_in_buffer (Qfirst_change_hook, buffer)))
+      if (!NILP (symbol_value_in_buffer (Qfirst_change_hook, buffer)))
        {
          int speccount = specpdl_depth ();
          record_unwind_protect (first_change_hook_restore, buffer);
@@ -2126,11 +2149,13 @@ static void
 signal_before_change (struct buffer *buf, Bufpos start, Bufpos end)
 {
   /* This function can GC */
-  Lisp_Object buffer;
-  XSETBUFFER (buffer, buf);
+  struct buffer *mbuf;
+  Lisp_Object bufcons;
 
   if (!inside_change_hook)
     {
+      Lisp_Object buffer;
+
       /* Are we in a multiple-change session? */
       if (buf->text->changes->in_multiple_change &&
          buf->text->changes->mc_begin != 0)
@@ -2159,35 +2184,46 @@ signal_before_change (struct buffer *buf, Bufpos start, Bufpos end)
 
       /* If buffer is unmodified, run a special hook for that case.  */
       if (BUF_SAVE_MODIFF (buf) >= BUF_MODIFF (buf))
-       signal_first_change (buf);
+       {
+         MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+           {
+             signal_first_change (mbuf);
+           }
+       }
 
       /* Now in any case run the before-change-functions if any.  */
 
-      if (!preparing_for_armageddon &&
-         (!NILP (symbol_value_in_buffer (Qbefore_change_functions, buffer)) ||
-          /* Obsolete, for compatibility */
-          !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer))))
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
        {
-         int speccount = specpdl_depth ();
-         record_unwind_protect (change_function_restore, Fcurrent_buffer ());
-         set_buffer_internal (buf);
-         inside_change_hook = 1;
-         va_run_hook_with_args (Qbefore_change_functions, 2,
-                                make_int (start), make_int (end));
-         /* Obsolete, for compatibility */
-         va_run_hook_with_args (Qbefore_change_function, 2,
-                                make_int (start), make_int (end));
-         unbind_to (speccount, Qnil);
+         XSETBUFFER (buffer, mbuf);
+         if (!NILP (symbol_value_in_buffer (Qbefore_change_functions, buffer))
+             /* Obsolete, for compatibility */
+             || !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer)))
+           {
+             int speccount = specpdl_depth ();
+             record_unwind_protect (change_function_restore, Fcurrent_buffer ());
+             set_buffer_internal (buf);
+             inside_change_hook = 1;
+             va_run_hook_with_args (Qbefore_change_functions, 2,
+                                    make_int (start), make_int (end));
+             /* Obsolete, for compatibility */
+             va_run_hook_with_args (Qbefore_change_function, 2,
+                                    make_int (start), make_int (end));
+             unbind_to (speccount, Qnil);
+           }
+       }
+
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+       {
+         XSETBUFFER (buffer, mbuf);
+         report_extent_modification (buffer, start, end,
+                                     &inside_change_hook, 0);
        }
 
       /* Only now do we indicate that the before-change-functions have
         been called, in case some function throws out. */
       buf->text->changes->mc_begin_signaled = 1;
     }
-
-  /* #### At this point we should map over extents calling
-     modification-hooks, insert-before-hooks and insert-after-hooks
-     of relevant extents */
 }
 
 /* Signal a change immediately after it happens.
@@ -2201,15 +2237,25 @@ signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
                     Bufpos new_end)
 {
   /* This function can GC */
-  Lisp_Object buffer;
-  XSETBUFFER (buffer, buf);
+  struct buffer *mbuf;
+  Lisp_Object bufcons;
 
-  /* always do this. */
-  buffer_signal_changed_region (buf, start, new_end);
-  font_lock_maybe_update_syntactic_caches (buf, start, orig_end, new_end);
+  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+    {
+      /* always do this. */
+      buffer_signal_changed_region (mbuf, start, new_end);
+    }
+  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+    {
+      /* #### This seems inefficient.  Wouldn't it be better to just
+         keep one cache per base buffer?  */
+      font_lock_maybe_update_syntactic_caches (mbuf, start, orig_end, new_end);
+    }
 
   if (!inside_change_hook)
     {
+      Lisp_Object buffer;
+
       if (buf->text->changes->in_multiple_change &&
          buf->text->changes->mc_begin != 0)
        {
@@ -2221,30 +2267,38 @@ signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
          return; /* after-change-functions signalled when all changes done */
        }
 
-      if (!preparing_for_armageddon &&
-         (!NILP (symbol_value_in_buffer (Qafter_change_functions, buffer)) ||
-          /* Obsolete, for compatibility */
-          !NILP (symbol_value_in_buffer (Qafter_change_function, buffer))))
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
        {
-         int speccount = specpdl_depth ();
-         record_unwind_protect (change_function_restore, Fcurrent_buffer ());
-         set_buffer_internal (buf);
-         inside_change_hook = 1;
-         /* The actual after-change functions take slightly
-            different arguments than what we were passed. */
-         va_run_hook_with_args (Qafter_change_functions, 3,
-                                make_int (start), make_int (new_end),
-                                make_int (orig_end - start));
-         /* Obsolete, for compatibility */
-         va_run_hook_with_args (Qafter_change_function, 3,
-                                make_int (start), make_int (new_end),
-                                make_int (orig_end - start));
-         unbind_to (speccount, Qnil);
+         XSETBUFFER (buffer, mbuf);
+
+         if (!NILP (symbol_value_in_buffer (Qafter_change_functions, buffer))
+             /* Obsolete, for compatibility */
+             || !NILP (symbol_value_in_buffer (Qafter_change_function, buffer)))
+           {
+             int speccount = specpdl_depth ();
+             record_unwind_protect (change_function_restore, Fcurrent_buffer ());
+             set_buffer_internal (buf);
+             inside_change_hook = 1;
+             /* The actual after-change functions take slightly
+                different arguments than what we were passed. */
+             va_run_hook_with_args (Qafter_change_functions, 3,
+                                    make_int (start), make_int (new_end),
+                                    make_int (orig_end - start));
+             /* Obsolete, for compatibility */
+             va_run_hook_with_args (Qafter_change_function, 3,
+                                    make_int (start), make_int (new_end),
+                                    make_int (orig_end - start));
+             unbind_to (speccount, Qnil);
+           }
        }
-    }
 
-  /* #### At this point we should map over extents calling
-     some sort of modification hooks of relevant extents */
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+       {
+         XSETBUFFER (buffer, mbuf);
+         report_extent_modification (buffer, start, new_end,
+                                     &inside_change_hook, 1);
+       }
+    }
 }
 
 /* Call this if you're about to change the region of BUFFER from START
@@ -2260,10 +2314,14 @@ prepare_to_modify_buffer (struct buffer *buf, Bufpos start, Bufpos end,
   /* dmoore - This function can also kill the buffer buf, the current
      buffer, and do anything it pleases.  So if you call it, be
      careful. */
-  Lisp_Object buffer;
+  struct buffer *mbuf;
+  Lisp_Object buffer, bufcons;
   struct gcpro gcpro1;
 
-  barf_if_buffer_read_only (buf, start, end);
+  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+    {
+      barf_if_buffer_read_only (mbuf, start, end);
+    }
 
   /* if this is the first modification, see about locking the buffer's
      file */
@@ -2307,7 +2365,10 @@ prepare_to_modify_buffer (struct buffer *buf, Bufpos start, Bufpos end,
   Vdeactivate_mark = Qt;
 #endif
 
-  buf->point_before_scroll = Qnil;
+  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+    {
+      mbuf->point_before_scroll = Qnil;
+    }
 }
 
 \f
@@ -2367,6 +2428,8 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
   Bytind ind;
   Charcount cclen;
   int move_point = 0;
+  struct buffer *mbuf;
+  Lisp_Object bufcons;
 
   /* Defensive steps just in case a buffer gets deleted and a calling
      function doesn't notice it. */
@@ -2391,7 +2454,8 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
   if ((length + BUF_Z (buf)) > EMACS_INT_MAX)
     error ("Maximum buffer size exceeded");
 
-  /* theoretically not necessary -- caller should GCPRO */
+  /* theoretically not necessary -- caller should GCPRO.
+     #### buffer_insert_from_buffer_1() doesn't!  */
   GCPRO1 (reloc);
 
   prepare_to_modify_buffer (buf, pos, pos, !(flags & INSDEL_NO_LOCKING));
@@ -2433,7 +2497,11 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
 
   insert_invalidate_line_number_cache (buf, pos, nonreloc + offset, length);
 
-  record_insert (buf, pos, cclen);
+  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+    {
+      record_insert (mbuf, pos, cclen);
+    }
+
   BUF_MODIFF (buf)++;
   MARK_BUFFERS_CHANGED;
 
@@ -2445,7 +2513,10 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
 
   SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) - length);
   SET_BI_BUF_GPT (buf, BI_BUF_GPT (buf) + length);
-  SET_BOTH_BUF_ZV (buf, BUF_ZV (buf) + cclen, BI_BUF_ZV (buf) + length);
+  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+    {
+      SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) + cclen, BI_BUF_ZV (mbuf) + length);
+    }
   SET_BOTH_BUF_Z (buf, BUF_Z (buf) + cclen, BI_BUF_Z (buf) + length);
   SET_GAP_SENTINEL (buf);
 
@@ -2453,29 +2524,48 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
   buffer_mule_signal_inserted_region (buf, pos, length, cclen);
 #endif
 
-  process_extents_for_insertion (make_buffer (buf), ind, length);
-  /* We know the gap is at IND so the cast is OK. */
-  adjust_markers_for_insert (buf, (Memind) ind, length);
+  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+    {
+      process_extents_for_insertion (make_buffer (mbuf), ind, length);
+    }
+
+  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+    {
+      /* We know the gap is at IND so the cast is OK. */
+      adjust_markers_for_insert (mbuf, (Memind) ind, length);
+    }
 
   /* Point logically doesn't move, but may need to be adjusted because
      it's a byte index.  point-marker doesn't change because it's a
      memory index. */
-  if (BI_BUF_PT (buf) > ind)
-    JUST_SET_POINT (buf, BUF_PT (buf) + cclen, BI_BUF_PT (buf) + length);
+  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+    {
+      if (BI_BUF_PT (mbuf) > ind)
+       JUST_SET_POINT (mbuf, BUF_PT (mbuf) + cclen,
+                       BI_BUF_PT (mbuf) + length);
+    }
 
   /* Well, point might move. */
   if (move_point)
     BI_BUF_SET_PT (buf, ind + length);
 
   if (STRINGP (reloc))
-    splice_in_string_extents (reloc, buf, ind, length, offset);
+    {
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+       {
+         splice_in_string_extents (reloc, mbuf, ind, length, offset);
+       }
+    }
 
   if (flags & INSDEL_BEFORE_MARKERS)
     {
-      /* ind - 1 is correct because the FROM argument is exclusive.
-        I formerly used DEC_BYTIND() but that caused problems at the
-        beginning of the buffer. */
-      adjust_markers (buf, ind - 1, ind, length);
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+       {
+         /* ind - 1 is correct because the FROM argument is exclusive.
+            I formerly used DEC_BYTIND() but that caused problems at the
+            beginning of the buffer. */
+         adjust_markers (mbuf, ind - 1, ind, length);
+       }
     }
 
   signal_after_change (buf, pos, pos, pos + cclen);
@@ -2507,7 +2597,9 @@ buffer_insert_lisp_string_1 (struct buffer *buf, Bufpos pos, Lisp_Object str,
                             int flags)
 {
   /* This function can GC */
+#ifdef ERROR_CHECK_TYPECHECK
   assert (STRINGP (str));
+#endif
   return buffer_insert_string_1 (buf, pos, 0, str, 0,
                                 XSTRING_LENGTH (str),
                                 flags);
@@ -2520,7 +2612,6 @@ buffer_insert_c_string_1 (struct buffer *buf, Bufpos pos, CONST char *s,
                          int flags)
 {
   /* This function can GC */
-
   CONST char *translated = GETTEXT (s);
   return buffer_insert_string_1 (buf, pos, (CONST Bufbyte *) translated, Qnil,
                                 0, strlen (translated), flags);
@@ -2532,9 +2623,7 @@ buffer_insert_emacs_char_1 (struct buffer *buf, Bufpos pos, Emchar ch,
 {
   /* This function can GC */
   Bufbyte str[MAX_EMCHAR_LEN];
-  Bytecount len;
-
-  len = set_charptr_emchar (str, ch);
+  Bytecount len = set_charptr_emchar (str, ch);
   return buffer_insert_string_1 (buf, pos, str, Qnil, 0, len, flags);
 }
 
@@ -2573,7 +2662,8 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
   Bytind bi_from, bi_to;
   Bytecount bc_numdel;
   EMACS_INT shortage;
-  Lisp_Object bufobj;
+  struct buffer *mbuf;
+  Lisp_Object bufcons;
 
   /* Defensive steps just in case a buffer gets deleted and a calling
      function doesn't notice it. */
@@ -2604,8 +2694,6 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
   if ((numdel = to - from) <= 0)
     return;
 
-  XSETBUFFER (bufobj, buf);
-
   /* Redisplay needs to know if a newline was in the deleted region.
      If we've already marked the changed region as having a deleted
      newline there is no use in performing the check. */
@@ -2613,7 +2701,12 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
     {
       scan_buffer (buf, '\n', from, to, 1, &shortage, 1);
       if (!shortage)
-       buf->changes->newline_was_deleted = 1;
+       {
+         MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+           {
+             mbuf->changes->newline_was_deleted = 1;
+           }
+       }
     }
 
   bi_from = bufpos_to_bytind (buf, from);
@@ -2627,49 +2720,70 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
     {
       /* avoid moving the gap just to delete from the bottom. */
 
-      record_delete (buf, from, numdel);
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+       {
+         record_delete (mbuf, from, numdel);
+       }
       BUF_MODIFF (buf)++;
       MARK_BUFFERS_CHANGED;
 
-      /* ### Point used to be modified here, but this causes problems with MULE,
-        as point is used to calculate bytinds, and if the offset in bc_numdel causes
-        point to move to a non first-byte location, causing some other function to
-        throw an assertion in ASSERT_VALID_BYTIND. I've moved the code to right after
-         the other movements and adjustments, but before the gap is moved.
-         -- jh 970813 */
+      /* #### Point used to be modified here, but this causes problems
+        with MULE, as point is used to calculate bytinds, and if the
+        offset in bc_numdel causes point to move to a non first-byte
+        location, causing some other function to throw an assertion
+        in ASSERT_VALID_BYTIND. I've moved the code to right after
+        the other movements and adjustments, but before the gap is
+        moved.  -- jh 970813 */
 
       /* Detach any extents that are completely within the range [FROM, TO],
         if the extents are detachable.
 
-        This must come AFTER record_delete(), so that the appropriate extents
-        will be present to be recorded, and BEFORE the gap size is increased,
-        as otherwise we will be confused about where the extents end. */
-      process_extents_for_deletion (bufobj, bi_from, bi_to, 0);
+        This must come AFTER record_delete(), so that the appropriate
+        extents will be present to be recorded, and BEFORE the gap
+        size is increased, as otherwise we will be confused about
+        where the extents end. */
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+       {
+         process_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to, 0);
+       }
 
-      /* Relocate all markers pointing into the new, larger gap
-        to point at the end of the text before the gap.  */
-      adjust_markers (buf,
-                     (bi_to + BUF_GAP_SIZE (buf)),
-                     (bi_to + BUF_GAP_SIZE (buf)),
-                     (- bc_numdel));
+      /* Relocate all markers pointing into the new, larger gap to
+        point at the end of the text before the gap.  */
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+       {
+         adjust_markers (mbuf,
+                         (bi_to + BUF_GAP_SIZE (mbuf)),
+                         (bi_to + BUF_GAP_SIZE (mbuf)),
+                         (- bc_numdel));
+       }
 
-      /* Relocate any extent endpoints just like markers. */
-      adjust_extents_for_deletion (bufobj, bi_from, bi_to,
-                                  BUF_GAP_SIZE (buf), bc_numdel, 0);
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+       {
+         /* Relocate any extent endpoints just like markers. */
+         adjust_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to,
+                                      BUF_GAP_SIZE (mbuf), bc_numdel, 0);
+       }
 
-      /* Relocate point as if it were a marker.  */
-      if (bi_from < BI_BUF_PT (buf))
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
        {
-         if (BI_BUF_PT (buf) < bi_to)
-           JUST_SET_POINT (buf, from, bi_from);
-         else
-           JUST_SET_POINT (buf, BUF_PT (buf) - numdel,
-                           BI_BUF_PT (buf) - bc_numdel);
+         /* Relocate point as if it were a marker.  */
+         if (bi_from < BI_BUF_PT (mbuf))
+           {
+             if (BI_BUF_PT (mbuf) < bi_to)
+               JUST_SET_POINT (mbuf, from, bi_from);
+             else
+               JUST_SET_POINT (mbuf, BUF_PT (mbuf) - numdel,
+                               BI_BUF_PT (mbuf) - bc_numdel);
+           }
        }
 
       SET_BUF_END_GAP_SIZE (buf, BUF_END_GAP_SIZE (buf) + bc_numdel);
 
-      SET_BOTH_BUF_ZV (buf, BUF_ZV (buf) - numdel, BI_BUF_ZV (buf) - bc_numdel);
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+       {
+         SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) - numdel,
+                          BI_BUF_ZV (mbuf) - bc_numdel);
+       }
       SET_BOTH_BUF_Z (buf, BUF_Z (buf) - numdel, BI_BUF_Z (buf) - bc_numdel);
       SET_GAP_SENTINEL (buf);
     }
@@ -2681,16 +2795,20 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
       if (bi_from > BI_BUF_GPT (buf))
        gap_right (buf, bi_from);
 
-      record_delete (buf, from, numdel);
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+       {
+         record_delete (mbuf, from, numdel);
+       }
       BUF_MODIFF (buf)++;
       MARK_BUFFERS_CHANGED;
 
-      /* ### Point used to be modified here, but this causes problems with MULE,
-        as point is used to calculate bytinds, and if the offset in bc_numdel causes
-        point to move to a non first-byte location, causing some other function to
-        throw an assertion in ASSERT_VALID_BYTIND. I've moved the code to right after
-         the other movements and adjustments, but before the gap is moved.
-         -- jh 970813 */
+      /* #### Point used to be modified here, but this causes problems
+        with MULE, as point is used to calculate bytinds, and if the
+        offset in bc_numdel causes point to move to a non first-byte
+        location, causing some other function to throw an assertion
+        in ASSERT_VALID_BYTIND. I've moved the code to right after
+        the other movements and adjustments, but before the gap is
+        moved.  -- jh 970813 */
 
       /* Detach any extents that are completely within the range [FROM, TO],
         if the extents are detachable.
@@ -2698,31 +2816,48 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
         This must come AFTER record_delete(), so that the appropriate extents
         will be present to be recorded, and BEFORE the gap size is increased,
         as otherwise we will be confused about where the extents end. */
-      process_extents_for_deletion (bufobj, bi_from, bi_to, 0);
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+       {
+         process_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to, 0);
+       }
 
-      /* Relocate all markers pointing into the new, larger gap
-        to point at the end of the text before the gap.  */
-      adjust_markers (buf,
-                     (bi_to + BUF_GAP_SIZE (buf)),
-                     (bi_to + BUF_GAP_SIZE (buf)),
-                     (- bc_numdel - BUF_GAP_SIZE (buf)));
+      /* Relocate all markers pointing into the new, larger gap to
+        point at the end of the text before the gap.  */
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+       {
+         adjust_markers (mbuf,
+                         (bi_to + BUF_GAP_SIZE (mbuf)),
+                         (bi_to + BUF_GAP_SIZE (mbuf)),
+                         (- bc_numdel - BUF_GAP_SIZE (mbuf)));
+       }
 
       /* Relocate any extent endpoints just like markers. */
-      adjust_extents_for_deletion (bufobj, bi_from, bi_to, BUF_GAP_SIZE (buf),
-                                  bc_numdel, BUF_GAP_SIZE (buf));
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+       {
+         adjust_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to,
+                                      BUF_GAP_SIZE (mbuf),
+                                      bc_numdel, BUF_GAP_SIZE (mbuf));
+       }
 
-      /* Relocate point as if it were a marker.  */
-      if (bi_from < BI_BUF_PT (buf))
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
        {
-         if (BI_BUF_PT (buf) < bi_to)
-           JUST_SET_POINT (buf, from, bi_from);
-         else
-           JUST_SET_POINT (buf, BUF_PT (buf) - numdel,
-                           BI_BUF_PT (buf) - bc_numdel);
+         /* Relocate point as if it were a marker.  */
+         if (bi_from < BI_BUF_PT (mbuf))
+           {
+             if (BI_BUF_PT (mbuf) < bi_to)
+               JUST_SET_POINT (mbuf, from, bi_from);
+             else
+               JUST_SET_POINT (mbuf, BUF_PT (mbuf) - numdel,
+                               BI_BUF_PT (mbuf) - bc_numdel);
+           }
        }
 
       SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + bc_numdel);
-      SET_BOTH_BUF_ZV (buf, BUF_ZV (buf) - numdel, BI_BUF_ZV (buf) - bc_numdel);
+      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+       {
+         SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) - numdel,
+                          BI_BUF_ZV (mbuf) - bc_numdel);
+       }
       SET_BOTH_BUF_Z (buf, BUF_Z (buf) - numdel, BI_BUF_Z (buf) - bc_numdel);
       SET_BI_BUF_GPT (buf, bi_from);
       SET_GAP_SENTINEL (buf);
@@ -2733,7 +2868,10 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
 #endif
 
 #ifdef ERROR_CHECK_EXTENTS
-  sledgehammer_extent_check (bufobj);
+  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+    {
+      sledgehammer_extent_check (make_buffer (mbuf));
+    }
 #endif
 
   signal_after_change (buf, from, to, from);
@@ -2747,7 +2885,7 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
 /* Replace the character at POS in buffer B with CH. */
 
 void
-buffer_replace_char (struct buffer *b, Bufpos pos, Emchar ch,
+buffer_replace_char (struct buffer *buf, Bufpos pos, Emchar ch,
                     int not_real_change, int force_lock_check)
 {
   /* This function can GC */
@@ -2757,42 +2895,54 @@ buffer_replace_char (struct buffer *b, Bufpos pos, Emchar ch,
 
   /* Defensive steps just in case a buffer gets deleted and a calling
      function doesn't notice it. */
-  if (!BUFFER_LIVE_P (b))
+  if (!BUFFER_LIVE_P (buf))
     return;
 
-  curlen = BUF_CHARPTR_COPY_CHAR (b, pos, curstr);
+  curlen = BUF_CHARPTR_COPY_CHAR (buf, pos, curstr);
   newlen = set_charptr_emchar (newstr, ch);
 
   if (curlen == newlen)
     {
+      struct buffer *mbuf;
+      Lisp_Object bufcons;
+
       /* then we can just replace the text. */
-      prepare_to_modify_buffer (b, pos, pos + 1,
+      prepare_to_modify_buffer (buf, pos, pos + 1,
                                !not_real_change || force_lock_check);
       /* Defensive steps in case the before-change-functions fuck around */
-      if (!BUFFER_LIVE_P (b))
+      if (!BUFFER_LIVE_P (buf))
        /* Bad bad pre-change function. */
        return;
 
       /* Make args be valid again.  prepare_to_modify_buffer() might have
         modified the buffer. */
-      if (pos < BUF_BEGV (b))
-       pos = BUF_BEGV (b);
-      if (pos >= BUF_ZV (b))
-       pos = BUF_ZV (b) - 1;
-      if (pos < BUF_BEGV (b))
+      if (pos < BUF_BEGV (buf))
+       pos = BUF_BEGV (buf);
+      if (pos >= BUF_ZV (buf))
+       pos = BUF_ZV (buf) - 1;
+      if (pos < BUF_BEGV (buf))
        /* no more characters in buffer! */
        return;
 
-      if (BUF_FETCH_CHAR (b, pos) == '\n')
-       b->changes->newline_was_deleted = 1;
+      if (BUF_FETCH_CHAR (buf, pos) == '\n')
+       {
+         MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+           {
+             mbuf->changes->newline_was_deleted = 1;
+           }
+       }
       MARK_BUFFERS_CHANGED;
       if (!not_real_change)
        {
-         record_change (b, pos, 1);
-         BUF_MODIFF (b)++;
+         MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+           {
+             record_change (mbuf, pos, 1);
+           }
+         BUF_MODIFF (buf)++;
        }
-      memcpy (BUF_BYTE_ADDRESS (b, pos), newstr, newlen);
-      signal_after_change (b, pos, pos + 1, pos + 1);
+      memcpy (BUF_BYTE_ADDRESS (buf, pos), newstr, newlen);
+
+      signal_after_change (buf, pos, pos + 1, pos + 1);
 
       /* We do not have to adjust the Mule data; we just replaced a
         character with another of the same number of bytes. */
@@ -2807,21 +2957,21 @@ buffer_replace_char (struct buffer *b, Bufpos pos, Emchar ch,
        * point.  Point will drift backward by one position and stay
        * there otherwise.
        */
-      int movepoint = (pos == BUF_PT (b) - 1);
+      int movepoint = (pos == BUF_PT (buf) - 1);
 
-      buffer_delete_range (b, pos, pos + 1, 0);
+      buffer_delete_range (buf, pos, pos + 1, 0);
       /* Defensive steps in case the before-change-functions fuck around */
-      if (!BUFFER_LIVE_P (b))
+      if (!BUFFER_LIVE_P (buf))
        /* Bad bad pre-change function. */
        return;
 
       /* Make args be valid again.  prepare_to_modify_buffer() might have
         modified the buffer. */
-      if (pos < BUF_BEGV (b))
-       pos = BUF_BEGV (b);
-      if (pos >= BUF_ZV (b))
-       pos = BUF_ZV (b) - 1;
-      if (pos < BUF_BEGV (b))
+      if (pos < BUF_BEGV (buf))
+       pos = BUF_BEGV (buf);
+      if (pos >= BUF_ZV (buf))
+       pos = BUF_ZV (buf) - 1;
+      if (pos < BUF_BEGV (buf))
        /* no more characters in buffer! */
        return;
       /*
@@ -2829,7 +2979,7 @@ buffer_replace_char (struct buffer *b, Bufpos pos, Emchar ch,
        * insertion, which we must do if the deletion moved point
        * backward so that it now equals the insertion point.
        */
-      buffer_insert_string_1 (b, (movepoint ? -1 : pos),
+      buffer_insert_string_1 (buf, (movepoint ? -1 : pos),
                              newstr, Qnil, 0, newlen, 0);
     }
 }
@@ -3085,9 +3235,9 @@ vars_of_insdel (void)
 }
 
 void
-init_buffer_text (struct buffer *b, int indirect_p)
+init_buffer_text (struct buffer *b)
 {
-  if (!indirect_p)
+  if (!b->base_buffer)
     {
       SET_BUF_GAP_SIZE (b, 20);
       BUFFER_ALLOC (b->text->beg, BUF_GAP_SIZE (b) + BUF_END_SENTINEL_SIZE);
@@ -3115,6 +3265,7 @@ init_buffer_text (struct buffer *b, int indirect_p)
          }
       }
 #endif /* MULE */
+      b->text->line_number_cache = Qnil;
 
       BUF_MODIFF (b) = 1;
       BUF_SAVE_MODIFF (b) = 1;
@@ -3145,9 +3296,9 @@ init_buffer_text (struct buffer *b, int indirect_p)
 }
 
 void
-uninit_buffer_text (struct buffer *b, int indirect_p)
+uninit_buffer_text (struct buffer *b)
 {
-  if (!indirect_p)
+  if (!b->base_buffer)
     {
       BUFFER_FREE (b->text->beg);
       xfree (b->text->changes);
index 0de1d3f..944fed3 100644 (file)
@@ -156,7 +156,7 @@ void font_lock_buffer_was_killed (struct buffer *buf);
 void barf_if_buffer_read_only (struct buffer *buf, Bufpos from,
                               Bufpos to);
 
-void init_buffer_text (struct buffer *b, int indirect_p);
-void uninit_buffer_text (struct buffer *b, int indirect_p);
+void init_buffer_text (struct buffer *b);
+void uninit_buffer_text (struct buffer *b);
 
 #endif /* _XEMACS_INSDEL_H_ */
index efab47d..e2a5152 100644 (file)
@@ -4325,10 +4325,12 @@ Keymap of key translations that can override keymaps.
 This keymap works like `function-key-map', but comes after that,
 and applies even for keys that have ordinary bindings.
 */ );
+  Vkey_translation_map = Qnil;
 
   DEFVAR_LISP ("vertical-divider-map", &Vvertical_divider_map /*
 Keymap which handles mouse clicks over vertical dividers.
 */ );
+  Vvertical_divider_map = Qnil;
 
   DEFVAR_INT ("keymap-tick", &keymap_tick /*
 Incremented for each change to any keymap.
index a0ad5e1..05b42ff 100644 (file)
@@ -74,8 +74,8 @@ Boston, MA 02111-1307, USA.  */
 #define LINE_NUMBER_LARGE_STRING 256
 
 /* To be used only when you *know* the cache has been allocated!  */
-#define LINE_NUMBER_RING(b) (XCAR ((b)->line_number_cache))
-#define LINE_NUMBER_BEGV(b) (XCDR ((b)->line_number_cache))
+#define LINE_NUMBER_RING(b) (XCAR ((b)->text->line_number_cache))
+#define LINE_NUMBER_BEGV(b) (XCDR ((b)->text->line_number_cache))
 
 
 /* Initialize the cache.  Cache is (in pseudo-BNF):
@@ -89,12 +89,12 @@ Boston, MA 02111-1307, USA.  */
 
    Line number cache should never, ever, be visible to Lisp (because
    destructively modifying its elements can cause crashes.)  Debug it
-   using debug_print (current_buffer->last_number_cache).  */
+   using debug_print (current_buffer->text->last_number_cache).  */
 static void
 allocate_line_number_cache (struct buffer *b)
 {
-  b->line_number_cache = Fcons (make_vector (LINE_NUMBER_RING_SIZE, Qnil),
-                               Qzero);
+  b->text->line_number_cache = Fcons (make_vector (LINE_NUMBER_RING_SIZE, Qnil),
+                                     Qzero);
   narrow_line_number_cache (b);
 }
 
@@ -103,7 +103,7 @@ allocate_line_number_cache (struct buffer *b)
 void
 narrow_line_number_cache (struct buffer *b)
 {
-  if (NILP (b->line_number_cache))
+  if (NILP (b->text->line_number_cache))
     return;
 
   if (BUF_BEG (b) == BUF_BEGV (b))
@@ -161,7 +161,7 @@ void
 insert_invalidate_line_number_cache (struct buffer *b, Bufpos pos,
                                     CONST Bufbyte *nonreloc, Bytecount length)
 {
-  if (NILP (b->line_number_cache))
+  if (NILP (b->text->line_number_cache))
     return;
 
   if (length > LINE_NUMBER_LARGE_STRING
@@ -182,7 +182,7 @@ insert_invalidate_line_number_cache (struct buffer *b, Bufpos pos,
 void
 delete_invalidate_line_number_cache (struct buffer *b, Bufpos from, Bufpos to)
 {
-  if (NILP (b->line_number_cache))
+  if (NILP (b->text->line_number_cache))
     return;
 
   if ((to - from) > LINE_NUMBER_LARGE_STRING)
@@ -280,7 +280,7 @@ buffer_line_number (struct buffer *b, Bufpos pos, int cachep)
 
   if (cachep)
     {
-      if (NILP (b->line_number_cache))
+      if (NILP (b->text->line_number_cache))
        allocate_line_number_cache (b);
       /* If we don't know the line number of BUF_BEGV, calculate it now.  */
       if (XINT (LINE_NUMBER_BEGV (b)) == -1)
index d8a1f7f..8d7360e 100644 (file)
@@ -2689,6 +2689,7 @@ EXFUN (Fsymbol_function, 1);
 EXFUN (Fsymbol_name, 1);
 EXFUN (Fsymbol_plist, 1);
 EXFUN (Fsymbol_value, 1);
+EXFUN (Fsystem_name, 0);
 EXFUN (Fthrow, 2);
 EXFUN (Ftimes, MANY);
 EXFUN (Ftruncate, 1);
index 9c0fa8b..98516f0 100644 (file)
@@ -91,9 +91,6 @@ int load_warn_when_source_only;
 /* Whether Fload_internal() should ignore .elc files when no suffix is given */
 int load_ignore_elc_files;
 
-/* Directory in which the sources were found.  */
-Lisp_Object Vsource_directory;
-
 /* Search path for files to be loaded. */
 Lisp_Object Vload_path;
 
@@ -796,10 +793,11 @@ encoding detection or end-of-line detection.
   if (purify_flag && noninteractive)
     {
       if (EQ (last_file_loaded, file))
-       message_append (" (%d)", purespace_usage() - pure_usage);
+       message_append (" (%ld)", 
+                       (unsigned long) (purespace_usage() - pure_usage));
       else
-       message ("Loading %s ...done (%d)", XSTRING_DATA (file),
-                purespace_usage() - pure_usage);
+       message ("Loading %s ...done (%ld)", XSTRING_DATA (file),
+                (unsigned long) (purespace_usage() - pure_usage));
     }
 /*#endif / * DEBUG_XEMACS */
 
@@ -3153,12 +3151,6 @@ This is useful when the file being loaded is a temporary copy.
 */ );
   load_force_doc_strings = 0;
 
-  DEFVAR_LISP ("source-directory", &Vsource_directory /*
-Directory in which XEmacs sources were found when XEmacs was built.
-You cannot count on them to still be there!
-*/ );
-  Vsource_directory = Qnil;
-
   /* See read_escape().  */
 #if 0
   /* Used to be named `puke-on-fsf-keys' */
index d4c6260..a163241 100644 (file)
@@ -105,7 +105,7 @@ An argument of zero means repeat until error.
   int repeat;
 
   if (NILP (con->defining_kbd_macro))
-    error ("Not defining kbd macro.");
+    error ("Not defining kbd macro");
 
   if (NILP (arg))
     repeat = -1;
@@ -275,7 +275,7 @@ COUNT is a repeat count, or nil for once, or 0 for infinite loop.
 
   final = indirect_function (macro, 1);
   if (!STRINGP (final) && !VECTORP (final))
-    error ("Keyboard macros must be strings or vectors.");
+    error ("Keyboard macros must be strings or vectors");
 
   tem = Fcons (Vexecuting_macro, make_int (executing_macro_index));
   record_unwind_protect (pop_kbd_macro, tem);
index 507e314..88ef60b 100644 (file)
@@ -523,7 +523,10 @@ init_buffer_markers (struct buffer *b)
   b->mark = Fmake_marker ();
   BUF_MARKERS (b) = 0;
   b->point_marker = Fmake_marker ();
-  Fset_marker (b->point_marker, make_int (1), buf);
+  Fset_marker (b->point_marker,
+              /* For indirect buffers, point is already set.  */
+              b->base_buffer ? make_int (BUF_PT (b)) : make_int (1),
+              buf);
 }
 
 void
index bc47b7f..2075f92 100644 (file)
@@ -123,7 +123,7 @@ static HMENU top_level_menu;
  * "Left Flush\tRight Flush"
  */
 static char*
-displayable_menu_item (struct gui_item* pgui_item)
+displayable_menu_item (struct gui_item* pgui_item, int bar_p)
 {
   /* We construct the name in a static buffer. That's fine, beause
      menu items longer than 128 chars are probably programming errors,
@@ -135,12 +135,15 @@ displayable_menu_item (struct gui_item* pgui_item)
   /* Left flush part of the string */
   ll = gui_item_display_flush_left (pgui_item, buf, MAX_MENUITEM_LENGTH);
 
-  /* Right flush part */
-  assert (MAX_MENUITEM_LENGTH > ll + 1);
-  lr = gui_item_display_flush_right (pgui_item, buf + ll + 1,
-                                    MAX_MENUITEM_LENGTH - ll - 1);
-  if (lr)
-    buf [ll] = '\t';
+  /* Right flush part, unless we're at the top-level where it's not allowed */
+  if (!bar_p)
+    {
+      assert (MAX_MENUITEM_LENGTH > ll + 1);
+      lr = gui_item_display_flush_right (pgui_item, buf + ll + 1,
+                                        MAX_MENUITEM_LENGTH - ll - 1);
+      if (lr)
+       buf [ll] = '\t';
+     }
 
   return buf;
 }
@@ -223,7 +226,8 @@ checksum_menu_item (Lisp_Object item)
 
 static void
 populate_menu_add_item (HMENU menu, Lisp_Object path,
-                       Lisp_Object hash_tab, Lisp_Object item, int flush_right)
+                       Lisp_Object hash_tab, Lisp_Object item,
+                       int flush_right, int bar_p)
 {
   MENUITEMINFO item_info;
 
@@ -271,7 +275,7 @@ populate_menu_add_item (HMENU menu, Lisp_Object path,
       submenu = create_empty_popup_menu();
 
       item_info.fMask |= MIIM_SUBMENU;
-      item_info.dwTypeData = displayable_menu_item (&gui_item);
+      item_info.dwTypeData = displayable_menu_item (&gui_item, bar_p);
       item_info.hSubMenu = submenu;
 
       if (!(item_info.fState & MFS_GRAYED))
@@ -332,13 +336,13 @@ populate_menu_add_item (HMENU menu, Lisp_Object path,
 
       item_info.wID = (UINT) XINT(id);
       item_info.fType |= MFT_STRING;
-      item_info.dwTypeData = displayable_menu_item (&gui_item);
+      item_info.dwTypeData = displayable_menu_item (&gui_item, bar_p);
 
       UNGCPRO; /* gui_item */
     }
   else
     {
-      signal_simple_error ("Mailformed menu item descriptor", item);
+      signal_simple_error ("Malformed menu item descriptor", item);
     }
 
   if (flush_right)
@@ -408,7 +412,7 @@ populate_or_checksum_helper (HMENU menu, Lisp_Object path, Lisp_Object desc,
        }
       else if (populate_p)
        populate_menu_add_item (menu, path, hash_tab,
-                               XCAR (item_desc), flush_right);
+                               XCAR (item_desc), flush_right, bar_p);
       else
        checksum = HASH2 (checksum,
                          checksum_menu_item (XCAR (item_desc)));
index fac1c60..a225eb5 100644 (file)
@@ -333,6 +333,33 @@ restore_in_menu_callback (Lisp_Object val)
 }
 #endif /* LWLIB_MENUBARS_LUCID || LWLIB_MENUBARS_MOTIF */
 
+#if 0
+/* #### Sort of a hack needed to process Vactivate_menubar_hook
+   correctly wrt buffer-local values.  A correct solution would
+   involve adding a callback mechanism to run_hook().  This function
+   is currently unused.  */
+static int
+my_run_hook (Lisp_Object hooksym, int allow_global_p)
+{
+  /* This function can GC */
+  Lisp_Object tail;
+  Lisp_Object value = Fsymbol_value (hooksym);
+  int changes = 0;
+
+  if (!NILP (value) && (!CONSP (value) || EQ (XCAR (value), Qlambda)))
+    return !EQ (call0 (value), Qt);
+
+  EXTERNAL_LIST_LOOP (tail, value)
+    {
+      if (allow_global_p && EQ (XCAR (tail), Qt))
+       changes |= my_run_hook (Fdefault_value (hooksym), 0);
+      if (!EQ (call0 (XCAR (tail)), Qt))
+       changes = 1;
+    }
+  return changes;
+}
+#endif
+
 
 /* The order in which callbacks are run is funny to say the least.
    It's sometimes tricky to avoid running a callback twice, and to
@@ -358,12 +385,9 @@ static void
 pre_activate_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
 {
   /* This function can GC */
-  struct gcpro gcpro1;
   struct device *d = get_device_from_display (XtDisplay (widget));
   struct frame *f = x_any_window_to_frame (d, XtWindow (widget));
-  Lisp_Object rest = Qnil;
   Lisp_Object frame;
-  int any_changes = 0;
   int count;
 
   /* set in lwlib to the time stamp associated with the most recent menu
@@ -418,24 +442,17 @@ pre_activate_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
       replace_widget_value_tree (hack_wv, wv->contents);
       free_popup_widget_value_tree (wv);
     }
+  else if (!POPUP_DATAP (FRAME_MENUBAR_DATA (f)))
+    return;
   else
     {
-      if (!POPUP_DATAP (FRAME_MENUBAR_DATA (f)))
-       return;
+#if 0 /* Unused, see comment below. */
+      int any_changes;
+
       /* #### - this menubar update mechanism is expensively anti-social and
         the activate-menubar-hook is now mostly obsolete. */
-      /* make the activate-menubar-hook be a list of functions, not a single
-        function, just to simplify things. */
-      if (!NILP (Vactivate_menubar_hook) &&
-         (!CONSP (Vactivate_menubar_hook) ||
-          EQ (XCAR (Vactivate_menubar_hook), Qlambda)))
-       Vactivate_menubar_hook = Fcons (Vactivate_menubar_hook, Qnil);
-
-      GCPRO1 (rest);
-      for (rest = Vactivate_menubar_hook; !NILP (rest); rest = Fcdr (rest))
-       if (!EQ (call0 (XCAR (rest)), Qt))
-         any_changes = 1;
-#if 0
+      any_changes = my_run_hook (Qactivate_menubar_hook, 1);
+
       /* #### - It is necessary to *ALWAYS* call set_frame_menubar() now that
         incremental menus are implemented.  If a subtree of a menu has been
         updated incrementally (a destructive operation), then that subtree
@@ -446,12 +463,14 @@ pre_activate_callback (Widget widget, LWLIB_ID id, XtPointer client_data)
         that an INCREMENTAL_TYPE widget_value can be recreated...  Hmmmmm. */
       if (any_changes ||
          !XFRAME_MENUBAR_DATA (f)->menubar_contents_up_to_date)
-#endif
        set_frame_menubar (f, 1, 0);
+#else
+      run_hook (Qactivate_menubar_hook);
+      set_frame_menubar (f, 1, 0);
+#endif
       DEVICE_X_MOUSE_TIMESTAMP (XDEVICE (FRAME_DEVICE (f))) =
        DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (XDEVICE (FRAME_DEVICE (f))) =
        x_focus_timestamp_really_sucks_fix_me_better;
-      UNGCPRO;
     }
 }
 
index 7ad6409..8b970e3 100644 (file)
@@ -169,21 +169,21 @@ extern char *jrKanjiError;
 static unsigned char buf[KEYTOSTRSIZE];
 static char **warning;
 
-static int Vcanna_empty_info, Vcanna_through_info;
-static int Vcanna_underline;
-static int Vcanna_inhibit_hankakukana;
+static int canna_empty_info, canna_through_info;
+static int canna_underline;
+static int canna_inhibit_hankakukana;
 
 static Lisp_Object Vcanna_kakutei_string;
 static Lisp_Object Vcanna_kakutei_yomi;
 static Lisp_Object Vcanna_kakutei_romaji;
 static Lisp_Object Vcanna_henkan_string;
-static int         Vcanna_henkan_length;
-static int         Vcanna_henkan_revPos;
-static int         Vcanna_henkan_revLen;
+static int         canna_henkan_length;
+static int         canna_henkan_revPos;
+static int         canna_henkan_revLen;
 static Lisp_Object Vcanna_ichiran_string;
-static int         Vcanna_ichiran_length;
-static int         Vcanna_ichiran_revPos;
-static int         Vcanna_ichiran_revLen;
+static int         canna_ichiran_length;
+static int         canna_ichiran_revPos;
+static int         canna_ichiran_revLen;
 static Lisp_Object Vcanna_mode_string;
 
 static int IRCP_context;
@@ -259,21 +259,21 @@ storeResults (unsigned char *buf, int len, jrKanjiStatus *ks)
        {
          Vcanna_henkan_string = make_string (ks->echoStr, ks->length);
 #ifndef CANNA_MULE
-         Vcanna_henkan_length = ks->length;
-         Vcanna_henkan_revPos = ks->revPos;
-         Vcanna_henkan_revLen = ks->revLen;
+         canna_henkan_length = ks->length;
+         canna_henkan_revPos = ks->revPos;
+         canna_henkan_revLen = ks->revLen;
 #else /* CANNA_MULE */
-         if (Vcanna_underline)
+         if (canna_underline)
            {
-             Vcanna_henkan_length = mule_strlen (ks->echoStr,ks->length);
-             Vcanna_henkan_revPos = mule_strlen (ks->echoStr,ks->revPos);
-             Vcanna_henkan_revLen = mule_strlen (ks->echoStr+ks->revPos,ks->revLen);
+             canna_henkan_length = mule_strlen (ks->echoStr,ks->length);
+             canna_henkan_revPos = mule_strlen (ks->echoStr,ks->revPos);
+             canna_henkan_revLen = mule_strlen (ks->echoStr+ks->revPos,ks->revLen);
            }
          else
            {
              count_char (ks->echoStr, ks->length, ks->revPos, ks->revLen,
-                         &Vcanna_henkan_length, &Vcanna_henkan_revPos,
-                         &Vcanna_henkan_revLen);
+                         &canna_henkan_length, &canna_henkan_revPos,
+                         &canna_henkan_revLen);
            }
 #endif /* CANNA_MULE */
        }
@@ -284,13 +284,13 @@ storeResults (unsigned char *buf, int len, jrKanjiStatus *ks)
        {
          Vcanna_ichiran_string = make_string (ks->gline.line, ks->gline.length);
 #ifndef CANNA_MULE
-         Vcanna_ichiran_length = ks->gline.length;
-         Vcanna_ichiran_revPos = ks->gline.revPos;
-         Vcanna_ichiran_revLen = ks->gline.revLen;
+         canna_ichiran_length = ks->gline.length;
+         canna_ichiran_revPos = ks->gline.revPos;
+         canna_ichiran_revLen = ks->gline.revLen;
 #else /* CANNA_MULE */
          count_char (ks->gline.line, ks->gline.length,
-                     ks->gline.revPos, ks->gline.revLen, &Vcanna_ichiran_length,
-                     &Vcanna_ichiran_revPos, &Vcanna_ichiran_revLen);
+                     ks->gline.revPos, ks->gline.revLen, &canna_ichiran_length,
+                     &canna_ichiran_revPos, &canna_ichiran_revLen);
 #endif /* CANNA_MULE */
        }
 
@@ -302,8 +302,8 @@ storeResults (unsigned char *buf, int len, jrKanjiStatus *ks)
        }
 
       /* ¤½¤Î¾¤Î¾ðÊó */
-      Vcanna_empty_info = (ks->info & KanjiEmptyInfo) ? 1 : 0;
-      Vcanna_through_info = (ks->info & KanjiThroughInfo) ? 1 : 0;
+      canna_empty_info = (ks->info & KanjiEmptyInfo) ? 1 : 0;
+      canna_through_info = (ks->info & KanjiThroughInfo) ? 1 : 0;
     }
 
   return val;
@@ -440,7 +440,7 @@ If nil is specified for each arg, the default value will be used.
       jrKanjiControl (0, KC_INHIBITHANKAKUKANA, (char *) 1);
 #else
       /* mule ¤À¤Ã¤¿¤éȾ³Ñ¥«¥¿¥«¥Ê¤â»È¤¨¤ë */
-      if (Vcanna_inhibit_hankakukana)
+      if (canna_inhibit_hankakukana)
        jrKanjiControl (0, KC_INHIBITHANKAKUKANA, (char *) 1);
 #endif
       jrKanjiControl (0, KC_YOMIINFO, (char *) 2); /* ¢¨£²: ¥í¡¼¥Þ»ú¤Þ¤ÇÊÖ¤¹ */
@@ -872,150 +872,149 @@ DEFUN ("canna-henkan-quit", Fcanna_henkan_quit, 0, 0, 0, /*
 
 /* variables below this line is constants of Canna */
 
-static int Vcanna_mode_AlphaMode = IROHA_MODE_AlphaMode;
-static int Vcanna_mode_EmptyMode = IROHA_MODE_EmptyMode;
-static int Vcanna_mode_KigoMode = IROHA_MODE_KigoMode;
-static int Vcanna_mode_YomiMode = IROHA_MODE_YomiMode;
-static int Vcanna_mode_JishuMode = IROHA_MODE_JishuMode;
-static int Vcanna_mode_TankouhoMode = IROHA_MODE_TankouhoMode;
-static int Vcanna_mode_IchiranMode = IROHA_MODE_IchiranMode;
-static int Vcanna_mode_YesNoMode = IROHA_MODE_YesNoMode;
-static int Vcanna_mode_OnOffMode = IROHA_MODE_OnOffMode;
+static int canna_mode_AlphaMode;
+static int canna_mode_EmptyMode;
+static int canna_mode_KigoMode;
+static int canna_mode_YomiMode;
+static int canna_mode_JishuMode;
+static int canna_mode_TankouhoMode;
+static int canna_mode_IchiranMode;
+static int canna_mode_YesNoMode;
+static int canna_mode_OnOffMode;
 #ifdef CANNA_MODE_AdjustBunsetsuMode
-static int Vcanna_mode_AdjustBunsetsuMode = CANNA_MODE_AdjustBunsetsuMode;
+static int canna_mode_AdjustBunsetsuMode;
 #endif
 #ifdef CANNA_MODE_ChikujiYomiMode
-static int Vcanna_mode_ChikujiYomiMode = CANNA_MODE_ChikujiYomiMode;
-static int Vcanna_mode_ChikujiTanMode = CANNA_MODE_ChikujiTanMode;
+static int canna_mode_ChikujiYomiMode;
+static int canna_mode_ChikujiTanMode;
 #endif
 
-static int Vcanna_mode_HenkanMode = IROHA_MODE_HenkanMode;
+static int canna_mode_HenkanMode;
 #ifdef CANNA_MODE_HenkanNyuryokuMode
-static int Vcanna_mode_HenkanNyuryokuMode = CANNA_MODE_HenkanNyuryokuMode;
+static int canna_mode_HenkanNyuryokuMode;
 #endif
 #ifdef CANNA_MODE_ZenHiraHenkanMode
-static int Vcanna_mode_ZenHiraHenkanMode = CANNA_MODE_ZenHiraHenkanMode;
+static int canna_mode_ZenHiraHenkanMode;
 #ifdef CANNA_MODE_HanHiraHenkanMode
-static int Vcanna_mode_HanHiraHenkanMode = CANNA_MODE_HanHiraHenkanMode;
+static int canna_mode_HanHiraHenkanMode;
 #endif
-static int Vcanna_mode_ZenKataHenkanMode = CANNA_MODE_ZenKataHenkanMode;
-static int Vcanna_mode_HanKataHenkanMode = CANNA_MODE_HanKataHenkanMode;
-static int Vcanna_mode_ZenAlphaHenkanMode = CANNA_MODE_ZenAlphaHenkanMode;
-static int Vcanna_mode_HanAlphaHenkanMode = CANNA_MODE_HanAlphaHenkanMode;
+static int canna_mode_ZenKataHenkanMode;
+static int canna_mode_HanKataHenkanMode;
+static int canna_mode_ZenAlphaHenkanMode;
+static int canna_mode_HanAlphaHenkanMode;
 #endif
-static int Vcanna_mode_ZenHiraKakuteiMode = IROHA_MODE_ZenHiraKakuteiMode;
+static int canna_mode_ZenHiraKakuteiMode;
 #ifdef CANNA_MODE_HanHiraKakuteiMode
-static int Vcanna_mode_HanHiraKakuteiMode = CANNA_MODE_HanHiraKakuteiMode;
+static int canna_mode_HanHiraKakuteiMode;
 #endif
-static int Vcanna_mode_ZenKataKakuteiMode = IROHA_MODE_ZenKataKakuteiMode;
-static int Vcanna_mode_HanKataKakuteiMode = IROHA_MODE_HanKataKakuteiMode;
-static int Vcanna_mode_ZenAlphaKakuteiMode = IROHA_MODE_ZenAlphaKakuteiMode;
-static int Vcanna_mode_HanAlphaKakuteiMode = IROHA_MODE_HanAlphaKakuteiMode;
-static int Vcanna_mode_HexMode = IROHA_MODE_HexMode;
-static int Vcanna_mode_BushuMode = IROHA_MODE_BushuMode;
-static int Vcanna_mode_ExtendMode = IROHA_MODE_ExtendMode;
-static int Vcanna_mode_RussianMode = IROHA_MODE_RussianMode;
-static int Vcanna_mode_GreekMode = IROHA_MODE_GreekMode;
-static int Vcanna_mode_LineMode = IROHA_MODE_LineMode;
-static int Vcanna_mode_ChangingServerMode = IROHA_MODE_ChangingServerMode;
-static int Vcanna_mode_HenkanMethodMode = IROHA_MODE_HenkanMethodMode;
-static int Vcanna_mode_DeleteDicMode = IROHA_MODE_DeleteDicMode;
-static int Vcanna_mode_TourokuMode = IROHA_MODE_TourokuMode;
-static int Vcanna_mode_TourokuEmptyMode = IROHA_MODE_TourokuEmptyMode;
-static int Vcanna_mode_TourokuHinshiMode = IROHA_MODE_TourokuHinshiMode;
-static int Vcanna_mode_TourokuDicMode = IROHA_MODE_TourokuDicMode;
-static int Vcanna_mode_QuotedInsertMode = IROHA_MODE_QuotedInsertMode;
-static int Vcanna_mode_BubunMuhenkanMode = IROHA_MODE_BubunMuhenkanMode;
-static int Vcanna_mode_MountDicMode = IROHA_MODE_MountDicMode;
-
-static int Vcanna_fn_SelfInsert = IROHA_FN_SelfInsert;
-static int Vcanna_fn_FunctionalInsert = IROHA_FN_FunctionalInsert;
-static int Vcanna_fn_QuotedInsert = IROHA_FN_QuotedInsert;
-static int Vcanna_fn_JapaneseMode = IROHA_FN_JapaneseMode;
-static int Vcanna_fn_AlphaMode = IROHA_FN_AlphaMode;
-static int Vcanna_fn_HenkanNyuryokuMode = IROHA_FN_HenkanNyuryokuMode;
-static int Vcanna_fn_Forward = IROHA_FN_Forward;
-static int Vcanna_fn_Backward = IROHA_FN_Backward;
-static int Vcanna_fn_Next = IROHA_FN_Next;
-static int Vcanna_fn_Prev = IROHA_FN_Prev;
-static int Vcanna_fn_BeginningOfLine = IROHA_FN_BeginningOfLine;
-static int Vcanna_fn_EndOfLine = IROHA_FN_EndOfLine;
-static int Vcanna_fn_DeleteNext = IROHA_FN_DeleteNext;
-static int Vcanna_fn_DeletePrevious = IROHA_FN_DeletePrevious;
-static int Vcanna_fn_KillToEndOfLine = IROHA_FN_KillToEndOfLine;
-static int Vcanna_fn_Henkan = IROHA_FN_Henkan;
-static int Vcanna_fn_Kakutei = IROHA_FN_Kakutei;
-static int Vcanna_fn_Extend = IROHA_FN_Extend;
-static int Vcanna_fn_Shrink = IROHA_FN_Shrink;
+static int canna_mode_ZenKataKakuteiMode;
+static int canna_mode_HanKataKakuteiMode;
+static int canna_mode_ZenAlphaKakuteiMode;
+static int canna_mode_HanAlphaKakuteiMode;
+static int canna_mode_HexMode;
+static int canna_mode_BushuMode;
+static int canna_mode_ExtendMode;
+static int canna_mode_RussianMode;
+static int canna_mode_GreekMode;
+static int canna_mode_LineMode;
+static int canna_mode_ChangingServerMode;
+static int canna_mode_HenkanMethodMode;
+static int canna_mode_DeleteDicMode;
+static int canna_mode_TourokuMode;
+static int canna_mode_TourokuEmptyMode;
+static int canna_mode_TourokuHinshiMode;
+static int canna_mode_TourokuDicMode;
+static int canna_mode_QuotedInsertMode;
+static int canna_mode_BubunMuhenkanMode;
+static int canna_mode_MountDicMode;
+
+static int canna_fn_SelfInsert;
+static int canna_fn_FunctionalInsert;
+static int canna_fn_QuotedInsert;
+static int canna_fn_JapaneseMode;
+static int canna_fn_AlphaMode;
+static int canna_fn_HenkanNyuryokuMode;
+static int canna_fn_Forward;
+static int canna_fn_Backward;
+static int canna_fn_Next;
+static int canna_fn_Prev;
+static int canna_fn_BeginningOfLine;
+static int canna_fn_EndOfLine;
+static int canna_fn_DeleteNext;
+static int canna_fn_DeletePrevious;
+static int canna_fn_KillToEndOfLine;
+static int canna_fn_Henkan;
+static int canna_fn_Kakutei;
+static int canna_fn_Extend;
+static int canna_fn_Shrink;
 #ifdef CANNA_FN_AdjustBunsetsu
-static int Vcanna_fn_AdjustBunsetsu = CANNA_FN_AdjustBunsetsu;
+static int canna_fn_AdjustBunsetsu;
 #endif
-static int Vcanna_fn_Quit = IROHA_FN_Quit;
-static int Vcanna_fn_ConvertAsHex = IROHA_FN_ConvertAsHex;
-static int Vcanna_fn_ConvertAsBushu = IROHA_FN_ConvertAsBushu;
-static int Vcanna_fn_KouhoIchiran = IROHA_FN_KouhoIchiran;
-static int Vcanna_fn_BubunMuhenkan = IROHA_FN_BubunMuhenkan;
-static int Vcanna_fn_Zenkaku = IROHA_FN_Zenkaku;
-static int Vcanna_fn_Hankaku = IROHA_FN_Hankaku;
-static int Vcanna_fn_ToUpper = IROHA_FN_ToUpper;
-static int Vcanna_fn_Capitalize = IROHA_FN_Capitalize;
-static int Vcanna_fn_ToLower = IROHA_FN_ToLower;
-static int Vcanna_fn_Hiragana = IROHA_FN_Hiragana;
-static int Vcanna_fn_Katakana = IROHA_FN_Katakana;
-static int Vcanna_fn_Romaji = IROHA_FN_Romaji;
+static int canna_fn_Quit;
+static int canna_fn_ConvertAsHex;
+static int canna_fn_ConvertAsBushu;
+static int canna_fn_KouhoIchiran;
+static int canna_fn_BubunMuhenkan;
+static int canna_fn_Zenkaku;
+static int canna_fn_Hankaku;
+static int canna_fn_ToUpper;
+static int canna_fn_Capitalize;
+static int canna_fn_ToLower;
+static int canna_fn_Hiragana;
+static int canna_fn_Katakana;
+static int canna_fn_Romaji;
 #ifdef CANNA_FN_BaseHiragana
-static int Vcanna_fn_BaseHiragana = CANNA_FN_BaseHiragana;
-static int Vcanna_fn_BaseKatakana = CANNA_FN_BaseKatakana;
-static int Vcanna_fn_BaseEisu = CANNA_FN_BaseEisu;
-static int Vcanna_fn_BaseZenkaku = CANNA_FN_BaseZenkaku;
-static int Vcanna_fn_BaseHankaku = CANNA_FN_BaseHankaku;
-static int Vcanna_fn_BaseKana = CANNA_FN_BaseKana;
-static int Vcanna_fn_BaseKakutei = CANNA_FN_BaseKakutei;
-static int Vcanna_fn_BaseHenkan = CANNA_FN_BaseHenkan;
-static int Vcanna_fn_BaseHiraKataToggle = CANNA_FN_BaseHiraKataToggle;
-static int Vcanna_fn_BaseZenHanToggle = CANNA_FN_BaseZenHanToggle;
-static int Vcanna_fn_BaseKanaEisuToggle = CANNA_FN_BaseKanaEisuToggle;
-static int Vcanna_fn_BaseKakuteiHenkanToggle =
-  CANNA_FN_BaseKakuteiHenkanToggle;
-static int Vcanna_fn_BaseRotateForward = CANNA_FN_BaseRotateForward;
-static int Vcanna_fn_BaseRotateBackward = CANNA_FN_BaseRotateBackward;
+static int canna_fn_BaseHiragana;
+static int canna_fn_BaseKatakana;
+static int canna_fn_BaseEisu;
+static int canna_fn_BaseZenkaku;
+static int canna_fn_BaseHankaku;
+static int canna_fn_BaseKana;
+static int canna_fn_BaseKakutei;
+static int canna_fn_BaseHenkan;
+static int canna_fn_BaseHiraKataToggle;
+static int canna_fn_BaseZenHanToggle;
+static int canna_fn_BaseKanaEisuToggle;
+static int canna_fn_BaseKakuteiHenkanToggle;
+static int canna_fn_BaseRotateForward;
+static int canna_fn_BaseRotateBackward;
 #endif
-static int Vcanna_fn_ExtendMode = IROHA_FN_ExtendMode;
-static int Vcanna_fn_Touroku = IROHA_FN_Touroku;
-static int Vcanna_fn_HexMode = IROHA_FN_HexMode;
-static int Vcanna_fn_BushuMode = IROHA_FN_BushuMode;
-static int Vcanna_fn_KigouMode = IROHA_FN_KigouMode;
+static int canna_fn_ExtendMode;
+static int canna_fn_Touroku;
+static int canna_fn_HexMode;
+static int canna_fn_BushuMode;
+static int canna_fn_KigouMode;
 #ifdef CANNA_FN_Mark
-static int Vcanna_fn_Mark = CANNA_FN_Mark;
+static int canna_fn_Mark;
 #endif
 #ifdef CANNA_FN_TemporalMode
-static int Vcanna_fn_TemporalMode = CANNA_FN_TemporalMode;
+static int canna_fn_TemporalMode;
 #endif
 
-static int Vcanna_key_Nfer = IROHA_KEY_Nfer;
-static int Vcanna_key_Xfer = IROHA_KEY_Xfer;
-static int Vcanna_key_Up = IROHA_KEY_Up;
-static int Vcanna_key_Left = IROHA_KEY_Left;
-static int Vcanna_key_Right = IROHA_KEY_Right;
-static int Vcanna_key_Down = IROHA_KEY_Down;
-static int Vcanna_key_Insert = IROHA_KEY_Insert;
-static int Vcanna_key_Rollup = IROHA_KEY_Rollup;
-static int Vcanna_key_Rolldown = IROHA_KEY_Rolldown;
-static int Vcanna_key_Home = IROHA_KEY_Home;
-static int Vcanna_key_Help = IROHA_KEY_Help;
-static int Vcanna_key_KP_Key = IROHA_KEY_KP_Key;
-static int Vcanna_key_Shift_Nfer = IROHA_KEY_Shift_Nfer;
-static int Vcanna_key_Shift_Xfer = IROHA_KEY_Shift_Xfer;
-static int Vcanna_key_Shift_Up = IROHA_KEY_Shift_Up;
-static int Vcanna_key_Shift_Left = IROHA_KEY_Shift_Left;
-static int Vcanna_key_Shift_Right = IROHA_KEY_Shift_Right;
-static int Vcanna_key_Shift_Down = IROHA_KEY_Shift_Down;
-static int Vcanna_key_Cntrl_Nfer = IROHA_KEY_Cntrl_Nfer;
-static int Vcanna_key_Cntrl_Xfer = IROHA_KEY_Cntrl_Xfer;
-static int Vcanna_key_Cntrl_Up = IROHA_KEY_Cntrl_Up;
-static int Vcanna_key_Cntrl_Left = IROHA_KEY_Cntrl_Left;
-static int Vcanna_key_Cntrl_Right = IROHA_KEY_Cntrl_Right;
-static int Vcanna_key_Cntrl_Down = IROHA_KEY_Cntrl_Down;
+static int canna_key_Nfer;
+static int canna_key_Xfer;
+static int canna_key_Up;
+static int canna_key_Left;
+static int canna_key_Right;
+static int canna_key_Down;
+static int canna_key_Insert;
+static int canna_key_Rollup;
+static int canna_key_Rolldown;
+static int canna_key_Home;
+static int canna_key_Help;
+static int canna_key_KP_Key;
+static int canna_key_Shift_Nfer;
+static int canna_key_Shift_Xfer;
+static int canna_key_Shift_Up;
+static int canna_key_Shift_Left;
+static int canna_key_Shift_Right;
+static int canna_key_Shift_Down;
+static int canna_key_Cntrl_Nfer;
+static int canna_key_Cntrl_Xfer;
+static int canna_key_Cntrl_Up;
+static int canna_key_Cntrl_Left;
+static int canna_key_Cntrl_Right;
+static int canna_key_Cntrl_Down;
 
 Lisp_Object VCANNA; /* by MORIOKA Tomohiko <morioka@jaist.ac.jp>
                          1996/6/7 */
@@ -1052,464 +1051,721 @@ vars_of_mule_canna (void)
   DEFVAR_LISP ("canna-kakutei-string", &Vcanna_kakutei_string /*
 
 */ );
+  Vcanna_kakutei_string = Qnil;
+
   DEFVAR_LISP ("canna-kakutei-yomi",   &Vcanna_kakutei_yomi /*
 
 */ );
+  Vcanna_kakutei_yomi = Qnil;
+
   DEFVAR_LISP ("canna-kakutei-romaji", &Vcanna_kakutei_romaji /*
 
 */ );
+  Vcanna_kakutei_romaji = Qnil;
+
   DEFVAR_LISP ("canna-henkan-string",  &Vcanna_henkan_string /*
 
 */ );
-  DEFVAR_INT ("canna-henkan-length",  &Vcanna_henkan_length /*
+  Vcanna_henkan_string = Qnil;
+
+  DEFVAR_INT ("canna-henkan-length",  &canna_henkan_length /*
 
 */ );
-  DEFVAR_INT ("canna-henkan-revpos",  &Vcanna_henkan_revPos /*
+  canna_henkan_length = 0;
+
+  DEFVAR_INT ("canna-henkan-revpos",  &canna_henkan_revPos /*
 
 */ );
-  DEFVAR_INT ("canna-henkan-revlen",  &Vcanna_henkan_revLen /*
+  canna_henkan_revPos = 0;
+
+  DEFVAR_INT ("canna-henkan-revlen",  &canna_henkan_revLen /*
 
 */ );
+  canna_henkan_revLen = 0;
+
   DEFVAR_LISP ("canna-ichiran-string", &Vcanna_ichiran_string /*
 
 */ );
-  DEFVAR_INT ("canna-ichiran-length", &Vcanna_ichiran_length /*
+  Vcanna_ichiran_string = Qnil;
+
+  DEFVAR_INT ("canna-ichiran-length", &canna_ichiran_length /*
 
 */ );
-  DEFVAR_INT ("canna-ichiran-revpos", &Vcanna_ichiran_revPos /*
+  canna_ichiran_length = 0;
+
+  DEFVAR_INT ("canna-ichiran-revpos", &canna_ichiran_revPos /*
 
 */ );
-  DEFVAR_INT ("canna-ichiran-revlen", &Vcanna_ichiran_revLen /*
+  canna_ichiran_revPos = 0;
+
+  DEFVAR_INT ("canna-ichiran-revlen", &canna_ichiran_revLen /*
 
 */ );
+  canna_ichiran_revLen = 0;
+
   DEFVAR_LISP ("canna-mode-string",    &Vcanna_mode_string /*
 
 */ );
+  Vcanna_mode_string = Qnil;
 
-  DEFVAR_BOOL ("canna-empty-info", &Vcanna_empty_info /*
+  DEFVAR_BOOL ("canna-empty-info", &canna_empty_info /*
 For canna
 */ );
-  DEFVAR_BOOL ("canna-through-info", &Vcanna_through_info /*
+  canna_empty_info = 0;
+
+  DEFVAR_BOOL ("canna-through-info", &canna_through_info /*
 For canna
 */ );
-  DEFVAR_BOOL ("canna-underline", &Vcanna_underline /*
+  canna_through_info = 0;
+
+  DEFVAR_BOOL ("canna-underline", &canna_underline /*
 For canna
 */ );
-  DEFVAR_BOOL ("canna-inhibit-hankakukana", &Vcanna_inhibit_hankakukana /*
+  canna_underline = 0;
+
+  DEFVAR_BOOL ("canna-inhibit-hankakukana", &canna_inhibit_hankakukana /*
 For canna
 */ );
+  canna_inhibit_hankakukana = 0;
 
-  DEFVAR_INT ("canna-mode-alpha-mode", &Vcanna_mode_AlphaMode /*
+  DEFVAR_INT ("canna-mode-alpha-mode", &canna_mode_AlphaMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-empty-mode", &Vcanna_mode_EmptyMode /*
+  canna_mode_AlphaMode = IROHA_MODE_AlphaMode;
+
+  DEFVAR_INT ("canna-mode-empty-mode", &canna_mode_EmptyMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-kigo-mode",  &Vcanna_mode_KigoMode /*
+  canna_mode_EmptyMode = IROHA_MODE_EmptyMode;
+
+  DEFVAR_INT ("canna-mode-kigo-mode",  &canna_mode_KigoMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-yomi-mode",  &Vcanna_mode_YomiMode /*
+  canna_mode_KigoMode = IROHA_MODE_KigoMode;
+
+  DEFVAR_INT ("canna-mode-yomi-mode",  &canna_mode_YomiMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-jishu-mode", &Vcanna_mode_JishuMode /*
+  canna_mode_YomiMode = IROHA_MODE_YomiMode;
+
+  DEFVAR_INT ("canna-mode-jishu-mode", &canna_mode_JishuMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-tankouho-mode", &Vcanna_mode_TankouhoMode /*
+  canna_mode_JishuMode = IROHA_MODE_JishuMode;
+
+  DEFVAR_INT ("canna-mode-tankouho-mode", &canna_mode_TankouhoMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-ichiran-mode",  &Vcanna_mode_IchiranMode /*
+  canna_mode_TankouhoMode = IROHA_MODE_TankouhoMode;
+
+  DEFVAR_INT ("canna-mode-ichiran-mode",  &canna_mode_IchiranMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-yes-no-mode", &Vcanna_mode_YesNoMode /*
+  canna_mode_IchiranMode = IROHA_MODE_IchiranMode;
+
+  DEFVAR_INT ("canna-mode-yes-no-mode", &canna_mode_YesNoMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-on-off-mode", &Vcanna_mode_OnOffMode /*
+  canna_mode_YesNoMode = IROHA_MODE_YesNoMode;
+
+  DEFVAR_INT ("canna-mode-on-off-mode", &canna_mode_OnOffMode /*
 
 */ );
+  canna_mode_OnOffMode = IROHA_MODE_OnOffMode;
+
 #ifdef CANNA_MODE_AdjustBunsetsuMode
   DEFVAR_INT ("canna-mode-adjust-bunsetsu-mode",
-             &Vcanna_mode_AdjustBunsetsuMode /*
+             &canna_mode_AdjustBunsetsuMode /*
 
 */ );
+  canna_mode_AdjustBunsetsuMode = CANNA_MODE_AdjustBunsetsuMode;
 #endif
 #ifdef CANNA_MODE_ChikujiYomiMode
-  DEFVAR_INT ("canna-mode-chikuji-yomi-mode", &Vcanna_mode_ChikujiYomiMode /*
+  DEFVAR_INT ("canna-mode-chikuji-yomi-mode", &canna_mode_ChikujiYomiMode /*
 
 */ );
+  canna_mode_ChikujiYomiMode = CANNA_MODE_ChikujiYomiMode;
+
   DEFVAR_INT ("canna-mode-chikuji-bunsetsu-mode",
-             &Vcanna_mode_ChikujiTanMode /*
+             &canna_mode_ChikujiTanMode /*
 
 */ );
+  canna_mode_ChikujiTanMode = CANNA_MODE_ChikujiTanMode;
 #endif
 
-  DEFVAR_INT ("canna-mode-henkan-mode", &Vcanna_mode_HenkanMode /*
+  DEFVAR_INT ("canna-mode-henkan-mode", &canna_mode_HenkanMode /*
 
 */ );
+  canna_mode_HenkanMode = IROHA_MODE_HenkanMode;
+
 #ifdef CANNA_MODE_HenkanNyuryokuMode
   DEFVAR_INT ("canna-mode-henkan-nyuuryoku-mode",
-             &Vcanna_mode_HenkanNyuryokuMode /*
+             &canna_mode_HenkanNyuryokuMode /*
 
 */ );
+  canna_mode_HenkanNyuryokuMode = CANNA_MODE_HenkanNyuryokuMode;
 #endif
 #ifdef CANNA_MODE_ZenHiraHenkanMode
   DEFVAR_INT ("canna-mode-zen-hira-henkan-mode",
-             &Vcanna_mode_ZenHiraHenkanMode /*
+             &canna_mode_ZenHiraHenkanMode /*
 
 */ );
+  canna_mode_ZenHiraHenkanMode = CANNA_MODE_ZenHiraHenkanMode;
 #ifdef CANNA_MODE_HanHiraHenkanMode
   DEFVAR_INT ("canna-mode-han-hira-henkan-mode",
-             &Vcanna_mode_HanHiraHenkanMode /*
+             &canna_mode_HanHiraHenkanMode /*
 
 */ );
+  canna_mode_HanHiraHenkanMode = CANNA_MODE_HanHiraHenkanMode;
 #endif
   DEFVAR_INT ("canna-mode-zen-kata-henkan-mode",
-             &Vcanna_mode_ZenKataHenkanMode /*
+             &canna_mode_ZenKataHenkanMode /*
 
 */ );
+  canna_mode_ZenKataHenkanMode = CANNA_MODE_ZenKataHenkanMode;
+
   DEFVAR_INT ("canna-mode-han-kata-henkan-mode",
-             &Vcanna_mode_HanKataHenkanMode /*
+             &canna_mode_HanKataHenkanMode /*
 
 */ );
+  canna_mode_HanKataHenkanMode = CANNA_MODE_HanKataHenkanMode;
+
   DEFVAR_INT ("canna-mode-zen-alpha-henkan-mode",
-             &Vcanna_mode_ZenAlphaHenkanMode /*
+             &canna_mode_ZenAlphaHenkanMode /*
 
 */ );
+  canna_mode_ZenAlphaHenkanMode = CANNA_MODE_ZenAlphaHenkanMode;
+
   DEFVAR_INT ("canna-mode-han-alpha-henkan-mode",
-             &Vcanna_mode_HanAlphaHenkanMode /*
+             &canna_mode_HanAlphaHenkanMode /*
 
 */ );
+  canna_mode_HanAlphaHenkanMode = CANNA_MODE_HanAlphaHenkanMode;
 #endif
   DEFVAR_INT ("canna-mode-zen-hira-kakutei-mode",
-             &Vcanna_mode_ZenHiraKakuteiMode /*
+             &canna_mode_ZenHiraKakuteiMode /*
 
 */ );
+  canna_mode_ZenHiraKakuteiMode = IROHA_MODE_ZenHiraKakuteiMode;
 #ifdef CANNA_MODE_HanHiraKakuteiMode
   DEFVAR_INT ("canna-mode-han-hira-kakutei-mode",
-             &Vcanna_mode_HanHiraKakuteiMode /*
+             &canna_mode_HanHiraKakuteiMode /*
 
 */ );
+  canna_mode_HanHiraKakuteiMode = CANNA_MODE_HanHiraKakuteiMode;
 #endif
   DEFVAR_INT ("canna-mode-zen-kata-kakutei-mode",
-             &Vcanna_mode_ZenKataKakuteiMode /*
+             &canna_mode_ZenKataKakuteiMode /*
 
 */ );
+  canna_mode_ZenKataKakuteiMode = IROHA_MODE_ZenKataKakuteiMode;
+
   DEFVAR_INT ("canna-mode-han-kata-kakutei-mode",
-             &Vcanna_mode_HanKataKakuteiMode /*
+             &canna_mode_HanKataKakuteiMode /*
 
 */ );
+  canna_mode_HanKataKakuteiMode = IROHA_MODE_HanKataKakuteiMode;
+
   DEFVAR_INT ("canna-mode-zen-alpha-kakutei-mode",
-             &Vcanna_mode_ZenAlphaKakuteiMode /*
+             &canna_mode_ZenAlphaKakuteiMode /*
 
 */ );
+  canna_mode_ZenAlphaKakuteiMode = IROHA_MODE_ZenAlphaKakuteiMode;
+
   DEFVAR_INT ("canna-mode-han-alpha-kakutei-mode",
-             &Vcanna_mode_HanAlphaKakuteiMode /*
+             &canna_mode_HanAlphaKakuteiMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-hex-mode", &Vcanna_mode_HexMode /*
+  canna_mode_HanAlphaKakuteiMode = IROHA_MODE_HanAlphaKakuteiMode;
+
+  DEFVAR_INT ("canna-mode-hex-mode", &canna_mode_HexMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-bushu-mode", &Vcanna_mode_BushuMode /*
+  canna_mode_HexMode = IROHA_MODE_HexMode;
+
+  DEFVAR_INT ("canna-mode-bushu-mode", &canna_mode_BushuMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-extend-mode", &Vcanna_mode_ExtendMode /*
+  canna_mode_BushuMode = IROHA_MODE_BushuMode;
+
+  DEFVAR_INT ("canna-mode-extend-mode", &canna_mode_ExtendMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-russian-mode", &Vcanna_mode_RussianMode /*
+  canna_mode_ExtendMode = IROHA_MODE_ExtendMode;
+
+  DEFVAR_INT ("canna-mode-russian-mode", &canna_mode_RussianMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-greek-mode", &Vcanna_mode_GreekMode /*
+  canna_mode_RussianMode = IROHA_MODE_RussianMode;
+
+  DEFVAR_INT ("canna-mode-greek-mode", &canna_mode_GreekMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-line-mode", &Vcanna_mode_LineMode /*
+  canna_mode_GreekMode = IROHA_MODE_GreekMode;
+
+  DEFVAR_INT ("canna-mode-line-mode", &canna_mode_LineMode /*
 
 */ );
+  canna_mode_LineMode = IROHA_MODE_LineMode;
+
   DEFVAR_INT ("canna-mode-changing-server-mode",
-             &Vcanna_mode_ChangingServerMode /*
+             &canna_mode_ChangingServerMode /*
 
 */ );
+  canna_mode_ChangingServerMode = IROHA_MODE_ChangingServerMode;
+
   DEFVAR_INT ("canna-mode-henkan-method-mode",
-             &Vcanna_mode_HenkanMethodMode /*
+             &canna_mode_HenkanMethodMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-delete-dic-mode", &Vcanna_mode_DeleteDicMode /*
+  canna_mode_HenkanMethodMode = IROHA_MODE_HenkanMethodMode;
+
+  DEFVAR_INT ("canna-mode-delete-dic-mode", &canna_mode_DeleteDicMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-touroku-mode", &Vcanna_mode_TourokuMode /*
+  canna_mode_DeleteDicMode = IROHA_MODE_DeleteDicMode;
+
+  DEFVAR_INT ("canna-mode-touroku-mode", &canna_mode_TourokuMode /*
 
 */ );
+  canna_mode_TourokuMode = IROHA_MODE_TourokuMode;
+
   DEFVAR_INT ("canna-mode-touroku-empty-mode",
-             &Vcanna_mode_TourokuEmptyMode /*
+             &canna_mode_TourokuEmptyMode /*
 
 */ );
+  canna_mode_TourokuEmptyMode = IROHA_MODE_TourokuEmptyMode;
+
   DEFVAR_INT ("canna-mode-touroku-hinshi-mode",
-             &Vcanna_mode_TourokuHinshiMode /*
+             &canna_mode_TourokuHinshiMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-touroku-dic-mode", &Vcanna_mode_TourokuDicMode /*
+  canna_mode_TourokuHinshiMode = IROHA_MODE_TourokuHinshiMode;
+
+  DEFVAR_INT ("canna-mode-touroku-dic-mode", &canna_mode_TourokuDicMode /*
 
 */ );
+  canna_mode_TourokuDicMode = IROHA_MODE_TourokuDicMode;
+
   DEFVAR_INT ("canna-mode-quoted-insert-mode",
-             &Vcanna_mode_QuotedInsertMode /*
+             &canna_mode_QuotedInsertMode /*
 
 */ );
+  canna_mode_QuotedInsertMode = IROHA_MODE_QuotedInsertMode;
+
   DEFVAR_INT ("canna-mode-bubun-muhenkan-mode",
-             &Vcanna_mode_BubunMuhenkanMode /*
+             &canna_mode_BubunMuhenkanMode /*
 
 */ );
-  DEFVAR_INT ("canna-mode-mount-dic-mode", &Vcanna_mode_MountDicMode /*
+  canna_mode_BubunMuhenkanMode = IROHA_MODE_BubunMuhenkanMode;
+
+  DEFVAR_INT ("canna-mode-mount-dic-mode", &canna_mode_MountDicMode /*
 
 */ );
+  canna_mode_MountDicMode = IROHA_MODE_MountDicMode;
 
-  DEFVAR_INT ("canna-func-self-insert", &Vcanna_fn_SelfInsert  /*
+  DEFVAR_INT ("canna-func-self-insert", &canna_fn_SelfInsert  /*
 
 */ );
-  DEFVAR_INT ("canna-func-functional-insert", &Vcanna_fn_FunctionalInsert  /*
+  canna_fn_SelfInsert = IROHA_FN_SelfInsert;
+
+  DEFVAR_INT ("canna-func-functional-insert", &canna_fn_FunctionalInsert  /*
 
 */ );
-  DEFVAR_INT ("canna-func-quoted-insert", &Vcanna_fn_QuotedInsert  /*
+  canna_fn_FunctionalInsert = IROHA_FN_FunctionalInsert;
+
+  DEFVAR_INT ("canna-func-quoted-insert", &canna_fn_QuotedInsert  /*
 
 */ );
-  DEFVAR_INT ("canna-func-japanese-mode", &Vcanna_fn_JapaneseMode  /*
+  canna_fn_QuotedInsert = IROHA_FN_QuotedInsert;
+
+  DEFVAR_INT ("canna-func-japanese-mode", &canna_fn_JapaneseMode  /*
 
 */ );
-  DEFVAR_INT ("canna-func-alpha-mode", &Vcanna_fn_AlphaMode  /*
+  canna_fn_JapaneseMode = IROHA_FN_JapaneseMode;
+
+  DEFVAR_INT ("canna-func-alpha-mode", &canna_fn_AlphaMode  /*
 
 */ );
+  canna_fn_AlphaMode = IROHA_FN_AlphaMode;
+
   DEFVAR_INT ("canna-func-henkan-nyuryoku-mode",
-             &Vcanna_fn_HenkanNyuryokuMode  /*
+             &canna_fn_HenkanNyuryokuMode  /*
 
 */ );
-  DEFVAR_INT ("canna-func-forward", &Vcanna_fn_Forward  /*
+  canna_fn_HenkanNyuryokuMode = IROHA_FN_HenkanNyuryokuMode;
+
+  DEFVAR_INT ("canna-func-forward", &canna_fn_Forward  /*
 
 */ );
-  DEFVAR_INT ("canna-func-backward", &Vcanna_fn_Backward  /*
+  canna_fn_Forward = IROHA_FN_Forward;
+
+  DEFVAR_INT ("canna-func-backward", &canna_fn_Backward  /*
 
 */ );
-  DEFVAR_INT ("canna-func-next", &Vcanna_fn_Next  /*
+  canna_fn_Backward = IROHA_FN_Backward;
+
+  DEFVAR_INT ("canna-func-next", &canna_fn_Next  /*
 
 */ );
-  DEFVAR_INT ("canna-func-previous", &Vcanna_fn_Prev  /*
+  canna_fn_Next = IROHA_FN_Next;
+
+  DEFVAR_INT ("canna-func-previous", &canna_fn_Prev  /*
 
 */ );
-  DEFVAR_INT ("canna-func-beginning-of-line", &Vcanna_fn_BeginningOfLine  /*
+  canna_fn_Prev = IROHA_FN_Prev;
+
+  DEFVAR_INT ("canna-func-beginning-of-line", &canna_fn_BeginningOfLine  /*
 
 */ );
-  DEFVAR_INT ("canna-func-end-of-line", &Vcanna_fn_EndOfLine  /*
+  canna_fn_BeginningOfLine = IROHA_FN_BeginningOfLine;
+
+  DEFVAR_INT ("canna-func-end-of-line", &canna_fn_EndOfLine  /*
 
 */ );
-  DEFVAR_INT ("canna-func-delete-next", &Vcanna_fn_DeleteNext  /*
+  canna_fn_EndOfLine = IROHA_FN_EndOfLine;
+
+  DEFVAR_INT ("canna-func-delete-next", &canna_fn_DeleteNext  /*
 
 */ );
-  DEFVAR_INT ("canna-func-delete_previous", &Vcanna_fn_DeletePrevious  /*
+  canna_fn_DeleteNext = IROHA_FN_DeleteNext;
+
+  DEFVAR_INT ("canna-func-delete_previous", &canna_fn_DeletePrevious  /*
 
 */ );
-  DEFVAR_INT ("canna-func-kill-to-end-of-line", &Vcanna_fn_KillToEndOfLine /*
+  canna_fn_DeletePrevious = IROHA_FN_DeletePrevious;
+
+  DEFVAR_INT ("canna-func-kill-to-end-of-line", &canna_fn_KillToEndOfLine /*
 
 */ );
-  DEFVAR_INT ("canna-func-henkan", &Vcanna_fn_Henkan  /*
+  canna_fn_KillToEndOfLine = IROHA_FN_KillToEndOfLine;
+
+  DEFVAR_INT ("canna-func-henkan", &canna_fn_Henkan  /*
 
 */ );
-  DEFVAR_INT ("canna-func-kakutei", &Vcanna_fn_Kakutei  /*
+  canna_fn_Henkan = IROHA_FN_Henkan;
+
+  DEFVAR_INT ("canna-func-kakutei", &canna_fn_Kakutei  /*
 
 */ );
-  DEFVAR_INT ("canna-func-extend", &Vcanna_fn_Extend  /*
+  canna_fn_Kakutei = IROHA_FN_Kakutei;
+
+  DEFVAR_INT ("canna-func-extend", &canna_fn_Extend  /*
 
 */ );
-  DEFVAR_INT ("canna-func-shrink", &Vcanna_fn_Shrink  /*
+  canna_fn_Extend = IROHA_FN_Extend;
+
+  DEFVAR_INT ("canna-func-shrink", &canna_fn_Shrink  /*
 
 */ );
+  canna_fn_Shrink = IROHA_FN_Shrink;
+
 #ifdef CANNA_FN_AdjustBunsetsu
-  DEFVAR_INT ("canna-func-adjust-bunsetsu", &Vcanna_fn_AdjustBunsetsu  /*
+  DEFVAR_INT ("canna-func-adjust-bunsetsu", &canna_fn_AdjustBunsetsu  /*
 
 */ );
+  canna_fn_AdjustBunsetsu = CANNA_FN_AdjustBunsetsu;
 #endif
-  DEFVAR_INT ("canna-func-quit", &Vcanna_fn_Quit  /*
+  DEFVAR_INT ("canna-func-quit", &canna_fn_Quit  /*
 
 */ );
-  DEFVAR_INT ("canna-func-convert-as-hex", &Vcanna_fn_ConvertAsHex  /*
+  canna_fn_Quit = IROHA_FN_Quit;
+
+  DEFVAR_INT ("canna-func-convert-as-hex", &canna_fn_ConvertAsHex  /*
 
 */ );
-  DEFVAR_INT ("canna-func-convert-as-bushu", &Vcanna_fn_ConvertAsBushu  /*
+  canna_fn_ConvertAsHex = IROHA_FN_ConvertAsHex;
+
+  DEFVAR_INT ("canna-func-convert-as-bushu", &canna_fn_ConvertAsBushu  /*
 
 */ );
-  DEFVAR_INT ("canna-func-kouho-ichiran", &Vcanna_fn_KouhoIchiran  /*
+  canna_fn_ConvertAsBushu = IROHA_FN_ConvertAsBushu;
+
+  DEFVAR_INT ("canna-func-kouho-ichiran", &canna_fn_KouhoIchiran  /*
 
 */ );
-  DEFVAR_INT ("canna-func-bubun-muhenkan", &Vcanna_fn_BubunMuhenkan  /*
+  canna_fn_KouhoIchiran = IROHA_FN_KouhoIchiran;
+
+  DEFVAR_INT ("canna-func-bubun-muhenkan", &canna_fn_BubunMuhenkan  /*
 
 */ );
-  DEFVAR_INT ("canna-func-zenkaku", &Vcanna_fn_Zenkaku  /*
+  canna_fn_BubunMuhenkan = IROHA_FN_BubunMuhenkan;
+
+  DEFVAR_INT ("canna-func-zenkaku", &canna_fn_Zenkaku  /*
 
 */ );
-  DEFVAR_INT ("canna-func-hankaku", &Vcanna_fn_Hankaku  /*
+  canna_fn_Zenkaku = IROHA_FN_Zenkaku;
+
+  DEFVAR_INT ("canna-func-hankaku", &canna_fn_Hankaku  /*
 
 */ );
-  DEFVAR_INT ("canna-func-to-upper", &Vcanna_fn_ToUpper  /*
+  canna_fn_Hankaku = IROHA_FN_Hankaku;
+
+  DEFVAR_INT ("canna-func-to-upper", &canna_fn_ToUpper  /*
 
 */ );
-  DEFVAR_INT ("canna-func-capitalize", &Vcanna_fn_Capitalize  /*
+  canna_fn_ToUpper = IROHA_FN_ToUpper;
+
+  DEFVAR_INT ("canna-func-capitalize", &canna_fn_Capitalize  /*
 
 */ );
-  DEFVAR_INT ("canna-func-to-lower", &Vcanna_fn_ToLower  /*
+  canna_fn_Capitalize = IROHA_FN_Capitalize;
+
+  DEFVAR_INT ("canna-func-to-lower", &canna_fn_ToLower  /*
 
 */ );
-  DEFVAR_INT ("canna-func-hiragana", &Vcanna_fn_Hiragana  /*
+  canna_fn_ToLower = IROHA_FN_ToLower;
+
+  DEFVAR_INT ("canna-func-hiragana", &canna_fn_Hiragana  /*
 
 */ );
-  DEFVAR_INT ("canna-func-katakana", &Vcanna_fn_Katakana  /*
+  canna_fn_Hiragana = IROHA_FN_Hiragana;
+
+  DEFVAR_INT ("canna-func-katakana", &canna_fn_Katakana  /*
 
 */ );
-  DEFVAR_INT ("canna-func-romaji", &Vcanna_fn_Romaji  /*
+  canna_fn_Katakana = IROHA_FN_Katakana;
+
+  DEFVAR_INT ("canna-func-romaji", &canna_fn_Romaji  /*
 
 */ );
+  canna_fn_Romaji = IROHA_FN_Romaji;
+
 #ifdef CANNA_FN_BaseHiragana
-  DEFVAR_INT ("canna-func-base-hiragana", &Vcanna_fn_BaseHiragana  /*
+  DEFVAR_INT ("canna-func-base-hiragana", &canna_fn_BaseHiragana  /*
 
 */ );
-  DEFVAR_INT ("canna-func-base-katakana", &Vcanna_fn_BaseKatakana  /*
+  canna_fn_BaseHiragana = CANNA_FN_BaseHiragana;
+
+  DEFVAR_INT ("canna-func-base-katakana", &canna_fn_BaseKatakana  /*
 
 */ );
-  DEFVAR_INT ("canna-func-base-eisu", &Vcanna_fn_BaseEisu  /*
+  canna_fn_BaseKatakana = CANNA_FN_BaseKatakana;
+
+  DEFVAR_INT ("canna-func-base-eisu", &canna_fn_BaseEisu  /*
 
 */ );
-  DEFVAR_INT ("canna-func-base-zenkaku", &Vcanna_fn_BaseZenkaku  /*
+  canna_fn_BaseEisu = CANNA_FN_BaseEisu;
+
+  DEFVAR_INT ("canna-func-base-zenkaku", &canna_fn_BaseZenkaku  /*
 
 */ );
-  DEFVAR_INT ("canna-func-base-hankaku", &Vcanna_fn_BaseHankaku  /*
+  canna_fn_BaseZenkaku = CANNA_FN_BaseZenkaku;
+
+  DEFVAR_INT ("canna-func-base-hankaku", &canna_fn_BaseHankaku  /*
 
 */ );
-  DEFVAR_INT ("canna-func-base-kana", &Vcanna_fn_BaseKana  /*
+  canna_fn_BaseHankaku = CANNA_FN_BaseHankaku;
+
+  DEFVAR_INT ("canna-func-base-kana", &canna_fn_BaseKana  /*
 
 */ );
-  DEFVAR_INT ("canna-func-base-kakutei", &Vcanna_fn_BaseKakutei  /*
+  canna_fn_BaseKana = CANNA_FN_BaseKana;
+
+  DEFVAR_INT ("canna-func-base-kakutei", &canna_fn_BaseKakutei  /*
 
 */ );
-  DEFVAR_INT ("canna-func-base-henkan", &Vcanna_fn_BaseHenkan  /*
+  canna_fn_BaseKakutei = CANNA_FN_BaseKakutei;
+
+  DEFVAR_INT ("canna-func-base-henkan", &canna_fn_BaseHenkan  /*
 
 */ );
+  canna_fn_BaseHenkan = CANNA_FN_BaseHenkan;
+
   DEFVAR_INT ("canna-func-base-hiragana-katakana-toggle",
-             &Vcanna_fn_BaseHiraKataToggle  /*
+             &canna_fn_BaseHiraKataToggle  /*
 
 */ );
+  canna_fn_BaseHiraKataToggle = CANNA_FN_BaseHiraKataToggle;
+
   DEFVAR_INT ("canna-func-base-zenkaku-hankaku-toggle",
-             &Vcanna_fn_BaseZenHanToggle  /*
+             &canna_fn_BaseZenHanToggle  /*
 
 */ );
+  canna_fn_BaseZenHanToggle = CANNA_FN_BaseZenHanToggle;
+
   DEFVAR_INT ("canna-func-base-kana-eisu-toggle",
-             &Vcanna_fn_BaseKanaEisuToggle  /*
+             &canna_fn_BaseKanaEisuToggle  /*
 
 */ );
+  canna_fn_BaseKanaEisuToggle = CANNA_FN_BaseKanaEisuToggle;
+
   DEFVAR_INT ("canna-func-base-kakutei-henkan-toggle",
-             &Vcanna_fn_BaseKakuteiHenkanToggle  /*
+             &canna_fn_BaseKakuteiHenkanToggle  /*
 
 */ );
+  canna_fn_BaseKakuteiHenkanToggle = CANNA_FN_BaseKakuteiHenkanToggle;
+
   DEFVAR_INT ("canna-func-base-rotate-forward",
-             &Vcanna_fn_BaseRotateForward  /*
+             &canna_fn_BaseRotateForward  /*
 
 */ );
+  canna_fn_BaseRotateForward = CANNA_FN_BaseRotateForward;
+
   DEFVAR_INT ("canna-func-base-rotate-backward",
-             &Vcanna_fn_BaseRotateBackward  /*
+             &canna_fn_BaseRotateBackward  /*
 
 */ );
+  canna_fn_BaseRotateBackward = CANNA_FN_BaseRotateBackward;
+
 #endif
-  DEFVAR_INT ("canna-func-extend-mode", &Vcanna_fn_ExtendMode  /*
+  DEFVAR_INT ("canna-func-extend-mode", &canna_fn_ExtendMode  /*
 
 */ );
-  DEFVAR_INT ("canna-func-touroku", &Vcanna_fn_Touroku  /*
+  canna_fn_ExtendMode = IROHA_FN_ExtendMode;
+
+  DEFVAR_INT ("canna-func-touroku", &canna_fn_Touroku  /*
 
 */ );
-  DEFVAR_INT ("canna-func-hex-mode", &Vcanna_fn_HexMode  /*
+  canna_fn_Touroku = IROHA_FN_Touroku;
+
+  DEFVAR_INT ("canna-func-hex-mode", &canna_fn_HexMode  /*
 
 */ );
-  DEFVAR_INT ("canna-func-bushu-mode", &Vcanna_fn_BushuMode  /*
+  canna_fn_HexMode = IROHA_FN_HexMode;
+
+  DEFVAR_INT ("canna-func-bushu-mode", &canna_fn_BushuMode  /*
 
 */ );
-  DEFVAR_INT ("canna-func-kigo-mode", &Vcanna_fn_KigouMode  /*
+  canna_fn_BushuMode = IROHA_FN_BushuMode;
+
+  DEFVAR_INT ("canna-func-kigo-mode", &canna_fn_KigouMode  /*
 
 */ );
+  canna_fn_KigouMode = IROHA_FN_KigouMode;
+
 #ifdef CANNA_FN_Mark
-  DEFVAR_INT ("canna-func-mark", &Vcanna_fn_Mark  /*
+  DEFVAR_INT ("canna-func-mark", &canna_fn_Mark  /*
 
 */ );
+  canna_fn_Mark = CANNA_FN_Mark;
 #endif
 #ifdef CANNA_FN_TemporalMode
-  DEFVAR_INT ("canna-func-temporal-mode", &Vcanna_fn_TemporalMode  /*
+  DEFVAR_INT ("canna-func-temporal-mode", &canna_fn_TemporalMode  /*
 
 */ );
+  canna_fn_TemporalMode = CANNA_FN_TemporalMode;
 #endif
 
-  DEFVAR_INT ("canna-key-nfer", &Vcanna_key_Nfer /*
+  DEFVAR_INT ("canna-key-nfer", &canna_key_Nfer /*
 
 */ );
-  DEFVAR_INT ("canna-key-xfer", &Vcanna_key_Xfer /*
+  canna_key_Nfer = IROHA_KEY_Nfer;
+
+  DEFVAR_INT ("canna-key-xfer", &canna_key_Xfer /*
 
 */ );
-  DEFVAR_INT ("canna-key-up", &Vcanna_key_Up /*
+  canna_key_Xfer = IROHA_KEY_Xfer;
+
+  DEFVAR_INT ("canna-key-up", &canna_key_Up /*
 
 */ );
-  DEFVAR_INT ("canna-key-left", &Vcanna_key_Left /*
+  canna_key_Up = IROHA_KEY_Up;
+
+  DEFVAR_INT ("canna-key-left", &canna_key_Left /*
 
 */ );
-  DEFVAR_INT ("canna-key-right", &Vcanna_key_Right /*
+  canna_key_Left = IROHA_KEY_Left;
+
+  DEFVAR_INT ("canna-key-right", &canna_key_Right /*
 
 */ );
-  DEFVAR_INT ("canna-key-down", &Vcanna_key_Down /*
+  canna_key_Right = IROHA_KEY_Right;
+
+  DEFVAR_INT ("canna-key-down", &canna_key_Down /*
 
 */ );
-  DEFVAR_INT ("canna-key-insert", &Vcanna_key_Insert /*
+  canna_key_Down = IROHA_KEY_Down;
+
+  DEFVAR_INT ("canna-key-insert", &canna_key_Insert /*
 
 */ );
-  DEFVAR_INT ("canna-key-rollup", &Vcanna_key_Rollup /*
+  canna_key_Insert = IROHA_KEY_Insert;
+
+  DEFVAR_INT ("canna-key-rollup", &canna_key_Rollup /*
 
 */ );
-  DEFVAR_INT ("canna-key-rolldown", &Vcanna_key_Rolldown /*
+  canna_key_Rollup = IROHA_KEY_Rollup;
+
+  DEFVAR_INT ("canna-key-rolldown", &canna_key_Rolldown /*
 
 */ );
-  DEFVAR_INT ("canna-key-home", &Vcanna_key_Home /*
+  canna_key_Rolldown = IROHA_KEY_Rolldown;
+
+  DEFVAR_INT ("canna-key-home", &canna_key_Home /*
 
 */ );
-  DEFVAR_INT ("canna-key-help", &Vcanna_key_Help /*
+  canna_key_Home = IROHA_KEY_Home;
+
+  DEFVAR_INT ("canna-key-help", &canna_key_Help /*
 
 */ );
-  DEFVAR_INT ("canna-key-kp-key", &Vcanna_key_KP_Key /*
+  canna_key_Help = IROHA_KEY_Help;
+
+  DEFVAR_INT ("canna-key-kp-key", &canna_key_KP_Key /*
 
 */ );
-  DEFVAR_INT ("canna-key-shift-nfer", &Vcanna_key_Shift_Nfer /*
+  canna_key_KP_Key = IROHA_KEY_KP_Key;
+
+  DEFVAR_INT ("canna-key-shift-nfer", &canna_key_Shift_Nfer /*
 
 */ );
-  DEFVAR_INT ("canna-key-shift-xfer", &Vcanna_key_Shift_Xfer /*
+  canna_key_Shift_Nfer = IROHA_KEY_Shift_Nfer;
+
+  DEFVAR_INT ("canna-key-shift-xfer", &canna_key_Shift_Xfer /*
 
 */ );
-  DEFVAR_INT ("canna-key-shift-up", &Vcanna_key_Shift_Up /*
+  canna_key_Shift_Xfer = IROHA_KEY_Shift_Xfer;
+
+  DEFVAR_INT ("canna-key-shift-up", &canna_key_Shift_Up /*
 
 */ );
-  DEFVAR_INT ("canna-key-shift-left", &Vcanna_key_Shift_Left /*
+  canna_key_Shift_Up = IROHA_KEY_Shift_Up;
+
+  DEFVAR_INT ("canna-key-shift-left", &canna_key_Shift_Left /*
 
 */ );
-  DEFVAR_INT ("canna-key-shift-right", &Vcanna_key_Shift_Right /*
+  canna_key_Shift_Left = IROHA_KEY_Shift_Left;
+
+  DEFVAR_INT ("canna-key-shift-right", &canna_key_Shift_Right /*
 
 */ );
-  DEFVAR_INT ("canna-key-shift-down", &Vcanna_key_Shift_Down /*
+  canna_key_Shift_Right = IROHA_KEY_Shift_Right;
+
+  DEFVAR_INT ("canna-key-shift-down", &canna_key_Shift_Down /*
 
 */ );
-  DEFVAR_INT ("canna-key-control-nfer", &Vcanna_key_Cntrl_Nfer /*
+  canna_key_Shift_Down = IROHA_KEY_Shift_Down;
+
+  DEFVAR_INT ("canna-key-control-nfer", &canna_key_Cntrl_Nfer /*
 
 */ );
-  DEFVAR_INT ("canna-key-control-xfer", &Vcanna_key_Cntrl_Xfer /*
+  canna_key_Cntrl_Nfer = IROHA_KEY_Cntrl_Nfer;
+
+  DEFVAR_INT ("canna-key-control-xfer", &canna_key_Cntrl_Xfer /*
 
 */ );
-  DEFVAR_INT ("canna-key-control-up", &Vcanna_key_Cntrl_Up /*
+  canna_key_Cntrl_Xfer = IROHA_KEY_Cntrl_Xfer;
+
+  DEFVAR_INT ("canna-key-control-up", &canna_key_Cntrl_Up /*
 
 */ );
-  DEFVAR_INT ("canna-key-control-left", &Vcanna_key_Cntrl_Left /*
+  canna_key_Cntrl_Up = IROHA_KEY_Cntrl_Up;
+
+  DEFVAR_INT ("canna-key-control-left", &canna_key_Cntrl_Left /*
 
 */ );
-  DEFVAR_INT ("canna-key-control-right", &Vcanna_key_Cntrl_Right /*
+  canna_key_Cntrl_Left = IROHA_KEY_Cntrl_Left;
+
+  DEFVAR_INT ("canna-key-control-right", &canna_key_Cntrl_Right /*
 
 */ );
-  DEFVAR_INT ("canna-key-control-down", &Vcanna_key_Cntrl_Down /*
+  canna_key_Cntrl_Right = IROHA_KEY_Cntrl_Right;
+
+  DEFVAR_INT ("canna-key-control-down", &canna_key_Cntrl_Down /*
 
 */ );
+  canna_key_Cntrl_Down = IROHA_KEY_Cntrl_Down;
 
   Fprovide(intern("CANNA"));
 }
index f144b04..bbfefee 100644 (file)
@@ -132,6 +132,8 @@ new_child (void)
   xzero (*cp);
   cp->fd = -1;
   cp->pid = -1;
+  if (cp->procinfo.hProcess)
+    CloseHandle(cp->procinfo.hProcess);
   cp->procinfo.hProcess = NULL;
   cp->status = STATUS_READ_ERROR;
 
@@ -234,10 +236,19 @@ reader_thread (void *arg)
   /* Our identity */
   cp = (child_process *)arg;
   
-  /* We have to wait for the go-ahead before we can start */
+  /* <matts@tibco.com> - I think the test below is wrong - we don't
+     want to wait for someone to signal char_consumed, as we haven't
+     read anything for them to consume yet! */
+
+  /*
   if (cp == NULL ||
       WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
-    return 1;
+  */
+
+  if (cp == NULL)
+  {
+      return 1;
+  }
 
   for (;;)
     {
@@ -255,7 +266,28 @@ reader_thread (void *arg)
        }
 
       if (rc == STATUS_READ_ERROR)
-       return 1;
+      {
+        /* We are finished, so clean up handles and set to NULL so
+           that CHILD_ACTIVE will see what is going on */
+        if (cp->char_avail) {
+          CloseHandle (cp->char_avail);
+          cp->char_avail = NULL;
+        }
+        if (cp->thrd) {
+          CloseHandle (cp->thrd);
+          cp->thrd = NULL;
+        }
+        if (cp->char_consumed) {
+          CloseHandle(cp->char_consumed);
+          cp->char_consumed = NULL;
+        }
+        if (cp->procinfo.hProcess)
+        {
+          CloseHandle (cp->procinfo.hProcess);
+          cp->procinfo.hProcess=NULL;
+        }
+        return 1;
+      }
         
       /* If the read died, the child has died so let the thread die */
       if (rc == STATUS_READ_FAILED)
@@ -269,6 +301,26 @@ reader_thread (void *arg)
          break;
         }
     }
+  /* We are finished, so clean up handles and set to NULL so that
+     CHILD_ACTIVE will see what is going on */
+  if (cp->char_avail) {
+    CloseHandle (cp->char_avail);
+    cp->char_avail = NULL;
+  }
+  if (cp->thrd) {
+    CloseHandle (cp->thrd);
+    cp->thrd = NULL;
+  }
+  if (cp->char_consumed) {
+    CloseHandle(cp->char_consumed);
+    cp->char_consumed = NULL;
+  }
+  if (cp->procinfo.hProcess)
+  {
+    CloseHandle (cp->procinfo.hProcess);
+    cp->procinfo.hProcess=NULL;
+  }
+  
   return 0;
 }
 
@@ -325,6 +377,11 @@ create_child (char *exe, char *cmdline, char *env,
 
   cp->pid = (int) cp->procinfo.dwProcessId;
 
+  CloseHandle (cp->procinfo.hThread);
+  CloseHandle (cp->procinfo.hProcess);
+  cp->procinfo.hThread=NULL;
+  cp->procinfo.hProcess=NULL;
+
   /* Hack for Windows 95, which assigns large (ie negative) pids */
   if (cp->pid < 0)
     cp->pid = -cp->pid;
index 255d3fd..20f2c75 100644 (file)
@@ -51,12 +51,14 @@ Boston, MA 02111-1307, USA.  */
 
 #ifdef __CYGWIN32__
 #define stricmp strcasecmp
+#define FONTENUMPROC FONTENUMEXPROC
+#define ntmTm ntmentm
 #endif
 
 typedef struct colormap_t 
 {
-  char *name;
-  COLORREF colorref;
+  CONST char *name;
+  CONST COLORREF colorref;
 } colormap_t;
 
 /* Colors from X11R6 "XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp" */
@@ -721,6 +723,58 @@ static CONST colormap_t mswindows_X_color_map[] =
   {"LightGreen"                        , PALETTERGB (144, 238, 144) }
 };
 
+
+typedef struct fontmap_t 
+{
+  CONST char *name;
+  CONST int value;
+} fontmap_t;
+
+/* Default weight first, preferred names listed before synonyms */
+static CONST fontmap_t fontweight_map[] = 
+{
+  {"Regular"           , FW_REGULAR},  /* The standard font weight */
+  {"Thin"              , FW_THIN},
+  {"Extra Light"       , FW_EXTRALIGHT},
+  {"Ultra Light"       , FW_ULTRALIGHT},
+  {"Light"             , FW_LIGHT},
+  {"Normal"            , FW_NORMAL},
+  {"Medium"            , FW_MEDIUM},
+  {"Semi Bold"         , FW_SEMIBOLD},
+  {"Demi Bold"         , FW_DEMIBOLD},
+  {"Bold"              , FW_BOLD},     /* The standard bold font weight */
+  {"Extra Bold"                , FW_EXTRABOLD},
+  {"Ultra Bold"                , FW_ULTRABOLD},
+  {"Heavy"             , FW_HEAVY},
+  {"Black"             , FW_BLACK}
+};
+
+/* Default charset first, no synonyms allowed because these names are 
+ * matched against the names reported by win32 by match_font() */
+static CONST fontmap_t charset_map[] = 
+{
+  {"Western"           , ANSI_CHARSET},
+  {"Symbol"            , SYMBOL_CHARSET},
+  {"Shift JIS"         , SHIFTJIS_CHARSET},    /* #### Name to be verified */
+  {"GB2312"            , GB2312_CHARSET},      /* #### Name to be verified */
+  {"Hanguel"           , HANGEUL_CHARSET},
+  {"Chinese Big 5"     , CHINESEBIG5_CHARSET}, /* #### Name to be verified */
+#if (WINVER >= 0x0400)
+  {"Johab"             , JOHAB_CHARSET},       /* #### Name to be verified */
+  {"Hebrew"            , HEBREW_CHARSET},      /* #### Name to be verified */
+  {"Arabic"            , ARABIC_CHARSET},      /* #### Name to be verified */
+  {"Greek"             , GREEK_CHARSET},
+  {"Turkish"           , TURKISH_CHARSET},
+  {"Vietnamese"                , VIETNAMESE_CHARSET},  /* #### Name to be verified */
+  {"Thai"              , THAI_CHARSET},        /* #### Name to be verified */
+  {"Central European"  , EASTEUROPE_CHARSET},
+  {"Cyrillic"          , RUSSIAN_CHARSET},
+  {"Mac"               , MAC_CHARSET},
+  {"Baltic"            , BALTIC_CHARSET},
+#endif
+  {"OEM/DOS"           , OEM_CHARSET}
+};
+
 \f
 /************************************************************************/
 /*                               helpers                                */
@@ -872,6 +926,120 @@ match_font (char *pattern1, char *pattern2, char *fontname)
   return 1;
 }
 
+
+
+
+\f
+/************************************************************************/
+/*                                 exports                              */
+/************************************************************************/
+
+struct font_enum_t
+{
+  HDC hdc;
+  struct device *d;
+};
+
+static int CALLBACK
+font_enum_callback_2 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, 
+                     int FontType, struct font_enum_t *font_enum)
+{
+  struct mswindows_font_enum *fontlist, **fonthead;
+  char fontname[MSW_FONTSIZE];
+  int i;
+
+  /*
+   * The enumerated font weights are not to be trusted because:
+   *  a) lpelfe->elfStyle is only filled in for TrueType fonts.
+   *  b) Not all Bold and Italic styles of all fonts (inluding some Vector,
+   *     Truetype and Raster fonts) are enumerated.
+   * I guess that fonts for which Bold and Italic styles are generated
+   * 'on-the-fly' are not enumerated. It would be overly restrictive to
+   * disallow Bold And Italic weights for these fonts, so we just leave
+   * weights unspecified. This means that we have to weed out duplicates of
+   * those fonts that do get enumerated with different weights.
+   */
+  if (FontType == 0 /*vector*/ || FontType == TRUETYPE_FONTTYPE)
+    /* Scalable, so leave pointsize blank */
+    sprintf (fontname, "%s::::", lpelfe->elfLogFont.lfFaceName);
+  else
+    /* Formula for pointsize->height from LOGFONT docs in Platform SDK */
+    sprintf (fontname, "%s::%d::", lpelfe->elfLogFont.lfFaceName,
+            MulDiv (lpntme->ntmTm.tmHeight - lpntme->ntmTm.tmInternalLeading,
+                    72, DEVICE_MSWINDOWS_LOGPIXELSY (font_enum->d)));
+
+  /*
+   * The enumerated font character set strings are not to be trusted because
+   * lpelfe->elfScript is returned in the host language and not in English.
+   * We can't know a priori the translations of "Western", "Central European"
+   * etc into the host language, so we must use English. The same argument
+   * applies to the font weight string when matching fonts.
+   */
+  for (i=0; i<countof (charset_map); i++)
+    if (lpelfe->elfLogFont.lfCharSet == charset_map[i].value)
+      {
+       strcat (fontname, charset_map[i].name);
+       break;
+      }
+  if (i==countof (charset_map))
+    strcpy (fontname, charset_map[0].name);
+
+  /* Check that the new font is not a duplicate */
+  fonthead = &DEVICE_MSWINDOWS_FONTLIST (font_enum->d);
+  fontlist = *fonthead;
+  while (fontlist)
+    if (!strcmp (fontname, fontlist->fontname))
+      return 1;                /* found a duplicate */
+    else
+      fontlist = fontlist->next;
+
+  /* Insert entry at head */
+  fontlist = *fonthead;
+  *fonthead = xmalloc (sizeof (struct mswindows_font_enum));
+  if (*fonthead == NULL)
+    {
+      *fonthead = fontlist;
+      return 0;
+    }
+  strcpy ((*fonthead)->fontname, fontname);
+  (*fonthead)->next = fontlist;
+  return 1;
+}
+
+static int CALLBACK
+font_enum_callback_1 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, 
+                     int FontType, struct font_enum_t *font_enum)
+{
+  /* This function gets called once per facename per character set.
+   * We call a second callback to enumerate the fonts in each facename */
+  return EnumFontFamiliesEx (font_enum->hdc, &lpelfe->elfLogFont,
+                            (FONTENUMPROC) font_enum_callback_2,
+                            (LPARAM) font_enum, 0);
+}
+
+/*
+ * Enumerate the available fonts. Called by mswindows_init_device().
+ * Fills in the device's device-type-specfic fontlist.
+ */
+void
+mswindows_enumerate_fonts (struct device *d)
+{
+  HDC hdc = CreateCompatibleDC (NULL);
+  LOGFONT logfont;
+  struct font_enum_t font_enum;
+
+  assert (hdc!=NULL);
+  logfont.lfCharSet = DEFAULT_CHARSET;
+  logfont.lfFaceName[0] = '\0';
+  logfont.lfPitchAndFamily = DEFAULT_PITCH;
+  font_enum.hdc = hdc;
+  font_enum.d = d;
+  DEVICE_MSWINDOWS_FONTLIST (d) = NULL;
+  EnumFontFamiliesEx (hdc, &logfont, (FONTENUMPROC) font_enum_callback_1,
+                     (LPARAM) (&font_enum), 0);
+  DeleteDC (hdc);
+}
+
 \f
 /************************************************************************/
 /*                               methods                                */
@@ -970,19 +1138,23 @@ mswindows_finalize_font_instance (struct Lisp_Font_Instance *f)
     }
 }
 
+
 static int
 mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object name,
                                    Lisp_Object device, Error_behavior errb)
 {
   CONST char *extname;
   LOGFONT logfont;
-  int fields;
+  int fields, i;
   int pt;
   char fontname[LF_FACESIZE], weight[LF_FACESIZE], *style, points[8];
   char effects[LF_FACESIZE], charset[LF_FACESIZE];
   char *c;
-  
-  GET_C_STRING_CTEXT_DATA_ALLOCA (f->name, extname);
+  HDC hdc;
+  HFONT holdfont;
+  TEXTMETRIC metrics;
+
+  extname = XSTRING_DATA (name);
 
   /*
    * mswindows fonts look like:
@@ -1003,12 +1175,12 @@ mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object na
   /* This function is implemented in a fairly ad-hoc manner.
    * The general idea is to validate and canonicalize each of the above fields
    * at the same time as we build up the win32 LOGFONT structure. This enables
-   * us to use math_font() on a canonicalized font string to check the
+   * us to use match_font() on a canonicalized font string to check the
    * availability of the requested font */
 
-  if (fields<0)
+  if (fields < 0)
   {
-    maybe_signal_simple_error ("Invalid font", f->name, Qfont, errb);
+    maybe_signal_simple_error ("Invalid font", name, Qfont, errb);
     return (0);
   }
 
@@ -1019,13 +1191,13 @@ mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object na
   }
   else
   {
-    maybe_signal_simple_error ("Must specify a font name", f->name, Qfont, errb);
+    maybe_signal_simple_error ("Must specify a font name", name, Qfont, errb);
     return (0);
   }
 
   /* weight */
   if (fields < 2)
-    strcpy (weight, "Regular");
+    strcpy (weight, fontweight_map[0].name);
 
   /* Maybe split weight into weight and style */
   if ((c=strchr(weight, ' ')))
@@ -1036,37 +1208,26 @@ mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object na
   else
     style = NULL;
 
-#define FROB(wgt)                              \
-  if (stricmp (weight, #wgt) == 0)             \
-    logfont.lfWeight = FW_##wgt
-
-  FROB (REGULAR);
-  else FROB (THIN);
-  else FROB (EXTRALIGHT);
-  else FROB (ULTRALIGHT);
-  else FROB (LIGHT);
-  else FROB (NORMAL);
-  else FROB (MEDIUM);
-  else FROB (SEMIBOLD);
-  else FROB (DEMIBOLD);
-  else FROB (BOLD);
-  else FROB (EXTRABOLD);
-  else FROB (ULTRABOLD);
-  else FROB (HEAVY);
-  else FROB (BLACK);
-  else if (!style)
-    {
-      logfont.lfWeight = FW_REGULAR;
-      style = weight;  /* May have specified style without weight */
-    }
-  else
+  for (i=0; i<countof (fontweight_map); i++)
+    if (!stricmp (weight, fontweight_map[i].name))
+      {        
+       logfont.lfWeight = fontweight_map[i].value;
+       break;
+      }
+  if (i == countof (fontweight_map))   /* No matching weight */
     {
-      maybe_signal_simple_error ("Invalid font weight", f->name, Qfont, errb);
-      return (0);
+      if (!style)
+       {
+         logfont.lfWeight = FW_REGULAR;
+         style = weight;       /* May have specified style without weight */
+       }
+      else
+       {
+         maybe_signal_simple_error ("Invalid font weight", name, Qfont, errb);
+         return (0);
+       }
     }
 
-#undef FROB
-
   if (style)
     {
       /* #### what about oblique? */
@@ -1074,7 +1235,7 @@ mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object na
        logfont.lfItalic = TRUE;
       else
       {
-        maybe_signal_simple_error ("Invalid font weight or style", f->name, Qfont, errb);
+        maybe_signal_simple_error ("Invalid font weight or style", name, Qfont, errb);
        return (0);
       }
 
@@ -1089,12 +1250,12 @@ mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object na
     pt = 10;   /* #### Should we reject strings that don't specify a size? */
   else if ((pt=atoi(points)) == 0)
     {
-      maybe_signal_simple_error ("Invalid font pointsize", f->name, Qfont, errb);
+      maybe_signal_simple_error ("Invalid font pointsize", name, Qfont, errb);
       return (0);
     }
 
   /* Formula for pointsize->height from LOGFONT docs in MSVC5 Platform SDK */
-  logfont.lfHeight = -MulDiv(pt, DEVICE_MSWINDOWS_LOGPIXELSY(XDEVICE (device)), 72);
+  logfont.lfHeight = -MulDiv(pt, DEVICE_MSWINDOWS_LOGPIXELSY (XDEVICE (device)), 72);
   logfont.lfWidth = 0;
 
   /* Effects */
@@ -1119,8 +1280,7 @@ mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object na
        logfont.lfStrikeOut = TRUE;
       else
         {
-          maybe_signal_simple_error ("Invalid font effect", f->name,
-                                    Qfont, errb);
+          maybe_signal_simple_error ("Invalid font effect", name, Qfont, errb);
          return (0);
        }
 
@@ -1132,7 +1292,7 @@ mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object na
            logfont.lfStrikeOut = TRUE;
          else
            {
-             maybe_signal_simple_error ("Invalid font effect", f->name,
+             maybe_signal_simple_error ("Invalid font effect", name,
                                         Qfont, errb);
              return (0);
            }
@@ -1152,63 +1312,50 @@ mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object na
   else
     effects[0] = '\0';
 
-#define FROB(cs)                               \
-  else if (stricmp (charset, #cs) == 0)                \
-    logfont.lfCharSet = cs##_CHARSET
-
-  /* Charset aliases. Hangeul = Hangul is defined in windows.h.
-     We do not use the name "russian", only "cyrillic", as it is
-     the common name of this charset, used in other languages
-     than Russian. */
-#define CYRILLIC_CHARSET RUSSIAN_CHARSET
-#define CENTRALEUROPEAN_CHARSET EASTEUROPE_CHARSET
-#define CENTRALEUROPEAN_CHARSET EASTEUROPE_CHARSET
-
+  /* Charset */
   /* charset can be specified even if earlier fields havn't been */
-  if ((fields < 5) && (c=strchr (extname, ':')) && (c=strchr (c+1, ':')) &&
-      (c=strchr (c+1, ':')) && (c=strchr (c+1, ':')))
-    {
-      strncpy (charset, c+1, LF_FACESIZE);
-      charset[LF_FACESIZE-1] = '\0';
-    }
-  else
-    charset[0] = '\0';
-         
-  if (charset[0] == '\0' || (stricmp (charset, "ansi") == 0) ||
-      (stricmp (charset, "western") == 0))
+  if (fields < 5)
     {
-      logfont.lfCharSet = ANSI_CHARSET;
-      strcpy (charset, "western");
+      if ((c=strchr (extname, ':')) && (c=strchr (c+1, ':')) &&
+         (c=strchr (c+1, ':')) && (c=strchr (c+1, ':')))
+       {
+         strncpy (charset, c+1, LF_FACESIZE);
+         charset[LF_FACESIZE-1] = '\0';
+       }
+      else
+       strcpy (charset, charset_map[0].name);
     }
-  FROB (SYMBOL);
-  FROB (SHIFTJIS);
-  FROB (GB2312);
-  FROB (HANGEUL);
-  FROB (CHINESEBIG5);
-  FROB (JOHAB);
-  FROB (HEBREW);
-  FROB (ARABIC);
-  FROB (GREEK);
-  FROB (TURKISH);
-  FROB (THAI);
-  FROB (EASTEUROPE);
-  FROB (CENTRALEUROPEAN);
-  FROB (CYRILLIC);
-  FROB (MAC);
-  FROB (BALTIC);
-  else if (stricmp (charset, "oem/dos") == 0)
-    logfont.lfCharSet = OEM_CHARSET;
-  else
+
+  for (i=0; i<countof (charset_map); i++)
+    if (!stricmp (charset, charset_map[i].name))
+      {
+       logfont.lfCharSet = charset_map[i].value;
+       break;
+      }
+
+  if (i == countof (charset_map))      /* No matching charset */
     {
-      maybe_signal_simple_error ("Invalid charset", f->name, Qfont, errb);
+      maybe_signal_simple_error ("Invalid charset", name, Qfont, errb);
       return 0;
     }
 
-#undef FROB
+  /* Misc crud */
+  logfont.lfEscapement = logfont.lfOrientation = 0;
+#if 1
+  logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
+  logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+  logfont.lfQuality = DEFAULT_QUALITY;
+#else
+  logfont.lfOutPrecision = OUT_STROKE_PRECIS;
+  logfont.lfClipPrecision = CLIP_STROKE_PRECIS;
+  logfont.lfQuality = PROOF_QUALITY;
+#endif
+  /* Default to monospaced if the specified fontname doesn't exist. */
+  logfont.lfPitchAndFamily = FF_MODERN;
 
   /* Windows will silently substitute a default font if the fontname 
    * specifies a non-existent font. So we check the font against the device's
-   * list of font patterns to make sure that at least one of them matches */
+   * list of font patterns to make sure that at least one of them matches. */
   {
     struct mswindows_font_enum *fontlist;
     char truename[MSW_FONTSIZE];
@@ -1223,58 +1370,37 @@ mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object na
       }
     if (!done)
       {
-       maybe_signal_simple_error ("No matching font", f->name, Qfont, errb);
+       maybe_signal_simple_error ("No matching font", name, Qfont, errb);
        return 0;
       }
   }
 
-  /* Misc crud */
-  logfont.lfEscapement = logfont.lfOrientation = 0;
-#if 1
-  logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
-  logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
-  logfont.lfQuality = DEFAULT_QUALITY;
-#else
-  logfont.lfOutPrecision = OUT_STROKE_PRECIS;
-  logfont.lfClipPrecision = CLIP_STROKE_PRECIS;
-  logfont.lfQuality = PROOF_QUALITY;
-#endif
-  /* Default to monospaced if the specified fontname doesn't exist.
-   * The match_font calls above should mean that this can't happen. */
-  logfont.lfPitchAndFamily = FF_MODERN;
-
   if ((f->data = CreateFontIndirect(&logfont)) == NULL)
   {
-    maybe_signal_simple_error ("Couldn't create font", f->name, Qfont, errb);
+    maybe_signal_simple_error ("Couldn't create font", name, Qfont, errb);
     return 0;
   }
 
-  {
-    HDC hdc;
-    HFONT holdfont;
-    TEXTMETRIC metrics;
-
-    hdc = CreateCompatibleDC (NULL);
-    if (hdc)
-      {
-       holdfont = SelectObject(hdc, f->data);
-       if (holdfont)
-         {
-           GetTextMetrics (hdc, &metrics);
-           SelectObject(hdc, holdfont);
-           DeleteDC (hdc);
-           f->width = (unsigned short) metrics.tmAveCharWidth;
-           f->height = (unsigned short) metrics.tmHeight;
-           f->ascent = (unsigned short) metrics.tmAscent;
-           f->descent = (unsigned short) metrics.tmDescent;
-           f->proportional_p = (metrics.tmPitchAndFamily & TMPF_FIXED_PITCH);
-           return 1;
-         }
-       DeleteDC (hdc);
-      }
-    mswindows_finalize_font_instance (f);
-    maybe_signal_simple_error ("Couldn't map font", f->name, Qfont, errb);
-  }
+  hdc = CreateCompatibleDC (NULL);
+  if (hdc)
+    {
+      holdfont = SelectObject(hdc, f->data);
+      if (holdfont)
+       {
+         GetTextMetrics (hdc, &metrics);
+         SelectObject(hdc, holdfont);
+         DeleteDC (hdc);
+         f->width = (unsigned short) metrics.tmAveCharWidth;
+         f->height = (unsigned short) metrics.tmHeight;
+         f->ascent = (unsigned short) metrics.tmAscent;
+         f->descent = (unsigned short) metrics.tmDescent;
+         f->proportional_p = (metrics.tmPitchAndFamily & TMPF_FIXED_PITCH);
+         return 1;
+       }
+      DeleteDC (hdc);
+    }
+  mswindows_finalize_font_instance (f);
+  maybe_signal_simple_error ("Couldn't map font", name, Qfont, errb);
   return 0;
 }
 
index 4435a25..dfe155d 100644 (file)
@@ -39,6 +39,9 @@ Boston, MA 02111-1307, USA.  */
 #include <winsock.h>
 #endif
 
+/* Arbitrary size limit for code fragments passed to run_in_other_process */
+#define FRAGMENT_CODE_SIZE 32
+
 /* Bound by winnt.el */
 Lisp_Object Qnt_quote_process_args;
 
@@ -143,8 +146,8 @@ free_process_memory (process_memory* pmc)
 
 /*
  * Run ROUTINE in the context of process determined by H_PROCESS. The
- * routine is passed the address of DATA as parameter. CODE_END is the 
- * address immediately after ROUTINE's code. DATA_SIZE is the size of
+ * routine is passed the address of DATA as parameter. The ROUTINE must
+ * not be longer than ROUTINE_CODE_SIZE bytes. DATA_SIZE is the size of
  * DATA structure.
  *
  * Note that the code must be positionally independent, and compiled
@@ -157,11 +160,11 @@ free_process_memory (process_memory* pmc)
  */
 static DWORD
 run_in_other_process (HANDLE h_process,
-                     LPTHREAD_START_ROUTINE routine, LPVOID code_end,
+                     LPTHREAD_START_ROUTINE routine,
                      LPVOID data, size_t data_size)
 {
   process_memory pm;
-  size_t code_size = (LPBYTE)code_end - (LPBYTE)routine;
+  CONST size_t code_size = FRAGMENT_CODE_SIZE;
   /* Need at most 3 extra bytes of memory, for data alignment */
   size_t total_size = code_size + data_size + 3;
   LPVOID remote_data;
@@ -223,6 +226,11 @@ run_in_other_process (HANDLE h_process,
  * SIGKILL, SIGTERM, SIGQUIT, SIGHUP - These four translate to ExitProcess
  *    executed by the remote process
  * SIGINT - The remote process is sent CTRL_BREAK_EVENT
+ *
+ * The MSVC5.0 compiler feels free to re-order functions within a
+ * compilation unit, so we have no way of finding out the size of the
+ * following functions. Therefore these functions must not be larger than
+ * FRAGMENT_CODE_SIZE.
  */
 
 /*
@@ -240,12 +248,6 @@ sigkill_proc (sigkill_data* data)
   return 1;
 }
 
-/* Watermark in code space */
-static void
-sigkill_code_end (void)
-{
-}
-
 /*
  * Sending break or control c
  */
@@ -261,12 +263,6 @@ sigint_proc (sigint_data* data)
   return (*data->adr_GenerateConsoleCtrlEvent) (data->event, 0);
 }
 
-/* Watermark in code space */
-static void
-sigint_code_end (void)
-{
-}
-
 /*
  * Enabling signals
  */
@@ -282,12 +278,6 @@ sig_enable_proc (sig_enable_data* data)
   return 1;
 }
 
-/* Watermark in code space */
-static void
-sig_enable_code_end (void)
-{
-}
-
 /*
  * Send signal SIGNO to process H_PROCESS.
  * Return nonzero if successful.
@@ -316,8 +306,7 @@ send_signal (HANDLE h_process, int signo)
        sigkill_data d;
        d.adr_ExitProcess = GetProcAddress (h_kernel, "ExitProcess");
        assert (d.adr_ExitProcess);
-       retval = run_in_other_process (h_process,
-                                      sigkill_proc, sigkill_code_end,
+       retval = run_in_other_process (h_process, sigkill_proc,
                                       &d, sizeof (d));
        break;
       }
@@ -328,8 +317,7 @@ send_signal (HANDLE h_process, int signo)
          GetProcAddress (h_kernel, "GenerateConsoleCtrlEvent");
        assert (d.adr_GenerateConsoleCtrlEvent);
        d.event = CTRL_C_EVENT;
-       retval = run_in_other_process (h_process,
-                                      sigint_proc, sigint_code_end,
+       retval = run_in_other_process (h_process, sigint_proc,
                                       &d, sizeof (d));
        break;
       }
@@ -353,8 +341,7 @@ enable_child_signals (HANDLE h_process)
   d.adr_SetConsoleCtrlHandler =
     GetProcAddress (h_kernel, "SetConsoleCtrlHandler");
   assert (d.adr_SetConsoleCtrlHandler);
-  run_in_other_process (h_process,
-                       sig_enable_proc, sig_enable_code_end,
+  run_in_other_process (h_process, sig_enable_proc,
                        &d, sizeof (d));
 }
   
index a0b6b74..85ad49b 100644 (file)
@@ -920,12 +920,14 @@ unix_create_process (struct Lisp_Process *p,
              EMACS_SET_TTY_PROCESS_GROUP (xforkin, &piddly);
            }
 
-# ifdef AIX
            /* On AIX, we've disabled SIGHUP above once we start a
               child on a pty.  Now reenable it in the child, so it
-              will die when we want it to.  */
+              will die when we want it to.
+              JV: This needs to be done ALWAYS as we might have inherited
+              a SIG_IGN handling from our parent (nohup) and we are in new
+              process group.          
+           */
            signal (SIGHUP, SIG_DFL);
-# endif /* AIX */
          }
 #endif /* HAVE_PTYS */
 
index f895d88..4c97bfc 100644 (file)
@@ -1108,7 +1108,9 @@ r_alloc_thaw ()
 \f
 /* The hook `malloc' uses for the function which gets more space
    from the system.  */
-/* extern POINTER (*__morecore) (long size); */
+#ifndef DOUG_LEA_MALLOC
+extern POINTER (*__morecore) (long size);
+#endif
 
 /* Initialize various things for memory allocation. */
 
index b6247a5..16bb75a 100644 (file)
@@ -693,8 +693,18 @@ x_get_gc (struct device *d, Lisp_Object font, Lisp_Object fg, Lisp_Object bg,
       mask |= GCBackground;
     }
 
-  if (IMAGE_INSTANCEP (bg_pmap)
-      && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap)))
+  /* This special case comes from a request to draw text with a face which has
+     the dim property. We'll use a stippled foreground GC. */
+  if (EQ (bg_pmap, Qdim))
+    {
+      assert (DEVICE_X_GRAY_PIXMAP (d) != None);
+
+      gcv.fill_style = FillStippled;
+      gcv.stipple = DEVICE_X_GRAY_PIXMAP (d);
+      mask |= (GCFillStyle | GCStipple);
+    }
+  else  if (IMAGE_INSTANCEP (bg_pmap)
+           && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap)))
     {
       if (XIMAGE_INSTANCE_PIXMAP_DEPTH (bg_pmap) == 0)
        {
@@ -915,6 +925,18 @@ x_output_string (struct window *w, struct display_line *dl,
       if (cursor && cursor_cachel && focus && NILP (bar_cursor_value))
        gc = x_get_gc (d, font, cursor_cachel->foreground,
                       cursor_cachel->background, Qnil, Qnil);
+      else if (cachel->dim)
+       {
+         /* Ensure the gray bitmap exists */
+         if (DEVICE_X_GRAY_PIXMAP (d) == None)
+           DEVICE_X_GRAY_PIXMAP (d) = 
+             XCreateBitmapFromData (dpy, x_win, (char *)gray_bits,
+                                    gray_width, gray_height);
+
+         /* Request a GC with the gray stipple pixmap to draw dimmed text */
+         gc = x_get_gc (d, font, cachel->foreground, cachel->background,
+                        Qdim, Qnil);
+       }
       else
        gc = x_get_gc (d, font, cachel->foreground, cachel->background,
                       Qnil, Qnil);
index 895f520..9ae8b46 100644 (file)
@@ -5066,7 +5066,10 @@ redisplay_window (Lisp_Object window, int skip_selected)
          temporary change to the echo area. */
       && !(MINI_WINDOW_P (w) && f->buffers_changed)
       && !f->frame_changed
-      && !truncation_changed)
+      && !truncation_changed
+      /* check whether start is really at the begining of a line  GE */
+      && (!w->start_at_line_beg || beginning_of_line_p (b, startp))
+      )
     {
       /* Check if the cursor has actually moved. */
       if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer)
index 1b68465..b8e9b25 100644 (file)
@@ -4857,8 +4857,16 @@ re_match_2_internal (struct re_pattern_buffer *bufp, CONST char *string1,
                   highest_active_reg = NO_HIGHEST_ACTIVE_REG;
                 }
               else
-                highest_active_reg = r;
-            }
+               {
+                 highest_active_reg = r;
+
+                 /* 98/9/21 jhod:  We've also gotta set lowest_active_reg, don't we? */
+                 r = 1;
+                 while (r < highest_active_reg && !IS_ACTIVE(reg_info[r]))
+                   r++;
+                 lowest_active_reg = r;
+               }
+           }
 
           /* If just failed to match something this time around with a
              group that's operated on by a repetition operator, try to
index e45a70f..b277934 100644 (file)
@@ -71,15 +71,21 @@ Boston, MA 02111-1307, USA.  */
 /* cheesy way to determine cygwin version */
 #ifndef NOT_C_CODE
 #include <signal.h>
+#ifdef HAVE_CYGWIN32_VERSION_H
+#include <cygwin32/version.h>
+#else
 #ifdef SIGIO
 #define CYGWIN_B19
 #else
 #define BROKEN_CYGWIN
 #endif
+#endif
+
 extern void cygwin32_win32_to_posix_path_list(const char*, char*);
 extern int cygwin32_win32_to_posix_path_list_buf_size(const char*);
 extern void cygwin32_posix_to_win32_path_list(const char*, char*);
 extern int cygwin32_posix_to_win32_path_list_buf_size(const char*);
+#ifndef CYGWIN_DLL_VERSION_MAJOR
 struct timeval;
 struct timezone;
 struct itimerval;
@@ -102,6 +108,14 @@ extern int utimes(char *file, struct timeval *tvp);
 
 extern int srandom( unsigned seed);
 extern long random();
+
+#define SND_ASYNC              1
+#define SND_NODEFAULT          2
+#define SND_MEMORY             4
+#define SND_FILENAME           0x2000L
+#define VK_APPS                        0x5D
+#define SIF_TRACKPOS   0x0010
+#endif
 #endif
 
 #ifdef HAVE_MS_WINDOWS
@@ -117,12 +131,10 @@ extern long random();
 #define LIBS_SYSTEM -lwinmm
 
 #define ICC_BAR_CLASSES 4
-#define SIF_TRACKPOS   0x0010
 #define FW_BLACK       FW_HEAVY
 #define FW_ULTRABOLD   FW_EXTRABOLD
 #define FW_DEMIBOLD    FW_SEMIBOLD
 #define FW_ULTRALIGHT  FW_EXTRALIGHT
-#define VK_APPS                        0x5D
 #define APPCMD_FILTERINITS     0x20L
 #define CBF_FAIL_SELFCONNECTIONS 0x1000
 #define CBF_SKIP_ALLNOTIFICATIONS      0x3C0000
@@ -130,10 +142,6 @@ extern long random();
 #define CBF_FAIL_POKES         0x10000
 #define CBF_FAIL_REQUESTS      0x20000
 #define SZDDESYS_TOPIC         "System"
-#define SND_ASYNC              1
-#define SND_NODEFAULT          2
-#define SND_MEMORY             4
-#define SND_FILENAME           0x2000L
 #define JOHAB_CHARSET          130
 #define MAC_CHARSET            77
 
index eae989c..5f9f4ff 100644 (file)
 #define regoff_t sys_regoff_t
 #define regmatch_t sys_regmatch_t
 
+/* A perfectly ordinary link wins again - martin */
 #undef C_SWITCH_SYSTEM
-#define C_SWITCH_SYSTEM "-D_BSD"
+#undef LIBS_SYSTEM
+#undef LIBS_DEBUG
+#define ORDINARY_LINK
 
 #define SYSTEM_MALLOC
 
+#if 0 /* martin */
 /* Some V4.0* versions before V4.0B don't detect rename properly. */
 #ifndef HAVE_RENAME
 #define HAVE_RENAME
 #endif
 
 #define LIBS_DEBUG
+#endif /* 0 */
index 8d0229f..32eec34 100644 (file)
 
 #define LIBS_TERMCAP "-ltermcap"
 
+#ifdef __ELF__ /* since from 3.0-CURRENT(maybe 19980831 or later) */
+#ifndef NOT_C_CODE
+#include <stddef.h>
+#endif
+#define LD_SWITCH_SYSTEM
+#define START_FILES pre-crt0.o /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o
+#define UNEXEC unexelf.o
+#define LIB_STANDARD -lgcc -lc -lgcc /usr/lib/crtend.o /usr/lib/crtn.o
+#define LINKER "$(CC) -nostdlib"
+#undef LIB_GCC
+#define LIB_GCC
+
+#else /* not __ELF__ */
+
 #ifndef NO_SHARED_LIBS
 #if 0 /* mrb */
 #define LIB_GCC "-lgcc"
@@ -79,6 +93,8 @@
 #endif /* __FreeBSD__ */
 #endif /* NO_SHARED_LIBS */
 
+#endif /* not __ELF__ */
+
 #define HAVE_GETLOADAVG
 /* #define NO_TERMIO */ /* detected in configure */
 #define DECLARE_GETPWUID_WITH_UID_T
index 6c12abf..dd9a443 100644 (file)
@@ -75,7 +75,9 @@ undo_prelude (struct buffer *b, int hack_pending_boundary)
   if (EQ (b->undo_list, Qt))
     return (0);
 
-  if (NILP (last_undo_buffer) || b != XBUFFER (last_undo_buffer))
+  if (NILP (last_undo_buffer)
+      || (BUFFER_BASE_BUFFER (b)
+         != BUFFER_BASE_BUFFER (XBUFFER (last_undo_buffer))))
     {
       undo_boundary (b);
       XSETBUFFER (last_undo_buffer, b);
index 9200f16..3a1a12f 100644 (file)
@@ -92,9 +92,11 @@ struct headers {
 #define DEFAULT_ENTRY_ADDRESS __start
 #endif
 \f
-unexec (new_name, a_name, data_start, bss_start, entry_address)
-     char *new_name, *a_name;
-     unsigned long data_start, bss_start, entry_address;
+int
+unexec (char *new_name, char *a_name,
+       unsigned long data_start,
+       unsigned long bss_start,
+       unsigned long entry_address)
 {
   int new, old;
   char * oldptr;
@@ -102,7 +104,6 @@ unexec (new_name, a_name, data_start, bss_start, entry_address)
   struct stat stat;
   long pagesize, brk;
   long newsyms, symrel;
-  int nread;
   int i;
   long vaddr, scnptr;
 #define BUFSIZE 8192
@@ -365,15 +366,15 @@ unexec (new_name, a_name, data_start, bss_start, entry_address)
 
 */
 
-
-update_dynamic_symbols (old, new_name, new, newsyms, nsyms, symoff, stroff)
-     char *old;                        /* Pointer to old executable */
-     char *new_name;            /* Name of new executable */
-     int new;                  /* File descriptor for new executable */
-     long newsyms;             /* Offset of Symbol table in new executable */
-     int nsyms;                        /* Number of symbol table entries */
-     long symoff;              /* Offset of External Symbols in old file */
-     long stroff;              /* Offset of string table in old file */
+int
+update_dynamic_symbols (
+     char *old,                        /* Pointer to old executable */
+     char *new_name,            /* Name of new executable */
+     int new,                  /* File descriptor for new executable */
+     long newsyms,             /* Offset of Symbol table in new executable */
+     int nsyms,                        /* Number of symbol table entries */
+     long symoff,              /* Offset of External Symbols in old file */
+     long stroff)              /* Offset of string table in old file */
 {
   long i;
   int found = 0;
index 4252ef1..785915e 100644 (file)
@@ -866,7 +866,9 @@ unexec (char *new_name, char *old_name, unsigned int data_start,
 
       for (; symp < symendp; symp ++)
        if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0
-           || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0)
+           || strcmp ((char *) (symnames + symp->st_name), "end") == 0
+           || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0
+           || strcmp ((char *) (symnames + symp->st_name), "edata") == 0)
          memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr));
     }
 
index 7d4f863..63a9aca 100644 (file)
@@ -1633,7 +1633,9 @@ from overriding motion of point in order to display at this exact start.
   CHECK_INT_COERCE_MARKER (pos);
   set_marker_restricted (w->start[CURRENT_DISP], pos, w->buffer);
   /* this is not right, but much easier than doing what is right. */
-  w->start_at_line_beg = 0;
+  /* w->start_at_line_beg = 0; */
+  /* WTF is the above supposed to mean?  GE */
+  w->start_at_line_beg = beginning_of_line_p (XBUFFER (w->buffer), XINT (pos));
   if (NILP (noforce))
     w->force_start = 1;
   w->redo_modeline = 1;
@@ -3163,7 +3165,9 @@ BUFFER can be a buffer or buffer name.
                         make_int (XBUFFER (buffer)->last_window_start),
                         buffer);
   Fset_marker (w->sb_point, w->start[CURRENT_DISP], buffer);
-  w->start_at_line_beg = 0;
+  /* set start_at_line_beg correctly. GE */
+  w->start_at_line_beg = beginning_of_line_p (XBUFFER (buffer),
+                                             XBUFFER (buffer)->last_window_start);  
   w->force_start = 0;           /* Lucid fix */
   SET_LAST_MODIFIED (w, 1);
   SET_LAST_FACECHANGE (w);