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.
 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));
 #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.)  */
 
   /* 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;
   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);
 }
 
 
   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.
 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))
 {
 */
        (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
 
 #ifdef I18N3
   /* #### Doc string should indicate that the buffer name will get
      translated. */
 #endif
-
+  CHECK_STRING (name);
   name = LISP_GETTEXT (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 (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;
 
   /* 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 =
   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);
 }
 
   return finish_init_buffer (b, name);
 }
-#endif /* 0 */
 
 
 \f
 
 
 \f
@@ -814,41 +811,6 @@ If BUFFER is indirect, the return value will always be nil; see
   return Fcopy_sequence (buf->indirect_children);
 }
 
   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.
 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)
       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;
     }
 
       UNGCPRO;
     }
@@ -1372,7 +1339,7 @@ with `delete-process'.
     kill_buffer_local_variables (b);
 
     b->name = Qnil;
     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)
     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);
   DEFSUBR (Fget_buffer);
   DEFSUBR (Fget_file_buffer);
   DEFSUBR (Fget_buffer_create);
-#if 0
   DEFSUBR (Fmake_indirect_buffer);
   DEFSUBR (Fmake_indirect_buffer);
-#endif
 
   DEFSUBR (Fgenerate_new_buffer_name);
   DEFSUBR (Fbuffer_name);
 
   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
 
   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;
 
   /* 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)
 
     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:
 \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 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) */
            {
             }
          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
              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 */
            {
          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
              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.
 /* 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.
 
 
 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.  */
 
 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 <config.h>
 #include "lisp.h"
 
 #include "buffer.h"
-#include "commands.h"
 #include "insdel.h"
 #include "syntax.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);
 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, /*
 }
 
 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.
 */
 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, /*
 }
 
 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.
 */
 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, /*
 }
 
 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.
 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.
 */
 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, /*
 
 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.
 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.
 */
 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.
 }
 \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;
   /* 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;
   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 */
 
   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++)
     {
 
   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);
 }
 
   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_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
 #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;
 
 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_ */
 #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;
 
   /* The X connection of this device. */
   Display *display;
 
+  /* Set by x_IO_error_handler(). */
+  int being_deleted;
+
   /* Xt application info. */
   Widget Xt_app_shell;
 
   /* 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 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)
 #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"
 
 #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;
 /* 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;
 
 
 Lisp_Object Qinit_pre_mswindows_win, Qinit_post_mswindows_win;
 
-struct font_enum_t
-{
-  HDC hdc;
-  struct device *d;
-};
-
 
 /************************************************************************/
 /*                               helpers                                */
 /************************************************************************/
 
 
 /************************************************************************/
 /*                               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)
 {
 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;
 {
   WNDCLASSEX wc;
   HDC hdc;
-  LOGFONT logfont;
-  struct font_enum_t font_enum;
 
   DEVICE_CLASS (d) = Qcolor;
   DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1;
 
   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_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);
 
   DeleteDC (hdc);
 
+  mswindows_enumerate_fonts (d);
+
   /* Register the main window class */
   wc.cbSize = sizeof (WNDCLASSEX);
   wc.style = CS_OWNDC; /* One DC per window */
   /* 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;
 
 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;
 
 /* 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);
 
   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)))
     {
 
   if (NILP (find_nonminibuffer_frame_not_on_device (dev)))
     {
@@ -903,31 +898,24 @@ x_IO_error_handler (Display *disp)
     {
       warn_when_safe
        (Qx, Qcritical,
     {
       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));
     }
 
         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);
   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, /*
 }
 
 DEFUN ("x-debug-mode", Fx_debug_mode, 1, 2, 0, /*
@@ -1734,14 +1722,6 @@ just reside in C.
 */ );
   Vx_initial_argv_list = Qnil;
 
 */ );
   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
 #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)
 {
 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);
 }
 
   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 "opaque.h"
 #include "sysfile.h"
 #include "sysdir.h"
+#include "systime.h"
+#include "syspwd.h"
 
 Lisp_Object Vcompletion_ignored_extensions;
 Lisp_Object Qdirectory_files;
 
 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);
 
   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;
 }
   free_cons (XCONS (locative));
   return Qnil;
 }
@@ -528,6 +531,252 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, int all_flag,
 }
 
 \f
 }
 
 \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)
 {
 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 (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);
 }
 
   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;
 `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 ();
 #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
 #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 ();
       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 ();
       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 ();
 
         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
       /* 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);
 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);
 #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;
      /* simple_p means don't try too hard (ASCII only) */
 {
   KeySym keysym = 0;
-
+  
 #ifdef HAVE_XIM
   int len;
   char buffer[64];
 #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);
          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 */
 
     }
 #endif /* ! XIM_MOTIF */
 
