X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Fevent-stream.c;h=de65d4e77b67f294825774fdf5838c39096c9e96;hp=0d090517699c33f5bd0ba86e5d33a9da97aff565;hb=7b241b273a632ab80d7c620b5add28d5f11b0fd3;hpb=59eec5f21669e81977b5b1fe9bf717cab49cf7fb diff --git a/src/event-stream.c b/src/event-stream.c index 0d09051..de65d4e 100644 --- a/src/event-stream.c +++ b/src/event-stream.c @@ -52,8 +52,6 @@ Boston, MA 02111-1307, USA. */ /* TODO: This stuff is way too hard to maintain - needs rework. - C-x @ h x causes a crash. - The command builder should deal only with key and button events. Other command events should be able to come in the MIDDLE of a key sequence, without disturbing the key sequence composition, or the @@ -102,7 +100,7 @@ Boston, MA 02111-1307, USA. */ #include /* The number of keystrokes between auto-saves. */ -static int auto_save_interval; +static Fixnum auto_save_interval; Lisp_Object Qundefined_keystroke_sequence; @@ -121,23 +119,19 @@ Lisp_Object Qpre_idle_hook, Vpre_idle_hook; /* Control gratuitous keyboard focus throwing. */ int focus_follows_mouse; +/* When true, modifier keys are sticky. */ int modifier_keys_are_sticky; +/* Modifier keys are sticky for this many milliseconds. */ +Lisp_Object Vmodifier_keys_sticky_time; -#if 0 /* FSF Emacs crap */ -/* Hook run after a command if there's no more input soon. */ -Lisp_Object Qpost_command_idle_hook, Vpost_command_idle_hook; - -/* Delay time in microseconds before running post-command-idle-hook. */ -int post_command_idle_delay; +/* Here FSF Emacs 20.7 defines Vpost_command_idle_hook, + post_command_idle_delay, Vdeferred_action_list, and + Vdeferred_action_function, but we don't because that stuff is crap, + and we're smarter than them, and their momas are fat. */ -/* List of deferred actions to be performed at a later time. - The precise format isn't relevant here; we just check whether it is nil. */ -Lisp_Object Vdeferred_action_list; - -/* Function to call to handle deferred actions, when there are any. */ -Lisp_Object Vdeferred_action_function; -Lisp_Object Qdeferred_action_function; -#endif /* FSF Emacs crap */ +/* FSF Emacs 20.7 also defines Vinput_method_function, + Qinput_method_exit_on_first_char and Qinput_method_use_echo_area. + I don't know this should be imported or not. */ /* Non-nil disable property on a command means do not execute it; call disabled-command-hook's value instead. */ @@ -256,7 +250,7 @@ Lisp_Object Qself_insert_defer_undo; extern Lisp_Object Fmake_keymap (Lisp_Object name); #ifdef DEBUG_XEMACS -int debug_emacs_events; +Fixnum debug_emacs_events; static void external_debugging_print_event (char *event_description, Lisp_Object event) @@ -429,7 +423,7 @@ check_event_stream_ok (enum event_stream_operation op) case EVENT_STREAM_READ: error ("Can't read events in -batch mode"); default: - abort (); + ABORT (); } } else if (!event_stream) @@ -502,15 +496,7 @@ event_stream_next_event (Lisp_Event *event) Let's hope it doesn't. I think the code here is fairly clean and doesn't do this. */ emacs_is_blocking = 1; -#if 0 - /* Do this if the poll-for-quit timer seems to be taking too - much CPU time when idle ... */ - reset_poll_for_quit (); -#endif event_stream->next_event_cb (event); -#if 0 - init_poll_for_quit (); -#endif emacs_is_blocking = 0; #ifdef DEBUG_XEMACS @@ -715,7 +701,8 @@ reset_key_echo (struct command_builder *command_builder, /* This function can GC */ struct frame *f = selected_frame (); - command_builder->echo_buf_index = -1; + if (command_builder) + command_builder->echo_buf_index = -1; if (remove_echo_area_echo) clear_echo_area (f, Qcommand, 0); @@ -759,7 +746,7 @@ maybe_kbd_translate (Lisp_Object event) This way is safer. */ zero_event (&ev2); character_to_event (XCHAR (traduit), &ev2, - XCONSOLE (EVENT_CHANNEL (XEVENT (event))), 1, 1); + XCONSOLE (EVENT_CHANNEL (XEVENT (event))), 0, 1); XEVENT (event)->event.key.keysym = ev2.event.key.keysym; XEVENT (event)->event.key.modifiers = ev2.event.key.modifiers; did_translate = 1; @@ -781,7 +768,7 @@ maybe_kbd_translate (Lisp_Object event) zero_event (&ev2); character_to_event (XCHAR (traduit), &ev2, - XCONSOLE (EVENT_CHANNEL (XEVENT (event))), 1, 1); + XCONSOLE (EVENT_CHANNEL (XEVENT (event))), 0, 1); XEVENT (event)->event.key.keysym = ev2.event.key.keysym; XEVENT (event)->event.key.modifiers |= ev2.event.key.modifiers; did_translate = 1; @@ -798,7 +785,8 @@ maybe_kbd_translate (Lisp_Object event) keystrokes_since_auto_save is equivalent to the difference between num_nonmacro_input_chars and last_auto_save. */ -/* When an auto-save happens, record the "time", and don't do again soon. */ +/* When an auto-save happens, record the number of keystrokes, and + don't do again soon. */ void record_auto_save (void) @@ -812,10 +800,6 @@ void force_auto_save_soon (void) { keystrokes_since_auto_save = 1 + max (auto_save_interval, 20); - -#if 0 /* FSFmacs */ - record_asynch_buffer_change (); -#endif } static void @@ -1403,7 +1387,7 @@ is a race condition. That's why the RESIGNAL argument exists. Lisp_Object lid; id = event_stream_generate_wakeup (msecs, msecs2, function, object, 0); lid = make_int (id); - if (id != XINT (lid)) abort (); + if (id != XINT (lid)) ABORT (); return lid; } @@ -1482,7 +1466,7 @@ is a race condition. That's why the RESIGNAL argument exists. Lisp_Object lid; id = event_stream_generate_wakeup (msecs, msecs2, function, object, 1); lid = make_int (id); - if (id != XINT (lid)) abort (); + if (id != XINT (lid)) ABORT (); return lid; } @@ -1695,19 +1679,6 @@ run_select_frame_hook (void) static void run_deselect_frame_hook (void) { -#if 0 /* unclean! FSF calls this at all sorts of random places, - including a bunch of places in their mouse.el. If this - is implemented, it has to be done cleanly. */ - run_hook (Qmouse_leave_buffer_hook); /* #### Correct? It's also - called in `call-interactively'. - Does this mean it will be - called twice? Oh well, FSF - bug -- FSF calls it in - `handle-switch-frame', - which is approximately the - same as the caller of this - function. */ -#endif run_hook (Qdeselect_frame_hook); } @@ -1837,7 +1808,8 @@ emacs_handle_focus_change_preliminary (Lisp_Object frame_inp_and_dev) MARK_WINDOWS_CHANGED (w); } - if (FRAMEP (focus_frame) && !EQ (frame, focus_frame)) + if (FRAMEP (focus_frame) && FRAME_LIVE_P (XFRAME (focus_frame)) + && !EQ (frame, focus_frame)) { /* Oops, we missed a focus-out event. */ DEVICE_FRAME_WITH_FOCUS_REAL (d) = Qnil; @@ -2039,6 +2011,7 @@ static void push_this_command_keys (Lisp_Object event); static void push_recent_keys (Lisp_Object event); static void dribble_out_event (Lisp_Object event); static void execute_internal_event (Lisp_Object event); +static int is_scrollbar_event (Lisp_Object event); DEFUN ("next-event", Fnext_event, 0, 2, 0, /* Return the next available event. @@ -2231,8 +2204,6 @@ The returned event will be one of the following types: switch (XEVENT_TYPE (event)) { - default: - goto RETURN; case button_release_event: case misc_user_event: /* don't echo menu accelerator keys */ @@ -2242,6 +2213,8 @@ The returned event will be one of the following types: goto STORE_AND_EXECUTE_KEY; case key_press_event: /* any key input can trigger autosave */ break; + default: + goto RETURN; } maybe_do_auto_save (); @@ -2299,7 +2272,9 @@ The returned event will be one of the following types: */ if (store_this_key) { - push_this_command_keys (event); + if (!is_scrollbar_event (event)) /* #### not quite right, see + comment in execute_command_event */ + push_this_command_keys (event); if (!inhibit_input_event_recording) push_recent_keys (event); dribble_out_event (event); @@ -2491,7 +2466,7 @@ A user event is a key press, button press, button release, or } if (!NILP (command_event_queue) || !NILP (command_event_queue_tail)) - abort (); + ABORT (); /* Now tack our chain of events back on to the front of the queue. Actually, since the queue is now drained, we can just replace it. @@ -2684,11 +2659,11 @@ Return non-nil iff we received any output before the timeout expired. } DEFUN ("sleep-for", Fsleep_for, 1, 1, 0, /* -Pause, without updating display, for ARG seconds. -ARG may be a float, meaning pause for some fractional part of a second. +Pause, without updating display, for SECONDS seconds. +SECONDS may be a float, allowing pauses for fractional parts of a second. It is recommended that you never call sleep-for from inside of a process - filter function or timer event (either synchronous or asynchronous). +filter function or timer event (either synchronous or asynchronous). */ (seconds)) { @@ -2751,9 +2726,9 @@ It is recommended that you never call sleep-for from inside of a process } DEFUN ("sit-for", Fsit_for, 1, 2, 0, /* -Perform redisplay, then wait ARG seconds or until user input is available. -ARG may be a float, meaning a fractional part of a second. -Optional second arg non-nil means don't redisplay, just wait for input. +Perform redisplay, then wait SECONDS seconds or until user input is available. +SECONDS may be a float, meaning a fractional part of a second. +Optional second arg NODISPLAY non-nil means don't redisplay; just wait. Redisplay is preempted as always if user input arrives, and does not happen if input is available before it starts. Value is t if waited the full time with no input arriving. @@ -3066,7 +3041,7 @@ execute_internal_event (Lisp_Object event) return; } default: - abort (); + ABORT (); } } @@ -3402,7 +3377,7 @@ modify them. { Vrecent_keys_ring = make_vector (recent_keys_ring_size, Qnil); /* And return nothing in particular. */ - return make_vector (0, Qnil); + RETURN_UNGCPRO (make_vector (0, Qnil)); } if (NILP (XVECTOR_DATA (Vrecent_keys_ring)[recent_keys_ring_index])) @@ -3434,7 +3409,7 @@ modify them. Lisp_Object e = XVECTOR_DATA (Vrecent_keys_ring)[j]; if (NILP (e)) - abort (); + ABORT (); XVECTOR_DATA (val)[i] = Fcopy_event (e, Qnil); if (++j >= recent_keys_ring_size) j = 0; @@ -3460,7 +3435,6 @@ Set the maximum number of events to be stored internally. Lisp_Object new_vector = Qnil; int i, j, nkeys, start, min; struct gcpro gcpro1; - GCPRO1 (new_vector); CHECK_INT (size); if (XINT (size) <= 0) @@ -3468,12 +3442,13 @@ Set the maximum number of events to be stored internally. if (XINT (size) == recent_keys_ring_size) return size; + GCPRO1 (new_vector); new_vector = make_vector (XINT (size), Qnil); if (NILP (Vrecent_keys_ring)) { Vrecent_keys_ring = new_vector; - return size; + RETURN_UNGCPRO (size); } if (NILP (XVECTOR_DATA (Vrecent_keys_ring)[recent_keys_ring_index])) @@ -3530,16 +3505,24 @@ Set the maximum number of events to be stored internally. void reset_this_command_keys (Lisp_Object console, int clear_echo_area_p) { - struct command_builder *command_builder = - XCOMMAND_BUILDER (XCONSOLE (console)->command_builder); - - reset_key_echo (command_builder, clear_echo_area_p); + if (!NILP (console)) + { + /* console is nil if we just deleted the console as a result of C-x 5 + 0. Unfortunately things are currently in a messy situation where + some stuff is console-local and other stuff isn't, so we need to + do everything that's not console-local. */ + struct command_builder *command_builder = + XCOMMAND_BUILDER (XCONSOLE (console)->command_builder); + + reset_key_echo (command_builder, clear_echo_area_p); + reset_current_events (command_builder); + } + else + reset_key_echo (0, clear_echo_area_p); deallocate_event_chain (Vthis_command_keys); Vthis_command_keys = Qnil; Vthis_command_keys_tail = Qnil; - - reset_current_events (command_builder); } static void @@ -3570,7 +3553,7 @@ extract_this_command_keys_nth_mouse_event (int n) { if (!n) { - /* must copy to avoid an abort() in next_event_internal() */ + /* must copy to avoid an ABORT() in next_event_internal() */ if (!NILP (XEVENT_NEXT (event))) return Fcopy_event (event, Qnil); else @@ -3701,7 +3684,7 @@ lookup_command_event (struct command_builder *command_builder, || e->event_type == button_release_event) e->event.button.modifiers |= XEMACS_MOD_META; else - abort (); + ABORT (); { int tckn = event_chain_count (Vthis_command_keys); @@ -3786,6 +3769,35 @@ lookup_command_event (struct command_builder *command_builder, } } +static int +is_scrollbar_event (Lisp_Object event) +{ +#ifdef HAVE_SCROLLBARS + Lisp_Object fun; + + if (XEVENT (event)->event_type != misc_user_event) + return 0; + fun = XEVENT (event)->event.misc.function; + + return (EQ (fun, Qscrollbar_line_up) || + EQ (fun, Qscrollbar_line_down) || + EQ (fun, Qscrollbar_page_up) || + EQ (fun, Qscrollbar_page_down) || + EQ (fun, Qscrollbar_to_top) || + EQ (fun, Qscrollbar_to_bottom) || + EQ (fun, Qscrollbar_vertical_drag) || + EQ (fun, Qscrollbar_char_left) || + EQ (fun, Qscrollbar_char_right) || + EQ (fun, Qscrollbar_page_left) || + EQ (fun, Qscrollbar_page_right) || + EQ (fun, Qscrollbar_to_left) || + EQ (fun, Qscrollbar_to_right) || + EQ (fun, Qscrollbar_horizontal_drag)); +#else + return 0; +#endif /* HAVE_SCROLLBARS */ +} + static void execute_command_event (struct command_builder *command_builder, Lisp_Object event) @@ -3795,7 +3807,59 @@ execute_command_event (struct command_builder *command_builder, struct gcpro gcpro1; GCPRO1 (event); /* event may be freshly created */ - reset_current_events (command_builder); + + /* #### This call to is_scrollbar_event() isn't quite right, but + fixing properly it requires more work than can go into 21.4. + (We really need to split out menu, scrollbar, dialog, and other + types of events from misc-user, and put the remaining ones in a + new `user-eval' type that behaves like an eval event but is a + user event and thus has all of its semantics -- e.g. being + delayed during `accept-process-output' and similar wait states.) + + The real issue here is that "user events" and "command events" + are not the same thing, but are very much confused in + event-stream.c. User events are, essentially, any event that + should be delayed by accept-process-output, should terminate a + sit-for, etc. -- basically, any event that needs to be processed + synchronously with key and mouse events. Command events are + those that participate in command building; scrollbar events + clearly don't belong because they should be transparent in a + sequence like C-x @ h x, which used to cause a + crash before checks similar to the is_scrollbar_event() call were + added. Do other events belong with scrollbar events? I'm not + sure; we need to categorize all misc-user events and see what + their semantics are. + + (You might ask, why do scrollbar events need to be user events? + That's a good question. The answer seems to be that they can + change point, and having this happen asynchronously would be a + very bad idea. According to the "proper" functioning of + scrollbars, this should not happen, but XEmacs does not allow + point to go outside of the window.) + + Scrollbar events and similar non-command events should obviously + not be recorded in this-command-keys, so we need to check for + this in next-event. + + #### We call reset_current_events() twice in this function -- + #### here, and later as a result of reset_this_command_keys(). + #### This is almost certainly wrong; need to figure out what's + #### correct. + + #### We need to figure out what's really correct w.r.t. scrollbar + #### events. With these new fixes in, it actually works to do + #### C-x 5 2, but the key echo gets messed up + #### (starts over at 5). We really need to be special-casing + #### scrollbar events at a lower level, and not really passing + #### them through the command builder at all. (e.g. do scrollbar + #### events belong in macros??? doubtful; probably only the + #### point movement, if any, belongs, special-cased as a + #### pseudo-issued M-x goto-char command). #### Need more work + #### here. Do this when separating out scrollbar events. + */ + + if (!is_scrollbar_event (event)) + reset_current_events (command_builder); switch (XEVENT (event)->event_type) { @@ -3862,17 +3926,16 @@ execute_command_event (struct command_builder *command_builder, post_command_hook (); -#if 0 /* #### here was an attempted fix that didn't work */ - if (XEVENT (event)->event_type == misc_user_event) - ; - else -#endif - if (!NILP (con->prefix_arg)) + /* Console might have been deleted by command */ + if (CONSOLE_LIVE_P (con) && !NILP (con->prefix_arg)) { /* Commands that set the prefix arg don't update last-command, don't reset the echoing state, and don't go into keyboard macros unless - followed by another command. */ + followed by another command. Also don't quit here. */ + int speccount = specpdl_depth (); + specbind (Qinhibit_quit, Qt); maybe_echo_keys (command_builder, 0); + unbind_to (speccount, Qnil); /* If we're recording a keyboard macro, and the last command executed set a prefix argument, then decrement the pointer to @@ -3891,7 +3954,10 @@ execute_command_event (struct command_builder *command_builder, /* Emacs 18 doesn't unconditionally clear the echoed keystrokes, so we don't either */ - reset_this_command_keys (make_console (con), 0); + + if (!is_scrollbar_event (event)) + reset_this_command_keys (CONSOLE_LIVE_P (con) ? make_console (con) + : Qnil, 0); } } @@ -3955,34 +4021,6 @@ post_command_hook (void) ("Error in `post-command-hook' (setting hook to nil)", Qpost_command_hook, 1); -#if 0 /* FSF Emacs crap */ - if (!NILP (Vdeferred_action_list)) - call0 (Vdeferred_action_function); - - if (NILP (Vunread_command_events) - && NILP (Vexecuting_macro) - && !NILP (Vpost_command_idle_hook) - && !NILP (Fsit_for (make_float ((double) post_command_idle_delay - / 1000000), Qnil))) - safe_run_hook_trapping_errors - ("Error in `post-command-idle-hook' (setting hook to nil)", - Qpost_command_idle_hook, 1); -#endif /* FSF Emacs crap */ - -#if 0 /* FSF Emacs */ - if (!NILP (current_buffer->mark_active)) - { - if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode)) - { - current_buffer->mark_active = Qnil; - run_hook (intern ("deactivate-mark-hook")); - } - else if (current_buffer != prev_buffer || - BUF_MODIFF (current_buffer) != prev_modiff) - run_hook (intern ("activate-mark-hook")); - } -#endif /* FSF Emacs */ - /* #### Kludge!!! This is necessary to make sure that things are properly positioned even if post-command-hook moves point. #### There should be a cleaner way of handling this. */ @@ -3991,7 +4029,7 @@ post_command_hook (void) DEFUN ("dispatch-event", Fdispatch_event, 1, 1, 0, /* -Given an event object as returned by `next-event', execute it. +Given an event object EVENT as returned by `next-event', execute it. Key-press, button-press, and button-release events get accumulated until a complete key sequence (see `read-key-sequence') is reached, @@ -4161,13 +4199,6 @@ Magic events are handled as necessary. command_builder->self_insert_countdown = 0; if (NILP (XCONSOLE (console)->prefix_arg) && NILP (Vexecuting_macro) -#if 0 - /* This was done in the days when there was no undo - in the minibuffer. If we don't disable this code, - then each instance of "undo" undoes everything in - the minibuffer. */ - && !EQ (minibuf_window, Fselected_window (Qnil)) -#endif && command_builder->self_insert_countdown == 0) Fundo_boundary (); @@ -4178,13 +4209,13 @@ Magic events are handled as necessary. } execute_command_event (command_builder, - internal_equal (event, command_builder-> most_current_event, 0) + internal_equal (event, command_builder->most_current_event, 0) ? event /* Use the translated event that was most recently seen. This way, last-command-event becomes f1 instead of the P from ESC O P. But we must copy it, else we'll lose when the command-builder events are deallocated. */ - : Fcopy_event (command_builder-> most_current_event, Qnil)); + : Fcopy_event (command_builder->most_current_event, Qnil)); } break; } @@ -4239,7 +4270,7 @@ Magic events are handled as necessary. DEFUN ("read-key-sequence", Fread_key_sequence, 1, 3, 0, /* Read a sequence of keystrokes or mouse clicks. Returns a vector of the event objects read. The vector and the event -objects it contains are freshly created (and will not be side-effected +objects it contains are freshly created (and so will not be side-effected by subsequent calls to this function). The sequence read is sufficient to specify a non-prefix command starting @@ -4247,19 +4278,17 @@ from the current local and global keymaps. A C-g typed while in this function is treated like any other character, and `quit-flag' is not set. First arg PROMPT is a prompt string. If nil, do not prompt specially. -Second (optional) arg CONTINUE-ECHO, if non-nil, means this key echoes -as a continuation of the previous key. -The third (optional) arg DONT-DOWNCASE-LAST, if non-nil, means do not -convert the last event to lower case. (Normally any upper case event -is converted to lower case if the original event is undefined and the lower -case equivalent is defined.) This argument is provided mostly for -FSF compatibility; the equivalent effect can be achieved more generally -by binding `retry-undefined-key-binding-unshifted' to nil around the -call to `read-key-sequence'. +Second optional arg CONTINUE-ECHO non-nil means this key echoes as a +continuation of the previous key. -A C-g typed while in this function is treated like any other character, -and `quit-flag' is not set. +Third optional arg DONT-DOWNCASE-LAST non-nil means do not convert the +last event to lower case. (Normally any upper case event is converted +to lower case if the original event is undefined and the lower case +equivalent is defined.) This argument is provided mostly for FSF +compatibility; the equivalent effect can be achieved more generally by +binding `retry-undefined-key-binding-unshifted' to nil around the call +to `read-key-sequence'. If the user selects a menu item while we are prompting for a key-sequence, the returned value will be a vector of a single menu-selection event. @@ -4267,8 +4296,8 @@ An error will be signalled if you pass this value to `lookup-key' or a related function. `read-key-sequence' checks `function-key-map' for function key -sequences, where they wouldn't conflict with ordinary bindings. See -`function-key-map' for more details. +sequences, where they wouldn't conflict with ordinary bindings. +See `function-key-map' for more details. */ (prompt, continue_echo, dont_downcase_last)) { @@ -4285,6 +4314,7 @@ sequences, where they wouldn't conflict with ordinary bindings. See struct gcpro gcpro1; GCPRO1 (event); + record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); if (!NILP (prompt)) CHECK_STRING (prompt); /* else prompt = Fkeymap_prompt (current_buffer->keymap); may GC */ @@ -4404,10 +4434,10 @@ dribble_out_event (Lisp_Object event) DEFUN ("open-dribble-file", Fopen_dribble_file, 1, 1, "FOpen dribble file: ", /* -Start writing all keyboard characters to a dribble file called FILE. -If FILE is nil, close any open dribble file. +Start writing all keyboard characters to a dribble file called FILENAME. +If FILENAME is nil, close any open dribble file. */ - (file)) + (filename)) { /* This function can GC */ /* XEmacs change: always close existing dribble file. */ @@ -4417,12 +4447,12 @@ If FILE is nil, close any open dribble file. Lstream_close (XLSTREAM (Vdribble_file)); Vdribble_file = Qnil; } - if (!NILP (file)) + if (!NILP (filename)) { int fd; - file = Fexpand_file_name (file, Qnil); - fd = open ((char*) XSTRING_DATA (file), + filename = Fexpand_file_name (filename, Qnil); + fd = open ((char*) XSTRING_DATA (filename), O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY, CREAT_MODE); if (fd < 0) @@ -4451,7 +4481,7 @@ CONSOLE defaults to the selected console if omitted. /* This junk is so that timestamps don't get to be negative, but contain as many bits as this particular emacs will allow. */ - return make_int (((1L << (VALBITS - 1)) - 1) & tiempo); + return make_int (EMACS_INT_MAX & tiempo); } @@ -4500,10 +4530,6 @@ syms_of_event_stream (void) defsymbol (&Qpre_idle_hook, "pre-idle-hook"); defsymbol (&Qhandle_pre_motion_command, "handle-pre-motion-command"); defsymbol (&Qhandle_post_motion_command, "handle-post-motion-command"); -#if 0 /* FSF Emacs crap */ - defsymbol (&Qpost_command_idle_hook, "post-command-idle-hook"); - defsymbol (&Qdeferred_action_function, "deferred-action-function"); -#endif defsymbol (&Qretry_undefined_key_binding_unshifted, "retry-undefined-key-binding-unshifted"); defsymbol (&Qauto_show_make_point_visible, @@ -4538,12 +4564,12 @@ vars_of_event_stream (void) Vthis_command_keys = Qnil; staticpro (&Vthis_command_keys); Vthis_command_keys_tail = Qnil; - pdump_wire (&Vthis_command_keys_tail); + dump_add_root_object (&Vthis_command_keys_tail); command_event_queue = Qnil; staticpro (&command_event_queue); command_event_queue_tail = Qnil; - pdump_wire (&command_event_queue_tail); + dump_add_root_object (&command_event_queue_tail); Vlast_selected_frame = Qnil; staticpro (&Vlast_selected_frame); @@ -4602,41 +4628,6 @@ used by the window manager, so it is up to the user to set it. */ ); focus_follows_mouse = 0; -#if 0 /* FSF Emacs crap */ - /* Ill-conceived because it's not run in all sorts of cases - where XEmacs is blocking. That's what `pre-idle-hook' - is designed to solve. */ - xxDEFVAR_LISP ("post-command-idle-hook", &Vpost_command_idle_hook /* -Normal hook run after each command is executed, if idle. -`post-command-idle-delay' specifies a time in microseconds that XEmacs -must be idle for in order for the functions on this hook to be called. -Errors running the hook are caught and ignored. -*/ ); - Vpost_command_idle_hook = Qnil; - - xxDEFVAR_INT ("post-command-idle-delay", &post_command_idle_delay /* -Delay time before running `post-command-idle-hook'. -This is measured in microseconds. -*/ ); - post_command_idle_delay = 5000; - - /* Random FSFmacs crap. There is absolutely nothing to gain, - and a great deal to lose, in using this in place of just - setting `post-command-hook'. */ - xxDEFVAR_LISP ("deferred-action-list", &Vdeferred_action_list /* -List of deferred actions to be performed at a later time. -The precise format isn't relevant here; we just check whether it is nil. -*/ ); - Vdeferred_action_list = Qnil; - - xxDEFVAR_LISP ("deferred-action-function", &Vdeferred_action_function /* -Function to call to handle deferred actions, after each command. -This function is called with no arguments after each command -whenever `deferred-action-list' is non-nil. -*/ ); - Vdeferred_action_function = Qnil; -#endif /* FSF Emacs crap */ - DEFVAR_LISP ("last-command-event", &Vlast_command_event /* Last keyboard or mouse button event that was part of a command. This variable is off limits: you may not set its value or modify the event that @@ -4815,9 +4806,22 @@ This means that you can release the modifier key before pressing down the key that you wish to be modified. Although this is non-standard behavior, it is recommended because it reduces the strain on your hand, thus reducing the incidence of the dreaded Emacs-pinky syndrome. + +Modifier keys are sticky within the inverval specified by +`modifier-keys-sticky-time'. */ ); modifier_keys_are_sticky = 0; + DEFVAR_LISP ("modifier-keys-sticky-time", &Vmodifier_keys_sticky_time /* +*Modifier keys are sticky within this many milliseconds. +If you don't want modifier keys sticking to be bounded, set this to +non-integer value. + +This variable has no effect when `modifier-keys-are-sticky' is nil. +Currently only implemented under X Window System. +*/ ); + Vmodifier_keys_sticky_time = make_int (500); + #ifdef HAVE_XIM DEFVAR_LISP ("composed-character-default-binding", &Vcomposed_character_default_binding /* @@ -4900,6 +4904,11 @@ init_event_stream (void) init_event_Xt_late (); else #endif +#ifdef HAVE_GTK + if (!strcmp (display_use, "gtk")) + init_event_gtk_late (); + else +#endif #ifdef HAVE_MS_WINDOWS if (!strcmp (display_use, "mswindows")) init_event_mswindows_late (); @@ -4936,20 +4945,23 @@ useful testcases for v18/v19 compatibility: (global-set-key "\^Q" 'foo) without the read-key-sequence: - ^Q ==> (65 17 65 [... ^Q] [^Q]) - ^U^U^Q ==> (65 17 65 [... ^U ^U ^Q] [^U ^U ^Q]) - ^U^U^U^G^Q ==> (65 17 65 [... ^U ^U ^U ^G ^Q] [^Q]) + ^Q ==> (?A ?\^Q ?A [... ^Q] [^Q]) + ^U^U^Q ==> (?A ?\^Q ?A [... ^U ^U ^Q] [^U ^U ^Q]) + ^U^U^U^G^Q ==> (?A ?\^Q ?A [... ^U ^U ^U ^G ^Q] [^Q]) with the read-key-sequence: - ^Qb ==> (65 [b] 17 98 [... ^Q b] [b]) - ^U^U^Qb ==> (65 [b] 17 98 [... ^U ^U ^Q b] [b]) - ^U^U^U^G^Qb ==> (65 [b] 17 98 [... ^U ^U ^U ^G ^Q b] [b]) + ^Qb ==> (?A [b] ?\^Q ?b [... ^Q b] [b]) + ^U^U^Qb ==> (?A [b] ?\^Q ?b [... ^U ^U ^Q b] [b]) + ^U^U^U^G^Qb ==> (?A [b] ?\^Q ?b [... ^U ^U ^U ^G ^Q b] [b]) ;the evi-mode command "4dlj.j.j.j.j.j." is also a good testcase (gag) ;(setq x (list (read-char) quit-flag))^J^G ;(let ((inhibit-quit t)) (setq x (list (read-char) quit-flag)))^J^G ;for BOTH, x should get set to (7 t), but no result should be printed. +;; #### According to the doc of quit-flag, second test should return +;; (?\^G nil). Accidentaly XEmacs returns correct value. However, +;; XEmacs 21.1.12 and 21.2.36 both fails on first test. ;also do this: make two frames, one viewing "*scratch*", the other "foo". ;in *scratch*, type (sit-for 20)^J @@ -4969,9 +4981,9 @@ with the read-key-sequence: (quit c)) (read-char))) - (tst)^Ja^G ==> ((quit) 97) with no signal - (tst)^J^Ga ==> ((quit) 97) with no signal - (tst)^Jabc^G ==> ((quit) 97) with no signal, and "bc" inserted in buffer + (tst)^Ja^G ==> ((quit) ?a) with no signal + (tst)^J^Ga ==> ((quit) ?a) with no signal + (tst)^Jabc^G ==> ((quit) ?a) with no signal, and "bc" inserted in buffer ; with sit-for only do the 2nd test. ; Do all 3 tests with (accept-process-output nil 20)