Mercurial > hg > xemacs-beta
comparison src/event-stream.c @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | de805c49cfc1 |
children | 41dbb7a9d5f2 |
comparison
equal
deleted
inserted
replaced
411:12e008d41344 | 412:697ef44129c6 |
---|---|
20 along with XEmacs; see the file COPYING. If not, write to | 20 along with XEmacs; see the file COPYING. If not, write to |
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
22 Boston, MA 02111-1307, USA. */ | 22 Boston, MA 02111-1307, USA. */ |
23 | 23 |
24 /* Synched up with: Not in FSF. */ | 24 /* Synched up with: Not in FSF. */ |
25 | |
26 /* Authorship: | |
27 | |
28 Created 1991 by Jamie Zawinski. | |
29 A great deal of work over the ages by Ben Wing (Mule-ization for 19.12, | |
30 device abstraction for 19.12/19.13, async timers for 19.14, | |
31 rewriting of focus code for 19.12, pre-idle hook for 19.12, | |
32 redoing of signal and quit handling for 19.9 and 19.12, | |
33 misc-user events to clean up menu/scrollbar handling for 19.11, | |
34 function-key-map/key-translation-map/keyboard-translate-table for | |
35 19.13/19.14, open-dribble-file for 19.13, much other cleanup). | |
36 focus-follows-mouse from Chuck Thompson, 1995. | |
37 XIM stuff by Martin Buchholz, c. 1996?. | |
38 */ | |
39 | 25 |
40 /* This file has been Mule-ized. */ | 26 /* This file has been Mule-ized. */ |
41 | 27 |
42 /* | 28 /* |
43 * DANGER!! | 29 * DANGER!! |
50 */ | 36 */ |
51 | 37 |
52 /* TODO: | 38 /* TODO: |
53 This stuff is way too hard to maintain - needs rework. | 39 This stuff is way too hard to maintain - needs rework. |
54 | 40 |
41 (global-set-key "\C-p" global-map) causes a crash - need recursion check. | |
42 | |
55 C-x @ h <scrollbar-drag> x causes a crash. | 43 C-x @ h <scrollbar-drag> x causes a crash. |
56 | 44 |
57 The command builder should deal only with key and button events. | 45 The command builder should deal only with key and button events. |
58 Other command events should be able to come in the MIDDLE of a key | 46 Other command events should be able to come in the MIDDLE of a key |
59 sequence, without disturbing the key sequence composition, or the | 47 sequence, without disturbing the key sequence composition, or the |
71 instead of RETYPING, the key sequence. | 59 instead of RETYPING, the key sequence. |
72 */ | 60 */ |
73 | 61 |
74 #include <config.h> | 62 #include <config.h> |
75 #include "lisp.h" | 63 #include "lisp.h" |
64 | |
65 #ifdef HAVE_X_WINDOWS | |
66 #include "console-x.h" /* for menu accelerators ... */ | |
67 #include "gui-x.h" | |
68 #include "../lwlib/lwlib.h" | |
69 #else | |
70 #define lw_menu_active 0 | |
71 #endif | |
76 | 72 |
77 #include "blocktype.h" | 73 #include "blocktype.h" |
78 #include "buffer.h" | 74 #include "buffer.h" |
79 #include "commands.h" | 75 #include "commands.h" |
80 #include "device.h" | 76 #include "device.h" |
83 #include "frame.h" | 79 #include "frame.h" |
84 #include "insdel.h" /* for buffer_reset_changes */ | 80 #include "insdel.h" /* for buffer_reset_changes */ |
85 #include "keymap.h" | 81 #include "keymap.h" |
86 #include "lstream.h" | 82 #include "lstream.h" |
87 #include "macros.h" /* for defining_keyboard_macro */ | 83 #include "macros.h" /* for defining_keyboard_macro */ |
88 #include "menubar.h" /* #### for evil kludges. */ | 84 #include "opaque.h" |
89 #include "process.h" | 85 #include "process.h" |
90 #include "window.h" | 86 #include "window.h" |
91 | 87 |
92 #include "sysdep.h" /* init_poll_for_quit() */ | 88 #include "sysdep.h" /* init_poll_for_quit() */ |
93 #include "syssignal.h" /* SIGCHLD, etc. */ | 89 #include "syssignal.h" /* SIGCHLD, etc. */ |
104 /* The number of keystrokes between auto-saves. */ | 100 /* The number of keystrokes between auto-saves. */ |
105 static int auto_save_interval; | 101 static int auto_save_interval; |
106 | 102 |
107 Lisp_Object Qundefined_keystroke_sequence; | 103 Lisp_Object Qundefined_keystroke_sequence; |
108 | 104 |
105 Lisp_Object Qcommand_execute; | |
106 | |
109 Lisp_Object Qcommand_event_p; | 107 Lisp_Object Qcommand_event_p; |
110 | 108 |
111 /* Hooks to run before and after each command. */ | 109 /* Hooks to run before and after each command. */ |
112 Lisp_Object Vpre_command_hook, Vpost_command_hook; | 110 Lisp_Object Vpre_command_hook, Vpost_command_hook; |
113 Lisp_Object Qpre_command_hook, Qpost_command_hook; | 111 Lisp_Object Qpre_command_hook, Qpost_command_hook; |
114 | 112 |
115 /* See simple.el */ | |
116 Lisp_Object Qhandle_pre_motion_command, Qhandle_post_motion_command; | |
117 | |
118 /* Hook run when XEmacs is about to be idle. */ | 113 /* Hook run when XEmacs is about to be idle. */ |
119 Lisp_Object Qpre_idle_hook, Vpre_idle_hook; | 114 Lisp_Object Qpre_idle_hook, Vpre_idle_hook; |
120 | 115 |
121 /* Control gratuitous keyboard focus throwing. */ | 116 /* Control gratuitous keyboard focus throwing. */ |
122 int focus_follows_mouse; | 117 int focus_follows_mouse; |
123 | 118 |
124 int modifier_keys_are_sticky; | 119 #ifdef ILL_CONCEIVED_HOOK |
125 | |
126 #if 0 /* FSF Emacs crap */ | |
127 /* Hook run after a command if there's no more input soon. */ | 120 /* Hook run after a command if there's no more input soon. */ |
128 Lisp_Object Qpost_command_idle_hook, Vpost_command_idle_hook; | 121 Lisp_Object Qpost_command_idle_hook, Vpost_command_idle_hook; |
129 | 122 |
130 /* Delay time in microseconds before running post-command-idle-hook. */ | 123 /* Delay time in microseconds before running post-command-idle-hook. */ |
131 int post_command_idle_delay; | 124 int post_command_idle_delay; |
132 | 125 #endif /* ILL_CONCEIVED_HOOK */ |
126 | |
127 #ifdef DEFERRED_ACTION_CRAP | |
133 /* List of deferred actions to be performed at a later time. | 128 /* List of deferred actions to be performed at a later time. |
134 The precise format isn't relevant here; we just check whether it is nil. */ | 129 The precise format isn't relevant here; we just check whether it is nil. */ |
135 Lisp_Object Vdeferred_action_list; | 130 Lisp_Object Vdeferred_action_list; |
136 | 131 |
137 /* Function to call to handle deferred actions, when there are any. */ | 132 /* Function to call to handle deferred actions, when there are any. */ |
138 Lisp_Object Vdeferred_action_function; | 133 Lisp_Object Vdeferred_action_function; |
139 Lisp_Object Qdeferred_action_function; | 134 Lisp_Object Qdeferred_action_function; |
140 #endif /* FSF Emacs crap */ | 135 #endif /* DEFERRED_ACTION_CRAP */ |
141 | 136 |
142 /* Non-nil disable property on a command means | 137 /* Non-nil disable property on a command means |
143 do not execute it; call disabled-command-hook's value instead. */ | 138 do not execute it; call disabled-command-hook's value instead. */ |
144 Lisp_Object Qdisabled, Vdisabled_command_hook; | 139 Lisp_Object Qdisabled, Vdisabled_command_hook; |
145 | 140 |
170 Lisp_Object Vunread_command_event; /* obsoleteness support */ | 165 Lisp_Object Vunread_command_event; /* obsoleteness support */ |
171 | 166 |
172 static Lisp_Object Qunread_command_events, Qunread_command_event; | 167 static Lisp_Object Qunread_command_events, Qunread_command_event; |
173 | 168 |
174 /* Previous command, represented by a Lisp object. | 169 /* Previous command, represented by a Lisp object. |
175 Does not include prefix commands and arg setting commands. */ | 170 Does not include prefix commands and arg setting commands */ |
176 Lisp_Object Vlast_command; | 171 Lisp_Object Vlast_command; |
177 | 172 |
178 /* Contents of this-command-properties for the last command. */ | |
179 Lisp_Object Vlast_command_properties; | |
180 | |
181 /* If a command sets this, the value goes into | 173 /* If a command sets this, the value goes into |
182 last-command for the next command. */ | 174 previous-command for the next command. */ |
183 Lisp_Object Vthis_command; | 175 Lisp_Object Vthis_command; |
184 | |
185 /* If a command sets this, the value goes into | |
186 last-command-properties for the next command. */ | |
187 Lisp_Object Vthis_command_properties; | |
188 | 176 |
189 /* The value of point when the last command was executed. */ | 177 /* The value of point when the last command was executed. */ |
190 Bufpos last_point_position; | 178 Bufpos last_point_position; |
191 | 179 |
192 /* The frame that was current when the last command was started. */ | 180 /* The frame that was current when the last command was started. */ |
248 | 236 |
249 /* Boolean specifying whether keystrokes should be added to | 237 /* Boolean specifying whether keystrokes should be added to |
250 recent-keys. */ | 238 recent-keys. */ |
251 int inhibit_input_event_recording; | 239 int inhibit_input_event_recording; |
252 | 240 |
253 Lisp_Object Qself_insert_defer_undo; | 241 /* prefix key(s) that must match in order to activate menu. |
242 This is ugly. fix me. | |
243 */ | |
244 Lisp_Object Vmenu_accelerator_prefix; | |
245 | |
246 /* list of modifier keys to match accelerator for top level menus */ | |
247 Lisp_Object Vmenu_accelerator_modifiers; | |
248 | |
249 /* whether menu accelerators are enabled */ | |
250 Lisp_Object Vmenu_accelerator_enabled; | |
251 | |
252 /* keymap for auxiliary menu accelerator functions */ | |
253 Lisp_Object Vmenu_accelerator_map; | |
254 | |
255 Lisp_Object Qmenu_force; | |
256 Lisp_Object Qmenu_fallback; | |
257 Lisp_Object Qmenu_quit; | |
258 Lisp_Object Qmenu_up; | |
259 Lisp_Object Qmenu_down; | |
260 Lisp_Object Qmenu_left; | |
261 Lisp_Object Qmenu_right; | |
262 Lisp_Object Qmenu_select; | |
263 Lisp_Object Qmenu_escape; | |
254 | 264 |
255 /* this is in keymap.c */ | 265 /* this is in keymap.c */ |
256 extern Lisp_Object Fmake_keymap (Lisp_Object name); | 266 extern Lisp_Object Fmake_keymap (Lisp_Object name); |
257 | 267 |
258 #ifdef DEBUG_XEMACS | 268 #ifdef DEBUG_XEMACS |
277 | 287 |
278 | 288 |
279 /* The callback routines for the window system or terminal driver */ | 289 /* The callback routines for the window system or terminal driver */ |
280 struct event_stream *event_stream; | 290 struct event_stream *event_stream; |
281 | 291 |
292 /* This structure is what we use to encapsulate the state of a command sequence | |
293 being composed; key events are executed by adding themselves to the command | |
294 builder; if the command builder is then complete (does not still represent | |
295 a prefix key sequence) it executes the corresponding command. | |
296 */ | |
297 struct command_builder | |
298 { | |
299 struct lcrecord_header header; | |
300 Lisp_Object console; /* back pointer to the console this command | |
301 builder is for */ | |
302 /* Qnil, or a Lisp_Event representing the first event read | |
303 * after the last command completed. Threaded. */ | |
304 /* #### NYI */ | |
305 Lisp_Object prefix_events; | |
306 /* Qnil, or a Lisp_Event representing event in the current | |
307 * keymap-lookup sequence. Subsequent events are threaded via | |
308 * the event's next slot */ | |
309 Lisp_Object current_events; | |
310 /* Last elt of above */ | |
311 Lisp_Object most_current_event; | |
312 /* Last elt before function map code took over. What this means is: | |
313 All prefixes up to (but not including) this event have non-nil | |
314 bindings, but the prefix including this event has a nil binding. | |
315 Any events in the chain after this one were read solely because | |
316 we're part of a possible function key. If we end up with | |
317 something that's not part of a possible function key, we have to | |
318 unread all of those events. */ | |
319 Lisp_Object last_non_munged_event; | |
320 /* One set of values for function-key-map, one for key-translation-map */ | |
321 struct munging_key_translation | |
322 { | |
323 /* First event that can begin a possible function key sequence | |
324 (to be translated according to function-key-map). Normally | |
325 this is the first event in the chain. However, once we've | |
326 translated a sequence through function-key-map, this will point | |
327 to the first event after the translated sequence: we don't ever | |
328 want to translate any events twice through function-key-map, or | |
329 things could get really screwed up (e.g. if the user created a | |
330 translation loop). If this is nil, then the next-read event is | |
331 the first that can begin a function key sequence. */ | |
332 Lisp_Object first_mungeable_event; | |
333 } munge_me[2]; | |
334 | |
335 Bufbyte *echo_buf; | |
336 Bytecount echo_buf_length; /* size of echo_buf */ | |
337 Bytecount echo_buf_index; /* index into echo_buf | |
338 * -1 before doing echoing for new cmd */ | |
339 /* Self-insert-command is magic in that it doesn't always push an undo- | |
340 boundary: up to 20 consecutive self-inserts can happen before an undo- | |
341 boundary is pushed. This variable is that counter. | |
342 */ | |
343 int self_insert_countdown; | |
344 }; | |
345 | |
282 static void echo_key_event (struct command_builder *, Lisp_Object event); | 346 static void echo_key_event (struct command_builder *, Lisp_Object event); |
283 static void maybe_kbd_translate (Lisp_Object event); | 347 static void maybe_kbd_translate (Lisp_Object event); |
284 | 348 |
285 /* This structure is basically a typeahead queue: things like | 349 /* This structure is basically a typeahead queue: things like |
286 wait-reading-process-output will delay the execution of | 350 wait-reading-process-output will delay the execution of |
319 | 383 |
320 #define XCOMMAND_BUILDER(x) \ | 384 #define XCOMMAND_BUILDER(x) \ |
321 XRECORD (x, command_builder, struct command_builder) | 385 XRECORD (x, command_builder, struct command_builder) |
322 #define XSETCOMMAND_BUILDER(x, p) XSETRECORD (x, p, command_builder) | 386 #define XSETCOMMAND_BUILDER(x, p) XSETRECORD (x, p, command_builder) |
323 #define COMMAND_BUILDERP(x) RECORDP (x, command_builder) | 387 #define COMMAND_BUILDERP(x) RECORDP (x, command_builder) |
388 #define GC_COMMAND_BUILDERP(x) GC_RECORDP (x, command_builder) | |
324 #define CHECK_COMMAND_BUILDER(x) CHECK_RECORD (x, command_builder) | 389 #define CHECK_COMMAND_BUILDER(x) CHECK_RECORD (x, command_builder) |
325 | 390 |
326 static Lisp_Object | 391 static Lisp_Object |
327 mark_command_builder (Lisp_Object obj) | 392 mark_command_builder (Lisp_Object obj, void (*markobj) (Lisp_Object)) |
328 { | 393 { |
329 struct command_builder *builder = XCOMMAND_BUILDER (obj); | 394 struct command_builder *builder = XCOMMAND_BUILDER (obj); |
330 mark_object (builder->prefix_events); | 395 markobj (builder->prefix_events); |
331 mark_object (builder->current_events); | 396 markobj (builder->current_events); |
332 mark_object (builder->most_current_event); | 397 markobj (builder->most_current_event); |
333 mark_object (builder->last_non_munged_event); | 398 markobj (builder->last_non_munged_event); |
334 mark_object (builder->munge_me[0].first_mungeable_event); | 399 markobj (builder->munge_me[0].first_mungeable_event); |
335 mark_object (builder->munge_me[1].first_mungeable_event); | 400 markobj (builder->munge_me[1].first_mungeable_event); |
336 return builder->console; | 401 return builder->console; |
337 } | 402 } |
338 | 403 |
339 static void | 404 static void |
340 finalize_command_builder (void *header, int for_disksave) | 405 finalize_command_builder (void *header, int for_disksave) |
346 } | 411 } |
347 } | 412 } |
348 | 413 |
349 DEFINE_LRECORD_IMPLEMENTATION ("command-builder", command_builder, | 414 DEFINE_LRECORD_IMPLEMENTATION ("command-builder", command_builder, |
350 mark_command_builder, internal_object_printer, | 415 mark_command_builder, internal_object_printer, |
351 finalize_command_builder, 0, 0, 0, | 416 finalize_command_builder, 0, 0, |
352 struct command_builder); | 417 struct command_builder); |
353 | 418 |
354 static void | 419 static void |
355 reset_command_builder_event_chain (struct command_builder *builder) | 420 reset_command_builder_event_chain (struct command_builder *builder) |
356 { | 421 { |
442 event_stream_event_pending_p (int user) | 507 event_stream_event_pending_p (int user) |
443 { | 508 { |
444 return event_stream && event_stream->event_pending_p (user); | 509 return event_stream && event_stream->event_pending_p (user); |
445 } | 510 } |
446 | 511 |
447 static void | |
448 event_stream_force_event_pending (struct frame* f) | |
449 { | |
450 if (event_stream->force_event_pending) | |
451 event_stream->force_event_pending (f); | |
452 } | |
453 | |
454 static int | 512 static int |
455 maybe_read_quit_event (Lisp_Event *event) | 513 maybe_read_quit_event (struct Lisp_Event *event) |
456 { | 514 { |
457 /* A C-g that came from `sigint_happened' will always come from the | 515 /* A C-g that came from `sigint_happened' will always come from the |
458 controlling terminal. If that doesn't exist, however, then the | 516 controlling terminal. If that doesn't exist, however, then the |
459 user manually sent us a SIGINT, and we pretend the C-g came from | 517 user manually sent us a SIGINT, and we pretend the C-g came from |
460 the selected console. */ | 518 the selected console. */ |
477 } | 535 } |
478 return 0; | 536 return 0; |
479 } | 537 } |
480 | 538 |
481 void | 539 void |
482 event_stream_next_event (Lisp_Event *event) | 540 event_stream_next_event (struct Lisp_Event *event) |
483 { | 541 { |
484 Lisp_Object event_obj; | 542 Lisp_Object event_obj; |
485 | 543 |
486 check_event_stream_ok (EVENT_STREAM_READ); | 544 check_event_stream_ok (EVENT_STREAM_READ); |
487 | 545 |
521 #endif | 579 #endif |
522 maybe_kbd_translate (event_obj); | 580 maybe_kbd_translate (event_obj); |
523 } | 581 } |
524 | 582 |
525 void | 583 void |
526 event_stream_handle_magic_event (Lisp_Event *event) | 584 event_stream_handle_magic_event (struct Lisp_Event *event) |
527 { | 585 { |
528 check_event_stream_ok (EVENT_STREAM_READ); | 586 check_event_stream_ok (EVENT_STREAM_READ); |
529 event_stream->handle_magic_event_cb (event); | 587 event_stream->handle_magic_event_cb (event); |
530 } | 588 } |
531 | 589 |
564 con->input_enabled = 0; | 622 con->input_enabled = 0; |
565 } | 623 } |
566 } | 624 } |
567 | 625 |
568 void | 626 void |
569 event_stream_select_process (Lisp_Process *proc) | 627 event_stream_select_process (struct Lisp_Process *proc) |
570 { | 628 { |
571 check_event_stream_ok (EVENT_STREAM_PROCESS); | 629 check_event_stream_ok (EVENT_STREAM_PROCESS); |
572 if (!get_process_selected_p (proc)) | 630 if (!get_process_selected_p (proc)) |
573 { | 631 { |
574 event_stream->select_process_cb (proc); | 632 event_stream->select_process_cb (proc); |
575 set_process_selected_p (proc, 1); | 633 set_process_selected_p (proc, 1); |
576 } | 634 } |
577 } | 635 } |
578 | 636 |
579 void | 637 void |
580 event_stream_unselect_process (Lisp_Process *proc) | 638 event_stream_unselect_process (struct Lisp_Process *proc) |
581 { | 639 { |
582 check_event_stream_ok (EVENT_STREAM_PROCESS); | 640 check_event_stream_ok (EVENT_STREAM_PROCESS); |
583 if (get_process_selected_p (proc)) | 641 if (get_process_selected_p (proc)) |
584 { | 642 { |
585 event_stream->unselect_process_cb (proc); | 643 event_stream->unselect_process_cb (proc); |
676 else | 734 else |
677 echo_keystrokes = 0; | 735 echo_keystrokes = 0; |
678 | 736 |
679 if (minibuf_level == 0 | 737 if (minibuf_level == 0 |
680 && echo_keystrokes > 0.0 | 738 && echo_keystrokes > 0.0 |
681 #if defined (HAVE_X_WINDOWS) && defined (LWLIB_MENUBARS_LUCID) | 739 && !lw_menu_active) |
682 && !x_kludge_lw_menu_active () | |
683 #endif | |
684 ) | |
685 { | 740 { |
686 if (!no_snooze) | 741 if (!no_snooze) |
687 { | 742 { |
688 /* #### C-g here will cause QUIT. Setting dont_check_for_quit | 743 /* #### C-g here will cause QUIT. Setting dont_check_for_quit |
689 doesn't work. See check_quit. */ | 744 doesn't work. See check_quit. */ |
742 XEVENT (event)->event.key.modifiers = 0; | 797 XEVENT (event)->event.key.modifiers = 0; |
743 did_translate = 1; | 798 did_translate = 1; |
744 } | 799 } |
745 else if (CHARP (traduit)) | 800 else if (CHARP (traduit)) |
746 { | 801 { |
747 Lisp_Event ev2; | 802 struct Lisp_Event ev2; |
748 | 803 |
749 /* This used to call Fcharacter_to_event() directly into EVENT, | 804 /* This used to call Fcharacter_to_event() directly into EVENT, |
750 but that can eradicate timestamps and other such stuff. | 805 but that can eradicate timestamps and other such stuff. |
751 This way is safer. */ | 806 This way is safer. */ |
752 zero_event (&ev2); | 807 zero_event (&ev2); |
928 | 983 |
929 /* We ensure that 0 is never a valid ID, so that a value of 0 can be | 984 /* We ensure that 0 is never a valid ID, so that a value of 0 can be |
930 used to indicate an absence of a timer. */ | 985 used to indicate an absence of a timer. */ |
931 static int low_level_timeout_id_tick; | 986 static int low_level_timeout_id_tick; |
932 | 987 |
933 static struct low_level_timeout_blocktype | 988 struct low_level_timeout_blocktype |
934 { | 989 { |
935 Blocktype_declare (struct low_level_timeout); | 990 Blocktype_declare (struct low_level_timeout); |
936 } *the_low_level_timeout_blocktype; | 991 } *the_low_level_timeout_blocktype; |
937 | 992 |
938 /* Add a one-shot timeout at time TIME to TIMEOUT_LIST. Return | 993 /* Add a one-shot timeout at time TIME to TIMEOUT_LIST. Return |
1044 | 1099 |
1045 /**** High-level timeout functions. ****/ | 1100 /**** High-level timeout functions. ****/ |
1046 | 1101 |
1047 static int timeout_id_tick; | 1102 static int timeout_id_tick; |
1048 | 1103 |
1104 /* Since timeout structures contain Lisp_Objects, they need to be GC'd | |
1105 properly. The opaque data type provides a convenient way of doing | |
1106 this without having to create a new Lisp object, since we can | |
1107 provide our own mark function. */ | |
1108 | |
1109 struct timeout | |
1110 { | |
1111 int id; /* Id we use to identify the timeout over its lifetime */ | |
1112 int interval_id; /* Id for this particular interval; this may | |
1113 be different each time the timeout is | |
1114 signalled.*/ | |
1115 Lisp_Object function, object; /* Function and object associated | |
1116 with timeout. */ | |
1117 EMACS_TIME next_signal_time; /* Absolute time when the timeout | |
1118 is next going to be signalled. */ | |
1119 unsigned int resignal_msecs; /* How far after the next timeout | |
1120 should the one after that | |
1121 occur? */ | |
1122 }; | |
1123 | |
1049 static Lisp_Object pending_timeout_list, pending_async_timeout_list; | 1124 static Lisp_Object pending_timeout_list, pending_async_timeout_list; |
1050 | 1125 |
1051 static Lisp_Object Vtimeout_free_list; | 1126 static Lisp_Object Vtimeout_free_list; |
1052 | 1127 |
1053 static Lisp_Object | 1128 static Lisp_Object |
1054 mark_timeout (Lisp_Object obj) | 1129 mark_timeout (Lisp_Object obj, void (*markobj) (Lisp_Object)) |
1055 { | 1130 { |
1056 Lisp_Timeout *tm = XTIMEOUT (obj); | 1131 struct timeout *tm = (struct timeout *) XOPAQUE_DATA (obj); |
1057 mark_object (tm->function); | 1132 markobj (tm->function); |
1058 return tm->object; | 1133 return tm->object; |
1059 } | 1134 } |
1060 | |
1061 /* Should never, ever be called. (except by an external debugger) */ | |
1062 static void | |
1063 print_timeout (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
1064 { | |
1065 const Lisp_Timeout *t = XTIMEOUT (obj); | |
1066 char buf[64]; | |
1067 | |
1068 sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (timeout) 0x%lx>", | |
1069 (unsigned long) t); | |
1070 write_c_string (buf, printcharfun); | |
1071 } | |
1072 | |
1073 static const struct lrecord_description timeout_description[] = { | |
1074 { XD_LISP_OBJECT, offsetof (Lisp_Timeout, function) }, | |
1075 { XD_LISP_OBJECT, offsetof (Lisp_Timeout, object) }, | |
1076 { XD_END } | |
1077 }; | |
1078 | |
1079 DEFINE_LRECORD_IMPLEMENTATION ("timeout", timeout, | |
1080 mark_timeout, print_timeout, | |
1081 0, 0, 0, timeout_description, Lisp_Timeout); | |
1082 | 1135 |
1083 /* Generate a timeout and return its ID. */ | 1136 /* Generate a timeout and return its ID. */ |
1084 | 1137 |
1085 int | 1138 int |
1086 event_stream_generate_wakeup (unsigned int milliseconds, | 1139 event_stream_generate_wakeup (unsigned int milliseconds, |
1087 unsigned int vanilliseconds, | 1140 unsigned int vanilliseconds, |
1088 Lisp_Object function, Lisp_Object object, | 1141 Lisp_Object function, Lisp_Object object, |
1089 int async_p) | 1142 int async_p) |
1090 { | 1143 { |
1091 Lisp_Object op = allocate_managed_lcrecord (Vtimeout_free_list); | 1144 Lisp_Object op = allocate_managed_opaque (Vtimeout_free_list, 0); |
1092 Lisp_Timeout *timeout = XTIMEOUT (op); | 1145 struct timeout *timeout = (struct timeout *) XOPAQUE_DATA (op); |
1093 EMACS_TIME current_time; | 1146 EMACS_TIME current_time; |
1094 EMACS_TIME interval; | 1147 EMACS_TIME interval; |
1095 | 1148 |
1096 timeout->id = timeout_id_tick++; | 1149 timeout->id = timeout_id_tick++; |
1097 timeout->resignal_msecs = vanilliseconds; | 1150 timeout->resignal_msecs = vanilliseconds; |
1136 static int | 1189 static int |
1137 event_stream_resignal_wakeup (int interval_id, int async_p, | 1190 event_stream_resignal_wakeup (int interval_id, int async_p, |
1138 Lisp_Object *function, Lisp_Object *object) | 1191 Lisp_Object *function, Lisp_Object *object) |
1139 { | 1192 { |
1140 Lisp_Object op = Qnil, rest; | 1193 Lisp_Object op = Qnil, rest; |
1141 Lisp_Timeout *timeout; | 1194 struct timeout *timeout; |
1142 Lisp_Object *timeout_list; | 1195 Lisp_Object *timeout_list; |
1143 struct gcpro gcpro1; | 1196 struct gcpro gcpro1; |
1144 int id; | 1197 int id; |
1145 | 1198 |
1146 GCPRO1 (op); /* just in case ... because it's removed from the list | 1199 GCPRO1 (op); /* just in case ... because it's removed from the list |
1149 timeout_list = async_p ? &pending_async_timeout_list : &pending_timeout_list; | 1202 timeout_list = async_p ? &pending_async_timeout_list : &pending_timeout_list; |
1150 | 1203 |
1151 /* Find the timeout on the list of pending ones. */ | 1204 /* Find the timeout on the list of pending ones. */ |
1152 LIST_LOOP (rest, *timeout_list) | 1205 LIST_LOOP (rest, *timeout_list) |
1153 { | 1206 { |
1154 timeout = XTIMEOUT (XCAR (rest)); | 1207 timeout = (struct timeout *) XOPAQUE_DATA (XCAR (rest)); |
1155 if (timeout->interval_id == interval_id) | 1208 if (timeout->interval_id == interval_id) |
1156 break; | 1209 break; |
1157 } | 1210 } |
1158 | 1211 |
1159 assert (!NILP (rest)); | 1212 assert (!NILP (rest)); |
1160 op = XCAR (rest); | 1213 op = XCAR (rest); |
1161 timeout = XTIMEOUT (op); | 1214 timeout = (struct timeout *) XOPAQUE_DATA (op); |
1162 /* We make sure to snarf the data out of the timeout object before | 1215 /* We make sure to snarf the data out of the timeout object before |
1163 we free it with free_managed_lcrecord(). */ | 1216 we free it with free_managed_opaque(). */ |
1164 id = timeout->id; | 1217 id = timeout->id; |
1165 *function = timeout->function; | 1218 *function = timeout->function; |
1166 *object = timeout->object; | 1219 *object = timeout->object; |
1167 | 1220 |
1168 /* Remove this one from the list of pending timeouts */ | 1221 /* Remove this one from the list of pending timeouts */ |
1200 is to move frequently-hit timeouts to the front of the | 1253 is to move frequently-hit timeouts to the front of the |
1201 list, which is a good thing. */ | 1254 list, which is a good thing. */ |
1202 *timeout_list = noseeum_cons (op, *timeout_list); | 1255 *timeout_list = noseeum_cons (op, *timeout_list); |
1203 } | 1256 } |
1204 else | 1257 else |
1205 free_managed_lcrecord (Vtimeout_free_list, op); | 1258 free_managed_opaque (Vtimeout_free_list, op); |
1206 | 1259 |
1207 UNGCPRO; | 1260 UNGCPRO; |
1208 return id; | 1261 return id; |
1209 } | 1262 } |
1210 | 1263 |
1211 void | 1264 void |
1212 event_stream_disable_wakeup (int id, int async_p) | 1265 event_stream_disable_wakeup (int id, int async_p) |
1213 { | 1266 { |
1214 Lisp_Timeout *timeout = 0; | 1267 struct timeout *timeout = 0; |
1215 Lisp_Object rest; | 1268 Lisp_Object rest; |
1216 Lisp_Object *timeout_list; | 1269 Lisp_Object *timeout_list; |
1217 | 1270 |
1218 if (async_p) | 1271 if (async_p) |
1219 timeout_list = &pending_async_timeout_list; | 1272 timeout_list = &pending_async_timeout_list; |
1221 timeout_list = &pending_timeout_list; | 1274 timeout_list = &pending_timeout_list; |
1222 | 1275 |
1223 /* Find the timeout on the list of pending ones, if it's still there. */ | 1276 /* Find the timeout on the list of pending ones, if it's still there. */ |
1224 LIST_LOOP (rest, *timeout_list) | 1277 LIST_LOOP (rest, *timeout_list) |
1225 { | 1278 { |
1226 timeout = XTIMEOUT (XCAR (rest)); | 1279 timeout = (struct timeout *) XOPAQUE_DATA (XCAR (rest)); |
1227 if (timeout->id == id) | 1280 if (timeout->id == id) |
1228 break; | 1281 break; |
1229 } | 1282 } |
1230 | 1283 |
1231 /* If we found it, remove it from the list and disable the pending | 1284 /* If we found it, remove it from the list and disable the pending |
1237 delq_no_quit_and_free_cons (op, *timeout_list); | 1290 delq_no_quit_and_free_cons (op, *timeout_list); |
1238 if (async_p) | 1291 if (async_p) |
1239 event_stream_remove_async_timeout (timeout->interval_id); | 1292 event_stream_remove_async_timeout (timeout->interval_id); |
1240 else | 1293 else |
1241 event_stream_remove_timeout (timeout->interval_id); | 1294 event_stream_remove_timeout (timeout->interval_id); |
1242 free_managed_lcrecord (Vtimeout_free_list, op); | 1295 free_managed_opaque (Vtimeout_free_list, op); |
1243 } | 1296 } |
1244 } | 1297 } |
1245 | 1298 |
1246 static int | 1299 static int |
1247 event_stream_wakeup_pending_p (int id, int async_p) | 1300 event_stream_wakeup_pending_p (int id, int async_p) |
1248 { | 1301 { |
1249 Lisp_Timeout *timeout; | 1302 struct timeout *timeout; |
1250 Lisp_Object rest; | 1303 Lisp_Object rest; |
1251 Lisp_Object timeout_list; | 1304 Lisp_Object timeout_list; |
1252 int found = 0; | 1305 int found = 0; |
1253 | 1306 |
1254 | 1307 |
1258 timeout_list = pending_timeout_list; | 1311 timeout_list = pending_timeout_list; |
1259 | 1312 |
1260 /* Find the element on the list of pending ones, if it's still there. */ | 1313 /* Find the element on the list of pending ones, if it's still there. */ |
1261 LIST_LOOP (rest, timeout_list) | 1314 LIST_LOOP (rest, timeout_list) |
1262 { | 1315 { |
1263 timeout = XTIMEOUT (XCAR (rest)); | 1316 timeout = (struct timeout *) XOPAQUE_DATA (XCAR (rest)); |
1264 if (timeout->id == id) | 1317 if (timeout->id == id) |
1265 { | 1318 { |
1266 found = 1; | 1319 found = 1; |
1267 break; | 1320 break; |
1268 } | 1321 } |
1961 Fdeallocate_event (event); | 2014 Fdeallocate_event (event); |
1962 DEBUG_PRINT_EMACS_EVENT ("command event queue", target_event); | 2015 DEBUG_PRINT_EMACS_EVENT ("command event queue", target_event); |
1963 } | 2016 } |
1964 else | 2017 else |
1965 { | 2018 { |
1966 Lisp_Event *e = XEVENT (target_event); | 2019 struct Lisp_Event *e = XEVENT (target_event); |
1967 | 2020 |
1968 /* The command_event_queue was empty. Wait for an event. */ | 2021 /* The command_event_queue was empty. Wait for an event. */ |
1969 event_stream_next_event (e); | 2022 event_stream_next_event (e); |
1970 /* If this was a timeout, then we need to extract some data | 2023 /* If this was a timeout, then we need to extract some data |
1971 out of the returned closure and might need to resignal | 2024 out of the returned closure and might need to resignal |
2068 struct console *con = XCONSOLE (Vselected_console); | 2121 struct console *con = XCONSOLE (Vselected_console); |
2069 struct command_builder *command_builder = | 2122 struct command_builder *command_builder = |
2070 XCOMMAND_BUILDER (con->command_builder); | 2123 XCOMMAND_BUILDER (con->command_builder); |
2071 int store_this_key = 0; | 2124 int store_this_key = 0; |
2072 struct gcpro gcpro1; | 2125 struct gcpro gcpro1; |
2126 #ifdef LWLIB_MENUBARS_LUCID | |
2127 extern int in_menu_callback; /* defined in menubar-x.c */ | |
2128 #endif /* LWLIB_MENUBARS_LUCID */ | |
2073 | 2129 |
2074 GCPRO1 (event); | 2130 GCPRO1 (event); |
2075 /* DO NOT do QUIT anywhere within this function or the functions it calls. | 2131 /* DO NOT do QUIT anywhere within this function or the functions it calls. |
2076 We want to read the ^G as an event. */ | 2132 We want to read the ^G as an event. */ |
2077 | 2133 |
2341 else | 2397 else |
2342 execute_internal_event (event); | 2398 execute_internal_event (event); |
2343 } | 2399 } |
2344 UNGCPRO; | 2400 UNGCPRO; |
2345 return event; | 2401 return event; |
2346 } | |
2347 | |
2348 DEFUN ("dispatch-non-command-events", Fdispatch_non_command_events, 0, 0, 0, /* | |
2349 Dispatch any pending "magic" events. | |
2350 | |
2351 This function is useful for forcing the redisplay of native | |
2352 widgets. Normally these are redisplayed through a native window-system | |
2353 event encoded as magic event, rather than by the redisplay code. This | |
2354 function does not call redisplay or do any of the other things that | |
2355 `next-event' does. | |
2356 */ | |
2357 ()) | |
2358 { | |
2359 /* This function can GC */ | |
2360 Lisp_Object event = Qnil; | |
2361 struct gcpro gcpro1; | |
2362 GCPRO1 (event); | |
2363 event = Fmake_event (Qnil, Qnil); | |
2364 | |
2365 /* Make sure that there will be something in the native event queue | |
2366 so that externally managed things (e.g. widgets) get some CPU | |
2367 time. */ | |
2368 event_stream_force_event_pending (selected_frame ()); | |
2369 | |
2370 while (event_stream_event_pending_p (0)) | |
2371 { | |
2372 QUIT; /* next_event_internal() does not QUIT. */ | |
2373 | |
2374 /* We're a generator of the command_event_queue, so we can't be a | |
2375 consumer as well. Also, we have no reason to consult the | |
2376 command_event_queue; there are only user and eval-events there, | |
2377 and we'd just have to put them back anyway. | |
2378 */ | |
2379 next_event_internal (event, 0); /* blocks */ | |
2380 /* See the comment in accept-process-output about Vquit_flag */ | |
2381 if (XEVENT_TYPE (event) == magic_event || | |
2382 XEVENT_TYPE (event) == timeout_event || | |
2383 XEVENT_TYPE (event) == process_event || | |
2384 XEVENT_TYPE (event) == pointer_motion_event) | |
2385 execute_internal_event (event); | |
2386 else | |
2387 { | |
2388 enqueue_command_event_1 (event); | |
2389 break; | |
2390 } | |
2391 } | |
2392 | |
2393 Fdeallocate_event (event); | |
2394 UNGCPRO; | |
2395 return Qnil; | |
2396 } | 2402 } |
2397 | 2403 |
2398 static void | 2404 static void |
2399 reset_current_events (struct command_builder *command_builder) | 2405 reset_current_events (struct command_builder *command_builder) |
2400 { | 2406 { |
3030 return; | 3036 return; |
3031 } | 3037 } |
3032 | 3038 |
3033 case timeout_event: | 3039 case timeout_event: |
3034 { | 3040 { |
3035 Lisp_Event *e = XEVENT (event); | 3041 struct Lisp_Event *e = XEVENT (event); |
3036 if (!NILP (e->event.timeout.function)) | 3042 if (!NILP (e->event.timeout.function)) |
3037 call1 (e->event.timeout.function, | 3043 call1 (e->event.timeout.function, |
3038 e->event.timeout.object); | 3044 e->event.timeout.object); |
3039 return; | 3045 return; |
3040 } | 3046 } |
3087 if (NILP (event0)) | 3093 if (NILP (event0)) |
3088 return Qnil; | 3094 return Qnil; |
3089 | 3095 |
3090 return event_binding (event0, 1); | 3096 return event_binding (event0, 1); |
3091 } | 3097 } |
3098 | |
3099 #if defined(HAVE_X_WINDOWS) && defined(LWLIB_MENUBARS_LUCID) | |
3100 static void | |
3101 menu_move_up (void) | |
3102 { | |
3103 widget_value *current, *prev; | |
3104 widget_value *entries; | |
3105 | |
3106 current = lw_get_entries (False); | |
3107 entries = lw_get_entries (True); | |
3108 prev = NULL; | |
3109 if (current != entries) | |
3110 { | |
3111 while (entries != current) | |
3112 { | |
3113 if (entries->name /*&& entries->enabled*/) prev = entries; | |
3114 entries = entries->next; | |
3115 assert (entries); | |
3116 } | |
3117 } | |
3118 | |
3119 if (!prev) | |
3120 /* move to last item */ | |
3121 { | |
3122 while (entries->next) | |
3123 { | |
3124 if (entries->name /*&& entries->enabled*/) prev = entries; | |
3125 entries = entries->next; | |
3126 } | |
3127 if (prev) | |
3128 { | |
3129 if (entries->name /*&& entries->enabled*/) | |
3130 prev = entries; | |
3131 } | |
3132 else | |
3133 { | |
3134 /* no selectable items in this menu, pop up to previous level */ | |
3135 lw_pop_menu (); | |
3136 return; | |
3137 } | |
3138 } | |
3139 lw_set_item (prev); | |
3140 } | |
3141 | |
3142 static void | |
3143 menu_move_down (void) | |
3144 { | |
3145 widget_value *current; | |
3146 widget_value *new; | |
3147 | |
3148 current = lw_get_entries (False); | |
3149 new = current; | |
3150 | |
3151 while (new->next) | |
3152 { | |
3153 new = new->next; | |
3154 if (new->name /*&& new->enabled*/) break; | |
3155 } | |
3156 | |
3157 if (new==current||!(new->name/*||new->enabled*/)) | |
3158 { | |
3159 new = lw_get_entries (True); | |
3160 while (new!=current) | |
3161 { | |
3162 if (new->name /*&& new->enabled*/) break; | |
3163 new = new->next; | |
3164 } | |
3165 if (new==current&&!(new->name /*|| new->enabled*/)) | |
3166 { | |
3167 lw_pop_menu (); | |
3168 return; | |
3169 } | |
3170 } | |
3171 | |
3172 lw_set_item (new); | |
3173 } | |
3174 | |
3175 static void | |
3176 menu_move_left (void) | |
3177 { | |
3178 int level = lw_menu_level (); | |
3179 int l = level; | |
3180 widget_value *current; | |
3181 | |
3182 while (level >= 3) | |
3183 { | |
3184 --level; | |
3185 lw_pop_menu (); | |
3186 } | |
3187 menu_move_up (); | |
3188 current = lw_get_entries (False); | |
3189 if (l > 2 && current->contents) | |
3190 lw_push_menu (current->contents); | |
3191 } | |
3192 | |
3193 static void | |
3194 menu_move_right (void) | |
3195 { | |
3196 int level = lw_menu_level (); | |
3197 int l = level; | |
3198 widget_value *current; | |
3199 | |
3200 while (level >= 3) | |
3201 { | |
3202 --level; | |
3203 lw_pop_menu (); | |
3204 } | |
3205 menu_move_down (); | |
3206 current = lw_get_entries (False); | |
3207 if (l > 2 && current->contents) | |
3208 lw_push_menu (current->contents); | |
3209 } | |
3210 | |
3211 static void | |
3212 menu_select_item (widget_value *val) | |
3213 { | |
3214 if (val == NULL) | |
3215 val = lw_get_entries (False); | |
3216 | |
3217 /* is match a submenu? */ | |
3218 | |
3219 if (val->contents) | |
3220 { | |
3221 /* enter the submenu */ | |
3222 | |
3223 lw_set_item (val); | |
3224 lw_push_menu (val->contents); | |
3225 } | |
3226 else | |
3227 { | |
3228 /* Execute the menu entry by calling the menu's `select' | |
3229 callback function | |
3230 */ | |
3231 lw_kill_menus (val); | |
3232 } | |
3233 } | |
3234 | |
3235 static Lisp_Object | |
3236 command_builder_operate_menu_accelerator (struct command_builder *builder) | |
3237 { | |
3238 /* this function can GC */ | |
3239 | |
3240 struct console *con = XCONSOLE (Vselected_console); | |
3241 Lisp_Object evee = builder->most_current_event; | |
3242 Lisp_Object binding; | |
3243 widget_value *entries; | |
3244 | |
3245 extern int lw_menu_accelerate; /* lwlib.c */ | |
3246 | |
3247 #if 0 | |
3248 { | |
3249 int i; | |
3250 Lisp_Object t; | |
3251 char buf[50]; | |
3252 | |
3253 t = builder->current_events; | |
3254 i = 0; | |
3255 while (!NILP (t)) | |
3256 { | |
3257 i++; | |
3258 sprintf (buf,"OPERATE (%d): ",i); | |
3259 write_c_string (buf, Qexternal_debugging_output); | |
3260 print_internal (t, Qexternal_debugging_output, 1); | |
3261 write_c_string ("\n", Qexternal_debugging_output); | |
3262 t = XEVENT_NEXT (t); | |
3263 } | |
3264 } | |
3265 #endif /* 0 */ | |
3266 | |
3267 /* menu accelerator keys don't go into keyboard macros */ | |
3268 if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro)) | |
3269 con->kbd_macro_ptr = con->kbd_macro_end; | |
3270 | |
3271 /* don't echo menu accelerator keys */ | |
3272 /*reset_key_echo (builder, 1);*/ | |
3273 | |
3274 if (!lw_menu_accelerate) | |
3275 { | |
3276 /* `convert' mouse display to keyboard display | |
3277 by entering the open submenu | |
3278 */ | |
3279 entries = lw_get_entries (False); | |
3280 if (entries->contents) | |
3281 { | |
3282 lw_push_menu (entries->contents); | |
3283 lw_display_menu (CurrentTime); | |
3284 } | |
3285 } | |
3286 | |
3287 /* compare event to the current menu accelerators */ | |
3288 | |
3289 entries=lw_get_entries (True); | |
3290 | |
3291 while (entries) | |
3292 { | |
3293 Lisp_Object accel; | |
3294 VOID_TO_LISP (accel, entries->accel); | |
3295 if (entries->name && !NILP (accel)) | |
3296 { | |
3297 if (event_matches_key_specifier_p (XEVENT (evee), accel)) | |
3298 { | |
3299 /* a match! */ | |
3300 | |
3301 menu_select_item (entries); | |
3302 | |
3303 if (lw_menu_active) lw_display_menu (CurrentTime); | |
3304 | |
3305 reset_this_command_keys (Vselected_console, 1); | |
3306 /*reset_command_builder_event_chain (builder);*/ | |
3307 return Vmenu_accelerator_map; | |
3308 } | |
3309 } | |
3310 entries = entries->next; | |
3311 } | |
3312 | |
3313 /* try to look up event in menu-accelerator-map */ | |
3314 | |
3315 binding = event_binding_in (evee, Vmenu_accelerator_map, 1); | |
3316 | |
3317 if (NILP (binding)) | |
3318 { | |
3319 /* beep at user for undefined key */ | |
3320 return Qnil; | |
3321 } | |
3322 else | |
3323 { | |
3324 if (EQ (binding, Qmenu_quit)) | |
3325 { | |
3326 /* turn off menus and set quit flag */ | |
3327 lw_kill_menus (NULL); | |
3328 Vquit_flag = Qt; | |
3329 } | |
3330 else if (EQ (binding, Qmenu_up)) | |
3331 { | |
3332 int level = lw_menu_level (); | |
3333 if (level > 2) | |
3334 menu_move_up (); | |
3335 } | |
3336 else if (EQ (binding, Qmenu_down)) | |
3337 { | |
3338 int level = lw_menu_level (); | |
3339 if (level > 2) | |
3340 menu_move_down (); | |
3341 else | |
3342 menu_select_item (NULL); | |
3343 } | |
3344 else if (EQ (binding, Qmenu_left)) | |
3345 { | |
3346 int level = lw_menu_level (); | |
3347 if (level > 3) | |
3348 { | |
3349 lw_pop_menu (); | |
3350 lw_display_menu (CurrentTime); | |
3351 } | |
3352 else | |
3353 menu_move_left (); | |
3354 } | |
3355 else if (EQ (binding, Qmenu_right)) | |
3356 { | |
3357 int level = lw_menu_level (); | |
3358 if (level > 2 && | |
3359 lw_get_entries (False)->contents) | |
3360 { | |
3361 widget_value *current = lw_get_entries (False); | |
3362 if (current->contents) | |
3363 menu_select_item (NULL); | |
3364 } | |
3365 else | |
3366 menu_move_right (); | |
3367 } | |
3368 else if (EQ (binding, Qmenu_select)) | |
3369 menu_select_item (NULL); | |
3370 else if (EQ (binding, Qmenu_escape)) | |
3371 { | |
3372 int level = lw_menu_level (); | |
3373 | |
3374 if (level > 2) | |
3375 { | |
3376 lw_pop_menu (); | |
3377 lw_display_menu (CurrentTime); | |
3378 } | |
3379 else | |
3380 { | |
3381 /* turn off menus quietly */ | |
3382 lw_kill_menus (NULL); | |
3383 } | |
3384 } | |
3385 else if (KEYMAPP (binding)) | |
3386 { | |
3387 /* prefix key */ | |
3388 reset_this_command_keys (Vselected_console, 1); | |
3389 /*reset_command_builder_event_chain (builder);*/ | |
3390 return binding; | |
3391 } | |
3392 else | |
3393 { | |
3394 /* turn off menus and execute binding */ | |
3395 lw_kill_menus (NULL); | |
3396 reset_this_command_keys (Vselected_console, 1); | |
3397 /*reset_command_builder_event_chain (builder);*/ | |
3398 return binding; | |
3399 } | |
3400 } | |
3401 | |
3402 if (lw_menu_active) lw_display_menu (CurrentTime); | |
3403 | |
3404 reset_this_command_keys (Vselected_console, 1); | |
3405 /*reset_command_builder_event_chain (builder);*/ | |
3406 | |
3407 return Vmenu_accelerator_map; | |
3408 } | |
3409 | |
3410 static Lisp_Object | |
3411 menu_accelerator_junk_on_error (Lisp_Object errordata, Lisp_Object ignored) | |
3412 { | |
3413 Vmenu_accelerator_prefix = Qnil; | |
3414 Vmenu_accelerator_modifiers = Qnil; | |
3415 Vmenu_accelerator_enabled = Qnil; | |
3416 if (!NILP (errordata)) | |
3417 { | |
3418 Lisp_Object args[2]; | |
3419 | |
3420 args[0] = build_string ("Error in menu accelerators (setting to nil)"); | |
3421 /* #### This should call | |
3422 (with-output-to-string (display-error errordata)) | |
3423 but that stuff is all in Lisp currently. */ | |
3424 args[1] = errordata; | |
3425 warn_when_safe_lispobj | |
3426 (Qerror, Qwarning, | |
3427 emacs_doprnt_string_lisp ((CONST Bufbyte *) "%s: %s", | |
3428 Qnil, -1, 2, args)); | |
3429 } | |
3430 | |
3431 return Qnil; | |
3432 } | |
3433 | |
3434 static Lisp_Object | |
3435 menu_accelerator_safe_compare (Lisp_Object event0) | |
3436 { | |
3437 if (CONSP (Vmenu_accelerator_prefix)) | |
3438 { | |
3439 Lisp_Object t; | |
3440 t=Vmenu_accelerator_prefix; | |
3441 while (!NILP (t) | |
3442 && !NILP (event0) | |
3443 && event_matches_key_specifier_p (XEVENT (event0), Fcar (t))) | |
3444 { | |
3445 t = Fcdr (t); | |
3446 event0 = XEVENT_NEXT (event0); | |
3447 } | |
3448 if (!NILP (t)) | |
3449 return Qnil; | |
3450 } | |
3451 else if (NILP (event0)) | |
3452 return Qnil; | |
3453 else if (event_matches_key_specifier_p (XEVENT (event0), Vmenu_accelerator_prefix)) | |
3454 event0 = XEVENT_NEXT (event0); | |
3455 else | |
3456 return Qnil; | |
3457 return event0; | |
3458 } | |
3459 | |
3460 static Lisp_Object | |
3461 menu_accelerator_safe_mod_compare (Lisp_Object cons) | |
3462 { | |
3463 return (event_matches_key_specifier_p (XEVENT (XCAR (cons)), XCDR (cons)) | |
3464 ? Qt | |
3465 : Qnil); | |
3466 } | |
3467 | |
3468 static Lisp_Object | |
3469 command_builder_find_menu_accelerator (struct command_builder *builder) | |
3470 { | |
3471 /* this function can GC */ | |
3472 Lisp_Object event0 = builder->current_events; | |
3473 struct console *con = XCONSOLE (Vselected_console); | |
3474 struct frame *f = XFRAME (CONSOLE_SELECTED_FRAME (con)); | |
3475 Widget menubar_widget; | |
3476 | |
3477 /* compare entries in event0 against the menu prefix */ | |
3478 | |
3479 if ((!CONSOLE_X_P (XCONSOLE (builder->console))) || NILP (event0) || | |
3480 XEVENT (event0)->event_type != key_press_event) | |
3481 return Qnil; | |
3482 | |
3483 if (!NILP (Vmenu_accelerator_prefix)) | |
3484 { | |
3485 event0 = condition_case_1 (Qerror, | |
3486 menu_accelerator_safe_compare, | |
3487 event0, | |
3488 menu_accelerator_junk_on_error, | |
3489 Qnil); | |
3490 } | |
3491 | |
3492 if (NILP (event0)) | |
3493 return Qnil; | |
3494 | |
3495 menubar_widget = FRAME_X_MENUBAR_WIDGET (f); | |
3496 if (menubar_widget | |
3497 && CONSP (Vmenu_accelerator_modifiers)) | |
3498 { | |
3499 Lisp_Object fake; | |
3500 Lisp_Object last = Qnil; | |
3501 struct gcpro gcpro1; | |
3502 Lisp_Object matchp; | |
3503 | |
3504 widget_value *val; | |
3505 LWLIB_ID id = XPOPUP_DATA (f->menubar_data)->id; | |
3506 | |
3507 val = lw_get_all_values (id); | |
3508 if (val) | |
3509 { | |
3510 val = val->contents; | |
3511 | |
3512 fake = Fcopy_sequence (Vmenu_accelerator_modifiers); | |
3513 last = fake; | |
3514 | |
3515 while (!NILP (Fcdr (last))) | |
3516 last = Fcdr (last); | |
3517 | |
3518 Fsetcdr (last, Fcons (Qnil, Qnil)); | |
3519 last = Fcdr (last); | |
3520 } | |
3521 | |
3522 fake = Fcons (Qnil, fake); | |
3523 | |
3524 GCPRO1 (fake); | |
3525 | |
3526 while (val) | |
3527 { | |
3528 Lisp_Object accel; | |
3529 VOID_TO_LISP (accel, val->accel); | |
3530 if (val->name && !NILP (accel)) | |
3531 { | |
3532 Fsetcar (last, accel); | |
3533 Fsetcar (fake, event0); | |
3534 matchp = condition_case_1 (Qerror, | |
3535 menu_accelerator_safe_mod_compare, | |
3536 fake, | |
3537 menu_accelerator_junk_on_error, | |
3538 Qnil); | |
3539 if (!NILP (matchp)) | |
3540 { | |
3541 /* we found one! */ | |
3542 | |
3543 lw_set_menu (menubar_widget, val); | |
3544 /* yah - yet another hack. | |
3545 pretend emacs timestamp is the same as an X timestamp, | |
3546 which for the moment it is. (read events.h) | |
3547 */ | |
3548 lw_map_menu (XEVENT (event0)->timestamp); | |
3549 | |
3550 if (val->contents) | |
3551 lw_push_menu (val->contents); | |
3552 | |
3553 lw_display_menu (CurrentTime); | |
3554 | |
3555 /* menu accelerator keys don't go into keyboard macros */ | |
3556 if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro)) | |
3557 con->kbd_macro_ptr = con->kbd_macro_end; | |
3558 | |
3559 /* don't echo menu accelerator keys */ | |
3560 /*reset_key_echo (builder, 1);*/ | |
3561 reset_this_command_keys (Vselected_console, 1); | |
3562 UNGCPRO; | |
3563 | |
3564 return Vmenu_accelerator_map; | |
3565 } | |
3566 } | |
3567 | |
3568 val = val->next; | |
3569 } | |
3570 | |
3571 UNGCPRO; | |
3572 } | |
3573 return Qnil; | |
3574 } | |
3575 | |
3576 | |
3577 DEFUN ("accelerate-menu", Faccelerate_menu, 0, 0, "_", /* | |
3578 Make the menubar active. Menu items can be selected using menu accelerators | |
3579 or by actions defined in menu-accelerator-map. | |
3580 */ | |
3581 ()) | |
3582 { | |
3583 struct console *con = XCONSOLE (Vselected_console); | |
3584 struct frame *f = XFRAME (CONSOLE_SELECTED_FRAME (con)); | |
3585 LWLIB_ID id; | |
3586 widget_value *val; | |
3587 | |
3588 if (NILP (f->menubar_data)) | |
3589 error ("Frame has no menubar."); | |
3590 | |
3591 id = XPOPUP_DATA (f->menubar_data)->id; | |
3592 val = lw_get_all_values (id); | |
3593 val = val->contents; | |
3594 lw_set_menu (FRAME_X_MENUBAR_WIDGET (f), val); | |
3595 lw_map_menu (CurrentTime); | |
3596 | |
3597 lw_display_menu (CurrentTime); | |
3598 | |
3599 /* menu accelerator keys don't go into keyboard macros */ | |
3600 if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro)) | |
3601 con->kbd_macro_ptr = con->kbd_macro_end; | |
3602 | |
3603 return Qnil; | |
3604 } | |
3605 #endif /* HAVE_X_WINDOWS && HAVE_MENUBARS */ | |
3092 | 3606 |
3093 /* See if we can do function-key-map or key-translation-map translation | 3607 /* See if we can do function-key-map or key-translation-map translation |
3094 on the current events in the command builder. If so, do this, and | 3608 on the current events in the command builder. If so, do this, and |
3095 return the resulting binding, if any. */ | 3609 return the resulting binding, if any. */ |
3096 | 3610 |
3209 XEVENT (evee)->event.eval.object); | 3723 XEVENT (evee)->event.eval.object); |
3210 else | 3724 else |
3211 return Qnil; | 3725 return Qnil; |
3212 } | 3726 } |
3213 | 3727 |
3214 /* if we're currently in a menu accelerator, check there for further | 3728 /* if we're currently in a menu accelerator, check there for further events */ |
3215 events */ | |
3216 /* #### fuck me! who wrote this crap? think "abstraction", baby. */ | |
3217 #if defined(HAVE_X_WINDOWS) && defined(LWLIB_MENUBARS_LUCID) | 3729 #if defined(HAVE_X_WINDOWS) && defined(LWLIB_MENUBARS_LUCID) |
3218 if (x_kludge_lw_menu_active ()) | 3730 if (lw_menu_active) |
3219 { | 3731 { |
3220 return command_builder_operate_menu_accelerator (builder); | 3732 return command_builder_operate_menu_accelerator (builder); |
3221 } | 3733 } |
3222 else | 3734 else |
3223 { | 3735 { |
3264 && !NILP (Vretry_undefined_key_binding_unshifted)) | 3776 && !NILP (Vretry_undefined_key_binding_unshifted)) |
3265 { | 3777 { |
3266 Lisp_Object terminal = builder->most_current_event; | 3778 Lisp_Object terminal = builder->most_current_event; |
3267 struct key_data* key = & XEVENT (terminal)->event.key; | 3779 struct key_data* key = & XEVENT (terminal)->event.key; |
3268 Emchar c = 0; | 3780 Emchar c = 0; |
3269 if ((key->modifiers & XEMACS_MOD_SHIFT) | 3781 if ((key->modifiers & MOD_SHIFT) |
3270 || (CHAR_OR_CHAR_INTP (key->keysym) | 3782 || (CHAR_OR_CHAR_INTP (key->keysym) |
3271 && ((c = XCHAR_OR_CHAR_INT (key->keysym)), c >= 'A' && c <= 'Z'))) | 3783 && ((c = XCHAR_OR_CHAR_INT (key->keysym)), c >= 'A' && c <= 'Z'))) |
3272 { | 3784 { |
3273 Lisp_Event terminal_copy = *XEVENT (terminal); | 3785 struct Lisp_Event terminal_copy = *XEVENT (terminal); |
3274 | 3786 |
3275 if (key->modifiers & XEMACS_MOD_SHIFT) | 3787 if (key->modifiers & MOD_SHIFT) |
3276 key->modifiers &= (~ XEMACS_MOD_SHIFT); | 3788 key->modifiers &= (~ MOD_SHIFT); |
3277 else | 3789 else |
3278 key->keysym = make_char (c + 'a' - 'A'); | 3790 key->keysym = make_char (c + 'a' - 'A'); |
3279 | 3791 |
3280 result = command_builder_find_leaf (builder, allow_misc_user_events_p); | 3792 result = command_builder_find_leaf (builder, allow_misc_user_events_p); |
3281 if (!NILP (result)) | 3793 if (!NILP (result)) |
3661 Lisp_Object recent = command_builder->most_current_event; | 4173 Lisp_Object recent = command_builder->most_current_event; |
3662 | 4174 |
3663 if (EVENTP (recent) | 4175 if (EVENTP (recent) |
3664 && event_matches_key_specifier_p (XEVENT (recent), Vmeta_prefix_char)) | 4176 && event_matches_key_specifier_p (XEVENT (recent), Vmeta_prefix_char)) |
3665 { | 4177 { |
3666 Lisp_Event *e; | 4178 struct Lisp_Event *e; |
3667 /* When we see a sequence like "ESC x", pretend we really saw "M-x". | 4179 /* When we see a sequence like "ESC x", pretend we really saw "M-x". |
3668 DoubleThink the recent-keys and this-command-keys as well. */ | 4180 DoubleThink the recent-keys and this-command-keys as well. */ |
3669 | 4181 |
3670 /* Modify the previous most-recently-pushed event on the command | 4182 /* Modify the previous most-recently-pushed event on the command |
3671 builder to be a copy of this one with the meta-bit set instead of | 4183 builder to be a copy of this one with the meta-bit set instead of |
3672 pushing a new event. | 4184 pushing a new event. |
3673 */ | 4185 */ |
3674 Fcopy_event (event, recent); | 4186 Fcopy_event (event, recent); |
3675 e = XEVENT (recent); | 4187 e = XEVENT (recent); |
3676 if (e->event_type == key_press_event) | 4188 if (e->event_type == key_press_event) |
3677 e->event.key.modifiers |= XEMACS_MOD_META; | 4189 e->event.key.modifiers |= MOD_META; |
3678 else if (e->event_type == button_press_event | 4190 else if (e->event_type == button_press_event |
3679 || e->event_type == button_release_event) | 4191 || e->event_type == button_release_event) |
3680 e->event.button.modifiers |= XEMACS_MOD_META; | 4192 e->event.button.modifiers |= MOD_META; |
3681 else | 4193 else |
3682 abort (); | 4194 abort (); |
3683 | 4195 |
3684 { | 4196 { |
3685 int tckn = event_chain_count (Vthis_command_keys); | 4197 int tckn = event_chain_count (Vthis_command_keys); |
3706 struct gcpro gcpro1; | 4218 struct gcpro gcpro1; |
3707 GCPRO1 (leaf); | 4219 GCPRO1 (leaf); |
3708 | 4220 |
3709 if (KEYMAPP (leaf)) | 4221 if (KEYMAPP (leaf)) |
3710 { | 4222 { |
3711 #if defined (HAVE_X_WINDOWS) && defined (LWLIB_MENUBARS_LUCID) | 4223 if (!lw_menu_active) |
3712 if (!x_kludge_lw_menu_active ()) | |
3713 #else | |
3714 if (1) | |
3715 #endif | |
3716 { | 4224 { |
3717 Lisp_Object prompt = Fkeymap_prompt (leaf, Qt); | 4225 Lisp_Object prompt = Fkeymap_prompt (leaf, Qt); |
3718 if (STRINGP (prompt)) | 4226 if (STRINGP (prompt)) |
3719 { | 4227 { |
3720 /* Append keymap prompt to key echo buffer */ | 4228 /* Append keymap prompt to key echo buffer */ |
3730 maybe_echo_keys (command_builder, 1); | 4238 maybe_echo_keys (command_builder, 1); |
3731 } | 4239 } |
3732 else | 4240 else |
3733 maybe_echo_keys (command_builder, 0); | 4241 maybe_echo_keys (command_builder, 0); |
3734 } | 4242 } |
3735 else if (!NILP (Vquit_flag)) | 4243 else if (!NILP (Vquit_flag)) { |
3736 { | 4244 Lisp_Object quit_event = Fmake_event(Qnil, Qnil); |
3737 Lisp_Object quit_event = Fmake_event (Qnil, Qnil); | 4245 struct Lisp_Event *e = XEVENT (quit_event); |
3738 Lisp_Event *e = XEVENT (quit_event); | 4246 /* if quit happened during menu acceleration, pretend we read it */ |
3739 /* if quit happened during menu acceleration, pretend we read it */ | 4247 struct console *con = XCONSOLE (Fselected_console ()); |
3740 struct console *con = XCONSOLE (Fselected_console ()); | 4248 int ch = CONSOLE_QUIT_CHAR (con); |
3741 int ch = CONSOLE_QUIT_CHAR (con); | 4249 |
3742 | 4250 character_to_event (ch, e, con, 1, 1); |
3743 character_to_event (ch, e, con, 1, 1); | 4251 e->channel = make_console (con); |
3744 e->channel = make_console (con); | 4252 |
3745 | 4253 enqueue_command_event (quit_event); |
3746 enqueue_command_event (quit_event); | 4254 Vquit_flag = Qnil; |
3747 Vquit_flag = Qnil; | 4255 } |
3748 } | |
3749 } | 4256 } |
3750 else if (!NILP (leaf)) | 4257 else if (!NILP (leaf)) |
3751 { | 4258 { |
3752 if (EQ (Qcommand, echo_area_status (f)) | 4259 if (EQ (Qcommand, echo_area_status (f)) |
3753 && command_builder->echo_buf_index > 0) | 4260 && command_builder->echo_buf_index > 0) |
3862 } | 4369 } |
3863 else | 4370 else |
3864 { | 4371 { |
3865 /* Start a new command next time */ | 4372 /* Start a new command next time */ |
3866 Vlast_command = Vthis_command; | 4373 Vlast_command = Vthis_command; |
3867 Vlast_command_properties = Vthis_command_properties; | |
3868 Vthis_command_properties = Qnil; | |
3869 | |
3870 /* Emacs 18 doesn't unconditionally clear the echoed keystrokes, | 4374 /* Emacs 18 doesn't unconditionally clear the echoed keystrokes, |
3871 so we don't either */ | 4375 so we don't either */ |
3872 reset_this_command_keys (make_console (con), 0); | 4376 reset_this_command_keys (make_console (con), 0); |
3873 } | 4377 } |
3874 } | 4378 } |
3885 XSETBUFFER (last_point_position_buffer, current_buffer); | 4389 XSETBUFFER (last_point_position_buffer, current_buffer); |
3886 /* This function can GC */ | 4390 /* This function can GC */ |
3887 safe_run_hook_trapping_errors | 4391 safe_run_hook_trapping_errors |
3888 ("Error in `pre-command-hook' (setting hook to nil)", | 4392 ("Error in `pre-command-hook' (setting hook to nil)", |
3889 Qpre_command_hook, 1); | 4393 Qpre_command_hook, 1); |
3890 | |
3891 /* This is a kludge, but necessary; see simple.el */ | |
3892 call0 (Qhandle_pre_motion_command); | |
3893 } | 4394 } |
3894 | 4395 |
3895 /* Run the post command hook. */ | 4396 /* Run the post command hook. */ |
3896 | 4397 |
3897 static void | 4398 static void |
3907 we don't want the user to accidentally remove it. | 4408 we don't want the user to accidentally remove it. |
3908 */ | 4409 */ |
3909 | 4410 |
3910 Lisp_Object win = Fselected_window (Qnil); | 4411 Lisp_Object win = Fselected_window (Qnil); |
3911 | 4412 |
4413 #if 0 | |
3912 /* If the last command deleted the frame, `win' might be nil. | 4414 /* If the last command deleted the frame, `win' might be nil. |
3913 It seems safest to do nothing in this case. */ | 4415 It seems safest to do nothing in this case. */ |
3914 /* Note: Someone added the following comment and put #if 0's around | 4416 /* ### This doesn't really fix the problem, |
3915 this code, not realizing that doing this invites a crash in the | |
3916 line after. */ | |
3917 /* #### This doesn't really fix the problem, | |
3918 if delete-frame is called by some hook */ | 4417 if delete-frame is called by some hook */ |
3919 if (NILP (win)) | 4418 if (NILP (win)) |
3920 return; | 4419 return; |
3921 | 4420 #endif |
3922 /* This is a kludge, but necessary; see simple.el */ | |
3923 call0 (Qhandle_post_motion_command); | |
3924 | 4421 |
3925 if (! zmacs_region_stays | 4422 if (! zmacs_region_stays |
3926 && (!MINI_WINDOW_P (XWINDOW (win)) | 4423 && (!MINI_WINDOW_P (XWINDOW (win)) |
3927 || EQ (zmacs_region_buffer (), WINDOW_BUFFER (XWINDOW (win))))) | 4424 || EQ (zmacs_region_buffer (), WINDOW_BUFFER (XWINDOW (win))))) |
3928 zmacs_deactivate_region (); | 4425 zmacs_deactivate_region (); |
3931 | 4428 |
3932 safe_run_hook_trapping_errors | 4429 safe_run_hook_trapping_errors |
3933 ("Error in `post-command-hook' (setting hook to nil)", | 4430 ("Error in `post-command-hook' (setting hook to nil)", |
3934 Qpost_command_hook, 1); | 4431 Qpost_command_hook, 1); |
3935 | 4432 |
3936 #if 0 /* FSF Emacs crap */ | 4433 #ifdef DEFERRED_ACTION_CRAP |
3937 if (!NILP (Vdeferred_action_list)) | 4434 if (!NILP (Vdeferred_action_list)) |
3938 call0 (Vdeferred_action_function); | 4435 call0 (Vdeferred_action_function); |
3939 | 4436 #endif |
4437 | |
4438 #ifdef ILL_CONCEIVED_HOOK | |
3940 if (NILP (Vunread_command_events) | 4439 if (NILP (Vunread_command_events) |
3941 && NILP (Vexecuting_macro) | 4440 && NILP (Vexecuting_macro) |
3942 && !NILP (Vpost_command_idle_hook) | 4441 && !NILP (Vpost_command_idle_hook) |
3943 && !NILP (Fsit_for (make_float ((double) post_command_idle_delay | 4442 && !NILP (Fsit_for (make_float ((double) post_command_idle_delay |
3944 / 1000000), Qnil))) | 4443 / 1000000), Qnil))) |
3945 safe_run_hook_trapping_errors | 4444 safe_run_hook_trapping_errors |
3946 ("Error in `post-command-idle-hook' (setting hook to nil)", | 4445 ("Error in `post-command-idle-hook' (setting hook to nil)", |
3947 Qpost_command_idle_hook, 1); | 4446 Qpost_command_idle_hook, 1); |
3948 #endif /* FSF Emacs crap */ | 4447 #endif |
3949 | 4448 |
3950 #if 0 /* FSF Emacs */ | 4449 #if 0 /* FSFmacs */ |
3951 if (!NILP (current_buffer->mark_active)) | 4450 if (!NILP (current_buffer->mark_active)) |
3952 { | 4451 { |
3953 if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode)) | 4452 if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode)) |
3954 { | 4453 { |
3955 current_buffer->mark_active = Qnil; | 4454 current_buffer->mark_active = Qnil; |
3957 } | 4456 } |
3958 else if (current_buffer != prev_buffer || | 4457 else if (current_buffer != prev_buffer || |
3959 BUF_MODIFF (current_buffer) != prev_modiff) | 4458 BUF_MODIFF (current_buffer) != prev_modiff) |
3960 run_hook (intern ("activate-mark-hook")); | 4459 run_hook (intern ("activate-mark-hook")); |
3961 } | 4460 } |
3962 #endif /* FSF Emacs */ | 4461 #endif /* FSFmacs */ |
3963 | 4462 |
3964 /* #### Kludge!!! This is necessary to make sure that things | 4463 /* #### Kludge!!! This is necessary to make sure that things |
3965 are properly positioned even if post-command-hook moves point. | 4464 are properly positioned even if post-command-hook moves point. |
3966 #### There should be a cleaner way of handling this. */ | 4465 #### There should be a cleaner way of handling this. */ |
3967 call0 (Qauto_show_make_point_visible); | 4466 call0 (Qauto_show_make_point_visible); |
3991 */ | 4490 */ |
3992 (event)) | 4491 (event)) |
3993 { | 4492 { |
3994 /* This function can GC */ | 4493 /* This function can GC */ |
3995 struct command_builder *command_builder; | 4494 struct command_builder *command_builder; |
3996 Lisp_Event *ev; | 4495 struct Lisp_Event *ev; |
3997 Lisp_Object console; | 4496 Lisp_Object console; |
3998 Lisp_Object channel; | 4497 Lisp_Object channel; |
3999 | 4498 |
4000 CHECK_LIVE_EVENT (event); | 4499 CHECK_LIVE_EVENT (event); |
4001 ev = XEVENT (event); | 4500 ev = XEVENT (event); |
4105 /* Reset the command builder for reading the next sequence. */ | 4604 /* Reset the command builder for reading the next sequence. */ |
4106 reset_this_command_keys (console, 1); | 4605 reset_this_command_keys (console, 1); |
4107 } | 4606 } |
4108 else /* key sequence is bound to a command */ | 4607 else /* key sequence is bound to a command */ |
4109 { | 4608 { |
4110 int magic_undo = 0; | |
4111 int magic_undo_count = 20; | |
4112 | |
4113 Vthis_command = leaf; | 4609 Vthis_command = leaf; |
4114 | |
4115 /* Don't push an undo boundary if the command set the prefix arg, | 4610 /* Don't push an undo boundary if the command set the prefix arg, |
4116 or if we are executing a keyboard macro, or if in the | 4611 or if we are executing a keyboard macro, or if in the |
4117 minibuffer. If the command we are about to execute is | 4612 minibuffer. If the command we are about to execute is |
4118 self-insert, it's tricky: up to 20 consecutive self-inserts may | 4613 self-insert, it's tricky: up to 20 consecutive self-inserts may |
4119 be done without an undo boundary. This counter is reset as | 4614 be done without an undo boundary. This counter is reset as |
4120 soon as a command other than self-insert-command is executed. | 4615 soon as a command other than self-insert-command is executed. |
4121 | 4616 */ |
4122 Programmers can also use the `self-insert-defer-undo' | 4617 if (! EQ (leaf, Qself_insert_command)) |
4123 property to install that behavior on functions other | |
4124 than `self-insert-command', or to change the magic | |
4125 number 20 to something else. #### DOCUMENT THIS! */ | |
4126 | |
4127 if (SYMBOLP (leaf)) | |
4128 { | |
4129 Lisp_Object prop = Fget (leaf, Qself_insert_defer_undo, Qnil); | |
4130 if (NATNUMP (prop)) | |
4131 magic_undo = 1, magic_undo_count = XINT (prop); | |
4132 else if (!NILP (prop)) | |
4133 magic_undo = 1; | |
4134 else if (EQ (leaf, Qself_insert_command)) | |
4135 magic_undo = 1; | |
4136 } | |
4137 | |
4138 if (!magic_undo) | |
4139 command_builder->self_insert_countdown = 0; | 4618 command_builder->self_insert_countdown = 0; |
4140 if (NILP (XCONSOLE (console)->prefix_arg) | 4619 if (NILP (XCONSOLE (console)->prefix_arg) |
4141 && NILP (Vexecuting_macro) | 4620 && NILP (Vexecuting_macro) |
4142 #if 0 | 4621 #if 0 |
4143 /* This was done in the days when there was no undo | 4622 /* This was done in the days when there was no undo |
4147 && !EQ (minibuf_window, Fselected_window (Qnil)) | 4626 && !EQ (minibuf_window, Fselected_window (Qnil)) |
4148 #endif | 4627 #endif |
4149 && command_builder->self_insert_countdown == 0) | 4628 && command_builder->self_insert_countdown == 0) |
4150 Fundo_boundary (); | 4629 Fundo_boundary (); |
4151 | 4630 |
4152 if (magic_undo) | 4631 if (EQ (leaf, Qself_insert_command)) |
4153 { | 4632 { |
4154 if (--command_builder->self_insert_countdown < 0) | 4633 if (--command_builder->self_insert_countdown < 0) |
4155 command_builder->self_insert_countdown = magic_undo_count; | 4634 command_builder->self_insert_countdown = 20; |
4156 } | 4635 } |
4157 execute_command_event | 4636 execute_command_event |
4158 (command_builder, | 4637 (command_builder, |
4159 internal_equal (event, command_builder-> most_current_event, 0) | 4638 internal_equal (event, command_builder-> most_current_event, 0) |
4160 ? event | 4639 ? event |
4336 the value of `this-command-keys' in addition to the raw original event. | 4815 the value of `this-command-keys' in addition to the raw original event. |
4337 That is not right. | 4816 That is not right. |
4338 | 4817 |
4339 Calling this function directs the translated event to replace | 4818 Calling this function directs the translated event to replace |
4340 the original event, so that only one version of the event actually | 4819 the original event, so that only one version of the event actually |
4341 appears in the echo area and in the value of `this-command-keys'. | 4820 appears in the echo area and in the value of `this-command-keys.'. |
4342 */ | 4821 */ |
4343 ()) | 4822 ()) |
4344 { | 4823 { |
4345 /* #### I don't understand this at all, so currently it does nothing. | 4824 /* #### I don't understand this at all, so currently it does nothing. |
4346 If there is ever a problem, maybe someone should investigate. */ | 4825 If there is ever a problem, maybe someone should investigate. */ |
4360 Lisp_Object keysym = XEVENT (event)->event.key.keysym; | 4839 Lisp_Object keysym = XEVENT (event)->event.key.keysym; |
4361 if (CHARP (XEVENT (event)->event.key.keysym)) | 4840 if (CHARP (XEVENT (event)->event.key.keysym)) |
4362 { | 4841 { |
4363 Emchar ch = XCHAR (keysym); | 4842 Emchar ch = XCHAR (keysym); |
4364 Bufbyte str[MAX_EMCHAR_LEN]; | 4843 Bufbyte str[MAX_EMCHAR_LEN]; |
4365 Bytecount len = set_charptr_emchar (str, ch); | 4844 Bytecount len; |
4845 | |
4846 len = set_charptr_emchar (str, ch); | |
4366 Lstream_write (XLSTREAM (Vdribble_file), str, len); | 4847 Lstream_write (XLSTREAM (Vdribble_file), str, len); |
4367 } | 4848 } |
4368 else if (string_char_length (XSYMBOL (keysym)->name) == 1) | 4849 else if (string_char_length (XSYMBOL (keysym)->name) == 1) |
4369 /* one-char key events are printed with just the key name */ | 4850 /* one-char key events are printed with just the key name */ |
4370 Fprinc (keysym, Vdribble_file); | 4851 Fprinc (keysym, Vdribble_file); |
4421 /************************************************************************/ | 4902 /************************************************************************/ |
4422 | 4903 |
4423 void | 4904 void |
4424 syms_of_event_stream (void) | 4905 syms_of_event_stream (void) |
4425 { | 4906 { |
4426 INIT_LRECORD_IMPLEMENTATION (command_builder); | |
4427 INIT_LRECORD_IMPLEMENTATION (timeout); | |
4428 | |
4429 defsymbol (&Qdisabled, "disabled"); | 4907 defsymbol (&Qdisabled, "disabled"); |
4430 defsymbol (&Qcommand_event_p, "command-event-p"); | 4908 defsymbol (&Qcommand_event_p, "command-event-p"); |
4431 | 4909 |
4432 deferror (&Qundefined_keystroke_sequence, "undefined-keystroke-sequence", | 4910 deferror (&Qundefined_keystroke_sequence, "undefined-keystroke-sequence", |
4433 "Undefined keystroke sequence", Qerror); | 4911 "Undefined keystroke sequence", Qerror); |
4912 defsymbol (&Qcommand_execute, "command-execute"); | |
4434 | 4913 |
4435 DEFSUBR (Frecent_keys); | 4914 DEFSUBR (Frecent_keys); |
4436 DEFSUBR (Frecent_keys_ring_size); | 4915 DEFSUBR (Frecent_keys_ring_size); |
4437 DEFSUBR (Fset_recent_keys_ring_size); | 4916 DEFSUBR (Fset_recent_keys_ring_size); |
4438 DEFSUBR (Finput_pending_p); | 4917 DEFSUBR (Finput_pending_p); |
4446 DEFSUBR (Fadd_timeout); | 4925 DEFSUBR (Fadd_timeout); |
4447 DEFSUBR (Fdisable_timeout); | 4926 DEFSUBR (Fdisable_timeout); |
4448 DEFSUBR (Fadd_async_timeout); | 4927 DEFSUBR (Fadd_async_timeout); |
4449 DEFSUBR (Fdisable_async_timeout); | 4928 DEFSUBR (Fdisable_async_timeout); |
4450 DEFSUBR (Fdispatch_event); | 4929 DEFSUBR (Fdispatch_event); |
4451 DEFSUBR (Fdispatch_non_command_events); | |
4452 DEFSUBR (Fread_key_sequence); | 4930 DEFSUBR (Fread_key_sequence); |
4453 DEFSUBR (Fthis_command_keys); | 4931 DEFSUBR (Fthis_command_keys); |
4454 DEFSUBR (Freset_this_command_lengths); | 4932 DEFSUBR (Freset_this_command_lengths); |
4455 DEFSUBR (Fopen_dribble_file); | 4933 DEFSUBR (Fopen_dribble_file); |
4934 #if defined(HAVE_X_WINDOWS) && defined(LWLIB_MENUBARS_LUCID) | |
4935 DEFSUBR (Faccelerate_menu); | |
4936 #endif | |
4456 | 4937 |
4457 defsymbol (&Qpre_command_hook, "pre-command-hook"); | 4938 defsymbol (&Qpre_command_hook, "pre-command-hook"); |
4458 defsymbol (&Qpost_command_hook, "post-command-hook"); | 4939 defsymbol (&Qpost_command_hook, "post-command-hook"); |
4459 defsymbol (&Qunread_command_events, "unread-command-events"); | 4940 defsymbol (&Qunread_command_events, "unread-command-events"); |
4460 defsymbol (&Qunread_command_event, "unread-command-event"); | 4941 defsymbol (&Qunread_command_event, "unread-command-event"); |
4461 defsymbol (&Qpre_idle_hook, "pre-idle-hook"); | 4942 defsymbol (&Qpre_idle_hook, "pre-idle-hook"); |
4462 defsymbol (&Qhandle_pre_motion_command, "handle-pre-motion-command"); | 4943 #ifdef ILL_CONCEIVED_HOOK |
4463 defsymbol (&Qhandle_post_motion_command, "handle-post-motion-command"); | |
4464 #if 0 /* FSF Emacs crap */ | |
4465 defsymbol (&Qpost_command_idle_hook, "post-command-idle-hook"); | 4944 defsymbol (&Qpost_command_idle_hook, "post-command-idle-hook"); |
4945 #endif | |
4946 #ifdef DEFERRED_ACTION_CRAP | |
4466 defsymbol (&Qdeferred_action_function, "deferred-action-function"); | 4947 defsymbol (&Qdeferred_action_function, "deferred-action-function"); |
4467 #endif | 4948 #endif |
4468 defsymbol (&Qretry_undefined_key_binding_unshifted, | 4949 defsymbol (&Qretry_undefined_key_binding_unshifted, |
4469 "retry-undefined-key-binding-unshifted"); | 4950 "retry-undefined-key-binding-unshifted"); |
4470 defsymbol (&Qauto_show_make_point_visible, | 4951 defsymbol (&Qauto_show_make_point_visible, |
4471 "auto-show-make-point-visible"); | 4952 "auto-show-make-point-visible"); |
4472 | 4953 |
4473 defsymbol (&Qself_insert_defer_undo, "self-insert-defer-undo"); | 4954 defsymbol (&Qmenu_force, "menu-force"); |
4955 defsymbol (&Qmenu_fallback, "menu-fallback"); | |
4956 | |
4957 defsymbol (&Qmenu_quit, "menu-quit"); | |
4958 defsymbol (&Qmenu_up, "menu-up"); | |
4959 defsymbol (&Qmenu_down, "menu-down"); | |
4960 defsymbol (&Qmenu_left, "menu-left"); | |
4961 defsymbol (&Qmenu_right, "menu-right"); | |
4962 defsymbol (&Qmenu_select, "menu-select"); | |
4963 defsymbol (&Qmenu_escape, "menu-escape"); | |
4964 | |
4474 defsymbol (&Qcancel_mode_internal, "cancel-mode-internal"); | 4965 defsymbol (&Qcancel_mode_internal, "cancel-mode-internal"); |
4475 } | 4966 } |
4476 | 4967 |
4477 void | 4968 void |
4478 reinit_vars_of_event_stream (void) | 4969 vars_of_event_stream (void) |
4479 { | 4970 { |
4480 recent_keys_ring_index = 0; | 4971 recent_keys_ring_index = 0; |
4481 recent_keys_ring_size = 100; | 4972 recent_keys_ring_size = 100; |
4482 num_input_chars = 0; | |
4483 Vtimeout_free_list = make_lcrecord_list (sizeof (Lisp_Timeout), | |
4484 &lrecord_timeout); | |
4485 staticpro_nodump (&Vtimeout_free_list); | |
4486 the_low_level_timeout_blocktype = | |
4487 Blocktype_new (struct low_level_timeout_blocktype); | |
4488 something_happened = 0; | |
4489 recursive_sit_for = Qnil; | |
4490 } | |
4491 | |
4492 void | |
4493 vars_of_event_stream (void) | |
4494 { | |
4495 reinit_vars_of_event_stream (); | |
4496 Vrecent_keys_ring = Qnil; | 4973 Vrecent_keys_ring = Qnil; |
4497 staticpro (&Vrecent_keys_ring); | 4974 staticpro (&Vrecent_keys_ring); |
4498 | 4975 |
4499 Vthis_command_keys = Qnil; | 4976 Vthis_command_keys = Qnil; |
4500 staticpro (&Vthis_command_keys); | 4977 staticpro (&Vthis_command_keys); |
4501 Vthis_command_keys_tail = Qnil; | 4978 Vthis_command_keys_tail = Qnil; |
4502 pdump_wire (&Vthis_command_keys_tail); | 4979 |
4980 num_input_chars = 0; | |
4503 | 4981 |
4504 command_event_queue = Qnil; | 4982 command_event_queue = Qnil; |
4505 staticpro (&command_event_queue); | 4983 staticpro (&command_event_queue); |
4506 command_event_queue_tail = Qnil; | 4984 command_event_queue_tail = Qnil; |
4507 pdump_wire (&command_event_queue_tail); | |
4508 | 4985 |
4509 Vlast_selected_frame = Qnil; | 4986 Vlast_selected_frame = Qnil; |
4510 staticpro (&Vlast_selected_frame); | 4987 staticpro (&Vlast_selected_frame); |
4511 | 4988 |
4512 pending_timeout_list = Qnil; | 4989 pending_timeout_list = Qnil; |
4513 staticpro (&pending_timeout_list); | 4990 staticpro (&pending_timeout_list); |
4514 | 4991 |
4515 pending_async_timeout_list = Qnil; | 4992 pending_async_timeout_list = Qnil; |
4516 staticpro (&pending_async_timeout_list); | 4993 staticpro (&pending_async_timeout_list); |
4517 | 4994 |
4995 Vtimeout_free_list = make_opaque_list (sizeof (struct timeout), | |
4996 mark_timeout); | |
4997 staticpro (&Vtimeout_free_list); | |
4998 | |
4999 the_low_level_timeout_blocktype = | |
5000 Blocktype_new (struct low_level_timeout_blocktype); | |
5001 | |
5002 something_happened = 0; | |
5003 | |
4518 last_point_position_buffer = Qnil; | 5004 last_point_position_buffer = Qnil; |
4519 staticpro (&last_point_position_buffer); | 5005 staticpro (&last_point_position_buffer); |
5006 | |
5007 recursive_sit_for = Qnil; | |
4520 | 5008 |
4521 DEFVAR_LISP ("echo-keystrokes", &Vecho_keystrokes /* | 5009 DEFVAR_LISP ("echo-keystrokes", &Vecho_keystrokes /* |
4522 *Nonzero means echo unfinished commands after this many seconds of pause. | 5010 *Nonzero means echo unfinished commands after this many seconds of pause. |
4523 */ ); | 5011 */ ); |
4524 Vecho_keystrokes = make_int (1); | 5012 Vecho_keystrokes = make_int (1); |
4561 the keyboard focus. XEmacs cannot in general detect when this mode is | 5049 the keyboard focus. XEmacs cannot in general detect when this mode is |
4562 used by the window manager, so it is up to the user to set it. | 5050 used by the window manager, so it is up to the user to set it. |
4563 */ ); | 5051 */ ); |
4564 focus_follows_mouse = 0; | 5052 focus_follows_mouse = 0; |
4565 | 5053 |
4566 #if 0 /* FSF Emacs crap */ | 5054 #ifdef ILL_CONCEIVED_HOOK |
4567 /* Ill-conceived because it's not run in all sorts of cases | 5055 /* Ill-conceived because it's not run in all sorts of cases |
4568 where XEmacs is blocking. That's what `pre-idle-hook' | 5056 where XEmacs is blocking. That's what `pre-idle-hook' |
4569 is designed to solve. */ | 5057 is designed to solve. */ |
4570 xxDEFVAR_LISP ("post-command-idle-hook", &Vpost_command_idle_hook /* | 5058 xxDEFVAR_LISP ("post-command-idle-hook", &Vpost_command_idle_hook /* |
4571 Normal hook run after each command is executed, if idle. | 5059 Normal hook run after each command is executed, if idle. |
4578 xxDEFVAR_INT ("post-command-idle-delay", &post_command_idle_delay /* | 5066 xxDEFVAR_INT ("post-command-idle-delay", &post_command_idle_delay /* |
4579 Delay time before running `post-command-idle-hook'. | 5067 Delay time before running `post-command-idle-hook'. |
4580 This is measured in microseconds. | 5068 This is measured in microseconds. |
4581 */ ); | 5069 */ ); |
4582 post_command_idle_delay = 5000; | 5070 post_command_idle_delay = 5000; |
4583 | 5071 #endif /* ILL_CONCEIVED_HOOK */ |
5072 | |
5073 #ifdef DEFERRED_ACTION_CRAP | |
4584 /* Random FSFmacs crap. There is absolutely nothing to gain, | 5074 /* Random FSFmacs crap. There is absolutely nothing to gain, |
4585 and a great deal to lose, in using this in place of just | 5075 and a great deal to lose, in using this in place of just |
4586 setting `post-command-hook'. */ | 5076 setting `post-command-hook'. */ |
4587 xxDEFVAR_LISP ("deferred-action-list", &Vdeferred_action_list /* | 5077 xxDEFVAR_LISP ("deferred-action-list", &Vdeferred_action_list /* |
4588 List of deferred actions to be performed at a later time. | 5078 List of deferred actions to be performed at a later time. |
4594 Function to call to handle deferred actions, after each command. | 5084 Function to call to handle deferred actions, after each command. |
4595 This function is called with no arguments after each command | 5085 This function is called with no arguments after each command |
4596 whenever `deferred-action-list' is non-nil. | 5086 whenever `deferred-action-list' is non-nil. |
4597 */ ); | 5087 */ ); |
4598 Vdeferred_action_function = Qnil; | 5088 Vdeferred_action_function = Qnil; |
4599 #endif /* FSF Emacs crap */ | 5089 #endif /* DEFERRED_ACTION_CRAP */ |
4600 | 5090 |
4601 DEFVAR_LISP ("last-command-event", &Vlast_command_event /* | 5091 DEFVAR_LISP ("last-command-event", &Vlast_command_event /* |
4602 Last keyboard or mouse button event that was part of a command. This | 5092 Last keyboard or mouse button event that was part of a command. This |
4603 variable is off limits: you may not set its value or modify the event that | 5093 variable is off limits: you may not set its value or modify the event that |
4604 is its value, as it is destructively modified by `read-key-sequence'. If | 5094 is its value, as it is destructively modified by `read-key-sequence'. If |
4683 The command now being executed. | 5173 The command now being executed. |
4684 The command can set this variable; whatever is put here | 5174 The command can set this variable; whatever is put here |
4685 will be in `last-command' during the following command. | 5175 will be in `last-command' during the following command. |
4686 */ ); | 5176 */ ); |
4687 Vthis_command = Qnil; | 5177 Vthis_command = Qnil; |
4688 | |
4689 DEFVAR_LISP ("last-command-properties", &Vlast_command_properties /* | |
4690 Value of `this-command-properties' for the last command. | |
4691 Used by commands to help synchronize consecutive commands, in preference | |
4692 to looking at `last-command' directly. | |
4693 */ ); | |
4694 Vlast_command_properties = Qnil; | |
4695 | |
4696 DEFVAR_LISP ("this-command-properties", &Vthis_command_properties /* | |
4697 Properties set by the current command. | |
4698 At the beginning of each command, the current value of this variable is | |
4699 copied to `last-command-properties', and then it is set to nil. Use `putf' | |
4700 to add properties to this variable. Commands should use this to communicate | |
4701 with pre/post-command hooks, subsequent commands, wrapping commands, etc. | |
4702 in preference to looking at and/or setting `this-command'. | |
4703 */ ); | |
4704 Vthis_command_properties = Qnil; | |
4705 | 5178 |
4706 DEFVAR_LISP ("help-char", &Vhelp_char /* | 5179 DEFVAR_LISP ("help-char", &Vhelp_char /* |
4707 Character to recognize as meaning Help. | 5180 Character to recognize as meaning Help. |
4708 When it is read, do `(eval help-form)', and display result if it's a string. | 5181 When it is read, do `(eval help-form)', and display result if it's a string. |
4709 If the value of `help-form' is nil, this char can be read normally. | 5182 If the value of `help-form' is nil, this char can be read normally. |
4754 If lookup still fails, a normal error is signalled. In general, | 5227 If lookup still fails, a normal error is signalled. In general, |
4755 you should *bind* this, not set it. | 5228 you should *bind* this, not set it. |
4756 */ ); | 5229 */ ); |
4757 Vretry_undefined_key_binding_unshifted = Qt; | 5230 Vretry_undefined_key_binding_unshifted = Qt; |
4758 | 5231 |
4759 DEFVAR_BOOL ("modifier-keys-are-sticky", &modifier_keys_are_sticky /* | |
4760 *Non-nil makes modifier keys sticky. | |
4761 This means that you can release the modifier key before pressing down | |
4762 the key that you wish to be modified. Although this is non-standard | |
4763 behavior, it is recommended because it reduces the strain on your hand, | |
4764 thus reducing the incidence of the dreaded Emacs-pinky syndrome. | |
4765 */ ); | |
4766 modifier_keys_are_sticky = 0; | |
4767 | |
4768 #ifdef HAVE_XIM | 5232 #ifdef HAVE_XIM |
4769 DEFVAR_LISP ("composed-character-default-binding", | 5233 DEFVAR_LISP ("composed-character-default-binding", |
4770 &Vcomposed_character_default_binding /* | 5234 &Vcomposed_character_default_binding /* |
4771 The default keybinding to use for key events from composed input. | 5235 The default keybinding to use for key events from composed input. |
4772 Window systems frequently have ways to allow the user to compose | 5236 Window systems frequently have ways to allow the user to compose |
4823 | 5287 |
4824 DEFVAR_BOOL ("inhibit-input-event-recording", &inhibit_input_event_recording /* | 5288 DEFVAR_BOOL ("inhibit-input-event-recording", &inhibit_input_event_recording /* |
4825 Non-nil inhibits recording of input-events to recent-keys ring. | 5289 Non-nil inhibits recording of input-events to recent-keys ring. |
4826 */ ); | 5290 */ ); |
4827 inhibit_input_event_recording = 0; | 5291 inhibit_input_event_recording = 0; |
5292 | |
5293 DEFVAR_LISP("menu-accelerator-prefix", &Vmenu_accelerator_prefix /* | |
5294 Prefix key(s) that must be typed before menu accelerators will be activated. | |
5295 Set this to a value acceptable by define-key. | |
5296 */ ); | |
5297 Vmenu_accelerator_prefix = Qnil; | |
5298 | |
5299 DEFVAR_LISP ("menu-accelerator-modifiers", &Vmenu_accelerator_modifiers /* | |
5300 Modifier keys which must be pressed to get to the top level menu accelerators. | |
5301 This is a list of modifier key symbols. All modifier keys must be held down | |
5302 while a valid menu accelerator key is pressed in order for the top level | |
5303 menu to become active. | |
5304 | |
5305 See also menu-accelerator-enabled and menu-accelerator-prefix. | |
5306 */ ); | |
5307 Vmenu_accelerator_modifiers = list1 (Qmeta); | |
5308 | |
5309 DEFVAR_LISP ("menu-accelerator-enabled", &Vmenu_accelerator_enabled /* | |
5310 Whether menu accelerator keys can cause the menubar to become active. | |
5311 If 'menu-force or 'menu-fallback, then menu accelerator keys can | |
5312 be used to activate the top level menu. Once the menubar becomes active, the | |
5313 accelerator keys can be used regardless of the value of this variable. | |
5314 | |
5315 menu-force is used to indicate that the menu accelerator key takes | |
5316 precedence over bindings in the current keymap(s). menu-fallback means | |
5317 that bindings in the current keymap take precedence over menu accelerator keys. | |
5318 Thus a top level menu with an accelerator of "T" would be activated on a | |
5319 keypress of Meta-t if menu-accelerator-enabled is menu-force. | |
5320 However, if menu-accelerator-enabled is menu-fallback, then | |
5321 Meta-t will not activate the menubar and will instead run the function | |
5322 transpose-words, to which it is normally bound. | |
5323 | |
5324 See also menu-accelerator-modifiers and menu-accelerator-prefix. | |
5325 */ ); | |
5326 Vmenu_accelerator_enabled = Qnil; | |
4828 } | 5327 } |
4829 | 5328 |
4830 void | 5329 void |
4831 complex_vars_of_event_stream (void) | 5330 complex_vars_of_event_stream (void) |
4832 { | 5331 { |
4833 Vkeyboard_translate_table = | 5332 Vkeyboard_translate_table = |
4834 make_lisp_hash_table (100, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ); | 5333 make_lisp_hash_table (100, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ); |
5334 | |
5335 DEFVAR_LISP ("menu-accelerator-map", &Vmenu_accelerator_map /* | |
5336 Keymap for use when the menubar is active. | |
5337 The actions menu-quit, menu-up, menu-down, menu-left, menu-right, | |
5338 menu-select and menu-escape can be mapped to keys in this map. | |
5339 | |
5340 menu-quit Immediately deactivate the menubar and any open submenus without | |
5341 selecting an item. | |
5342 menu-up Move the menu cursor up one row in the current menu. If the | |
5343 move extends past the top of the menu, wrap around to the bottom. | |
5344 menu-down Move the menu cursor down one row in the current menu. If the | |
5345 move extends past the bottom of the menu, wrap around to the top. | |
5346 If executed while the cursor is in the top level menu, move down | |
5347 into the selected menu. | |
5348 menu-left Move the cursor from a submenu into the parent menu. If executed | |
5349 while the cursor is in the top level menu, move the cursor to the | |
5350 left. If the move extends past the left edge of the menu, wrap | |
5351 around to the right edge. | |
5352 menu-right Move the cursor into a submenu. If the cursor is located in the | |
5353 top level menu or is not currently on a submenu heading, then move | |
5354 the cursor to the next top level menu entry. If the move extends | |
5355 past the right edge of the menu, wrap around to the left edge. | |
5356 menu-select Activate the item under the cursor. If the cursor is located on | |
5357 a submenu heading, then move the cursor into the submenu. | |
5358 menu-escape Pop up to the next level of menus. Moves from a submenu into its | |
5359 parent menu. From the top level menu, this deactivates the | |
5360 menubar. | |
5361 | |
5362 This keymap can also contain normal key-command bindings, in which case the | |
5363 menubar is deactivated and the corresponding command is executed. | |
5364 | |
5365 The action bindings used by the menu accelerator code are designed to mimic | |
5366 the actions of menu traversal keys in a commonly used PC operating system. | |
5367 */ ); | |
5368 Vmenu_accelerator_map = Fmake_keymap(Qnil); | |
4835 } | 5369 } |
4836 | 5370 |
4837 void | 5371 void |
4838 init_event_stream (void) | 5372 init_event_stream (void) |
4839 { | 5373 { |