@@ -843,7 +847,8 @@ x_to_emacs_keysym (XKeyPressedEvent *event, int simple_p)
     {
     case XLookupKeySym:
     case XLookupBoth:
     {
     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:
       {
 
     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);
 
   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)
   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;
          {
            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);
 
            /* 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;
 
            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)
 {
 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.
    */
   /*
    * 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. */
   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));
 
   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)
     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;
 #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
 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);
   
   {
     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
        || 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;
        }
          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)
       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;
 
     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:
   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 ();
     {
       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);
 
       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
       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()) };
          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;
 
          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))
          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);
 
            }
          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)
          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);
   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;
 #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->read_only));
   ((markobj) (data->mouse_face));
   ((markobj) (data->initial_redisplay_function));
+  ((markobj) (data->before_change_functions));
+  ((markobj) (data->after_change_functions));
   return data->parent;
 }
 
   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, 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)
       || 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);
 }
 
                      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                               */
 \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);
     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: */
   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);
     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: */
   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);
 
     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);
 
   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.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
 }
 
 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 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.
                                              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
     /* --- 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 read_only;
   Lisp_Object mouse_face;
   Lisp_Object initial_redisplay_function;
+  Lisp_Object before_change_functions, after_change_functions;
   int priority;
 };
 
   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_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)
 
 #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)
 /* 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)
 
 #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);
                                    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);
 
 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);
 #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);
   }
 #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))
        {
       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);
        }
     }
          beg = res;
          p = beg + strlen ((char *) beg);
        }
     }
-  CORRECT_DIR_SEPS (beg);
 #endif /* WINDOWSNT */
   return make_string (beg, p - 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';
        }
     }
          out[size + 1] = '\0';
        }
     }
-#ifdef WINDOWSNT
-  CORRECT_DIR_SEPS (out);
-#endif
   return out;
 }
 
   return out;
 }
 
@@ -608,9 +608,6 @@ directory_file_name (CONST char *src, char *dst)
       )
     dst[slen - 1] = 0;
 #endif /* APOLLO */
       )
     dst[slen - 1] = 0;
 #endif /* APOLLO */
-#ifdef WINDOWSNT
-  CORRECT_DIR_SEPS (dst);
-#endif /* WINDOWSNT */
   return 1;
 }
 
   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));
 
   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)
   /* 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
 
 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.  */
 
 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"
 
 #include <config.h>
 #include "lisp.h"
@@ -31,169 +30,271 @@ Boston, MA 02111-1307, USA.  */
 #include "syspwd.h"
 #include "syssignal.h" /* for kill */
 
 #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;
 
 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
 
 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.
    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.
 
    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.
 
    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,
    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.  */
 
    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)
 {
 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. */
   /* 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;
 
   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.  */
 
   /* 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. */
 
   /* 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 */
     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) :
   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 */
     {
   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 */
       goto done;
     }
   /* User says ignore the lock */
@@ -251,197 +355,46 @@ lock_file (Lisp_Object fn)
   UNGCPRO;
 }
 
   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)
 {
 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);
 
 
   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 (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
 }
 
 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)));
     {
       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);
     }
        unlock_file (b->file_truename);
     }
-  UNGCPRO;
 }
 }
-
 \f
 \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.
 */
 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)
   if (BUF_SAVE_MODIFF (current_buffer) < BUF_MODIFF (current_buffer)
-      && !NILP (fn))
-    lock_file (fn);
+      && !NILP (file))
+    lock_file (file);
   return Qnil;
 }
 
   return Qnil;
 }
 
@@ -462,9 +415,9 @@ if it should normally be locked.
   return Qnil;
 }
 
   return Qnil;
 }
 
-\f
 /* Unlock the file visited in buffer BUFFER.  */
 
 /* Unlock the file visited in buffer BUFFER.  */
 
