comparison src/event-stream.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 576fb035e263
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
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 */
25 39
26 /* This file has been Mule-ized. */ 40 /* This file has been Mule-ized. */
27 41
28 /* 42 /*
29 * DANGER!! 43 * DANGER!!
36 */ 50 */
37 51
38 /* TODO: 52 /* TODO:
39 This stuff is way too hard to maintain - needs rework. 53 This stuff is way too hard to maintain - needs rework.
40 54
41 (global-set-key "\C-p" global-map) causes a crash - need recursion check.
42
43 C-x @ h <scrollbar-drag> x causes a crash. 55 C-x @ h <scrollbar-drag> x causes a crash.
44 56
45 The command builder should deal only with key and button events. 57 The command builder should deal only with key and button events.
46 Other command events should be able to come in the MIDDLE of a key 58 Other command events should be able to come in the MIDDLE of a key
47 sequence, without disturbing the key sequence composition, or the 59 sequence, without disturbing the key sequence composition, or the
59 instead of RETYPING, the key sequence. 71 instead of RETYPING, the key sequence.
60 */ 72 */
61 73
62 #include <config.h> 74 #include <config.h>
63 #include "lisp.h" 75 #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
72 76
73 #include "blocktype.h" 77 #include "blocktype.h"
74 #include "buffer.h" 78 #include "buffer.h"
75 #include "commands.h" 79 #include "commands.h"
76 #include "device.h" 80 #include "device.h"
79 #include "frame.h" 83 #include "frame.h"
80 #include "insdel.h" /* for buffer_reset_changes */ 84 #include "insdel.h" /* for buffer_reset_changes */
81 #include "keymap.h" 85 #include "keymap.h"
82 #include "lstream.h" 86 #include "lstream.h"
83 #include "macros.h" /* for defining_keyboard_macro */ 87 #include "macros.h" /* for defining_keyboard_macro */
88 #include "menubar.h" /* #### for evil kludges. */
84 #include "process.h" 89 #include "process.h"
85 #include "window.h" 90 #include "window.h"
86 91
87 #include "sysdep.h" /* init_poll_for_quit() */ 92 #include "sysdep.h" /* init_poll_for_quit() */
88 #include "syssignal.h" /* SIGCHLD, etc. */ 93 #include "syssignal.h" /* SIGCHLD, etc. */
105 110
106 /* Hooks to run before and after each command. */ 111 /* Hooks to run before and after each command. */
107 Lisp_Object Vpre_command_hook, Vpost_command_hook; 112 Lisp_Object Vpre_command_hook, Vpost_command_hook;
108 Lisp_Object Qpre_command_hook, Qpost_command_hook; 113 Lisp_Object Qpre_command_hook, Qpost_command_hook;
109 114
115 /* See simple.el */
116 Lisp_Object Qhandle_pre_motion_command, Qhandle_post_motion_command;
117
110 /* Hook run when XEmacs is about to be idle. */ 118 /* Hook run when XEmacs is about to be idle. */
111 Lisp_Object Qpre_idle_hook, Vpre_idle_hook; 119 Lisp_Object Qpre_idle_hook, Vpre_idle_hook;
112 120
113 /* Control gratuitous keyboard focus throwing. */ 121 /* Control gratuitous keyboard focus throwing. */
114 int focus_follows_mouse; 122 int focus_follows_mouse;
115 123
116 #ifdef ILL_CONCEIVED_HOOK 124 int modifier_keys_are_sticky;
125
126 #if 0 /* FSF Emacs crap */
117 /* Hook run after a command if there's no more input soon. */ 127 /* Hook run after a command if there's no more input soon. */
118 Lisp_Object Qpost_command_idle_hook, Vpost_command_idle_hook; 128 Lisp_Object Qpost_command_idle_hook, Vpost_command_idle_hook;
119 129
120 /* Delay time in microseconds before running post-command-idle-hook. */ 130 /* Delay time in microseconds before running post-command-idle-hook. */
121 int post_command_idle_delay; 131 int post_command_idle_delay;
122 #endif /* ILL_CONCEIVED_HOOK */ 132
123
124 #ifdef DEFERRED_ACTION_CRAP
125 /* List of deferred actions to be performed at a later time. 133 /* List of deferred actions to be performed at a later time.
126 The precise format isn't relevant here; we just check whether it is nil. */ 134 The precise format isn't relevant here; we just check whether it is nil. */
127 Lisp_Object Vdeferred_action_list; 135 Lisp_Object Vdeferred_action_list;
128 136
129 /* Function to call to handle deferred actions, when there are any. */ 137 /* Function to call to handle deferred actions, when there are any. */
130 Lisp_Object Vdeferred_action_function; 138 Lisp_Object Vdeferred_action_function;
131 Lisp_Object Qdeferred_action_function; 139 Lisp_Object Qdeferred_action_function;
132 #endif /* DEFERRED_ACTION_CRAP */ 140 #endif /* FSF Emacs crap */
133 141
134 /* Non-nil disable property on a command means 142 /* Non-nil disable property on a command means
135 do not execute it; call disabled-command-hook's value instead. */ 143 do not execute it; call disabled-command-hook's value instead. */
136 Lisp_Object Qdisabled, Vdisabled_command_hook; 144 Lisp_Object Qdisabled, Vdisabled_command_hook;
137 145
162 Lisp_Object Vunread_command_event; /* obsoleteness support */ 170 Lisp_Object Vunread_command_event; /* obsoleteness support */
163 171
164 static Lisp_Object Qunread_command_events, Qunread_command_event; 172 static Lisp_Object Qunread_command_events, Qunread_command_event;
165 173
166 /* Previous command, represented by a Lisp object. 174 /* Previous command, represented by a Lisp object.
167 Does not include prefix commands and arg setting commands */ 175 Does not include prefix commands and arg setting commands. */
168 Lisp_Object Vlast_command; 176 Lisp_Object Vlast_command;
169 177
178 /* Contents of this-command-properties for the last command. */
179 Lisp_Object Vlast_command_properties;
180
170 /* If a command sets this, the value goes into 181 /* If a command sets this, the value goes into
171 previous-command for the next command. */ 182 last-command for the next command. */
172 Lisp_Object Vthis_command; 183 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;
173 188
174 /* The value of point when the last command was executed. */ 189 /* The value of point when the last command was executed. */
175 Bufpos last_point_position; 190 Bufpos last_point_position;
176 191
177 /* The frame that was current when the last command was started. */ 192 /* The frame that was current when the last command was started. */
232 int recent_keys_ring_index; 247 int recent_keys_ring_index;
233 248
234 /* Boolean specifying whether keystrokes should be added to 249 /* Boolean specifying whether keystrokes should be added to
235 recent-keys. */ 250 recent-keys. */
236 int inhibit_input_event_recording; 251 int inhibit_input_event_recording;
237
238 /* prefix key(s) that must match in order to activate menu.
239 This is ugly. fix me.
240 */
241 Lisp_Object Vmenu_accelerator_prefix;
242
243 /* list of modifier keys to match accelerator for top level menus */
244 Lisp_Object Vmenu_accelerator_modifiers;
245
246 /* whether menu accelerators are enabled */
247 Lisp_Object Vmenu_accelerator_enabled;
248
249 /* keymap for auxiliary menu accelerator functions */
250 Lisp_Object Vmenu_accelerator_map;
251
252 Lisp_Object Qmenu_force;
253 Lisp_Object Qmenu_fallback;
254 Lisp_Object Qmenu_quit;
255 Lisp_Object Qmenu_up;
256 Lisp_Object Qmenu_down;
257 Lisp_Object Qmenu_left;
258 Lisp_Object Qmenu_right;
259 Lisp_Object Qmenu_select;
260 Lisp_Object Qmenu_escape;
261 252
262 Lisp_Object Qself_insert_defer_undo; 253 Lisp_Object Qself_insert_defer_undo;
263 254
264 /* this is in keymap.c */ 255 /* this is in keymap.c */
265 extern Lisp_Object Fmake_keymap (Lisp_Object name); 256 extern Lisp_Object Fmake_keymap (Lisp_Object name);
285 #endif 276 #endif
286 277
287 278
288 /* The callback routines for the window system or terminal driver */ 279 /* The callback routines for the window system or terminal driver */
289 struct event_stream *event_stream; 280 struct event_stream *event_stream;
290
291 /* This structure is what we use to encapsulate the state of a command sequence
292 being composed; key events are executed by adding themselves to the command
293 builder; if the command builder is then complete (does not still represent
294 a prefix key sequence) it executes the corresponding command.
295 */
296 struct command_builder
297 {
298 struct lcrecord_header header;
299 Lisp_Object console; /* back pointer to the console this command
300 builder is for */
301 /* Qnil, or a Lisp_Event representing the first event read
302 * after the last command completed. Threaded. */
303 /* #### NYI */
304 Lisp_Object prefix_events;
305 /* Qnil, or a Lisp_Event representing event in the current
306 * keymap-lookup sequence. Subsequent events are threaded via
307 * the event's next slot */
308 Lisp_Object current_events;
309 /* Last elt of above */
310 Lisp_Object most_current_event;
311 /* Last elt before function map code took over. What this means is:
312 All prefixes up to (but not including) this event have non-nil
313 bindings, but the prefix including this event has a nil binding.
314 Any events in the chain after this one were read solely because
315 we're part of a possible function key. If we end up with
316 something that's not part of a possible function key, we have to
317 unread all of those events. */
318 Lisp_Object last_non_munged_event;
319 /* One set of values for function-key-map, one for key-translation-map */
320 struct munging_key_translation
321 {
322 /* First event that can begin a possible function key sequence
323 (to be translated according to function-key-map). Normally
324 this is the first event in the chain. However, once we've
325 translated a sequence through function-key-map, this will point
326 to the first event after the translated sequence: we don't ever
327 want to translate any events twice through function-key-map, or
328 things could get really screwed up (e.g. if the user created a
329 translation loop). If this is nil, then the next-read event is
330 the first that can begin a function key sequence. */
331 Lisp_Object first_mungeable_event;
332 } munge_me[2];
333
334 Bufbyte *echo_buf;
335 Bytecount echo_buf_length; /* size of echo_buf */
336 Bytecount echo_buf_index; /* index into echo_buf
337 * -1 before doing echoing for new cmd */
338 /* Self-insert-command is magic in that it doesn't always push an undo-
339 boundary: up to 20 consecutive self-inserts can happen before an undo-
340 boundary is pushed. This variable is that counter.
341 */
342 int self_insert_countdown;
343 };
344 281
345 static void echo_key_event (struct command_builder *, Lisp_Object event); 282 static void echo_key_event (struct command_builder *, Lisp_Object event);
346 static void maybe_kbd_translate (Lisp_Object event); 283 static void maybe_kbd_translate (Lisp_Object event);
347 284
348 /* This structure is basically a typeahead queue: things like 285 /* This structure is basically a typeahead queue: things like
503 440
504 static int 441 static int
505 event_stream_event_pending_p (int user) 442 event_stream_event_pending_p (int user)
506 { 443 {
507 return event_stream && event_stream->event_pending_p (user); 444 return event_stream && event_stream->event_pending_p (user);
445 }
446
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);
508 } 452 }
509 453
510 static int 454 static int
511 maybe_read_quit_event (Lisp_Event *event) 455 maybe_read_quit_event (Lisp_Event *event)
512 { 456 {
664 { 608 {
665 if (event_stream) 609 if (event_stream)
666 event_stream->quit_p_cb (); 610 event_stream->quit_p_cb ();
667 } 611 }
668 612
613 static int
614 event_stream_current_event_timestamp (struct console *c)
615 {
616 if (event_stream && event_stream->current_event_timestamp_cb)
617 return event_stream->current_event_timestamp_cb (c);
618 else
619 return 0;
620 }
669 621
670 622
671 /**********************************************************************/ 623 /**********************************************************************/
672 /* Character prompting */ 624 /* Character prompting */
673 /**********************************************************************/ 625 /**********************************************************************/
732 else 684 else
733 echo_keystrokes = 0; 685 echo_keystrokes = 0;
734 686
735 if (minibuf_level == 0 687 if (minibuf_level == 0
736 && echo_keystrokes > 0.0 688 && echo_keystrokes > 0.0
737 && !lw_menu_active) 689 #if defined (HAVE_X_WINDOWS) && defined (LWLIB_MENUBARS_LUCID)
690 && !x_kludge_lw_menu_active ()
691 #endif
692 )
738 { 693 {
739 if (!no_snooze) 694 if (!no_snooze)
740 { 695 {
741 /* #### C-g here will cause QUIT. Setting dont_check_for_quit 696 /* #### C-g here will cause QUIT. Setting dont_check_for_quit
742 doesn't work. See check_quit. */ 697 doesn't work. See check_quit. */
816 Lisp_Object traduit = Fgethash (XEVENT (event)->event.key.keysym, 771 Lisp_Object traduit = Fgethash (XEVENT (event)->event.key.keysym,
817 Vkeyboard_translate_table, Qnil); 772 Vkeyboard_translate_table, Qnil);
818 if (!NILP (traduit) && SYMBOLP (traduit)) 773 if (!NILP (traduit) && SYMBOLP (traduit))
819 { 774 {
820 XEVENT (event)->event.key.keysym = traduit; 775 XEVENT (event)->event.key.keysym = traduit;
776 did_translate = 1;
777 }
778 else if (CHARP (traduit))
779 {
780 Lisp_Event ev2;
781
782 zero_event (&ev2);
783 character_to_event (XCHAR (traduit), &ev2,
784 XCONSOLE (EVENT_CHANNEL (XEVENT (event))), 1, 1);
785 XEVENT (event)->event.key.keysym = ev2.event.key.keysym;
786 XEVENT (event)->event.key.modifiers |= ev2.event.key.modifiers;
821 did_translate = 1; 787 did_translate = 1;
822 } 788 }
823 } 789 }
824 790
825 #ifdef DEBUG_XEMACS 791 #ifdef DEBUG_XEMACS
1113 1079
1114 /* Should never, ever be called. (except by an external debugger) */ 1080 /* Should never, ever be called. (except by an external debugger) */
1115 static void 1081 static void
1116 print_timeout (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) 1082 print_timeout (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1117 { 1083 {
1118 CONST Lisp_Timeout *t = XTIMEOUT (obj); 1084 const Lisp_Timeout *t = XTIMEOUT (obj);
1119 char buf[64]; 1085 char buf[64];
1120 1086
1121 sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (timeout) 0x%lx>", 1087 sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (timeout) 0x%lx>",
1122 (unsigned long) t); 1088 (unsigned long) t);
1123 write_c_string (buf, printcharfun); 1089 write_c_string (buf, printcharfun);
2088 2054
2089 The next available event will be 2055 The next available event will be
2090 2056
2091 -- any events in `unread-command-events' or `unread-command-event'; else 2057 -- any events in `unread-command-events' or `unread-command-event'; else
2092 -- the next event in the currently executing keyboard macro, if any; else 2058 -- the next event in the currently executing keyboard macro, if any; else
2093 -- an event queued by `enqueue-eval-event', if any; else 2059 -- an event queued by `enqueue-eval-event', if any, or any similar event
2060 queued internally, such as a misc-user event. (For example, when an item
2061 is selected from a menu or from a `question'-type dialog box, the item's
2062 callback is not immediately executed, but instead a misc-user event
2063 is generated and placed onto this queue; when it is dispatched, the
2064 callback is executed.) Else
2094 -- the next available event from the window system or terminal driver. 2065 -- the next available event from the window system or terminal driver.
2095 2066
2096 In the last case, this function will block until an event is available. 2067 In the last case, this function will block until an event is available.
2097 2068
2098 The returned event will be one of the following types: 2069 The returned event will be one of the following types:
2121 struct console *con = XCONSOLE (Vselected_console); 2092 struct console *con = XCONSOLE (Vselected_console);
2122 struct command_builder *command_builder = 2093 struct command_builder *command_builder =
2123 XCOMMAND_BUILDER (con->command_builder); 2094 XCOMMAND_BUILDER (con->command_builder);
2124 int store_this_key = 0; 2095 int store_this_key = 0;
2125 struct gcpro gcpro1; 2096 struct gcpro gcpro1;
2126 #ifdef LWLIB_MENUBARS_LUCID
2127 extern int in_menu_callback; /* defined in menubar-x.c */
2128 #endif /* LWLIB_MENUBARS_LUCID */
2129 2097
2130 GCPRO1 (event); 2098 GCPRO1 (event);
2131 /* DO NOT do QUIT anywhere within this function or the functions it calls. 2099 /* DO NOT do QUIT anywhere within this function or the functions it calls.
2132 We want to read the ^G as an event. */ 2100 We want to read the ^G as an event. */
2133 2101
2399 } 2367 }
2400 UNGCPRO; 2368 UNGCPRO;
2401 return event; 2369 return event;
2402 } 2370 }
2403 2371
2372 DEFUN ("dispatch-non-command-events", Fdispatch_non_command_events, 0, 0, 0, /*
2373 Dispatch any pending "magic" events.
2374
2375 This function is useful for forcing the redisplay of native
2376 widgets. Normally these are redisplayed through a native window-system
2377 event encoded as magic event, rather than by the redisplay code. This
2378 function does not call redisplay or do any of the other things that
2379 `next-event' does.
2380 */
2381 ())
2382 {
2383 /* This function can GC */
2384 Lisp_Object event = Qnil;
2385 struct gcpro gcpro1;
2386 GCPRO1 (event);
2387 event = Fmake_event (Qnil, Qnil);
2388
2389 /* Make sure that there will be something in the native event queue
2390 so that externally managed things (e.g. widgets) get some CPU
2391 time. */
2392 event_stream_force_event_pending (selected_frame ());
2393
2394 while (event_stream_event_pending_p (0))
2395 {
2396 QUIT; /* next_event_internal() does not QUIT. */
2397
2398 /* We're a generator of the command_event_queue, so we can't be a
2399 consumer as well. Also, we have no reason to consult the
2400 command_event_queue; there are only user and eval-events there,
2401 and we'd just have to put them back anyway.
2402 */
2403 next_event_internal (event, 0); /* blocks */
2404 /* See the comment in accept-process-output about Vquit_flag */
2405 if (XEVENT_TYPE (event) == magic_event ||
2406 XEVENT_TYPE (event) == timeout_event ||
2407 XEVENT_TYPE (event) == process_event ||
2408 XEVENT_TYPE (event) == pointer_motion_event)
2409 execute_internal_event (event);
2410 else
2411 {
2412 enqueue_command_event_1 (event);
2413 break;
2414 }
2415 }
2416
2417 Fdeallocate_event (event);
2418 UNGCPRO;
2419 return Qnil;
2420 }
2421
2404 static void 2422 static void
2405 reset_current_events (struct command_builder *command_builder) 2423 reset_current_events (struct command_builder *command_builder)
2406 { 2424 {
2407 Lisp_Object event = command_builder->current_events; 2425 Lisp_Object event = command_builder->current_events;
2408 reset_command_builder_event_chain (command_builder); 2426 reset_command_builder_event_chain (command_builder);
2879 2897
2880 UNGCPRO; 2898 UNGCPRO;
2881 return result; 2899 return result;
2882 } 2900 }
2883 2901
2884 /* This handy little function is used by xselect.c and energize.c to 2902 /* This handy little function is used by select-x.c to wait for replies
2885 wait for replies from processes that aren't really processes (that is, 2903 from processes that aren't really processes (e.g. the X server) */
2886 the X server and the Energize server).
2887 */
2888 void 2904 void
2889 wait_delaying_user_input (int (*predicate) (void *arg), void *predicate_arg) 2905 wait_delaying_user_input (int (*predicate) (void *arg), void *predicate_arg)
2890 { 2906 {
2891 /* This function can GC */ 2907 /* This function can GC */
2892 Lisp_Object event = Fmake_event (Qnil, Qnil); 2908 Lisp_Object event = Fmake_event (Qnil, Qnil);
3094 return Qnil; 3110 return Qnil;
3095 3111
3096 return event_binding (event0, 1); 3112 return event_binding (event0, 1);
3097 } 3113 }
3098 3114
3099 #if defined(HAVE_X_WINDOWS) && defined(LWLIB_MENUBARS_LUCID)
3100 static void
3101 menu_move_up (void)
3102 {
3103 widget_value *current = lw_get_entries (False);
3104 widget_value *entries = lw_get_entries (True);
3105 widget_value *prev = NULL;
3106
3107 while (entries != current)
3108 {
3109 if (entries->name /*&& entries->enabled*/) prev = entries;
3110 entries = entries->next;
3111 assert (entries);
3112 }
3113
3114 if (!prev)
3115 /* move to last item */
3116 {
3117 while (entries->next)
3118 {
3119 if (entries->name /*&& entries->enabled*/) prev = entries;
3120 entries = entries->next;
3121 }
3122 if (prev)
3123 {
3124 if (entries->name /*&& entries->enabled*/)
3125 prev = entries;
3126 }
3127 else
3128 {
3129 /* no selectable items in this menu, pop up to previous level */
3130 lw_pop_menu ();
3131 return;
3132 }
3133 }
3134 lw_set_item (prev);
3135 }
3136
3137 static void
3138 menu_move_down (void)
3139 {
3140 widget_value *current = lw_get_entries (False);
3141 widget_value *new = current;
3142
3143 while (new->next)
3144 {
3145 new = new->next;
3146 if (new->name /*&& new->enabled*/) break;
3147 }
3148
3149 if (new==current||!(new->name/*||new->enabled*/))
3150 {
3151 new = lw_get_entries (True);
3152 while (new!=current)
3153 {
3154 if (new->name /*&& new->enabled*/) break;
3155 new = new->next;
3156 }
3157 if (new==current&&!(new->name /*|| new->enabled*/))
3158 {
3159 lw_pop_menu ();
3160 return;
3161 }
3162 }
3163
3164 lw_set_item (new);
3165 }
3166
3167 static void
3168 menu_move_left (void)
3169 {
3170 int level = lw_menu_level ();
3171 int l = level;
3172 widget_value *current;
3173
3174 while (level-- >= 3)
3175 lw_pop_menu ();
3176
3177 menu_move_up ();
3178 current = lw_get_entries (False);
3179 if (l > 2 && current->contents)
3180 lw_push_menu (current->contents);
3181 }
3182
3183 static void
3184 menu_move_right (void)
3185 {
3186 int level = lw_menu_level ();
3187 int l = level;
3188 widget_value *current;
3189
3190 while (level-- >= 3)
3191 lw_pop_menu ();
3192
3193 menu_move_down ();
3194 current = lw_get_entries (False);
3195 if (l > 2 && current->contents)
3196 lw_push_menu (current->contents);
3197 }
3198
3199 static void
3200 menu_select_item (widget_value *val)
3201 {
3202 if (val == NULL)
3203 val = lw_get_entries (False);
3204
3205 /* is match a submenu? */
3206
3207 if (val->contents)
3208 {
3209 /* enter the submenu */
3210
3211 lw_set_item (val);
3212 lw_push_menu (val->contents);
3213 }
3214 else
3215 {
3216 /* Execute the menu entry by calling the menu's `select'
3217 callback function
3218 */
3219 lw_kill_menus (val);
3220 }
3221 }
3222
3223 static Lisp_Object
3224 command_builder_operate_menu_accelerator (struct command_builder *builder)
3225 {
3226 /* this function can GC */
3227
3228 struct console *con = XCONSOLE (Vselected_console);
3229 Lisp_Object evee = builder->most_current_event;
3230 Lisp_Object binding;
3231 widget_value *entries;
3232
3233 extern int lw_menu_accelerate; /* lwlib.c */
3234
3235 #if 0
3236 {
3237 int i;
3238 Lisp_Object t;
3239 char buf[50];
3240
3241 t = builder->current_events;
3242 i = 0;
3243 while (!NILP (t))
3244 {
3245 i++;
3246 sprintf (buf,"OPERATE (%d): ",i);
3247 write_c_string (buf, Qexternal_debugging_output);
3248 print_internal (t, Qexternal_debugging_output, 1);
3249 write_c_string ("\n", Qexternal_debugging_output);
3250 t = XEVENT_NEXT (t);
3251 }
3252 }
3253 #endif /* 0 */
3254
3255 /* menu accelerator keys don't go into keyboard macros */
3256 if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro))
3257 con->kbd_macro_ptr = con->kbd_macro_end;
3258
3259 /* don't echo menu accelerator keys */
3260 /*reset_key_echo (builder, 1);*/
3261
3262 if (!lw_menu_accelerate)
3263 {
3264 /* `convert' mouse display to keyboard display
3265 by entering the open submenu
3266 */
3267 entries = lw_get_entries (False);
3268 if (entries->contents)
3269 {
3270 lw_push_menu (entries->contents);
3271 lw_display_menu (CurrentTime);
3272 }
3273 }
3274
3275 /* compare event to the current menu accelerators */
3276
3277 entries=lw_get_entries (True);
3278
3279 while (entries)
3280 {
3281 Lisp_Object accel;
3282 VOID_TO_LISP (accel, entries->accel);
3283 if (entries->name && !NILP (accel))
3284 {
3285 if (event_matches_key_specifier_p (XEVENT (evee), accel))
3286 {
3287 /* a match! */
3288
3289 menu_select_item (entries);
3290
3291 if (lw_menu_active) lw_display_menu (CurrentTime);
3292
3293 reset_this_command_keys (Vselected_console, 1);
3294 /*reset_command_builder_event_chain (builder);*/
3295 return Vmenu_accelerator_map;
3296 }
3297 }
3298 entries = entries->next;
3299 }
3300
3301 /* try to look up event in menu-accelerator-map */
3302
3303 binding = event_binding_in (evee, Vmenu_accelerator_map, 1);
3304
3305 if (NILP (binding))
3306 {
3307 /* beep at user for undefined key */
3308 return Qnil;
3309 }
3310 else
3311 {
3312 if (EQ (binding, Qmenu_quit))
3313 {
3314 /* turn off menus and set quit flag */
3315 lw_kill_menus (NULL);
3316 Vquit_flag = Qt;
3317 }
3318 else if (EQ (binding, Qmenu_up))
3319 {
3320 int level = lw_menu_level ();
3321 if (level > 2)
3322 menu_move_up ();
3323 }
3324 else if (EQ (binding, Qmenu_down))
3325 {
3326 int level = lw_menu_level ();
3327 if (level > 2)
3328 menu_move_down ();
3329 else
3330 menu_select_item (NULL);
3331 }
3332 else if (EQ (binding, Qmenu_left))
3333 {
3334 int level = lw_menu_level ();
3335 if (level > 3)
3336 {
3337 lw_pop_menu ();
3338 lw_display_menu (CurrentTime);
3339 }
3340 else
3341 menu_move_left ();
3342 }
3343 else if (EQ (binding, Qmenu_right))
3344 {
3345 int level = lw_menu_level ();
3346 if (level > 2 &&
3347 lw_get_entries (False)->contents)
3348 {
3349 widget_value *current = lw_get_entries (False);
3350 if (current->contents)
3351 menu_select_item (NULL);
3352 }
3353 else
3354 menu_move_right ();
3355 }
3356 else if (EQ (binding, Qmenu_select))
3357 menu_select_item (NULL);
3358 else if (EQ (binding, Qmenu_escape))
3359 {
3360 int level = lw_menu_level ();
3361
3362 if (level > 2)
3363 {
3364 lw_pop_menu ();
3365 lw_display_menu (CurrentTime);
3366 }
3367 else
3368 {
3369 /* turn off menus quietly */
3370 lw_kill_menus (NULL);
3371 }
3372 }
3373 else if (KEYMAPP (binding))
3374 {
3375 /* prefix key */
3376 reset_this_command_keys (Vselected_console, 1);
3377 /*reset_command_builder_event_chain (builder);*/
3378 return binding;
3379 }
3380 else
3381 {
3382 /* turn off menus and execute binding */
3383 lw_kill_menus (NULL);
3384 reset_this_command_keys (Vselected_console, 1);
3385 /*reset_command_builder_event_chain (builder);*/
3386 return binding;
3387 }
3388 }
3389
3390 if (lw_menu_active) lw_display_menu (CurrentTime);
3391
3392 reset_this_command_keys (Vselected_console, 1);
3393 /*reset_command_builder_event_chain (builder);*/
3394
3395 return Vmenu_accelerator_map;
3396 }
3397
3398 static Lisp_Object
3399 menu_accelerator_junk_on_error (Lisp_Object errordata, Lisp_Object ignored)
3400 {
3401 Vmenu_accelerator_prefix = Qnil;
3402 Vmenu_accelerator_modifiers = Qnil;
3403 Vmenu_accelerator_enabled = Qnil;
3404 if (!NILP (errordata))
3405 {
3406 Lisp_Object args[2];
3407
3408 args[0] = build_string ("Error in menu accelerators (setting to nil)");
3409 /* #### This should call
3410 (with-output-to-string (display-error errordata))
3411 but that stuff is all in Lisp currently. */
3412 args[1] = errordata;
3413 warn_when_safe_lispobj
3414 (Qerror, Qwarning,
3415 emacs_doprnt_string_lisp ((CONST Bufbyte *) "%s: %s",
3416 Qnil, -1, 2, args));
3417 }
3418
3419 return Qnil;
3420 }
3421
3422 static Lisp_Object
3423 menu_accelerator_safe_compare (Lisp_Object event0)
3424 {
3425 if (CONSP (Vmenu_accelerator_prefix))
3426 {
3427 Lisp_Object t;
3428 t=Vmenu_accelerator_prefix;
3429 while (!NILP (t)
3430 && !NILP (event0)
3431 && event_matches_key_specifier_p (XEVENT (event0), Fcar (t)))
3432 {
3433 t = Fcdr (t);
3434 event0 = XEVENT_NEXT (event0);
3435 }
3436 if (!NILP (t))
3437 return Qnil;
3438 }
3439 else if (NILP (event0))
3440 return Qnil;
3441 else if (event_matches_key_specifier_p (XEVENT (event0), Vmenu_accelerator_prefix))
3442 event0 = XEVENT_NEXT (event0);
3443 else
3444 return Qnil;
3445 return event0;
3446 }
3447
3448 static Lisp_Object
3449 menu_accelerator_safe_mod_compare (Lisp_Object cons)
3450 {
3451 return (event_matches_key_specifier_p (XEVENT (XCAR (cons)), XCDR (cons))
3452 ? Qt
3453 : Qnil);
3454 }
3455
3456 static Lisp_Object
3457 command_builder_find_menu_accelerator (struct command_builder *builder)
3458 {
3459 /* this function can GC */
3460 Lisp_Object event0 = builder->current_events;
3461 struct console *con = XCONSOLE (Vselected_console);
3462 struct frame *f = XFRAME (CONSOLE_SELECTED_FRAME (con));
3463 Widget menubar_widget;
3464
3465 /* compare entries in event0 against the menu prefix */
3466
3467 if ((!CONSOLE_X_P (XCONSOLE (builder->console))) || NILP (event0) ||
3468 XEVENT (event0)->event_type != key_press_event)
3469 return Qnil;
3470
3471 if (!NILP (Vmenu_accelerator_prefix))
3472 {
3473 event0 = condition_case_1 (Qerror,
3474 menu_accelerator_safe_compare,
3475 event0,
3476 menu_accelerator_junk_on_error,
3477 Qnil);
3478 }
3479
3480 if (NILP (event0))
3481 return Qnil;
3482
3483 menubar_widget = FRAME_X_MENUBAR_WIDGET (f);
3484 if (menubar_widget
3485 && CONSP (Vmenu_accelerator_modifiers))
3486 {
3487 Lisp_Object fake;
3488 Lisp_Object last = Qnil;
3489 struct gcpro gcpro1;
3490 Lisp_Object matchp;
3491
3492 widget_value *val;
3493 LWLIB_ID id = XPOPUP_DATA (f->menubar_data)->id;
3494
3495 val = lw_get_all_values (id);
3496 if (val)
3497 {
3498 val = val->contents;
3499
3500 fake = Fcopy_sequence (Vmenu_accelerator_modifiers);
3501 last = fake;
3502
3503 while (!NILP (Fcdr (last)))
3504 last = Fcdr (last);
3505
3506 Fsetcdr (last, Fcons (Qnil, Qnil));
3507 last = Fcdr (last);
3508 }
3509
3510 fake = Fcons (Qnil, fake);
3511
3512 GCPRO1 (fake);
3513
3514 while (val)
3515 {
3516 Lisp_Object accel;
3517 VOID_TO_LISP (accel, val->accel);
3518 if (val->name && !NILP (accel))
3519 {
3520 Fsetcar (last, accel);
3521 Fsetcar (fake, event0);
3522 matchp = condition_case_1 (Qerror,
3523 menu_accelerator_safe_mod_compare,
3524 fake,
3525 menu_accelerator_junk_on_error,
3526 Qnil);
3527 if (!NILP (matchp))
3528 {
3529 /* we found one! */
3530
3531 lw_set_menu (menubar_widget, val);
3532 /* yah - yet another hack.
3533 pretend emacs timestamp is the same as an X timestamp,
3534 which for the moment it is. (read events.h)
3535 */
3536 lw_map_menu (XEVENT (event0)->timestamp);
3537
3538 if (val->contents)
3539 lw_push_menu (val->contents);
3540
3541 lw_display_menu (CurrentTime);
3542
3543 /* menu accelerator keys don't go into keyboard macros */
3544 if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro))
3545 con->kbd_macro_ptr = con->kbd_macro_end;
3546
3547 /* don't echo menu accelerator keys */
3548 /*reset_key_echo (builder, 1);*/
3549 reset_this_command_keys (Vselected_console, 1);
3550 UNGCPRO;
3551
3552 return Vmenu_accelerator_map;
3553 }
3554 }
3555
3556 val = val->next;
3557 }
3558
3559 UNGCPRO;
3560 }
3561 return Qnil;
3562 }
3563
3564
3565 DEFUN ("accelerate-menu", Faccelerate_menu, 0, 0, "_", /*
3566 Make the menubar active. Menu items can be selected using menu accelerators
3567 or by actions defined in menu-accelerator-map.
3568 */
3569 ())
3570 {
3571 struct console *con = XCONSOLE (Vselected_console);
3572 struct frame *f = XFRAME (CONSOLE_SELECTED_FRAME (con));
3573 LWLIB_ID id;
3574 widget_value *val;
3575
3576 if (NILP (f->menubar_data))
3577 error ("Frame has no menubar.");
3578
3579 id = XPOPUP_DATA (f->menubar_data)->id;
3580 val = lw_get_all_values (id);
3581 val = val->contents;
3582 lw_set_menu (FRAME_X_MENUBAR_WIDGET (f), val);
3583 lw_map_menu (CurrentTime);
3584
3585 lw_display_menu (CurrentTime);
3586
3587 /* menu accelerator keys don't go into keyboard macros */
3588 if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro))
3589 con->kbd_macro_ptr = con->kbd_macro_end;
3590
3591 return Qnil;
3592 }
3593 #endif /* HAVE_X_WINDOWS && HAVE_MENUBARS */
3594
3595 /* See if we can do function-key-map or key-translation-map translation 3115 /* See if we can do function-key-map or key-translation-map translation
3596 on the current events in the command builder. If so, do this, and 3116 on the current events in the command builder. If so, do this, and
3597 return the resulting binding, if any. */ 3117 return the resulting binding, if any. */
3598 3118
3599 static Lisp_Object 3119 static Lisp_Object
3711 XEVENT (evee)->event.eval.object); 3231 XEVENT (evee)->event.eval.object);
3712 else 3232 else
3713 return Qnil; 3233 return Qnil;
3714 } 3234 }
3715 3235
3716 /* if we're currently in a menu accelerator, check there for further events */ 3236 /* if we're currently in a menu accelerator, check there for further
3237 events */
3238 /* #### fuck me! who wrote this crap? think "abstraction", baby. */
3717 #if defined(HAVE_X_WINDOWS) && defined(LWLIB_MENUBARS_LUCID) 3239 #if defined(HAVE_X_WINDOWS) && defined(LWLIB_MENUBARS_LUCID)
3718 if (lw_menu_active) 3240 if (x_kludge_lw_menu_active ())
3719 { 3241 {
3720 return command_builder_operate_menu_accelerator (builder); 3242 return command_builder_operate_menu_accelerator (builder);
3721 } 3243 }
3722 else 3244 else
3723 { 3245 {
3764 && !NILP (Vretry_undefined_key_binding_unshifted)) 3286 && !NILP (Vretry_undefined_key_binding_unshifted))
3765 { 3287 {
3766 Lisp_Object terminal = builder->most_current_event; 3288 Lisp_Object terminal = builder->most_current_event;
3767 struct key_data* key = & XEVENT (terminal)->event.key; 3289 struct key_data* key = & XEVENT (terminal)->event.key;
3768 Emchar c = 0; 3290 Emchar c = 0;
3769 if ((key->modifiers & MOD_SHIFT) 3291 if ((key->modifiers & XEMACS_MOD_SHIFT)
3770 || (CHAR_OR_CHAR_INTP (key->keysym) 3292 || (CHAR_OR_CHAR_INTP (key->keysym)
3771 && ((c = XCHAR_OR_CHAR_INT (key->keysym)), c >= 'A' && c <= 'Z'))) 3293 && ((c = XCHAR_OR_CHAR_INT (key->keysym)), c >= 'A' && c <= 'Z')))
3772 { 3294 {
3773 Lisp_Event terminal_copy = *XEVENT (terminal); 3295 Lisp_Event terminal_copy = *XEVENT (terminal);
3774 3296
3775 if (key->modifiers & MOD_SHIFT) 3297 if (key->modifiers & XEMACS_MOD_SHIFT)
3776 key->modifiers &= (~ MOD_SHIFT); 3298 key->modifiers &= (~ XEMACS_MOD_SHIFT);
3777 else 3299 else
3778 key->keysym = make_char (c + 'a' - 'A'); 3300 key->keysym = make_char (c + 'a' - 'A');
3779 3301
3780 result = command_builder_find_leaf (builder, allow_misc_user_events_p); 3302 result = command_builder_find_leaf (builder, allow_misc_user_events_p);
3781 if (!NILP (result)) 3303 if (!NILP (result))
4172 pushing a new event. 3694 pushing a new event.
4173 */ 3695 */
4174 Fcopy_event (event, recent); 3696 Fcopy_event (event, recent);
4175 e = XEVENT (recent); 3697 e = XEVENT (recent);
4176 if (e->event_type == key_press_event) 3698 if (e->event_type == key_press_event)
4177 e->event.key.modifiers |= MOD_META; 3699 e->event.key.modifiers |= XEMACS_MOD_META;
4178 else if (e->event_type == button_press_event 3700 else if (e->event_type == button_press_event
4179 || e->event_type == button_release_event) 3701 || e->event_type == button_release_event)
4180 e->event.button.modifiers |= MOD_META; 3702 e->event.button.modifiers |= XEMACS_MOD_META;
4181 else 3703 else
4182 abort (); 3704 abort ();
4183 3705
4184 { 3706 {
4185 int tckn = event_chain_count (Vthis_command_keys); 3707 int tckn = event_chain_count (Vthis_command_keys);
4206 struct gcpro gcpro1; 3728 struct gcpro gcpro1;
4207 GCPRO1 (leaf); 3729 GCPRO1 (leaf);
4208 3730
4209 if (KEYMAPP (leaf)) 3731 if (KEYMAPP (leaf))
4210 { 3732 {
4211 if (!lw_menu_active) 3733 #if defined (HAVE_X_WINDOWS) && defined (LWLIB_MENUBARS_LUCID)
3734 if (!x_kludge_lw_menu_active ())
3735 #else
3736 if (1)
3737 #endif
4212 { 3738 {
4213 Lisp_Object prompt = Fkeymap_prompt (leaf, Qt); 3739 Lisp_Object prompt = Fkeymap_prompt (leaf, Qt);
4214 if (STRINGP (prompt)) 3740 if (STRINGP (prompt))
4215 { 3741 {
4216 /* Append keymap prompt to key echo buffer */ 3742 /* Append keymap prompt to key echo buffer */
4226 maybe_echo_keys (command_builder, 1); 3752 maybe_echo_keys (command_builder, 1);
4227 } 3753 }
4228 else 3754 else
4229 maybe_echo_keys (command_builder, 0); 3755 maybe_echo_keys (command_builder, 0);
4230 } 3756 }
4231 else if (!NILP (Vquit_flag)) { 3757 else if (!NILP (Vquit_flag))
4232 Lisp_Object quit_event = Fmake_event(Qnil, Qnil); 3758 {
4233 Lisp_Event *e = XEVENT (quit_event); 3759 Lisp_Object quit_event = Fmake_event (Qnil, Qnil);
4234 /* if quit happened during menu acceleration, pretend we read it */ 3760 Lisp_Event *e = XEVENT (quit_event);
4235 struct console *con = XCONSOLE (Fselected_console ()); 3761 /* if quit happened during menu acceleration, pretend we read it */
4236 int ch = CONSOLE_QUIT_CHAR (con); 3762 struct console *con = XCONSOLE (Fselected_console ());
4237 3763 int ch = CONSOLE_QUIT_CHAR (con);
4238 character_to_event (ch, e, con, 1, 1); 3764
4239 e->channel = make_console (con); 3765 character_to_event (ch, e, con, 1, 1);
4240 3766 e->channel = make_console (con);
4241 enqueue_command_event (quit_event); 3767
4242 Vquit_flag = Qnil; 3768 enqueue_command_event (quit_event);
4243 } 3769 Vquit_flag = Qnil;
3770 }
4244 } 3771 }
4245 else if (!NILP (leaf)) 3772 else if (!NILP (leaf))
4246 { 3773 {
4247 if (EQ (Qcommand, echo_area_status (f)) 3774 if (EQ (Qcommand, echo_area_status (f))
4248 && command_builder->echo_buf_index > 0) 3775 && command_builder->echo_buf_index > 0)
4357 } 3884 }
4358 else 3885 else
4359 { 3886 {
4360 /* Start a new command next time */ 3887 /* Start a new command next time */
4361 Vlast_command = Vthis_command; 3888 Vlast_command = Vthis_command;
3889 Vlast_command_properties = Vthis_command_properties;
3890 Vthis_command_properties = Qnil;
3891
4362 /* Emacs 18 doesn't unconditionally clear the echoed keystrokes, 3892 /* Emacs 18 doesn't unconditionally clear the echoed keystrokes,
4363 so we don't either */ 3893 so we don't either */
4364 reset_this_command_keys (make_console (con), 0); 3894 reset_this_command_keys (make_console (con), 0);
4365 } 3895 }
4366 } 3896 }
4377 XSETBUFFER (last_point_position_buffer, current_buffer); 3907 XSETBUFFER (last_point_position_buffer, current_buffer);
4378 /* This function can GC */ 3908 /* This function can GC */
4379 safe_run_hook_trapping_errors 3909 safe_run_hook_trapping_errors
4380 ("Error in `pre-command-hook' (setting hook to nil)", 3910 ("Error in `pre-command-hook' (setting hook to nil)",
4381 Qpre_command_hook, 1); 3911 Qpre_command_hook, 1);
3912
3913 /* This is a kludge, but necessary; see simple.el */
3914 call0 (Qhandle_pre_motion_command);
4382 } 3915 }
4383 3916
4384 /* Run the post command hook. */ 3917 /* Run the post command hook. */
4385 3918
4386 static void 3919 static void
4396 we don't want the user to accidentally remove it. 3929 we don't want the user to accidentally remove it.
4397 */ 3930 */
4398 3931
4399 Lisp_Object win = Fselected_window (Qnil); 3932 Lisp_Object win = Fselected_window (Qnil);
4400 3933
4401 #if 0
4402 /* If the last command deleted the frame, `win' might be nil. 3934 /* If the last command deleted the frame, `win' might be nil.
4403 It seems safest to do nothing in this case. */ 3935 It seems safest to do nothing in this case. */
3936 /* Note: Someone added the following comment and put #if 0's around
3937 this code, not realizing that doing this invites a crash in the
3938 line after. */
4404 /* #### This doesn't really fix the problem, 3939 /* #### This doesn't really fix the problem,
4405 if delete-frame is called by some hook */ 3940 if delete-frame is called by some hook */
4406 if (NILP (win)) 3941 if (NILP (win))
4407 return; 3942 return;
4408 #endif 3943
3944 /* This is a kludge, but necessary; see simple.el */
3945 call0 (Qhandle_post_motion_command);
4409 3946
4410 if (! zmacs_region_stays 3947 if (! zmacs_region_stays
4411 && (!MINI_WINDOW_P (XWINDOW (win)) 3948 && (!MINI_WINDOW_P (XWINDOW (win))
4412 || EQ (zmacs_region_buffer (), WINDOW_BUFFER (XWINDOW (win))))) 3949 || EQ (zmacs_region_buffer (), WINDOW_BUFFER (XWINDOW (win)))))
4413 zmacs_deactivate_region (); 3950 zmacs_deactivate_region ();
4416 3953
4417 safe_run_hook_trapping_errors 3954 safe_run_hook_trapping_errors
4418 ("Error in `post-command-hook' (setting hook to nil)", 3955 ("Error in `post-command-hook' (setting hook to nil)",
4419 Qpost_command_hook, 1); 3956 Qpost_command_hook, 1);
4420 3957
4421 #ifdef DEFERRED_ACTION_CRAP 3958 #if 0 /* FSF Emacs crap */
4422 if (!NILP (Vdeferred_action_list)) 3959 if (!NILP (Vdeferred_action_list))
4423 call0 (Vdeferred_action_function); 3960 call0 (Vdeferred_action_function);
4424 #endif 3961
4425
4426 #ifdef ILL_CONCEIVED_HOOK
4427 if (NILP (Vunread_command_events) 3962 if (NILP (Vunread_command_events)
4428 && NILP (Vexecuting_macro) 3963 && NILP (Vexecuting_macro)
4429 && !NILP (Vpost_command_idle_hook) 3964 && !NILP (Vpost_command_idle_hook)
4430 && !NILP (Fsit_for (make_float ((double) post_command_idle_delay 3965 && !NILP (Fsit_for (make_float ((double) post_command_idle_delay
4431 / 1000000), Qnil))) 3966 / 1000000), Qnil)))
4432 safe_run_hook_trapping_errors 3967 safe_run_hook_trapping_errors
4433 ("Error in `post-command-idle-hook' (setting hook to nil)", 3968 ("Error in `post-command-idle-hook' (setting hook to nil)",
4434 Qpost_command_idle_hook, 1); 3969 Qpost_command_idle_hook, 1);
4435 #endif 3970 #endif /* FSF Emacs crap */
4436 3971
4437 #if 0 /* FSFmacs */ 3972 #if 0 /* FSF Emacs */
4438 if (!NILP (current_buffer->mark_active)) 3973 if (!NILP (current_buffer->mark_active))
4439 { 3974 {
4440 if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode)) 3975 if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode))
4441 { 3976 {
4442 current_buffer->mark_active = Qnil; 3977 current_buffer->mark_active = Qnil;
4444 } 3979 }
4445 else if (current_buffer != prev_buffer || 3980 else if (current_buffer != prev_buffer ||
4446 BUF_MODIFF (current_buffer) != prev_modiff) 3981 BUF_MODIFF (current_buffer) != prev_modiff)
4447 run_hook (intern ("activate-mark-hook")); 3982 run_hook (intern ("activate-mark-hook"));
4448 } 3983 }
4449 #endif /* FSFmacs */ 3984 #endif /* FSF Emacs */
4450 3985
4451 /* #### Kludge!!! This is necessary to make sure that things 3986 /* #### Kludge!!! This is necessary to make sure that things
4452 are properly positioned even if post-command-hook moves point. 3987 are properly positioned even if post-command-hook moves point.
4453 #### There should be a cleaner way of handling this. */ 3988 #### There should be a cleaner way of handling this. */
4454 call0 (Qauto_show_make_point_visible); 3989 call0 (Qauto_show_make_point_visible);
4604 minibuffer. If the command we are about to execute is 4139 minibuffer. If the command we are about to execute is
4605 self-insert, it's tricky: up to 20 consecutive self-inserts may 4140 self-insert, it's tricky: up to 20 consecutive self-inserts may
4606 be done without an undo boundary. This counter is reset as 4141 be done without an undo boundary. This counter is reset as
4607 soon as a command other than self-insert-command is executed. 4142 soon as a command other than self-insert-command is executed.
4608 4143
4609 Programmers can also use the `self-insert-undo-magic' 4144 Programmers can also use the `self-insert-defer-undo'
4610 property to install that behaviour on functions other 4145 property to install that behavior on functions other
4611 than `self-insert-command', or to change the magic 4146 than `self-insert-command', or to change the magic
4612 number 20 to something else. */ 4147 number 20 to something else. #### DOCUMENT THIS! */
4613 4148
4614 if (SYMBOLP (leaf)) 4149 if (SYMBOLP (leaf))
4615 { 4150 {
4616 Lisp_Object prop = Fget (leaf, Qself_insert_defer_undo, Qnil); 4151 Lisp_Object prop = Fget (leaf, Qself_insert_defer_undo, Qnil);
4617 if (NATNUMP (prop)) 4152 if (NATNUMP (prop))
4901 } 4436 }
4902 return Qnil; 4437 return Qnil;
4903 } 4438 }
4904 4439
4905 4440
4441
4442 DEFUN ("current-event-timestamp", Fcurrent_event_timestamp, 0, 1, 0, /*
4443 Return the current event timestamp of the window system associated with CONSOLE.
4444 CONSOLE defaults to the selected console if omitted.
4445 */
4446 (console))
4447 {
4448 struct console *c = decode_console (console);
4449 int tiempo = event_stream_current_event_timestamp (c);
4450
4451 /* This junk is so that timestamps don't get to be negative, but contain
4452 as many bits as this particular emacs will allow.
4453 */
4454 return make_int (((1L << (VALBITS - 1)) - 1) & tiempo);
4455 }
4456
4457
4906 /************************************************************************/ 4458 /************************************************************************/
4907 /* initialization */ 4459 /* initialization */
4908 /************************************************************************/ 4460 /************************************************************************/
4909 4461
4910 void 4462 void
4911 syms_of_event_stream (void) 4463 syms_of_event_stream (void)
4912 { 4464 {
4465 INIT_LRECORD_IMPLEMENTATION (command_builder);
4466 INIT_LRECORD_IMPLEMENTATION (timeout);
4467
4913 defsymbol (&Qdisabled, "disabled"); 4468 defsymbol (&Qdisabled, "disabled");
4914 defsymbol (&Qcommand_event_p, "command-event-p"); 4469 defsymbol (&Qcommand_event_p, "command-event-p");
4915 4470
4916 deferror (&Qundefined_keystroke_sequence, "undefined-keystroke-sequence", 4471 DEFERROR_STANDARD (Qundefined_keystroke_sequence, Qinvalid_argument);
4917 "Undefined keystroke sequence", Qerror);
4918 4472
4919 DEFSUBR (Frecent_keys); 4473 DEFSUBR (Frecent_keys);
4920 DEFSUBR (Frecent_keys_ring_size); 4474 DEFSUBR (Frecent_keys_ring_size);
4921 DEFSUBR (Fset_recent_keys_ring_size); 4475 DEFSUBR (Fset_recent_keys_ring_size);
4922 DEFSUBR (Finput_pending_p); 4476 DEFSUBR (Finput_pending_p);
4930 DEFSUBR (Fadd_timeout); 4484 DEFSUBR (Fadd_timeout);
4931 DEFSUBR (Fdisable_timeout); 4485 DEFSUBR (Fdisable_timeout);
4932 DEFSUBR (Fadd_async_timeout); 4486 DEFSUBR (Fadd_async_timeout);
4933 DEFSUBR (Fdisable_async_timeout); 4487 DEFSUBR (Fdisable_async_timeout);
4934 DEFSUBR (Fdispatch_event); 4488 DEFSUBR (Fdispatch_event);
4489 DEFSUBR (Fdispatch_non_command_events);
4935 DEFSUBR (Fread_key_sequence); 4490 DEFSUBR (Fread_key_sequence);
4936 DEFSUBR (Fthis_command_keys); 4491 DEFSUBR (Fthis_command_keys);
4937 DEFSUBR (Freset_this_command_lengths); 4492 DEFSUBR (Freset_this_command_lengths);
4938 DEFSUBR (Fopen_dribble_file); 4493 DEFSUBR (Fopen_dribble_file);
4939 #if defined(HAVE_X_WINDOWS) && defined(LWLIB_MENUBARS_LUCID) 4494 DEFSUBR (Fcurrent_event_timestamp);
4940 DEFSUBR (Faccelerate_menu);
4941 #endif
4942 4495
4943 defsymbol (&Qpre_command_hook, "pre-command-hook"); 4496 defsymbol (&Qpre_command_hook, "pre-command-hook");
4944 defsymbol (&Qpost_command_hook, "post-command-hook"); 4497 defsymbol (&Qpost_command_hook, "post-command-hook");
4945 defsymbol (&Qunread_command_events, "unread-command-events"); 4498 defsymbol (&Qunread_command_events, "unread-command-events");
4946 defsymbol (&Qunread_command_event, "unread-command-event"); 4499 defsymbol (&Qunread_command_event, "unread-command-event");
4947 defsymbol (&Qpre_idle_hook, "pre-idle-hook"); 4500 defsymbol (&Qpre_idle_hook, "pre-idle-hook");
4948 #ifdef ILL_CONCEIVED_HOOK 4501 defsymbol (&Qhandle_pre_motion_command, "handle-pre-motion-command");
4502 defsymbol (&Qhandle_post_motion_command, "handle-post-motion-command");
4503 #if 0 /* FSF Emacs crap */
4949 defsymbol (&Qpost_command_idle_hook, "post-command-idle-hook"); 4504 defsymbol (&Qpost_command_idle_hook, "post-command-idle-hook");
4950 #endif
4951 #ifdef DEFERRED_ACTION_CRAP
4952 defsymbol (&Qdeferred_action_function, "deferred-action-function"); 4505 defsymbol (&Qdeferred_action_function, "deferred-action-function");
4953 #endif 4506 #endif
4954 defsymbol (&Qretry_undefined_key_binding_unshifted, 4507 defsymbol (&Qretry_undefined_key_binding_unshifted,
4955 "retry-undefined-key-binding-unshifted"); 4508 "retry-undefined-key-binding-unshifted");
4956 defsymbol (&Qauto_show_make_point_visible, 4509 defsymbol (&Qauto_show_make_point_visible,
4957 "auto-show-make-point-visible"); 4510 "auto-show-make-point-visible");
4958
4959 defsymbol (&Qmenu_force, "menu-force");
4960 defsymbol (&Qmenu_fallback, "menu-fallback");
4961
4962 defsymbol (&Qmenu_quit, "menu-quit");
4963 defsymbol (&Qmenu_up, "menu-up");
4964 defsymbol (&Qmenu_down, "menu-down");
4965 defsymbol (&Qmenu_left, "menu-left");
4966 defsymbol (&Qmenu_right, "menu-right");
4967 defsymbol (&Qmenu_select, "menu-select");
4968 defsymbol (&Qmenu_escape, "menu-escape");
4969 4511
4970 defsymbol (&Qself_insert_defer_undo, "self-insert-defer-undo"); 4512 defsymbol (&Qself_insert_defer_undo, "self-insert-defer-undo");
4971 defsymbol (&Qcancel_mode_internal, "cancel-mode-internal"); 4513 defsymbol (&Qcancel_mode_internal, "cancel-mode-internal");
4972 } 4514 }
4973 4515
5045 DEFVAR_LISP ("pre-idle-hook", &Vpre_idle_hook /* 4587 DEFVAR_LISP ("pre-idle-hook", &Vpre_idle_hook /*
5046 Normal hook run when XEmacs it about to be idle. 4588 Normal hook run when XEmacs it about to be idle.
5047 This occurs whenever it is going to block, waiting for an event. 4589 This occurs whenever it is going to block, waiting for an event.
5048 This generally happens as a result of a call to `next-event', 4590 This generally happens as a result of a call to `next-event',
5049 `next-command-event', `sit-for', `sleep-for', `accept-process-output', 4591 `next-command-event', `sit-for', `sleep-for', `accept-process-output',
5050 `x-get-selection', or various Energize-specific commands. 4592 or `x-get-selection'.
5051 Errors running the hook are caught and ignored. 4593 Errors running the hook are caught and ignored.
5052 */ ); 4594 */ );
5053 Vpre_idle_hook = Qnil; 4595 Vpre_idle_hook = Qnil;
5054 4596
5055 DEFVAR_BOOL ("focus-follows-mouse", &focus_follows_mouse /* 4597 DEFVAR_BOOL ("focus-follows-mouse", &focus_follows_mouse /*
5058 the keyboard focus. XEmacs cannot in general detect when this mode is 4600 the keyboard focus. XEmacs cannot in general detect when this mode is
5059 used by the window manager, so it is up to the user to set it. 4601 used by the window manager, so it is up to the user to set it.
5060 */ ); 4602 */ );
5061 focus_follows_mouse = 0; 4603 focus_follows_mouse = 0;
5062 4604
5063 #ifdef ILL_CONCEIVED_HOOK 4605 #if 0 /* FSF Emacs crap */
5064 /* Ill-conceived because it's not run in all sorts of cases 4606 /* Ill-conceived because it's not run in all sorts of cases
5065 where XEmacs is blocking. That's what `pre-idle-hook' 4607 where XEmacs is blocking. That's what `pre-idle-hook'
5066 is designed to solve. */ 4608 is designed to solve. */
5067 xxDEFVAR_LISP ("post-command-idle-hook", &Vpost_command_idle_hook /* 4609 xxDEFVAR_LISP ("post-command-idle-hook", &Vpost_command_idle_hook /*
5068 Normal hook run after each command is executed, if idle. 4610 Normal hook run after each command is executed, if idle.
5075 xxDEFVAR_INT ("post-command-idle-delay", &post_command_idle_delay /* 4617 xxDEFVAR_INT ("post-command-idle-delay", &post_command_idle_delay /*
5076 Delay time before running `post-command-idle-hook'. 4618 Delay time before running `post-command-idle-hook'.
5077 This is measured in microseconds. 4619 This is measured in microseconds.
5078 */ ); 4620 */ );
5079 post_command_idle_delay = 5000; 4621 post_command_idle_delay = 5000;
5080 #endif /* ILL_CONCEIVED_HOOK */ 4622
5081
5082 #ifdef DEFERRED_ACTION_CRAP
5083 /* Random FSFmacs crap. There is absolutely nothing to gain, 4623 /* Random FSFmacs crap. There is absolutely nothing to gain,
5084 and a great deal to lose, in using this in place of just 4624 and a great deal to lose, in using this in place of just
5085 setting `post-command-hook'. */ 4625 setting `post-command-hook'. */
5086 xxDEFVAR_LISP ("deferred-action-list", &Vdeferred_action_list /* 4626 xxDEFVAR_LISP ("deferred-action-list", &Vdeferred_action_list /*
5087 List of deferred actions to be performed at a later time. 4627 List of deferred actions to be performed at a later time.
5093 Function to call to handle deferred actions, after each command. 4633 Function to call to handle deferred actions, after each command.
5094 This function is called with no arguments after each command 4634 This function is called with no arguments after each command
5095 whenever `deferred-action-list' is non-nil. 4635 whenever `deferred-action-list' is non-nil.
5096 */ ); 4636 */ );
5097 Vdeferred_action_function = Qnil; 4637 Vdeferred_action_function = Qnil;
5098 #endif /* DEFERRED_ACTION_CRAP */ 4638 #endif /* FSF Emacs crap */
5099 4639
5100 DEFVAR_LISP ("last-command-event", &Vlast_command_event /* 4640 DEFVAR_LISP ("last-command-event", &Vlast_command_event /*
5101 Last keyboard or mouse button event that was part of a command. This 4641 Last keyboard or mouse button event that was part of a command. This
5102 variable is off limits: you may not set its value or modify the event that 4642 variable is off limits: you may not set its value or modify the event that
5103 is its value, as it is destructively modified by `read-key-sequence'. If 4643 is its value, as it is destructively modified by `read-key-sequence'. If
5183 The command can set this variable; whatever is put here 4723 The command can set this variable; whatever is put here
5184 will be in `last-command' during the following command. 4724 will be in `last-command' during the following command.
5185 */ ); 4725 */ );
5186 Vthis_command = Qnil; 4726 Vthis_command = Qnil;
5187 4727
4728 DEFVAR_LISP ("last-command-properties", &Vlast_command_properties /*
4729 Value of `this-command-properties' for the last command.
4730 Used by commands to help synchronize consecutive commands, in preference
4731 to looking at `last-command' directly.
4732 */ );
4733 Vlast_command_properties = Qnil;
4734
4735 DEFVAR_LISP ("this-command-properties", &Vthis_command_properties /*
4736 Properties set by the current command.
4737 At the beginning of each command, the current value of this variable is
4738 copied to `last-command-properties', and then it is set to nil. Use `putf'
4739 to add properties to this variable. Commands should use this to communicate
4740 with pre/post-command hooks, subsequent commands, wrapping commands, etc.
4741 in preference to looking at and/or setting `this-command'.
4742 */ );
4743 Vthis_command_properties = Qnil;
4744
5188 DEFVAR_LISP ("help-char", &Vhelp_char /* 4745 DEFVAR_LISP ("help-char", &Vhelp_char /*
5189 Character to recognize as meaning Help. 4746 Character to recognize as meaning Help.
5190 When it is read, do `(eval help-form)', and display result if it's a string. 4747 When it is read, do `(eval help-form)', and display result if it's a string.
5191 If the value of `help-form' is nil, this char can be read normally. 4748 If the value of `help-form' is nil, this char can be read normally.
5192 This can be any form recognized as a single key specifier. 4749 This can be any form recognized as a single key specifier.
5216 -- If an entry maps a symbol to a symbol, then a key-press event whose 4773 -- If an entry maps a symbol to a symbol, then a key-press event whose
5217 keysym is the former symbol (with any modifiers at all) gets its 4774 keysym is the former symbol (with any modifiers at all) gets its
5218 keysym changed and its modifiers left alone. This is useful for 4775 keysym changed and its modifiers left alone. This is useful for
5219 dealing with non-standard X keyboards, such as the grievous damage 4776 dealing with non-standard X keyboards, such as the grievous damage
5220 that Sun has inflicted upon the world. 4777 that Sun has inflicted upon the world.
4778 -- If an entry maps a symbol to a character, then a key-press event
4779 whose keysym is the former symbol (with any modifiers at all) gets
4780 changed into a key-press event matching the latter character, and the
4781 resulting modifiers are the union of the original and new modifiers.
5221 -- If an entry maps a character to a character, then a key-press event 4782 -- If an entry maps a character to a character, then a key-press event
5222 matching the former character gets converted to a key-press event 4783 matching the former character gets converted to a key-press event
5223 matching the latter character. This is useful on ASCII terminals 4784 matching the latter character. This is useful on ASCII terminals
5224 for (e.g.) making C-\\ look like C-s, to get around flow-control 4785 for (e.g.) making C-\\ look like C-s, to get around flow-control
5225 problems. 4786 problems.
5226 -- If an entry maps a character to a symbol, then a key-press event 4787 -- If an entry maps a character to a symbol, then a key-press event
5227 matching the character gets converted to a key-press event whose 4788 matching the character gets converted to a key-press event whose
5228 keysym is the given symbol and which has no modifiers. 4789 keysym is the given symbol and which has no modifiers.
4790
4791 Here's an example: This makes typing parens and braces easier by rerouting
4792 their positions to eliminate the need to use the Shift key.
4793
4794 (keyboard-translate ?[ ?()
4795 (keyboard-translate ?] ?))
4796 (keyboard-translate ?{ ?[)
4797 (keyboard-translate ?} ?])
4798 (keyboard-translate 'f11 ?{)
4799 (keyboard-translate 'f12 ?})
5229 */ ); 4800 */ );
5230 4801
5231 DEFVAR_LISP ("retry-undefined-key-binding-unshifted", 4802 DEFVAR_LISP ("retry-undefined-key-binding-unshifted",
5232 &Vretry_undefined_key_binding_unshifted /* 4803 &Vretry_undefined_key_binding_unshifted /*
5233 If a key-sequence which ends with a shifted keystroke is undefined 4804 If a key-sequence which ends with a shifted keystroke is undefined
5235 with the last key unshifted. (e.g. C-X C-F would be retried as C-X C-f.) 4806 with the last key unshifted. (e.g. C-X C-F would be retried as C-X C-f.)
5236 If lookup still fails, a normal error is signalled. In general, 4807 If lookup still fails, a normal error is signalled. In general,
5237 you should *bind* this, not set it. 4808 you should *bind* this, not set it.
5238 */ ); 4809 */ );
5239 Vretry_undefined_key_binding_unshifted = Qt; 4810 Vretry_undefined_key_binding_unshifted = Qt;
4811
4812 DEFVAR_BOOL ("modifier-keys-are-sticky", &modifier_keys_are_sticky /*
4813 *Non-nil makes modifier keys sticky.
4814 This means that you can release the modifier key before pressing down
4815 the key that you wish to be modified. Although this is non-standard
4816 behavior, it is recommended because it reduces the strain on your hand,
4817 thus reducing the incidence of the dreaded Emacs-pinky syndrome.
4818 */ );
4819 modifier_keys_are_sticky = 0;
5240 4820
5241 #ifdef HAVE_XIM 4821 #ifdef HAVE_XIM
5242 DEFVAR_LISP ("composed-character-default-binding", 4822 DEFVAR_LISP ("composed-character-default-binding",
5243 &Vcomposed_character_default_binding /* 4823 &Vcomposed_character_default_binding /*
5244 The default keybinding to use for key events from composed input. 4824 The default keybinding to use for key events from composed input.
5296 4876
5297 DEFVAR_BOOL ("inhibit-input-event-recording", &inhibit_input_event_recording /* 4877 DEFVAR_BOOL ("inhibit-input-event-recording", &inhibit_input_event_recording /*
5298 Non-nil inhibits recording of input-events to recent-keys ring. 4878 Non-nil inhibits recording of input-events to recent-keys ring.
5299 */ ); 4879 */ );
5300 inhibit_input_event_recording = 0; 4880 inhibit_input_event_recording = 0;
5301
5302 DEFVAR_LISP("menu-accelerator-prefix", &Vmenu_accelerator_prefix /*
5303 Prefix key(s) that must be typed before menu accelerators will be activated.
5304 Set this to a value acceptable by define-key.
5305 */ );
5306 Vmenu_accelerator_prefix = Qnil;
5307
5308 DEFVAR_LISP ("menu-accelerator-modifiers", &Vmenu_accelerator_modifiers /*
5309 Modifier keys which must be pressed to get to the top level menu accelerators.
5310 This is a list of modifier key symbols. All modifier keys must be held down
5311 while a valid menu accelerator key is pressed in order for the top level
5312 menu to become active.
5313
5314 See also menu-accelerator-enabled and menu-accelerator-prefix.
5315 */ );
5316 Vmenu_accelerator_modifiers = list1 (Qmeta);
5317
5318 DEFVAR_LISP ("menu-accelerator-enabled", &Vmenu_accelerator_enabled /*
5319 Whether menu accelerator keys can cause the menubar to become active.
5320 If 'menu-force or 'menu-fallback, then menu accelerator keys can
5321 be used to activate the top level menu. Once the menubar becomes active, the
5322 accelerator keys can be used regardless of the value of this variable.
5323
5324 menu-force is used to indicate that the menu accelerator key takes
5325 precedence over bindings in the current keymap(s). menu-fallback means
5326 that bindings in the current keymap take precedence over menu accelerator keys.
5327 Thus a top level menu with an accelerator of "T" would be activated on a
5328 keypress of Meta-t if menu-accelerator-enabled is menu-force.
5329 However, if menu-accelerator-enabled is menu-fallback, then
5330 Meta-t will not activate the menubar and will instead run the function
5331 transpose-words, to which it is normally bound.
5332
5333 See also menu-accelerator-modifiers and menu-accelerator-prefix.
5334 */ );
5335 Vmenu_accelerator_enabled = Qnil;
5336 } 4881 }
5337 4882
5338 void 4883 void
5339 complex_vars_of_event_stream (void) 4884 complex_vars_of_event_stream (void)
5340 { 4885 {
5341 Vkeyboard_translate_table = 4886 Vkeyboard_translate_table =
5342 make_lisp_hash_table (100, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ); 4887 make_lisp_hash_table (100, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
5343
5344 DEFVAR_LISP ("menu-accelerator-map", &Vmenu_accelerator_map /*
5345 Keymap for use when the menubar is active.
5346 The actions menu-quit, menu-up, menu-down, menu-left, menu-right,
5347 menu-select and menu-escape can be mapped to keys in this map.
5348
5349 menu-quit Immediately deactivate the menubar and any open submenus without
5350 selecting an item.
5351 menu-up Move the menu cursor up one row in the current menu. If the
5352 move extends past the top of the menu, wrap around to the bottom.
5353 menu-down Move the menu cursor down one row in the current menu. If the
5354 move extends past the bottom of the menu, wrap around to the top.
5355 If executed while the cursor is in the top level menu, move down
5356 into the selected menu.
5357 menu-left Move the cursor from a submenu into the parent menu. If executed
5358 while the cursor is in the top level menu, move the cursor to the
5359 left. If the move extends past the left edge of the menu, wrap
5360 around to the right edge.
5361 menu-right Move the cursor into a submenu. If the cursor is located in the
5362 top level menu or is not currently on a submenu heading, then move
5363 the cursor to the next top level menu entry. If the move extends
5364 past the right edge of the menu, wrap around to the left edge.
5365 menu-select Activate the item under the cursor. If the cursor is located on
5366 a submenu heading, then move the cursor into the submenu.
5367 menu-escape Pop up to the next level of menus. Moves from a submenu into its
5368 parent menu. From the top level menu, this deactivates the
5369 menubar.
5370
5371 This keymap can also contain normal key-command bindings, in which case the
5372 menubar is deactivated and the corresponding command is executed.
5373
5374 The action bindings used by the menu accelerator code are designed to mimic
5375 the actions of menu traversal keys in a commonly used PC operating system.
5376 */ );
5377 Vmenu_accelerator_map = Fmake_keymap(Qnil);
5378 } 4888 }
5379 4889
5380 void 4890 void
5381 init_event_stream (void) 4891 init_event_stream (void)
5382 { 4892 {