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