+
 void
 unlock_buffer (struct 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, /*
 }
 
 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.
 */
 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;
   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)
   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)
 {
 void
 syms_of_filelock (void)
 {
@@ -517,30 +475,5 @@ syms_of_filelock (void)
   defsymbol (&Qask_user_about_lock, "ask-user-about-lock");
 }
 
   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);
       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);
        {
          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);
     {
       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);
        {
          if (NILP (prev))
            list = XCDR (tail);
index 2fddbae..3c538f0 100644 (file)
@@ -2651,6 +2651,7 @@ x_delete_frame (struct frame *f)
   }
 #else
   XtDestroyWidget (w);
   }
 #else
   XtDestroyWidget (w);
+  XFlush (XtDisplay(w));   /* make sure the windows are really gone! */
 #endif /* EXTERNAL_WIDGET */
 
   if (FRAME_X_GEOM_FREE_ME_PLEASE (f))
 #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 "lstream.h"
 #include "console.h"
 #include "device.h"
+#include "faces.h"
 #include "glyphs.h"
 #include "objects.h"
 
 #include "glyphs.h"
 #include "objects.h"
 
@@ -516,7 +517,7 @@ jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
  *                               GIF                                  *
  **********************************************************************/
 
  *                               GIF                                  *
  **********************************************************************/
 
-#include <gifrlib.h>
+#include "gifrlib.h"
 
 static void
 gif_validate (Lisp_Object instantiator)
 
 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++)
       {
     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++)
          {
        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->instream)
     fclose (data->instream);
 
+  if (data->eimage) xfree(data->eimage);
+
   return Qnil;
 }
 
   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);
 
     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 */
     /* 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);
     /* 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);
     /* 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);
       }
 
          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);
     
     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))
     {
                   IMAGE_INSTANCE_PIXMAP_HEIGHT (ii), 
                   SRCCOPY))
     {
+      DeleteObject (newbmp);
+      DeleteDC (hdcDst);
       return 0;
     }
 
       return 0;
     }
 
@@ -553,6 +555,8 @@ mswindows_create_resized_mask (struct Lisp_Image_Instance* ii,
                      IMAGE_INSTANCE_PIXMAP_HEIGHT (ii), 
                      SRCCOPY))
        {
                      IMAGE_INSTANCE_PIXMAP_HEIGHT (ii), 
                      SRCCOPY))
        {
+         DeleteObject (newmask);
+         DeleteDC (hdcDst);
          return NULL;
        }
       
          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
    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?
 
    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
   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
 '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
    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
 '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;
       ++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;
   }
     }
     ++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;
   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);
 
   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, 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
   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;
 }
 #endif
   QUIT;
 }
@@ -1725,6 +1736,8 @@ gap_right (struct buffer *buf, Bytind pos)
   Bufbyte *to, *from;
   Bytecount i;
   Bytind new_s1;
   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);
 
   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);
 
   {
     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
     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))
 #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)
 {
 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;
   inside_change_hook = 0;
+  Fset_buffer (buffer);
   return Qnil;
 }
 
   return Qnil;
 }
 
@@ -2090,8 +2114,8 @@ static int in_first_change;
 static Lisp_Object
 first_change_hook_restore (Lisp_Object buffer)
 {
 static Lisp_Object
 first_change_hook_restore (Lisp_Object buffer)
 {
-  Fset_buffer (buffer);
   in_first_change = 0;
   in_first_change = 0;
+  Fset_buffer (buffer);
   return Qnil;
 }
 
   return Qnil;
 }
 
@@ -2106,8 +2130,7 @@ signal_first_change (struct buffer *buf)
 
   if (!in_first_change)
     {
 
   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);
        {
          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 */
 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)
     {
 
   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)
       /* 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))
 
       /* 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.  */
 
 
       /* 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;
     }
        }
 
       /* 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.
 }
 
 /* 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 */
                     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)
     {
 
   if (!inside_change_hook)
     {
+      Lisp_Object buffer;
+
       if (buf->text->changes->in_multiple_change &&
          buf->text->changes->mc_begin != 0)
        {
       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 */
        }
 
          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
 }
 
 /* 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. */
   /* 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;
 
   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 */
 
   /* 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
 
   Vdeactivate_mark = Qt;
 #endif
 
-  buf->point_before_scroll = Qnil;
+  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+    {
+      mbuf->point_before_scroll = Qnil;
+    }
 }
 
 \f
 }
 
 \f
@@ -2367,6 +2428,8 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
   Bytind ind;
   Charcount cclen;
   int move_point = 0;
   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. */
 
   /* 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");
 
   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));
   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);
 
 
   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;
 
   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_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);
 
   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
 
   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. */
 
   /* 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))
 
   /* 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)
     {
 
   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);
     }
 
   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 */
                             int flags)
 {
   /* This function can GC */
+#ifdef ERROR_CHECK_TYPECHECK
   assert (STRINGP (str));
   assert (STRINGP (str));
+#endif
   return buffer_insert_string_1 (buf, pos, 0, str, 0,
                                 XSTRING_LENGTH (str),
                                 flags);
   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 */
                          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);
   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];
 {
   /* 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);
 }
 
   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;
   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. */
 
   /* 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;
 
   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. */
   /* 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)
     {
       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);
     }
 
   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. */
 
     {
       /* 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;
 
       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.
 
 
       /* 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_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);
     }
       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);
 
       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;
 
       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.
 
       /* 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. */
         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. */
 
       /* 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_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);
       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
 #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);
 #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
 /* 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 */
                     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. */
 
   /* 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;
 
     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)
     {
   newlen = set_charptr_emchar (newstr, ch);
 
   if (curlen == newlen)
     {
+      struct buffer *mbuf;
+      Lisp_Object bufcons;
+
       /* then we can just replace the text. */
       /* 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 */
                                !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. */
        /* 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;
 
        /* 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)
        {
       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. */
 
       /* 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.
        */
        * 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 */
       /* 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. */
        /* 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;
       /*
        /* 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.
        */
        * 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);
     }
 }
                              newstr, Qnil, 0, newlen, 0);
     }
 }
@@ -3085,9 +3235,9 @@ vars_of_insdel (void)
 }
 
 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);
     {
       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 */
          }
       }
 #endif /* MULE */
+      b->text->line_number_cache = Qnil;
 
       BUF_MODIFF (b) = 1;
       BUF_SAVE_MODIFF (b) = 1;
 
       BUF_MODIFF (b) = 1;
       BUF_SAVE_MODIFF (b) = 1;
@@ -3145,9 +3296,9 @@ init_buffer_text (struct buffer *b, int indirect_p)
 }
 
 void
 }
 
 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);
     {
       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 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_ */
 
 #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.
 */ );
 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.
 */ );
 
   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.
 
   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_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):
 
 
 /* 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
 
    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)
 {
 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);
 }
 
   narrow_line_number_cache (b);
 }
 
@@ -103,7 +103,7 @@ allocate_line_number_cache (struct buffer *b)
 void
 narrow_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))
     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)
 {
 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
     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)
 {
 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)
     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 (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)
        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 (Fsymbol_name, 1);
 EXFUN (Fsymbol_plist, 1);
 EXFUN (Fsymbol_value, 1);
+EXFUN (Fsystem_name, 0);
 EXFUN (Fthrow, 2);
 EXFUN (Ftimes, MANY);
 EXFUN (Ftruncate, 1);
 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;
 
 /* 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;
 
 /* 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))
   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
       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 */
 
     }
 /*#endif / * DEBUG_XEMACS */
 
@@ -3153,12 +3151,6 @@ This is useful when the file being loaded is a temporary copy.
 */ );
   load_force_doc_strings = 0;
 
 */ );
   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' */
   /* 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))
   int repeat;
 
   if (NILP (con->defining_kbd_macro))
-    error ("Not defining kbd macro.");
+    error ("Not defining kbd macro");
 
   if (NILP (arg))
     repeat = -1;
 
   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))
 
   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);
 
   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 ();
   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
 }
 
 void
index bc47b7f..2075f92 100644 (file)
@@ -123,7 +123,7 @@ static HMENU top_level_menu;
  * "Left Flush\tRight Flush"
  */
 static char*
  * "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,
 {
   /* 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);
 
   /* 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;
 }
 
   return buf;
 }
@@ -223,7 +226,8 @@ checksum_menu_item (Lisp_Object item)
 
 static void
 populate_menu_add_item (HMENU menu, Lisp_Object path,
 
 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;
 
 {
   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;
       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))
       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.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
     {
 
       UNGCPRO; /* gui_item */
     }
   else
     {
-      signal_simple_error ("Mailformed menu item descriptor", item);
+      signal_simple_error ("Malformed menu item descriptor", item);
     }
 
   if (flush_right)
     }
 
   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,
        }
       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)));
       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 */
 
 }
 #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
 
 /* 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 */
 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));
   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;
   Lisp_Object frame;
-  int any_changes = 0;
   int count;
 
   /* set in lwlib to the time stamp associated with the most recent menu
   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);
     }
       replace_widget_value_tree (hack_wv, wv->contents);
       free_popup_widget_value_tree (wv);
     }
+  else if (!POPUP_DATAP (FRAME_MENUBAR_DATA (f)))
+    return;
   else
     {
   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. */
       /* #### - 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
       /* #### - 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)
         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);
        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;
       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 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 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 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;
 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_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 */
 #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,
            }
          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 */
        }
            }
 #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_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,
 #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 */
        }
 
 #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;
     }
 
   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 Â¤Ã€Â¤ÃƒÂ¤Â¿Â¤Ã©ÃˆÂ¾Â³Ã‘¥«¥¿¥«¥Ê¤â»È¤¨¤ë */
       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); /* Â¢Â¨Â£Â²: Â¥Ã­Â¡Â¼Â¥ÃžÂ»ÃºÂ¤ÃžÂ¤Ã‡ÃŠÃ–¤¹ */
        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 */
 
 
 /* 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
 #ifdef CANNA_MODE_AdjustBunsetsuMode
-static int Vcanna_mode_AdjustBunsetsuMode = CANNA_MODE_AdjustBunsetsuMode;
+static int canna_mode_AdjustBunsetsuMode;
 #endif
 #ifdef CANNA_MODE_ChikujiYomiMode
 #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
 
 #endif
 
-static int Vcanna_mode_HenkanMode = IROHA_MODE_HenkanMode;
+static int canna_mode_HenkanMode;
 #ifdef CANNA_MODE_HenkanNyuryokuMode
 #ifdef CANNA_MODE_HenkanNyuryokuMode
-static int Vcanna_mode_HenkanNyuryokuMode = CANNA_MODE_HenkanNyuryokuMode;
+static int canna_mode_HenkanNyuryokuMode;
 #endif
 #ifdef CANNA_MODE_ZenHiraHenkanMode
 #endif
 #ifdef CANNA_MODE_ZenHiraHenkanMode
-static int Vcanna_mode_ZenHiraHenkanMode = CANNA_MODE_ZenHiraHenkanMode;
+static int canna_mode_ZenHiraHenkanMode;
 #ifdef CANNA_MODE_HanHiraHenkanMode
 #ifdef CANNA_MODE_HanHiraHenkanMode
-static int Vcanna_mode_HanHiraHenkanMode = CANNA_MODE_HanHiraHenkanMode;
+static int canna_mode_HanHiraHenkanMode;
 #endif
 #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
 #endif
-static int Vcanna_mode_ZenHiraKakuteiMode = IROHA_MODE_ZenHiraKakuteiMode;
+static int canna_mode_ZenHiraKakuteiMode;
 #ifdef CANNA_MODE_HanHiraKakuteiMode
 #ifdef CANNA_MODE_HanHiraKakuteiMode
-static int Vcanna_mode_HanHiraKakuteiMode = CANNA_MODE_HanHiraKakuteiMode;
+static int canna_mode_HanHiraKakuteiMode;
 #endif
 #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
 #ifdef CANNA_FN_AdjustBunsetsu
-static int Vcanna_fn_AdjustBunsetsu = CANNA_FN_AdjustBunsetsu;
+static int canna_fn_AdjustBunsetsu;
 #endif
 #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
 #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
 #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
 #ifdef CANNA_FN_Mark
-static int Vcanna_fn_Mark = CANNA_FN_Mark;
+static int canna_fn_Mark;
 #endif
 #ifdef CANNA_FN_TemporalMode
 #endif
 #ifdef CANNA_FN_TemporalMode
-static int Vcanna_fn_TemporalMode = CANNA_FN_TemporalMode;
+static int canna_fn_TemporalMode;
 #endif
 
 #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 */
 
 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 /*
 
 */ );
   DEFVAR_LISP ("canna-kakutei-string", &Vcanna_kakutei_string /*
 
 */ );
+  Vcanna_kakutei_string = Qnil;
+
   DEFVAR_LISP ("canna-kakutei-yomi",   &Vcanna_kakutei_yomi /*
 
 */ );
   DEFVAR_LISP ("canna-kakutei-yomi",   &Vcanna_kakutei_yomi /*
 
 */ );
+  Vcanna_kakutei_yomi = Qnil;
+
   DEFVAR_LISP ("canna-kakutei-romaji", &Vcanna_kakutei_romaji /*
 
 */ );
   DEFVAR_LISP ("canna-kakutei-romaji", &Vcanna_kakutei_romaji /*
 
 */ );
+  Vcanna_kakutei_romaji = Qnil;
+
   DEFVAR_LISP ("canna-henkan-string",  &Vcanna_henkan_string /*
 
 */ );
   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_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 /*
 
 */ );
   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
 */ );
 For canna
 */ );
-  DEFVAR_BOOL ("canna-through-info", &Vcanna_through_info /*
+  canna_empty_info = 0;
+
+  DEFVAR_BOOL ("canna-through-info", &canna_through_info /*
 For canna
 */ );
 For canna
 */ );
-  DEFVAR_BOOL ("canna-underline", &Vcanna_underline /*
+  canna_through_info = 0;
+
+  DEFVAR_BOOL ("canna-underline", &canna_underline /*
 For canna
 */ );
 For canna
 */ );
-  DEFVAR_BOOL ("canna-inhibit-hankakukana", &Vcanna_inhibit_hankakukana /*
+  canna_underline = 0;
+
+  DEFVAR_BOOL ("canna-inhibit-hankakukana", &canna_inhibit_hankakukana /*
 For canna
 */ );
 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",
 #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
 #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",
   DEFVAR_INT ("canna-mode-chikuji-bunsetsu-mode",
-             &Vcanna_mode_ChikujiTanMode /*
+             &canna_mode_ChikujiTanMode /*
 
 */ );
 
 */ );
+  canna_mode_ChikujiTanMode = CANNA_MODE_ChikujiTanMode;
 #endif
 
 #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",
 #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",
 #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",
 #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",
 #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",
   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",
   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",
   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",
 #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",
 #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",
 #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",
   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",
   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",
   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",
   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",
   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",
   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",
   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",
   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",
   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",
   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
 #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
 #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
 #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",
   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",
   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",
   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",
   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",
   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",
   DEFVAR_INT ("canna-func-base-rotate-backward",
-             &Vcanna_fn_BaseRotateBackward  /*
+             &canna_fn_BaseRotateBackward  /*
 
 */ );
 
 */ );
+  canna_fn_BaseRotateBackward = CANNA_FN_BaseRotateBackward;
+
 #endif
 #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
 #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
 #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
 
 #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"));
 }
 
   Fprovide(intern("CANNA"));
 }
index f144b04..bbfefee 100644 (file)
@@ -132,6 +132,8 @@ new_child (void)
   xzero (*cp);
   cp->fd = -1;
   cp->pid = -1;
   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;
 
   cp->procinfo.hProcess = NULL;
   cp->status = STATUS_READ_ERROR;
 
@@ -234,10 +236,19 @@ reader_thread (void *arg)
   /* Our identity */
   cp = (child_process *)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)
   if (cp == NULL ||
       WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
-    return 1;
+  */
+
+  if (cp == NULL)
+  {
+      return 1;
+  }
 
   for (;;)
     {
 
   for (;;)
     {
@@ -255,7 +266,28 @@ reader_thread (void *arg)
        }
 
       if (rc == STATUS_READ_ERROR)
        }
 
       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)
         
       /* 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;
         }
     }
          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;
 }
 
   return 0;
 }
 
@@ -325,6 +377,11 @@ create_child (char *exe, char *cmdline, char *env,
 
   cp->pid = (int) cp->procinfo.dwProcessId;
 
 
   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;
   /* 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
 
 #ifdef __CYGWIN32__
 #define stricmp strcasecmp
+#define FONTENUMPROC FONTENUMEXPROC
+#define ntmTm ntmentm
 #endif
 
 typedef struct colormap_t 
 {
 #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" */
 } 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) }
 };
 
   {"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                                */
 \f
 /************************************************************************/
 /*                               helpers                                */
@@ -872,6 +926,120 @@ match_font (char *pattern1, char *pattern2, char *fontname)
   return 1;
 }
 
   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                                */
 \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;
 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;
   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:
 
   /*
    * 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
   /* 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 */
 
    * 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);
   }
 
     return (0);
   }
 
@@ -1019,13 +1191,13 @@ mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object na
   }
   else
   {
   }
   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)
     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, ' ')))
 
   /* 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;
 
   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? */
   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
       {
        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);
       }
 
        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)
     {
     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 */
       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 */
   logfont.lfWidth = 0;
 
   /* Effects */
@@ -1119,8 +1280,7 @@ mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object na
        logfont.lfStrikeOut = TRUE;
       else
         {
        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);
        }
 
          return (0);
        }
 
@@ -1132,7 +1292,7 @@ mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object na
            logfont.lfStrikeOut = TRUE;
          else
            {
            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);
            }
                                         Qfont, errb);
              return (0);
            }
@@ -1152,63 +1312,50 @@ mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object na
   else
     effects[0] = '\0';
 
   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 */
   /* 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;
     }
 
       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
 
   /* 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];
   {
     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)
       {
       }
     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;
       }
   }
 
        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)
   {
   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;
   }
 
     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;
 }
 
   return 0;
 }
 
index 4435a25..dfe155d 100644 (file)
@@ -39,6 +39,9 @@ Boston, MA 02111-1307, USA.  */
 #include <winsock.h>
 #endif
 
 #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;
 
 /* 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
 
 /*
  * 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
  * 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,
  */
 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;
                      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;
   /* 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
  * 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;
 }
 
   return 1;
 }
 
-/* Watermark in code space */
-static void
-sigkill_code_end (void)
-{
-}
-
 /*
  * Sending break or control c
  */
 /*
  * Sending break or control c
  */
@@ -261,12 +263,6 @@ sigint_proc (sigint_data* data)
   return (*data->adr_GenerateConsoleCtrlEvent) (data->event, 0);
 }
 
   return (*data->adr_GenerateConsoleCtrlEvent) (data->event, 0);
 }
 
-/* Watermark in code space */
-static void
-sigint_code_end (void)
-{
-}
-
 /*
  * Enabling signals
  */
 /*
  * Enabling signals
  */
@@ -282,12 +278,6 @@ sig_enable_proc (sig_enable_data* data)
   return 1;
 }
 
   return 1;
 }
 
-/* Watermark in code space */
-static void
-sig_enable_code_end (void)
-{
-}
-
 /*
  * Send signal SIGNO to process H_PROCESS.
  * Return nonzero if successful.
 /*
  * 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);
        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;
       }
                                       &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;
          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;
       }
                                       &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);
   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));
 }
   
                        &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);
            }
 
              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
            /* 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);
            signal (SIGHUP, SIG_DFL);
-# endif /* AIX */
          }
 #endif /* HAVE_PTYS */
 
          }
 #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.  */
 \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. */
 
 
 /* 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;
     }
 
       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)
        {
     {
       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);
       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);
       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
          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)
     {
       /* 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 = 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
 
           /* 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>
 /* 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
 #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*);
 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;
 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();
 
 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
 #endif
 
 #ifdef HAVE_MS_WINDOWS
@@ -117,12 +131,10 @@ extern long random();
 #define LIBS_SYSTEM -lwinmm
 
 #define ICC_BAR_CLASSES 4
 #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 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
 #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 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
 
 #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
 
 #define regoff_t sys_regoff_t
 #define regmatch_t sys_regmatch_t
 
+/* A perfectly ordinary link wins again - martin */
 #undef C_SWITCH_SYSTEM
 #undef C_SWITCH_SYSTEM
-#define C_SWITCH_SYSTEM "-D_BSD"
+#undef LIBS_SYSTEM
+#undef LIBS_DEBUG
+#define ORDINARY_LINK
 
 #define SYSTEM_MALLOC
 
 
 #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
 /* 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"
 
 
 #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"
 #ifndef NO_SHARED_LIBS
 #if 0 /* mrb */
 #define LIB_GCC "-lgcc"
@@ -79,6 +93,8 @@
 #endif /* __FreeBSD__ */
 #endif /* NO_SHARED_LIBS */
 
 #endif /* __FreeBSD__ */
 #endif /* NO_SHARED_LIBS */
 
+#endif /* not __ELF__ */
+
 #define HAVE_GETLOADAVG
 /* #define NO_TERMIO */ /* detected in configure */
 #define DECLARE_GETPWUID_WITH_UID_T
 #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 (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);
     {
       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
 #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;
 {
   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;
   struct stat stat;
   long pagesize, brk;
   long newsyms, symrel;
-  int nread;
   int i;
   long vaddr, scnptr;
 #define BUFSIZE 8192
   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;
 {
   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
 
       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));
     }
 
          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. */
   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;
   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);
                         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);
   w->force_start = 0;           /* Lucid fix */
   SET_LAST_MODIFIED (w, 1);
   SET_LAST_FACECHANGE (w);