(Fx_create_frame): Set default frame parameter value
[bpt/emacs.git] / src / keyboard.c
CommitLineData
284f4730 1/* Keyboard and mouse input; editor command loop.
39aab679
DL
2 Copyright (C) 1985,86,87,88,89,93,94,95,96,97,99, 2000
3 Free Software Foundation, Inc.
284f4730
JB
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
7b4aedb9 9the Free Software Foundation; either version 2, or (at your option)
284f4730
JB
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
284f4730 21
18160b98 22#include <config.h>
68c45bf0 23#include <signal.h>
284f4730 24#include <stdio.h>
284f4730
JB
25#include "termchar.h"
26#include "termopts.h"
27#include "lisp.h"
28#include "termhooks.h"
29#include "macros.h"
02639609 30#include "keyboard.h"
ff11dfa1 31#include "frame.h"
284f4730
JB
32#include "window.h"
33#include "commands.h"
34#include "buffer.h"
37cd9f30 35#include "charset.h"
284f4730 36#include "disptab.h"
f4255cd1 37#include "dispextern.h"
e39da3d7 38#include "syntax.h"
497ba7a1 39#include "intervals.h"
9ac0d9e0 40#include "blockinput.h"
e8886a1d 41#include "puresize.h"
8a9f5d3c
GM
42#include "systime.h"
43#include "atimer.h"
284f4730
JB
44#include <setjmp.h>
45#include <errno.h>
46
80e4aa30
RS
47#ifdef MSDOS
48#include "msdos.h"
49#include <time.h>
50#else /* not MSDOS */
284f4730
JB
51#ifndef VMS
52#include <sys/ioctl.h>
284f4730 53#endif
80e4aa30 54#endif /* not MSDOS */
284f4730 55
52baf19e 56#include "syssignal.h"
6ef5b54f 57#include "systty.h"
52baf19e 58
03cee6ae
GM
59#include <sys/types.h>
60#ifdef HAVE_UNISTD_H
61#include <unistd.h>
62#endif
63
c5e3b6c5
RS
64/* This is to get the definitions of the XK_ symbols. */
65#ifdef HAVE_X_WINDOWS
66#include "xterm.h"
67#endif
68
e98a93eb
GV
69#ifdef HAVE_NTGUI
70#include "w32term.h"
71#endif /* HAVE_NTGUI */
72
0c2611c5
RS
73/* Include systime.h after xterm.h to avoid double inclusion of time.h. */
74#include "systime.h"
75
02639609 76#ifndef USE_CRT_DLL
52baf19e 77extern int errno;
02639609 78#endif
52baf19e 79
9ac0d9e0
JB
80/* Variables for blockinput.h: */
81
82/* Non-zero if interrupt input is blocked right now. */
63927c41 83int interrupt_input_blocked;
9ac0d9e0
JB
84
85/* Nonzero means an input interrupt has arrived
86 during the current critical section. */
63927c41 87int interrupt_input_pending;
9ac0d9e0
JB
88
89
437f6112
RS
90/* File descriptor to use for input. */
91extern int input_fd;
284f4730 92
e98a93eb 93#ifdef HAVE_WINDOW_SYSTEM
284f4730 94/* Make all keyboard buffers much bigger when using X windows. */
f019cded
RS
95#ifdef macintosh
96/* But not too big (local data > 32K error) if on macintosh */
97#define KBD_BUFFER_SIZE 512
98#else
284f4730 99#define KBD_BUFFER_SIZE 4096
f019cded 100#endif
284f4730
JB
101#else /* No X-windows, character input */
102#define KBD_BUFFER_SIZE 256
103#endif /* No X-windows */
104
105/* Following definition copied from eval.c */
106
107struct backtrace
108 {
109 struct backtrace *next;
110 Lisp_Object *function;
111 Lisp_Object *args; /* Points to vector of args. */
112 int nargs; /* length of vector. If nargs is UNEVALLED,
113 args points to slot holding list of
114 unevalled args */
115 char evalargs;
116 };
117
c5fdd383
KH
118#ifdef MULTI_KBOARD
119KBOARD *initial_kboard;
120KBOARD *current_kboard;
121KBOARD *all_kboards;
1e8bd3da 122int single_kboard;
6c6083a9 123#else
c5fdd383 124KBOARD the_only_kboard;
6c6083a9 125#endif
612b78ef 126
284f4730
JB
127/* Non-nil disable property on a command means
128 do not execute it; call disabled-command-hook's value instead. */
2e894dab 129Lisp_Object Qdisabled, Qdisabled_command_hook;
284f4730
JB
130
131#define NUM_RECENT_KEYS (100)
132int recent_keys_index; /* Index for storing next element into recent_keys */
133int total_keys; /* Total number of elements stored into recent_keys */
5160df46 134Lisp_Object recent_keys; /* A vector, holding the last 100 keystrokes */
284f4730 135
6569cc8d
JB
136/* Vector holding the key sequence that invoked the current command.
137 It is reused for each command, and it may be longer than the current
138 sequence; this_command_key_count indicates how many elements
139 actually mean something.
140 It's easier to staticpro a single Lisp_Object than an array. */
141Lisp_Object this_command_keys;
142int this_command_key_count;
284f4730 143
7d18f9ae
RS
144/* This vector is used as a buffer to record the events that were actually read
145 by read_key_sequence. */
146Lisp_Object raw_keybuf;
147int raw_keybuf_count;
148
149#define GROW_RAW_KEYBUF \
150if (raw_keybuf_count == XVECTOR (raw_keybuf)->size) \
151 { \
152 int newsize = 2 * XVECTOR (raw_keybuf)->size; \
153 Lisp_Object new; \
154 new = Fmake_vector (make_number (newsize), Qnil); \
155 bcopy (XVECTOR (raw_keybuf)->contents, XVECTOR (new)->contents, \
156 raw_keybuf_count * sizeof (Lisp_Object)); \
157 raw_keybuf = new; \
158 }
159
6321824f
RS
160/* Number of elements of this_command_keys
161 that precede this key sequence. */
162int this_single_command_key_start;
163
71918b75
RS
164/* Record values of this_command_key_count and echo_length ()
165 before this command was read. */
166static int before_command_key_count;
167static int before_command_echo_length;
168/* Values of before_command_key_count and before_command_echo_length
169 saved by reset-this-command-lengths. */
170static int before_command_key_count_1;
171static int before_command_echo_length_1;
172/* Flag set by reset-this-command-lengths,
173 saying to reset the lengths when add_command_key is called. */
174static int before_command_restore_flag;
175
284f4730
JB
176extern int minbuf_level;
177
a59b172a
RS
178extern int message_enable_multibyte;
179
284f4730
JB
180extern struct backtrace *backtrace_list;
181
7ee32cda
GM
182/* If non-nil, the function that implements the display of help.
183 It's called with one argument, the help string to display. */
184
185Lisp_Object Vshow_help_function;
186
284f4730
JB
187/* Nonzero means do menu prompting. */
188static int menu_prompting;
189
190/* Character to see next line of menu prompt. */
191static Lisp_Object menu_prompt_more_char;
192
193/* For longjmp to where kbd input is being done. */
194static jmp_buf getcjmp;
195
196/* True while doing kbd input. */
197int waiting_for_input;
198
199/* True while displaying for echoing. Delays C-g throwing. */
985f9f66 200
284f4730
JB
201static int echoing;
202
985f9f66
GM
203/* Non-null means we can start echoing at the next input pause even
204 though there is something in the echo area. */
205
206static struct kboard *ok_to_echo_at_next_pause;
207
59a84f8e
GM
208/* The kboard last echoing, or null for none. Reset to 0 in
209 cancel_echoing. If non-null, and a current echo area message
210 exists, and echo_message_buffer is eq to the current message
211 buffer, we know that the message comes from echo_kboard. */
985f9f66
GM
212
213static struct kboard *echo_kboard;
1fc93d49 214
59a84f8e
GM
215/* The buffer used for echoing. Set in echo_now, reset in
216 cancel_echoing. */
217
218static Lisp_Object echo_message_buffer;
219
03361bcc
RS
220/* Nonzero means disregard local maps for the menu bar. */
221static int inhibit_local_menu_bar_menus;
222
80e4aa30 223/* Nonzero means C-g should cause immediate error-signal. */
284f4730
JB
224int immediate_quit;
225
fa90970d
RS
226/* The user's ERASE setting. */
227Lisp_Object Vtty_erase_char;
228
284f4730 229/* Character to recognize as the help char. */
7e85b935 230Lisp_Object Vhelp_char;
284f4730 231
ecb7cb34
KH
232/* List of other event types to recognize as meaning "help". */
233Lisp_Object Vhelp_event_list;
234
284f4730
JB
235/* Form to execute when help char is typed. */
236Lisp_Object Vhelp_form;
237
7e85b935
RS
238/* Command to run when the help character follows a prefix key. */
239Lisp_Object Vprefix_help_command;
240
9f9c0e27
RS
241/* List of items that should move to the end of the menu bar. */
242Lisp_Object Vmenu_bar_final_items;
a73c5e29 243
6526ab49
RS
244/* Non-nil means show the equivalent key-binding for
245 any M-x command that has one.
246 The value can be a length of time to show the message for.
247 If the value is non-nil and not a number, we wait 2 seconds. */
248Lisp_Object Vsuggest_key_bindings;
249
284f4730
JB
250/* Character that causes a quit. Normally C-g.
251
252 If we are running on an ordinary terminal, this must be an ordinary
253 ASCII char, since we want to make it our interrupt character.
254
255 If we are not running on an ordinary terminal, it still needs to be
256 an ordinary ASCII char. This character needs to be recognized in
257 the input interrupt handler. At this point, the keystroke is
258 represented as a struct input_event, while the desired quit
259 character is specified as a lispy event. The mapping from struct
260 input_events to lispy events cannot run in an interrupt handler,
261 and the reverse mapping is difficult for anything but ASCII
262 keystrokes.
263
264 FOR THESE ELABORATE AND UNSATISFYING REASONS, quit_char must be an
265 ASCII character. */
266int quit_char;
267
268extern Lisp_Object current_global_map;
269extern int minibuf_level;
270
9dd3131c
RS
271/* If non-nil, this is a map that overrides all other local maps. */
272Lisp_Object Voverriding_local_map;
273
d0a49716
RS
274/* If non-nil, Voverriding_local_map applies to the menu bar. */
275Lisp_Object Voverriding_local_map_menu_flag;
276
7f07d5ca
RS
277/* Keymap that defines special misc events that should
278 be processed immediately at a low level. */
279Lisp_Object Vspecial_event_map;
280
284f4730
JB
281/* Current depth in recursive edits. */
282int command_loop_level;
283
284/* Total number of times command_loop has read a key sequence. */
285int num_input_keys;
286
287/* Last input character read as a command. */
288Lisp_Object last_command_char;
289
7d6de002
RS
290/* Last input character read as a command, not counting menus
291 reached by the mouse. */
292Lisp_Object last_nonmenu_event;
293
284f4730
JB
294/* Last input character read for any purpose. */
295Lisp_Object last_input_char;
296
dbc4e1c1 297/* If not Qnil, a list of objects to be read as subsequent command input. */
24597608 298Lisp_Object Vunread_command_events;
284f4730 299
7d18f9ae
RS
300/* If not Qnil, a list of objects to be read as subsequent command input
301 including input method processing. */
302Lisp_Object Vunread_input_method_events;
303
304/* If not Qnil, a list of objects to be read as subsequent command input
305 but NOT including input method processing. */
306Lisp_Object Vunread_post_input_method_events;
307
86e5706b
RS
308/* If not -1, an event to be read as subsequent command input. */
309int unread_command_char;
310
cd21b839
JB
311/* If not Qnil, this is a switch-frame event which we decided to put
312 off until the end of a key sequence. This should be read as the
dbc4e1c1 313 next command input, after any unread_command_events.
8f805655
JB
314
315 read_key_sequence uses this to delay switch-frame events until the
316 end of the key sequence; Fread_char uses it to put off switch-frame
317 events until a non-ASCII event is acceptable as input. */
318Lisp_Object unread_switch_frame;
cd21b839 319
9fa4395d
RS
320/* A mask of extra modifier bits to put into every keyboard char. */
321int extra_keyboard_modifiers;
322
284f4730
JB
323/* Char to use as prefix when a meta character is typed in.
324 This is bound on entry to minibuffer in case ESC is changed there. */
325
326Lisp_Object meta_prefix_char;
327
328/* Last size recorded for a current buffer which is not a minibuffer. */
329static int last_non_minibuf_size;
330
06ef7355 331/* Number of idle seconds before an auto-save and garbage collection. */
284f4730
JB
332static Lisp_Object Vauto_save_timeout;
333
334/* Total number of times read_char has returned. */
4abfba1f 335int num_input_events;
284f4730 336
51172b6d 337/* Total number of times read_char has returned, outside of macros. */
c43b1734 338int num_nonmacro_input_events;
51172b6d 339
284f4730
JB
340/* Auto-save automatically when this many characters have been typed
341 since the last time. */
342
343static int auto_save_interval;
344
c43b1734 345/* Value of num_nonmacro_input_events as of last auto save. */
284f4730
JB
346
347int last_auto_save;
348
284f4730 349/* The command being executed by the command loop.
6c7178b9
KH
350 Commands may set this, and the value set will be copied into
351 current_kboard->Vlast_command instead of the actual command. */
d5eecefb
RS
352Lisp_Object Vthis_command;
353
354/* This is like Vthis_command, except that commands never set it. */
355Lisp_Object real_this_command;
284f4730 356
b453f72e
KH
357/* The value of point when the last command was executed. */
358int last_point_position;
359
047688cb
RS
360/* The buffer that was current when the last command was started. */
361Lisp_Object last_point_position_buffer;
362
4c52b668
KH
363/* The frame in which the last input event occurred, or Qmacro if the
364 last event came from a macro. We use this to determine when to
365 generate switch-frame events. This may be cleared by functions
366 like Fselect_frame, to make sure that a switch-frame event is
367 generated by the next character. */
368Lisp_Object internal_last_event_frame;
4c52b668
KH
369
370/* A user-visible version of the above, intended to allow users to
371 figure out where the last event came from, if the event doesn't
372 carry that information itself (i.e. if it was a character). */
373Lisp_Object Vlast_event_frame;
374
1113d9db
JB
375/* The timestamp of the last input event we received from the X server.
376 X Windows wants this for selection ownership. */
284f4730
JB
377unsigned long last_event_timestamp;
378
379Lisp_Object Qself_insert_command;
380Lisp_Object Qforward_char;
381Lisp_Object Qbackward_char;
e58aa385 382Lisp_Object Qundefined;
d925fb39 383Lisp_Object Qtimer_event_handler;
284f4730
JB
384
385/* read_key_sequence stores here the command definition of the
386 key sequence that it reads. */
387Lisp_Object read_key_sequence_cmd;
388
39aab679
DL
389/* Echo unfinished commands after this many seconds of pause. */
390Lisp_Object Vecho_keystrokes;
391
284f4730
JB
392/* Form to evaluate (if non-nil) when Emacs is started. */
393Lisp_Object Vtop_level;
394
395/* User-supplied string to translate input characters through. */
396Lisp_Object Vkeyboard_translate_table;
397
398/* Keymap mapping ASCII function key sequences onto their preferred forms. */
399extern Lisp_Object Vfunction_key_map;
400
e0301c07
RS
401/* Another keymap that maps key sequences into key sequences.
402 This one takes precedence over ordinary definitions. */
403extern Lisp_Object Vkey_translation_map;
a612e298 404
7d18f9ae
RS
405/* If non-nil, this implements the current input method. */
406Lisp_Object Vinput_method_function;
407Lisp_Object Qinput_method_function;
408
d5eecefb
RS
409/* When we call Vinput_method_function,
410 this holds the echo area message that was just erased. */
411Lisp_Object Vinput_method_previous_message;
412
86e5706b
RS
413/* Non-nil means deactivate the mark at end of this command. */
414Lisp_Object Vdeactivate_mark;
415
48e416d4
RS
416/* Menu bar specified in Lucid Emacs fashion. */
417
418Lisp_Object Vlucid_menu_bar_dirty_flag;
419Lisp_Object Qrecompute_lucid_menubar, Qactivate_menubar_hook;
420
cdb9d665
RS
421Lisp_Object Qecho_area_clear_hook;
422
86e5706b 423/* Hooks to run before and after each command. */
59aadc81
RS
424Lisp_Object Qpre_command_hook, Vpre_command_hook;
425Lisp_Object Qpost_command_hook, Vpost_command_hook;
40932d1a 426Lisp_Object Qcommand_hook_internal, Vcommand_hook_internal;
59aadc81
RS
427/* Hook run after a command if there's no more input soon. */
428Lisp_Object Qpost_command_idle_hook, Vpost_command_idle_hook;
429
430/* Delay time in microseconds before running post-command-idle-hook. */
431int post_command_idle_delay;
86e5706b 432
8a792f3a
RS
433/* List of deferred actions to be performed at a later time.
434 The precise format isn't relevant here; we just check whether it is nil. */
435Lisp_Object Vdeferred_action_list;
436
437/* Function to call to handle deferred actions, when there are any. */
438Lisp_Object Vdeferred_action_function;
3ef14e46 439Lisp_Object Qdeferred_action_function;
8a792f3a 440
d5eecefb
RS
441Lisp_Object Qinput_method_exit_on_first_char;
442Lisp_Object Qinput_method_use_echo_area;
443
284f4730
JB
444/* File in which we write all commands we read. */
445FILE *dribble;
446
447/* Nonzero if input is available. */
448int input_pending;
449
b04904fb
RS
450/* 1 if should obey 0200 bit in input chars as "Meta", 2 if should
451 keep 0200 bit in input chars. 0 to ignore the 0200 bit. */
452
284f4730
JB
453int meta_key;
454
455extern char *pending_malloc_warning;
456
beecf6a1 457/* Circular buffer for pre-read keyboard input. */
da8f7368 458
beecf6a1
KH
459static struct input_event kbd_buffer[KBD_BUFFER_SIZE];
460
da8f7368 461/* Vector to GCPRO the Lisp objects referenced from kbd_buffer.
beecf6a1
KH
462
463 The interrupt-level event handlers will never enqueue an event on a
464 frame which is not in Vframe_list, and once an event is dequeued,
465 internal_last_event_frame or the event itself points to the frame.
466 So that's all fine.
467
468 But while the event is sitting in the queue, it's completely
469 unprotected. Suppose the user types one command which will run for
470 a while and then delete a frame, and then types another event at
471 the frame that will be deleted, before the command gets around to
472 it. Suppose there are no references to this frame elsewhere in
473 Emacs, and a GC occurs before the second event is dequeued. Now we
474 have an event referring to a freed frame, which will crash Emacs
475 when it is dequeued.
476
477 Similar things happen when an event on a scroll bar is enqueued; the
478 window may be deleted while the event is in the queue.
479
da8f7368
GM
480 So, we use this vector to protect the Lisp_Objects in the event
481 queue. That way, they'll be dequeued as dead frames or windows,
482 but still valid Lisp objects.
beecf6a1
KH
483
484 If kbd_buffer[i].kind != no_event, then
da8f7368
GM
485
486 AREF (kbd_buffer_gcpro, 2 * i) == kbd_buffer[i].frame_or_window.
487 AREF (kbd_buffer_gcpro, 2 * i + 1) == kbd_buffer[i].arg. */
488
489static Lisp_Object kbd_buffer_gcpro;
beecf6a1
KH
490
491/* Pointer to next available character in kbd_buffer.
492 If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty.
493 This may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the the
494 next available char is in kbd_buffer[0]. */
495static struct input_event *kbd_fetch_ptr;
496
497/* Pointer to next place to store character in kbd_buffer. This
498 may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the next
499 character should go in kbd_buffer[0]. */
7ee32cda 500static struct input_event * volatile kbd_store_ptr;
beecf6a1
KH
501
502/* The above pair of variables forms a "queue empty" flag. When we
503 enqueue a non-hook event, we increment kbd_store_ptr. When we
504 dequeue a non-hook event, we increment kbd_fetch_ptr. We say that
505 there is input available iff the two pointers are not equal.
506
507 Why not just have a flag set and cleared by the enqueuing and
508 dequeuing functions? Such a flag could be screwed up by interrupts
509 at inopportune times. */
510
f3253854 511/* If this flag is non-nil, we check mouse_moved to see when the
a9d77f1f
RS
512 mouse moves, and motion events will appear in the input stream.
513 Otherwise, mouse motion is ignored. */
514static Lisp_Object do_mouse_tracking;
284f4730 515
284f4730
JB
516/* Symbols to head events. */
517Lisp_Object Qmouse_movement;
3c370943 518Lisp_Object Qscroll_bar_movement;
cd21b839 519Lisp_Object Qswitch_frame;
bbdc2092 520Lisp_Object Qdelete_frame;
af17bd2b
KH
521Lisp_Object Qiconify_frame;
522Lisp_Object Qmake_frame_visible;
7ee32cda 523Lisp_Object Qhelp_echo;
cd21b839 524
284f4730
JB
525/* Symbols to denote kinds of events. */
526Lisp_Object Qfunction_key;
527Lisp_Object Qmouse_click;
07de30b9
GV
528#ifdef WINDOWSNT
529Lisp_Object Qmouse_wheel;
1161d367 530Lisp_Object Qlanguage_change;
07de30b9 531#endif
a24dc617 532Lisp_Object Qdrag_n_drop;
284f4730 533/* Lisp_Object Qmouse_movement; - also an event header */
284f4730
JB
534
535/* Properties of event headers. */
536Lisp_Object Qevent_kind;
88cb0656 537Lisp_Object Qevent_symbol_elements;
284f4730 538
e8886a1d
RS
539/* menu item parts */
540Lisp_Object Qmenu_alias;
598a9fa7 541Lisp_Object Qmenu_enable;
74c1de23
RS
542Lisp_Object QCenable, QCvisible, QChelp, QCfilter, QCkeys, QCkey_sequence;
543Lisp_Object QCbutton, QCtoggle, QCradio;
e8886a1d
RS
544extern Lisp_Object Vdefine_key_rebound_commands;
545extern Lisp_Object Qmenu_item;
598a9fa7 546
0a7f1fc0
JB
547/* An event header symbol HEAD may have a property named
548 Qevent_symbol_element_mask, which is of the form (BASE MODIFIERS);
549 BASE is the base, unmodified version of HEAD, and MODIFIERS is the
550 mask of modifiers applied to it. If present, this is used to help
551 speed up parse_modifiers. */
552Lisp_Object Qevent_symbol_element_mask;
553
554/* An unmodified event header BASE may have a property named
555 Qmodifier_cache, which is an alist mapping modifier masks onto
556 modified versions of BASE. If present, this helps speed up
557 apply_modifiers. */
558Lisp_Object Qmodifier_cache;
559
5ec75a55 560/* Symbols to use for parts of windows. */
284f4730 561Lisp_Object Qmode_line;
e5d77022 562Lisp_Object Qvertical_line;
3c370943 563Lisp_Object Qvertical_scroll_bar;
5ec75a55
RS
564Lisp_Object Qmenu_bar;
565
f4255cd1
JB
566Lisp_Object recursive_edit_unwind (), command_loop ();
567Lisp_Object Fthis_command_keys ();
03b4122a 568Lisp_Object Qextended_command_history;
c04cbc3b 569EMACS_TIME timer_check ();
284f4730 570
f4385381
RS
571extern Lisp_Object Vhistory_length;
572
2c834fb3
KH
573extern char *x_get_keysym_name ();
574
8eb4d8ef
RS
575static void record_menu_key ();
576
f4eef8b4
RS
577Lisp_Object Qpolling_period;
578
d9d4c147 579/* List of absolute timers. Appears in order of next scheduled event. */
c04cbc3b
RS
580Lisp_Object Vtimer_list;
581
d9d4c147
KH
582/* List of idle time timers. Appears in order of next scheduled event. */
583Lisp_Object Vtimer_idle_list;
584
87dd9b9b
RS
585/* Incremented whenever a timer is run. */
586int timers_run;
587
a9f16aa9
KH
588extern Lisp_Object Vprint_level, Vprint_length;
589
ffd56f97
JB
590/* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt
591 happens. */
592EMACS_TIME *input_available_clear_time;
284f4730
JB
593
594/* Nonzero means use SIGIO interrupts; zero means use CBREAK mode.
595 Default is 1 if INTERRUPT_INPUT is defined. */
596int interrupt_input;
597
598/* Nonzero while interrupts are temporarily deferred during redisplay. */
599int interrupts_deferred;
600
87dd9b9b 601/* Nonzero means use ^S/^Q for flow control. */
284f4730
JB
602int flow_control;
603
284f4730
JB
604/* Allow m- file to inhibit use of FIONREAD. */
605#ifdef BROKEN_FIONREAD
606#undef FIONREAD
607#endif
608
609/* We are unable to use interrupts if FIONREAD is not available,
610 so flush SIGIO so we won't try. */
611#ifndef FIONREAD
612#ifdef SIGIO
613#undef SIGIO
614#endif
615#endif
616
e98a93eb 617/* If we support a window system, turn on the code to poll periodically
34f04431 618 to detect C-g. It isn't actually used when doing interrupt input. */
e98a93eb 619#ifdef HAVE_WINDOW_SYSTEM
284f4730
JB
620#define POLL_FOR_INPUT
621#endif
adf5cb9c
KH
622
623/* After a command is executed, if point is moved into a region that
624 has specific properties (e.g. composition, display), we adjust
625 point to the boundary of the region. But, if a command sets this
626 valiable to non-nil, we suppress this point adjustment. This
627 variable is set to nil before reading a command. */
da8f7368 628
adf5cb9c
KH
629Lisp_Object Vdisable_point_adjustment;
630
631/* If non-nil, always disable point adjustment. */
da8f7368 632
adf5cb9c
KH
633Lisp_Object Vglobal_disable_point_adjustment;
634
284f4730
JB
635\f
636/* Global variable declarations. */
637
638/* Function for init_keyboard to call with no args (if nonzero). */
639void (*keyboard_init_hook) ();
640
0bbfdc25
GM
641static int read_avail_input P_ ((int));
642static void get_input_pending P_ ((int *, int));
643static int readable_events P_ ((int));
644static Lisp_Object read_char_x_menu_prompt P_ ((int, Lisp_Object *,
645 Lisp_Object, int *));
8150596a 646static Lisp_Object read_char_x_menu_prompt ();
0bbfdc25
GM
647static Lisp_Object read_char_minibuf_menu_prompt P_ ((int, int,
648 Lisp_Object *));
649static Lisp_Object make_lispy_event P_ ((struct input_event *));
514354e9 650#ifdef HAVE_MOUSE
0bbfdc25
GM
651static Lisp_Object make_lispy_movement P_ ((struct frame *, Lisp_Object,
652 enum scroll_bar_part,
653 Lisp_Object, Lisp_Object,
654 unsigned long));
514354e9 655#endif
0bbfdc25
GM
656static Lisp_Object modify_event_symbol P_ ((int, unsigned, Lisp_Object,
657 Lisp_Object, char **,
658 Lisp_Object *, unsigned));
659static Lisp_Object make_lispy_switch_frame P_ ((Lisp_Object));
660static int parse_solitary_modifier P_ ((Lisp_Object));
3d31316f 661static int parse_solitary_modifier ();
0bbfdc25 662static void save_getcjmp P_ ((jmp_buf));
dfcf069d 663static void save_getcjmp ();
0bbfdc25 664static void restore_getcjmp P_ ((jmp_buf));
7ee32cda 665static Lisp_Object apply_modifiers P_ ((int, Lisp_Object));
0bbfdc25 666static void clear_event P_ ((struct input_event *));
284f4730 667
8026024c
KH
668/* Nonzero means don't try to suspend even if the operating system seems
669 to support it. */
670static int cannot_suspend;
671
284f4730
JB
672#define min(a,b) ((a)<(b)?(a):(b))
673#define max(a,b) ((a)>(b)?(a):(b))
674
675/* Install the string STR as the beginning of the string of echoing,
676 so that it serves as a prompt for the next character.
677 Also start echoing. */
678
dfcf069d 679void
284f4730
JB
680echo_prompt (str)
681 char *str;
682{
683 int len = strlen (str);
7a80a6f6 684
ba72822c
KH
685 if (len > ECHOBUFSIZE - 4)
686 len = ECHOBUFSIZE - 4;
c5fdd383
KH
687 bcopy (str, current_kboard->echobuf, len);
688 current_kboard->echoptr = current_kboard->echobuf + len;
689 *current_kboard->echoptr = '\0';
284f4730 690
c5fdd383 691 current_kboard->echo_after_prompt = len;
7a80a6f6 692
3dbd9ee4 693 echo_now ();
284f4730
JB
694}
695
df0f2ba1 696/* Add C to the echo string, if echoing is going on.
284f4730
JB
697 C can be a character, which is printed prettily ("M-C-x" and all that
698 jazz), or a symbol, whose name is printed. */
699
dfcf069d 700void
284f4730
JB
701echo_char (c)
702 Lisp_Object c;
703{
704 extern char *push_key_description ();
705
c5fdd383 706 if (current_kboard->immediate_echo)
284f4730 707 {
c5fdd383 708 char *ptr = current_kboard->echoptr;
df0f2ba1 709
c5fdd383 710 if (ptr != current_kboard->echobuf)
284f4730
JB
711 *ptr++ = ' ';
712
713 /* If someone has passed us a composite event, use its head symbol. */
88cb0656 714 c = EVENT_HEAD (c);
284f4730 715
8c18cbfb 716 if (INTEGERP (c))
284f4730 717 {
2d0ffc9a
KH
718 if (ptr - current_kboard->echobuf
719 > ECHOBUFSIZE - KEY_DESCRIPTION_SIZE)
284f4730
JB
720 return;
721
cb5df6ae 722 ptr = push_key_description (XINT (c), ptr);
284f4730 723 }
8c18cbfb 724 else if (SYMBOLP (c))
284f4730
JB
725 {
726 struct Lisp_String *name = XSYMBOL (c)->name;
fc932ac6 727 if ((ptr - current_kboard->echobuf) + STRING_BYTES (name) + 4
301738ed 728 > ECHOBUFSIZE)
284f4730 729 return;
fc932ac6
RS
730 bcopy (name->data, ptr, STRING_BYTES (name));
731 ptr += STRING_BYTES (name);
284f4730
JB
732 }
733
c5fdd383 734 if (current_kboard->echoptr == current_kboard->echobuf
ecb7cb34 735 && help_char_p (c))
284f4730
JB
736 {
737 strcpy (ptr, " (Type ? for further options)");
738 ptr += strlen (ptr);
739 }
740
741 *ptr = 0;
c5fdd383 742 current_kboard->echoptr = ptr;
284f4730 743
3dbd9ee4 744 echo_now ();
284f4730
JB
745 }
746}
747
748/* Temporarily add a dash to the end of the echo string if it's not
749 empty, so that it serves as a mini-prompt for the very next character. */
750
dfcf069d 751void
284f4730
JB
752echo_dash ()
753{
c5fdd383
KH
754 if (!current_kboard->immediate_echo
755 && current_kboard->echoptr == current_kboard->echobuf)
284f4730 756 return;
7a80a6f6 757 /* Do nothing if we just printed a prompt. */
c5fdd383
KH
758 if (current_kboard->echo_after_prompt
759 == current_kboard->echoptr - current_kboard->echobuf)
7a80a6f6 760 return;
4bafa972 761 /* Do nothing if not echoing at all. */
c5fdd383 762 if (current_kboard->echoptr == 0)
4bafa972 763 return;
284f4730
JB
764
765 /* Put a dash at the end of the buffer temporarily,
766 but make it go away when the next character is added. */
c5fdd383
KH
767 current_kboard->echoptr[0] = '-';
768 current_kboard->echoptr[1] = 0;
284f4730 769
3dbd9ee4 770 echo_now ();
284f4730
JB
771}
772
773/* Display the current echo string, and begin echoing if not already
774 doing so. */
775
07a59269 776void
3dbd9ee4 777echo_now ()
284f4730 778{
c5fdd383 779 if (!current_kboard->immediate_echo)
284f4730
JB
780 {
781 int i;
c5fdd383 782 current_kboard->immediate_echo = 1;
284f4730
JB
783
784 for (i = 0; i < this_command_key_count; i++)
d0a57728
RS
785 {
786 Lisp_Object c;
787 c = XVECTOR (this_command_keys)->contents[i];
788 if (! (EVENT_HAS_PARAMETERS (c)
789 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
790 echo_char (c);
791 }
284f4730
JB
792 echo_dash ();
793 }
794
795 echoing = 1;
301738ed
RS
796 message2_nolog (current_kboard->echobuf, strlen (current_kboard->echobuf),
797 ! NILP (current_buffer->enable_multibyte_characters));
284f4730
JB
798 echoing = 0;
799
59a84f8e
GM
800 /* Record in what buffer we echoed, and from which kboard. */
801 echo_message_buffer = echo_area_buffer[0];
802 echo_kboard = current_kboard;
803
284f4730
JB
804 if (waiting_for_input && !NILP (Vquit_flag))
805 quit_throw_to_read_char ();
806}
807
808/* Turn off echoing, for the start of a new command. */
809
dfcf069d 810void
284f4730
JB
811cancel_echoing ()
812{
c5fdd383
KH
813 current_kboard->immediate_echo = 0;
814 current_kboard->echoptr = current_kboard->echobuf;
815 current_kboard->echo_after_prompt = -1;
59a84f8e
GM
816 ok_to_echo_at_next_pause = NULL;
817 echo_kboard = NULL;
818 echo_message_buffer = Qnil;
284f4730
JB
819}
820
821/* Return the length of the current echo string. */
822
823static int
824echo_length ()
825{
c5fdd383 826 return current_kboard->echoptr - current_kboard->echobuf;
284f4730
JB
827}
828
829/* Truncate the current echo message to its first LEN chars.
830 This and echo_char get used by read_key_sequence when the user
ff11dfa1 831 switches frames while entering a key sequence. */
284f4730
JB
832
833static void
834echo_truncate (len)
835 int len;
836{
c5fdd383
KH
837 current_kboard->echobuf[len] = '\0';
838 current_kboard->echoptr = current_kboard->echobuf + len;
40932d1a 839 truncate_echo_area (len);
284f4730
JB
840}
841
842\f
843/* Functions for manipulating this_command_keys. */
844static void
845add_command_key (key)
846 Lisp_Object key;
847{
6569cc8d
JB
848 int size = XVECTOR (this_command_keys)->size;
849
71918b75
RS
850 /* If reset-this-command-length was called recently, obey it now.
851 See the doc string of that function for an explanation of why. */
852 if (before_command_restore_flag)
853 {
854 this_command_key_count = before_command_key_count_1;
6321824f
RS
855 if (this_command_key_count < this_single_command_key_start)
856 this_single_command_key_start = this_command_key_count;
71918b75
RS
857 echo_truncate (before_command_echo_length_1);
858 before_command_restore_flag = 0;
859 }
860
6569cc8d 861 if (this_command_key_count >= size)
284f4730 862 {
9b8eb840 863 Lisp_Object new_keys;
6569cc8d 864
9b8eb840 865 new_keys = Fmake_vector (make_number (size * 2), Qnil);
6569cc8d
JB
866 bcopy (XVECTOR (this_command_keys)->contents,
867 XVECTOR (new_keys)->contents,
8f805655 868 size * sizeof (Lisp_Object));
6569cc8d
JB
869
870 this_command_keys = new_keys;
284f4730 871 }
6569cc8d
JB
872
873 XVECTOR (this_command_keys)->contents[this_command_key_count++] = key;
284f4730
JB
874}
875\f
876Lisp_Object
877recursive_edit_1 ()
878{
879 int count = specpdl_ptr - specpdl;
880 Lisp_Object val;
881
882 if (command_loop_level > 0)
883 {
884 specbind (Qstandard_output, Qt);
885 specbind (Qstandard_input, Qt);
886 }
887
84265027
GM
888#ifdef HAVE_X_WINDOWS
889 /* The command loop has started a busy-cursor timer, so we have to
890 cancel it here, otherwise it will fire because the recursive edit
891 can take some time. */
892 if (display_busy_cursor_p)
893 cancel_busy_cursor ();
894#endif
895
284f4730
JB
896 val = command_loop ();
897 if (EQ (val, Qt))
898 Fsignal (Qquit, Qnil);
cb252880
RS
899 /* Handle throw from read_minibuf when using minibuffer
900 while it's active but we're in another window. */
901 if (STRINGP (val))
902 Fsignal (Qerror, Fcons (val, Qnil));
284f4730 903
cb5df6ae 904 return unbind_to (count, Qnil);
284f4730
JB
905}
906
907/* When an auto-save happens, record the "time", and don't do again soon. */
5846638c 908
07a59269 909void
284f4730
JB
910record_auto_save ()
911{
c43b1734 912 last_auto_save = num_nonmacro_input_events;
284f4730 913}
5846638c
RS
914
915/* Make an auto save happen as soon as possible at command level. */
916
dfcf069d 917void
5846638c
RS
918force_auto_save_soon ()
919{
920 last_auto_save = - auto_save_interval - 1;
241ceaf7
RS
921
922 record_asynch_buffer_change ();
5846638c 923}
284f4730 924\f
284f4730
JB
925DEFUN ("recursive-edit", Frecursive_edit, Srecursive_edit, 0, 0, "",
926 "Invoke the editor command loop recursively.\n\
927To get out of the recursive edit, a command can do `(throw 'exit nil)';\n\
928that tells this function to return.\n\
929Alternately, `(throw 'exit t)' makes this function signal an error.\n\
930This function is called by the editor initialization to begin editing.")
931 ()
932{
933 int count = specpdl_ptr - specpdl;
284f4730
JB
934
935 command_loop_level++;
936 update_mode_lines = 1;
937
938 record_unwind_protect (recursive_edit_unwind,
939 (command_loop_level
940 && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer))
941 ? Fcurrent_buffer ()
942 : Qnil);
943 recursive_edit_1 ();
944 return unbind_to (count, Qnil);
945}
946
947Lisp_Object
948recursive_edit_unwind (buffer)
949 Lisp_Object buffer;
950{
951 if (!NILP (buffer))
952 Fset_buffer (buffer);
953
954 command_loop_level--;
955 update_mode_lines = 1;
956 return Qnil;
957}
958\f
604ccd1d 959static void
1e8bd3da 960any_kboard_state ()
604ccd1d 961{
1e8bd3da
RS
962#ifdef MULTI_KBOARD
963#if 0 /* Theory: if there's anything in Vunread_command_events,
964 it will right away be read by read_key_sequence,
965 and then if we do switch KBOARDS, it will go into the side
966 queue then. So we don't need to do anything special here -- rms. */
604ccd1d 967 if (CONSP (Vunread_command_events))
4524b161 968 {
c5fdd383
KH
969 current_kboard->kbd_queue
970 = nconc2 (Vunread_command_events, current_kboard->kbd_queue);
971 current_kboard->kbd_queue_has_data = 1;
4524b161 972 }
604ccd1d 973 Vunread_command_events = Qnil;
1e8bd3da
RS
974#endif
975 single_kboard = 0;
976#endif
604ccd1d 977}
1e8bd3da
RS
978
979/* Switch to the single-kboard state, making current_kboard
980 the only KBOARD from which further input is accepted. */
981
982void
983single_kboard_state ()
984{
985#ifdef MULTI_KBOARD
986 single_kboard = 1;
604ccd1d 987#endif
1e8bd3da
RS
988}
989
990/* Maintain a stack of kboards, so other parts of Emacs
991 can switch temporarily to the kboard of a given frame
992 and then revert to the previous status. */
993
994struct kboard_stack
995{
996 KBOARD *kboard;
997 struct kboard_stack *next;
998};
999
1000static struct kboard_stack *kboard_stack;
1001
1002void
1003push_frame_kboard (f)
1004 FRAME_PTR f;
1005{
ab48365b 1006#ifdef MULTI_KBOARD
1e8bd3da
RS
1007 struct kboard_stack *p
1008 = (struct kboard_stack *) xmalloc (sizeof (struct kboard_stack));
1009
1010 p->next = kboard_stack;
1011 p->kboard = current_kboard;
1012 kboard_stack = p;
1013
1014 current_kboard = FRAME_KBOARD (f);
ab48365b 1015#endif
1e8bd3da
RS
1016}
1017
1018void
1019pop_frame_kboard ()
1020{
ab48365b 1021#ifdef MULTI_KBOARD
1e8bd3da
RS
1022 struct kboard_stack *p = kboard_stack;
1023 current_kboard = p->kboard;
1024 kboard_stack = p->next;
1025 xfree (p);
ab48365b 1026#endif
1e8bd3da
RS
1027}
1028\f
1029/* Handle errors that are not handled at inner levels
1030 by printing an error message and returning to the editor command loop. */
604ccd1d 1031
284f4730
JB
1032Lisp_Object
1033cmd_error (data)
1034 Lisp_Object data;
a1341f75 1035{
a9f16aa9 1036 Lisp_Object old_level, old_length;
e881d8b2
RS
1037 char macroerror[50];
1038
1039 if (!NILP (executing_macro))
1040 {
1041 if (executing_macro_iterations == 1)
1042 sprintf (macroerror, "After 1 kbd macro iteration: ");
1043 else
1044 sprintf (macroerror, "After %d kbd macro iterations: ",
1045 executing_macro_iterations);
1046 }
1047 else
1048 *macroerror = 0;
a9f16aa9 1049
a1341f75
RS
1050 Vstandard_output = Qt;
1051 Vstandard_input = Qt;
1052 Vexecuting_macro = Qnil;
9f58e89e 1053 executing_macro = Qnil;
d8bcf58e 1054 current_kboard->Vprefix_arg = Qnil;
75045dcb 1055 current_kboard->Vlast_prefix_arg = Qnil;
df0f2ba1 1056 cancel_echoing ();
a9f16aa9
KH
1057
1058 /* Avoid unquittable loop if data contains a circular list. */
1059 old_level = Vprint_level;
1060 old_length = Vprint_length;
0c04a67e
RS
1061 XSETFASTINT (Vprint_level, 10);
1062 XSETFASTINT (Vprint_length, 10);
e881d8b2 1063 cmd_error_internal (data, macroerror);
a9f16aa9
KH
1064 Vprint_level = old_level;
1065 Vprint_length = old_length;
a1341f75
RS
1066
1067 Vquit_flag = Qnil;
1068
1069 Vinhibit_quit = Qnil;
c5fdd383 1070#ifdef MULTI_KBOARD
1e8bd3da 1071 any_kboard_state ();
ff4b06d3 1072#endif
a1341f75
RS
1073
1074 return make_number (0);
1075}
1076
301738ed
RS
1077/* Take actions on handling an error. DATA is the data that describes
1078 the error.
1079
1080 CONTEXT is a C-string containing ASCII characters only which
1081 describes the context in which the error happened. If we need to
1082 generalize CONTEXT to allow multibyte characters, make it a Lisp
1083 string. */
1084
07a59269 1085void
a1341f75
RS
1086cmd_error_internal (data, context)
1087 Lisp_Object data;
1088 char *context;
284f4730 1089{
284f4730 1090 Lisp_Object stream;
7ee32cda 1091 int kill_emacs_p = 0;
788f89eb 1092 struct frame *sf = SELECTED_FRAME ();
284f4730
JB
1093
1094 Vquit_flag = Qnil;
1095 Vinhibit_quit = Qt;
985f9f66 1096 clear_message (1, 0);
284f4730 1097
ff11dfa1 1098 /* If the window system or terminal frame hasn't been initialized
284f4730
JB
1099 yet, or we're not interactive, it's best to dump this message out
1100 to stderr and exit. */
788f89eb 1101 if (!sf->glyphs_initialized_p
7ee32cda
GM
1102 /* This is the case of the frame dumped with Emacs, when we're
1103 running under a window system. */
1104 || (!NILP (Vwindow_system)
1105 && !inhibit_window_system
788f89eb 1106 && FRAME_TERMCAP_P (sf))
284f4730 1107 || noninteractive)
7ee32cda
GM
1108 {
1109 stream = Qexternal_debugging_output;
1110 kill_emacs_p = 1;
1111 }
284f4730
JB
1112 else
1113 {
1114 Fdiscard_input ();
1115 bitch_at_user ();
1116 stream = Qt;
1117 }
1118
a1341f75
RS
1119 if (context != 0)
1120 write_string_1 (context, -1, stream);
1121
22a51344 1122 print_error_message (data, stream);
284f4730 1123
ff11dfa1 1124 /* If the window system or terminal frame hasn't been initialized
284f4730 1125 yet, or we're in -batch mode, this error should cause Emacs to exit. */
7ee32cda 1126 if (kill_emacs_p)
284f4730
JB
1127 {
1128 Fterpri (stream);
1129 Fkill_emacs (make_number (-1));
1130 }
284f4730
JB
1131}
1132\f
1133Lisp_Object command_loop_1 ();
1134Lisp_Object command_loop_2 ();
1135Lisp_Object top_level_1 ();
1136
1137/* Entry to editor-command-loop.
1138 This level has the catches for exiting/returning to editor command loop.
1139 It returns nil to exit recursive edit, t to abort it. */
1140
1141Lisp_Object
1142command_loop ()
1143{
1144 if (command_loop_level > 0 || minibuf_level > 0)
1145 {
07ba902e
RS
1146 Lisp_Object val;
1147 val = internal_catch (Qexit, command_loop_2, Qnil);
68c46464
RS
1148 executing_macro = Qnil;
1149 return val;
284f4730
JB
1150 }
1151 else
1152 while (1)
1153 {
1154 internal_catch (Qtop_level, top_level_1, Qnil);
1155 internal_catch (Qtop_level, command_loop_2, Qnil);
68c46464 1156 executing_macro = Qnil;
df0f2ba1 1157
284f4730
JB
1158 /* End of file in -batch run causes exit here. */
1159 if (noninteractive)
1160 Fkill_emacs (Qt);
1161 }
1162}
1163
1164/* Here we catch errors in execution of commands within the
1165 editing loop, and reenter the editing loop.
1166 When there is an error, cmd_error runs and returns a non-nil
1167 value to us. A value of nil means that cmd_loop_1 itself
1168 returned due to end of file (or end of kbd macro). */
1169
1170Lisp_Object
1171command_loop_2 ()
1172{
1173 register Lisp_Object val;
1174
1175 do
1176 val = internal_condition_case (command_loop_1, Qerror, cmd_error);
1177 while (!NILP (val));
1178
1179 return Qnil;
1180}
1181
1182Lisp_Object
1183top_level_2 ()
1184{
1185 return Feval (Vtop_level);
1186}
1187
1188Lisp_Object
1189top_level_1 ()
1190{
1191 /* On entry to the outer level, run the startup file */
1192 if (!NILP (Vtop_level))
1193 internal_condition_case (top_level_2, Qerror, cmd_error);
1194 else if (!NILP (Vpurify_flag))
1195 message ("Bare impure Emacs (standard Lisp code not loaded)");
1196 else
1197 message ("Bare Emacs (standard Lisp code not loaded)");
1198 return Qnil;
1199}
1200
1201DEFUN ("top-level", Ftop_level, Stop_level, 0, 0, "",
1202 "Exit all recursive editing levels.")
1203 ()
1204{
2c9cf2c8
GM
1205#ifdef HAVE_X_WINDOWS
1206 if (display_busy_cursor_p)
1207 cancel_busy_cursor ();
1208#endif
8c907a56 1209 return Fthrow (Qtop_level, Qnil);
284f4730
JB
1210}
1211
1212DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, "",
1213 "Exit from the innermost recursive edit or minibuffer.")
1214 ()
1215{
1216 if (command_loop_level > 0 || minibuf_level > 0)
1217 Fthrow (Qexit, Qnil);
1218
1219 error ("No recursive edit is in progress");
8c907a56 1220 return Qnil;
284f4730
JB
1221}
1222
1223DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0, 0, "",
1224 "Abort the command that requested this recursive edit or minibuffer input.")
1225 ()
1226{
1227 if (command_loop_level > 0 || minibuf_level > 0)
1228 Fthrow (Qexit, Qt);
1229
1230 error ("No recursive edit is in progress");
8c907a56 1231 return Qnil;
284f4730
JB
1232}
1233\f
1234/* This is the actual command reading loop,
1235 sans error-handling encapsulation. */
1236
1237Lisp_Object Fcommand_execute ();
1238static int read_key_sequence ();
68f297c5 1239void safe_run_hooks ();
adf5cb9c 1240static void adjust_point_for_property ();
284f4730
JB
1241
1242Lisp_Object
1243command_loop_1 ()
1244{
03cee6ae
GM
1245 Lisp_Object cmd;
1246 int lose;
284f4730
JB
1247 int nonundocount;
1248 Lisp_Object keybuf[30];
1249 int i;
284f4730 1250 int no_direct;
86e5706b 1251 int prev_modiff;
8c907a56 1252 struct buffer *prev_buffer = NULL;
c5fdd383 1253#ifdef MULTI_KBOARD
1e8bd3da 1254 int was_locked = single_kboard;
bded54dd 1255#endif
284f4730 1256
d9b641bb 1257 current_kboard->Vprefix_arg = Qnil;
75045dcb 1258 current_kboard->Vlast_prefix_arg = Qnil;
86e5706b 1259 Vdeactivate_mark = Qnil;
284f4730 1260 waiting_for_input = 0;
df0f2ba1 1261 cancel_echoing ();
284f4730 1262
284f4730 1263 nonundocount = 0;
284f4730 1264 this_command_key_count = 0;
6321824f 1265 this_single_command_key_start = 0;
284f4730 1266
a612e298
RS
1267 /* Make sure this hook runs after commands that get errors and
1268 throw to top level. */
a98ea3f9
RS
1269 /* Note that the value cell will never directly contain nil
1270 if the symbol is a local variable. */
e98a93eb 1271 if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
a98ea3f9 1272 safe_run_hooks (Qpost_command_hook);
a612e298 1273
8f12e41d
GM
1274 /* If displaying a message, resize the echo area window to fit
1275 that message's size exactly. */
1276 if (!NILP (echo_area_buffer[0]))
1277 resize_echo_area_axactly ();
1278
8a792f3a
RS
1279 if (!NILP (Vdeferred_action_list))
1280 call0 (Vdeferred_action_function);
1281
e98a93eb 1282 if (!NILP (Vpost_command_idle_hook) && !NILP (Vrun_hooks))
59aadc81
RS
1283 {
1284 if (NILP (Vunread_command_events)
7d18f9ae
RS
1285 && NILP (Vunread_input_method_events)
1286 && NILP (Vunread_post_input_method_events)
59aadc81 1287 && NILP (Vexecuting_macro)
41365083 1288 && !NILP (sit_for (0, post_command_idle_delay, 0, 1, 1)))
59aadc81
RS
1289 safe_run_hooks (Qpost_command_idle_hook);
1290 }
1291
51d5a2c9 1292 /* Do this after running Vpost_command_hook, for consistency. */
d5eecefb
RS
1293 current_kboard->Vlast_command = Vthis_command;
1294 current_kboard->Vreal_last_command = real_this_command;
51d5a2c9 1295
284f4730
JB
1296 while (1)
1297 {
788f89eb 1298 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
a94a4335
KH
1299 Fkill_emacs (Qnil);
1300
284f4730
JB
1301 /* Make sure the current window's buffer is selected. */
1302 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
1303 set_buffer_internal (XBUFFER (XWINDOW (selected_window)->buffer));
1304
1305 /* Display any malloc warning that just came out. Use while because
1306 displaying one warning can cause another. */
1307
1308 while (pending_malloc_warning)
1309 display_malloc_warning ();
1310
1311 no_direct = 0;
1312
86e5706b
RS
1313 Vdeactivate_mark = Qnil;
1314
284f4730 1315 /* If minibuffer on and echo area in use,
eb8c3be9 1316 wait 2 sec and redraw minibuffer. */
284f4730 1317
7ee32cda 1318 if (minibuf_level
985f9f66 1319 && !NILP (echo_area_buffer[0])
93127526 1320 && EQ (minibuf_window, echo_area_window))
284f4730 1321 {
f1bed6d8
RS
1322 /* Bind inhibit-quit to t so that C-g gets read in
1323 rather than quitting back to the minibuffer. */
1324 int count = specpdl_ptr - specpdl;
1325 specbind (Qinhibit_quit, Qt);
f1bed6d8 1326
db08707d 1327 Fsit_for (make_number (2), Qnil, Qnil);
e6aa7813 1328 /* Clear the echo area. */
301738ed 1329 message2 (0, 0, 0);
cdb9d665 1330 safe_run_hooks (Qecho_area_clear_hook);
e6aa7813 1331
db08707d
RS
1332 unbind_to (count, Qnil);
1333
e6aa7813 1334 /* If a C-g came in before, treat it as input now. */
284f4730
JB
1335 if (!NILP (Vquit_flag))
1336 {
1337 Vquit_flag = Qnil;
24597608 1338 Vunread_command_events = Fcons (make_number (quit_char), Qnil);
284f4730
JB
1339 }
1340 }
1341
1342#ifdef C_ALLOCA
ff4b06d3 1343 alloca (0); /* Cause a garbage collection now */
284f4730
JB
1344 /* Since we can free the most stuff here. */
1345#endif /* C_ALLOCA */
1346
8f805655 1347#if 0
8f805655
JB
1348 /* Select the frame that the last event came from. Usually,
1349 switch-frame events will take care of this, but if some lisp
1350 code swallows a switch-frame event, we'll fix things up here.
1351 Is this a good idea? */
8c18cbfb 1352 if (FRAMEP (internal_last_event_frame)
788f89eb 1353 && !EQ (internal_last_event_frame, selected_frame))
3c370943 1354 Fselect_frame (internal_last_event_frame, Qnil);
284f4730 1355#endif
48e416d4
RS
1356 /* If it has changed current-menubar from previous value,
1357 really recompute the menubar from the value. */
a646e520
RS
1358 if (! NILP (Vlucid_menu_bar_dirty_flag)
1359 && !NILP (Ffboundp (Qrecompute_lucid_menubar)))
48e416d4
RS
1360 call0 (Qrecompute_lucid_menubar);
1361
71918b75
RS
1362 before_command_key_count = this_command_key_count;
1363 before_command_echo_length = echo_length ();
1364
d5eecefb
RS
1365 Vthis_command = Qnil;
1366 real_this_command = Qnil;
d7437ef6 1367
8f805655 1368 /* Read next key sequence; i gets its length. */
ce98e608 1369 i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0],
f571ae0d 1370 Qnil, 0, 1, 1);
8f805655 1371
6fac1409 1372 /* A filter may have run while we were reading the input. */
788f89eb 1373 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
a94a4335 1374 Fkill_emacs (Qnil);
6fac1409
RS
1375 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
1376 set_buffer_internal (XBUFFER (XWINDOW (selected_window)->buffer));
1377
8f805655
JB
1378 ++num_input_keys;
1379
284f4730
JB
1380 /* Now we have read a key sequence of length I,
1381 or else I is 0 and we found end of file. */
1382
1383 if (i == 0) /* End of file -- happens only in */
1384 return Qnil; /* a kbd macro, at the end. */
dcc408a0
RS
1385 /* -1 means read_key_sequence got a menu that was rejected.
1386 Just loop around and read another command. */
1387 if (i == -1)
1388 {
1389 cancel_echoing ();
1390 this_command_key_count = 0;
6321824f 1391 this_single_command_key_start = 0;
ff4b06d3 1392 goto finalize;
dcc408a0 1393 }
284f4730 1394
284f4730
JB
1395 last_command_char = keybuf[i - 1];
1396
75c0b143
RS
1397 /* If the previous command tried to force a specific window-start,
1398 forget about that, in case this command moves point far away
c422836d
KH
1399 from that position. But also throw away beg_unchanged and
1400 end_unchanged information in that case, so that redisplay will
1401 update the whole window properly. */
1402 if (!NILP (XWINDOW (selected_window)->force_start))
1403 {
9351ebd0 1404 struct buffer *b;
c422836d 1405 XWINDOW (selected_window)->force_start = Qnil;
9351ebd0
GM
1406 b = XBUFFER (XWINDOW (selected_window)->buffer);
1407 BUF_BEG_UNCHANGED (b) = BUF_END_UNCHANGED (b) = 0;
c422836d 1408 }
75c0b143 1409
284f4730
JB
1410 cmd = read_key_sequence_cmd;
1411 if (!NILP (Vexecuting_macro))
1412 {
1413 if (!NILP (Vquit_flag))
1414 {
1415 Vexecuting_macro = Qt;
1416 QUIT; /* Make some noise. */
1417 /* Will return since macro now empty. */
1418 }
1419 }
1420
1421 /* Do redisplay processing after this command except in special
e35b6123 1422 cases identified below. */
86e5706b
RS
1423 prev_buffer = current_buffer;
1424 prev_modiff = MODIFF;
8746da95 1425 last_point_position = PT;
18cd2eeb 1426 XSETBUFFER (last_point_position_buffer, prev_buffer);
86e5706b 1427
adf5cb9c
KH
1428 /* By default, we adjust point to a boundary of a region that
1429 has such a property that should be treated intangible
1430 (e.g. composition, display). But, some commands will set
1431 this variable differently. */
1432 Vdisable_point_adjustment = Qnil;
1433
284f4730
JB
1434 /* Execute the command. */
1435
d5eecefb
RS
1436 Vthis_command = cmd;
1437 real_this_command = cmd;
a98ea3f9
RS
1438 /* Note that the value cell will never directly contain nil
1439 if the symbol is a local variable. */
e98a93eb 1440 if (!NILP (Vpre_command_hook) && !NILP (Vrun_hooks))
a98ea3f9 1441 safe_run_hooks (Qpre_command_hook);
75045dcb 1442
d5eecefb 1443 if (NILP (Vthis_command))
284f4730
JB
1444 {
1445 /* nil means key is undefined. */
1446 bitch_at_user ();
c5fdd383 1447 current_kboard->defining_kbd_macro = Qnil;
284f4730 1448 update_mode_lines = 1;
d8bcf58e 1449 current_kboard->Vprefix_arg = Qnil;
284f4730
JB
1450 }
1451 else
1452 {
d8bcf58e 1453 if (NILP (current_kboard->Vprefix_arg) && ! no_direct)
284f4730 1454 {
75045dcb
RS
1455 /* In case we jump to directly_done. */
1456 Vcurrent_prefix_arg = current_kboard->Vprefix_arg;
1457
284f4730
JB
1458 /* Recognize some common commands in common situations and
1459 do them directly. */
d5eecefb 1460 if (EQ (Vthis_command, Qforward_char) && PT < ZV)
284f4730 1461 {
51ad8a68 1462 struct Lisp_Char_Table *dp
284f4730 1463 = window_display_table (XWINDOW (selected_window));
aaf35234 1464 lose = FETCH_CHAR (PT_BYTE);
8458ede6 1465 SET_PT (PT + 1);
0f7a8fee 1466 if ((dp
82ba47d7 1467 ? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
9a5540db
RS
1468 ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
1469 : (NILP (DISP_CHAR_VECTOR (dp, lose))
1470 && (lose >= 0x20 && lose < 0x7f)))
0f7a8fee 1471 : (lose >= 0x20 && lose < 0x7f))
37cd9f30
KH
1472 /* To extract the case of continuation on
1473 wide-column characters. */
8458ede6 1474 && (WIDTH_BY_CHAR_HEAD (FETCH_BYTE (PT_BYTE)) == 1)
284f4730
JB
1475 && (XFASTINT (XWINDOW (selected_window)->last_modified)
1476 >= MODIFF)
598ba4c7
RS
1477 && (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
1478 >= OVERLAY_MODIFF)
284f4730 1479 && (XFASTINT (XWINDOW (selected_window)->last_point)
8001d352 1480 == PT - 1)
284f4730
JB
1481 && !windows_or_buffers_changed
1482 && EQ (current_buffer->selective_display, Qnil)
1483 && !detect_input_pending ()
962ae636 1484 && NILP (XWINDOW (selected_window)->column_number_displayed)
284f4730 1485 && NILP (Vexecuting_macro))
e35b6123 1486 direct_output_forward_char (1);
284f4730
JB
1487 goto directly_done;
1488 }
d5eecefb 1489 else if (EQ (Vthis_command, Qbackward_char) && PT > BEGV)
284f4730 1490 {
51ad8a68 1491 struct Lisp_Char_Table *dp
284f4730 1492 = window_display_table (XWINDOW (selected_window));
8458ede6 1493 SET_PT (PT - 1);
aaf35234 1494 lose = FETCH_CHAR (PT_BYTE);
0f7a8fee 1495 if ((dp
ca873d73 1496 ? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
9a5540db
RS
1497 ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
1498 : (NILP (DISP_CHAR_VECTOR (dp, lose))
1499 && (lose >= 0x20 && lose < 0x7f)))
0f7a8fee 1500 : (lose >= 0x20 && lose < 0x7f))
284f4730
JB
1501 && (XFASTINT (XWINDOW (selected_window)->last_modified)
1502 >= MODIFF)
598ba4c7
RS
1503 && (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
1504 >= OVERLAY_MODIFF)
284f4730 1505 && (XFASTINT (XWINDOW (selected_window)->last_point)
8001d352 1506 == PT + 1)
284f4730
JB
1507 && !windows_or_buffers_changed
1508 && EQ (current_buffer->selective_display, Qnil)
1509 && !detect_input_pending ()
962ae636 1510 && NILP (XWINDOW (selected_window)->column_number_displayed)
284f4730 1511 && NILP (Vexecuting_macro))
e35b6123 1512 direct_output_forward_char (-1);
284f4730
JB
1513 goto directly_done;
1514 }
d5eecefb 1515 else if (EQ (Vthis_command, Qself_insert_command)
284f4730 1516 /* Try this optimization only on ascii keystrokes. */
8c18cbfb 1517 && INTEGERP (last_command_char))
284f4730 1518 {
89599794 1519 unsigned int c = XINT (last_command_char);
fc9cce4e 1520 int value;
fc9cce4e
RS
1521 if (NILP (Vexecuting_macro)
1522 && !EQ (minibuf_window, selected_window))
284f4730
JB
1523 {
1524 if (!nonundocount || nonundocount >= 20)
1525 {
1526 Fundo_boundary ();
1527 nonundocount = 0;
1528 }
1529 nonundocount++;
1530 }
7ee32cda 1531
fc9cce4e
RS
1532 lose = ((XFASTINT (XWINDOW (selected_window)->last_modified)
1533 < MODIFF)
598ba4c7
RS
1534 || (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
1535 < OVERLAY_MODIFF)
fc9cce4e
RS
1536 || (XFASTINT (XWINDOW (selected_window)->last_point)
1537 != PT)
4c61f38e 1538 || MODIFF <= SAVE_MODIFF
fc9cce4e
RS
1539 || windows_or_buffers_changed
1540 || !EQ (current_buffer->selective_display, Qnil)
1541 || detect_input_pending ()
962ae636 1542 || !NILP (XWINDOW (selected_window)->column_number_displayed)
fc9cce4e 1543 || !NILP (Vexecuting_macro));
7ee32cda 1544
fc9cce4e 1545 value = internal_self_insert (c, 0);
7ee32cda 1546
fc9cce4e
RS
1547 if (value == 2)
1548 nonundocount = 0;
1549
7ee32cda
GM
1550 /* VALUE == 1 when AFTER-CHANGE functions are
1551 installed which is the case most of the time
1552 because FONT-LOCK installs one. */
1553 if (!lose && !value)
e35b6123 1554 direct_output_for_insert (c);
284f4730
JB
1555 goto directly_done;
1556 }
1557 }
1558
1559 /* Here for a command that isn't executed directly */
1560
7ee32cda
GM
1561#ifdef HAVE_X_WINDOWS
1562 if (display_busy_cursor_p)
d0c48478 1563 start_busy_cursor ();
7ee32cda
GM
1564#endif
1565
284f4730 1566 nonundocount = 0;
d8bcf58e 1567 if (NILP (current_kboard->Vprefix_arg))
284f4730 1568 Fundo_boundary ();
d5eecefb 1569 Fcommand_execute (Vthis_command, Qnil, Qnil, Qnil);
d0c48478
GM
1570
1571#ifdef HAVE_X_WINDOWS
1572 if (display_busy_cursor_p)
1573 cancel_busy_cursor ();
1574#endif
284f4730 1575 }
a764a753 1576 directly_done: ;
75045dcb 1577 current_kboard->Vlast_prefix_arg = Vcurrent_prefix_arg;
284f4730 1578
84ee6048
RS
1579 /* Note that the value cell will never directly contain nil
1580 if the symbol is a local variable. */
1581 if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
1582 safe_run_hooks (Qpost_command_hook);
1583
8f12e41d
GM
1584 /* If displaying a message, resize the echo area window to fit
1585 that message's size exactly. */
1586 if (!NILP (echo_area_buffer[0]))
1587 resize_echo_area_axactly ();
1588
84ee6048
RS
1589 if (!NILP (Vdeferred_action_list))
1590 safe_run_hooks (Qdeferred_action_function);
1591
1592 if (!NILP (Vpost_command_idle_hook) && !NILP (Vrun_hooks))
1593 {
1594 if (NILP (Vunread_command_events)
7d18f9ae
RS
1595 && NILP (Vunread_input_method_events)
1596 && NILP (Vunread_post_input_method_events)
84ee6048
RS
1597 && NILP (Vexecuting_macro)
1598 && !NILP (sit_for (0, post_command_idle_delay, 0, 1, 1)))
1599 safe_run_hooks (Qpost_command_idle_hook);
1600 }
1601
284f4730 1602 /* If there is a prefix argument,
6c7178b9
KH
1603 1) We don't want Vlast_command to be ``universal-argument''
1604 (that would be dumb), so don't set Vlast_command,
284f4730
JB
1605 2) we want to leave echoing on so that the prefix will be
1606 echoed as part of this key sequence, so don't call
1607 cancel_echoing, and
1608 3) we want to leave this_command_key_count non-zero, so that
1609 read_char will realize that it is re-reading a character, and
217258d5
KH
1610 not echo it a second time.
1611
1612 If the command didn't actually create a prefix arg,
1613 but is merely a frame event that is transparent to prefix args,
1614 then the above doesn't apply. */
1615 if (NILP (current_kboard->Vprefix_arg) || CONSP (last_command_char))
284f4730 1616 {
d5eecefb
RS
1617 current_kboard->Vlast_command = Vthis_command;
1618 current_kboard->Vreal_last_command = real_this_command;
284f4730
JB
1619 cancel_echoing ();
1620 this_command_key_count = 0;
6321824f 1621 this_single_command_key_start = 0;
284f4730 1622 }
86e5706b 1623
88ce066e 1624 if (!NILP (current_buffer->mark_active) && !NILP (Vrun_hooks))
86e5706b
RS
1625 {
1626 if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode))
1627 {
1628 current_buffer->mark_active = Qnil;
1629 call1 (Vrun_hooks, intern ("deactivate-mark-hook"));
1630 }
1631 else if (current_buffer != prev_buffer || MODIFF != prev_modiff)
1632 call1 (Vrun_hooks, intern ("activate-mark-hook"));
1633 }
ff4b06d3
KH
1634
1635 finalize:
adf5cb9c
KH
1636
1637 if (current_buffer == prev_buffer
1638 && last_point_position != PT
1639 && NILP (Vdisable_point_adjustment)
1640 && NILP (Vglobal_disable_point_adjustment))
1641 adjust_point_for_property (last_point_position);
1642
ff4b06d3
KH
1643 /* Install chars successfully executed in kbd macro. */
1644
d8bcf58e
KH
1645 if (!NILP (current_kboard->defining_kbd_macro)
1646 && NILP (current_kboard->Vprefix_arg))
ff4b06d3
KH
1647 finalize_kbd_macro_chars ();
1648
c5fdd383 1649#ifdef MULTI_KBOARD
604ccd1d 1650 if (!was_locked)
1e8bd3da 1651 any_kboard_state ();
ff4b06d3 1652#endif
284f4730
JB
1653 }
1654}
1c9784c9 1655
adf5cb9c
KH
1656extern Lisp_Object Qcomposition, Qdisplay;
1657
1658/* Adjust point to a boundary of a region that has such a property
1659 that should be treated intangible. For the moment, we check
1660 `composition' and `display' property. LAST_PT is the last position
1661 of point. */
1662
1663static void
1664adjust_point_for_property (last_pt)
1665 int last_pt;
1666{
1667 int start, end;
1668 Lisp_Object val;
1669 int check_composition = 1, check_display = 1;
1670
1671 while (check_composition || check_display)
1672 {
1673 if (check_composition
1674 && PT > BEGV && PT < ZV
1675 && get_property_and_range (PT, Qcomposition, &val, &start, &end, Qnil)
1676 && COMPOSITION_VALID_P (start, end, val)
1677 && start < PT && end > PT
1678 && (last_pt <= start || last_pt >= end))
1679 {
1680 if (PT < last_pt)
1681 SET_PT (start);
1682 else
1683 SET_PT (end);
1684 check_display = 1;
1685 }
1686 check_composition = 0;
1687 if (check_display
1688 && PT > BEGV && PT < ZV
1689 && get_property_and_range (PT, Qdisplay, &val, &start, &end, Qnil)
3e9ac4b7 1690 && display_prop_intangible_p (val)
adf5cb9c
KH
1691 && start < PT && end > PT
1692 && (last_pt <= start || last_pt >= end))
1693 {
1694 if (PT < last_pt)
1695 SET_PT (start);
1696 else
1697 SET_PT (end);
1698 check_composition = 1;
1699 }
1700 check_display = 0;
1701 }
1702}
1703
0bc3db2b
RS
1704/* Subroutine for safe_run_hooks: run the hook HOOK. */
1705
1706static Lisp_Object
1707safe_run_hooks_1 (hook)
1708 Lisp_Object hook;
1709{
1710 return call1 (Vrun_hooks, Vinhibit_quit);
1711}
1712
1713/* Subroutine for safe_run_hooks: handle an error by clearing out the hook. */
1714
1715static Lisp_Object
1716safe_run_hooks_error (data)
1717 Lisp_Object data;
1718{
30690496 1719 return Fset (Vinhibit_quit, Qnil);
0bc3db2b
RS
1720}
1721
1c9784c9
KH
1722/* If we get an error while running the hook, cause the hook variable
1723 to be nil. Also inhibit quits, so that C-g won't cause the hook
1724 to mysteriously evaporate. */
0bc3db2b 1725
68f297c5 1726void
1c9784c9 1727safe_run_hooks (hook)
a98ea3f9 1728 Lisp_Object hook;
1c9784c9
KH
1729{
1730 int count = specpdl_ptr - specpdl;
0bc3db2b
RS
1731 specbind (Qinhibit_quit, hook);
1732
e702932d 1733 internal_condition_case (safe_run_hooks_1, Qt, safe_run_hooks_error);
1c9784c9
KH
1734
1735 unbind_to (count, Qnil);
1736}
8a9f5d3c 1737
284f4730 1738\f
8a9f5d3c
GM
1739/* Number of seconds between polling for input. This is a Lisp
1740 variable that can be bound. */
1741
284f4730
JB
1742int polling_period;
1743
eb8c3be9 1744/* Nonzero means polling for input is temporarily suppressed. */
8a9f5d3c 1745
284f4730
JB
1746int poll_suppress_count;
1747
8a9f5d3c
GM
1748/* Asynchronous timer for polling. */
1749
1750struct atimer *poll_timer;
1751
284f4730 1752
36922b18
RS
1753#ifdef POLL_FOR_INPUT
1754
8a9f5d3c
GM
1755/* Poll for input, so what we catch a C-g if it comes in. This
1756 function is called from x_make_frame_visible, see comment
1757 there. */
284f4730 1758
8a9f5d3c
GM
1759void
1760poll_for_input_1 ()
284f4730 1761{
9ac0d9e0
JB
1762 if (interrupt_input_blocked == 0
1763 && !waiting_for_input)
1764 read_avail_input (0);
284f4730
JB
1765}
1766
8a9f5d3c
GM
1767/* Timer callback function for poll_timer. TIMER is equal to
1768 poll_timer. */
1769
1770void
1771poll_for_input (timer)
1772 struct atimer *timer;
1773{
1774 if (poll_suppress_count == 0)
1775 poll_for_input_1 ();
1776}
1777
1778#endif /* POLL_FOR_INPUT */
284f4730
JB
1779
1780/* Begin signals to poll for input, if they are appropriate.
1781 This function is called unconditionally from various places. */
1782
07a59269 1783void
284f4730
JB
1784start_polling ()
1785{
1786#ifdef POLL_FOR_INPUT
34f04431 1787 if (read_socket_hook && !interrupt_input)
284f4730 1788 {
8a9f5d3c
GM
1789 /* Turn alarm handling on unconditionally. It might have
1790 been turned off in process.c. */
1791 turn_on_atimers (1);
1792
1793 /* If poll timer doesn't exist, are we need one with
1794 a different interval, start a new one. */
1795 if (poll_timer == NULL
1796 || EMACS_SECS (poll_timer->interval) != polling_period)
284f4730 1797 {
8a9f5d3c
GM
1798 EMACS_TIME interval;
1799
1800 if (poll_timer)
1801 cancel_atimer (poll_timer);
1802
1803 EMACS_SET_SECS_USECS (interval, polling_period, 0);
1804 poll_timer = start_atimer (ATIMER_CONTINUOUS, interval,
1805 poll_for_input, NULL);
284f4730 1806 }
8a9f5d3c
GM
1807
1808 /* Let the timer's callback function poll for input
1809 if this becomes zero. */
1810 --poll_suppress_count;
284f4730
JB
1811 }
1812#endif
1813}
1814
1d3195db
RS
1815/* Nonzero if we are using polling to handle input asynchronously. */
1816
1817int
1818input_polling_used ()
1819{
1820#ifdef POLL_FOR_INPUT
1821 return read_socket_hook && !interrupt_input;
1822#else
1823 return 0;
1824#endif
1825}
1826
284f4730
JB
1827/* Turn off polling. */
1828
07a59269 1829void
284f4730
JB
1830stop_polling ()
1831{
1832#ifdef POLL_FOR_INPUT
34f04431 1833 if (read_socket_hook && !interrupt_input)
8a9f5d3c 1834 ++poll_suppress_count;
284f4730
JB
1835#endif
1836}
fe8aeef3
RS
1837
1838/* Set the value of poll_suppress_count to COUNT
1839 and start or stop polling accordingly. */
1840
1841void
1842set_poll_suppress_count (count)
1843 int count;
1844{
1845#ifdef POLL_FOR_INPUT
1846 if (count == 0 && poll_suppress_count != 0)
1847 {
1848 poll_suppress_count = 1;
1849 start_polling ();
1850 }
1851 else if (count != 0 && poll_suppress_count == 0)
1852 {
1853 stop_polling ();
1854 }
1855 poll_suppress_count = count;
1856#endif
1857}
f4eef8b4 1858
d0a57728
RS
1859/* Bind polling_period to a value at least N.
1860 But don't decrease it. */
1861
07a59269 1862void
f4eef8b4
RS
1863bind_polling_period (n)
1864 int n;
1865{
1866#ifdef POLL_FOR_INPUT
d0a57728
RS
1867 int new = polling_period;
1868
1869 if (n > new)
1870 new = n;
1871
6fe007f7 1872 stop_other_atimers (poll_timer);
f4eef8b4 1873 stop_polling ();
d0a57728
RS
1874 specbind (Qpolling_period, make_number (new));
1875 /* Start a new alarm with the new period. */
f4eef8b4
RS
1876 start_polling ();
1877#endif
1878}
284f4730 1879\f
6da3dd3a
RS
1880/* Apply the control modifier to CHARACTER. */
1881
faf5e407
JB
1882int
1883make_ctrl_char (c)
1884 int c;
1885{
d205953b
JB
1886 /* Save the upper bits here. */
1887 int upper = c & ~0177;
1888
1889 c &= 0177;
1890
1891 /* Everything in the columns containing the upper-case letters
1892 denotes a control character. */
1893 if (c >= 0100 && c < 0140)
1894 {
1895 int oc = c;
1896 c &= ~0140;
1897 /* Set the shift modifier for a control char
1898 made from a shifted letter. But only for letters! */
1899 if (oc >= 'A' && oc <= 'Z')
1900 c |= shift_modifier;
1901 }
1902
1903 /* The lower-case letters denote control characters too. */
1904 else if (c >= 'a' && c <= 'z')
1905 c &= ~0140;
1906
1907 /* Include the bits for control and shift
1908 only if the basic ASCII code can't indicate them. */
1909 else if (c >= ' ')
1910 c |= ctrl_modifier;
1911
1912 /* Replace the high bits. */
1913 c |= (upper & ~ctrl_modifier);
faf5e407
JB
1914
1915 return c;
1916}
1917
d4e68eea
GM
1918/* Display help echo in the echo area.
1919
8dfd92c9
GM
1920 HELP a string means display that string, HELP nil means clear the
1921 help echo. If HELP is a function, call it with OBJECT and POS as
1922 arguments; the function should return a help string or nil for
1923 none. For all other types of HELP evaluate it to obtain a string.
1924
2190735a
GM
1925 WINDOW is the window in which the help was generated, if any.
1926 It is nil if not in a window.
1927
5b2ec2d0
GM
1928 If OBJECT is a buffer, POS is the position in the buffer where the
1929 `help-echo' text property was found.
1930
1931 If OBJECT is an overlay, that overlay has a `help-echo' property,
1932 and POS is the position in the overlay's buffer under the mouse.
1933
1934 If OBJECT is a string (an overlay string or a string displayed with
1935 the `display' property). POS is the position in that string under
1936 the mouse.
d4e68eea
GM
1937
1938 OK_TO_IVERWRITE_KEYSTROKE_ECHO non-zero means it's okay if the help
1939 echo overwrites a keystroke echo currently displayed in the echo
1940 area.
1941
8dfd92c9
GM
1942 Note: this function may only be called with HELP nil or a string
1943 from X code running asynchronously. */
d4e68eea 1944
31f84d03 1945void
2190735a
GM
1946show_help_echo (help, window, object, pos, ok_to_overwrite_keystroke_echo)
1947 Lisp_Object help, window, object, pos;
adc84f48 1948 int ok_to_overwrite_keystroke_echo;
31f84d03 1949{
8dfd92c9 1950 if (!NILP (help) && !STRINGP (help))
d4e68eea 1951 {
8dfd92c9
GM
1952 if (FUNCTIONP (help))
1953 {
2190735a 1954 Lisp_Object args[4];
8dfd92c9 1955 args[0] = help;
2190735a
GM
1956 args[1] = window;
1957 args[2] = object;
1958 args[3] = pos;
1959 help = call_function (4, args);
8dfd92c9
GM
1960 }
1961 else
1962 help = eval_form (help);
1963
1964 if (!STRINGP (help))
d4e68eea 1965 return;
31f84d03
SM
1966 }
1967
8dfd92c9 1968 if (STRINGP (help) || NILP (help))
d4e68eea
GM
1969 {
1970 if (!NILP (Vshow_help_function))
8dfd92c9 1971 call1 (Vshow_help_function, help);
d4e68eea
GM
1972 else if (/* Don't overwrite minibuffer contents. */
1973 !MINI_WINDOW_P (XWINDOW (selected_window))
1974 /* Don't overwrite a keystroke echo. */
8dfd92c9
GM
1975 && (NILP (echo_message_buffer)
1976 || ok_to_overwrite_keystroke_echo)
d4e68eea
GM
1977 /* Don't overwrite a prompt. */
1978 && !cursor_in_echo_area)
1979 {
8dfd92c9 1980 if (STRINGP (help))
d4e68eea
GM
1981 {
1982 int count = specpdl_ptr - specpdl;
1983 specbind (Qmessage_truncate_lines, Qt);
8dfd92c9
GM
1984 message3_nolog (help, XSTRING (help)->size,
1985 STRING_MULTIBYTE (help));
d4e68eea
GM
1986 unbind_to (count, Qnil);
1987 }
1988 else
1989 message (0);
1990 }
1991 }
31f84d03
SM
1992}
1993
faf5e407
JB
1994
1995\f
284f4730
JB
1996/* Input of single characters from keyboard */
1997
1998Lisp_Object print_help ();
1999static Lisp_Object kbd_buffer_get_event ();
e4fe371d 2000static void record_char ();
284f4730 2001
c5fdd383
KH
2002#ifdef MULTI_KBOARD
2003static jmp_buf wrong_kboard_jmpbuf;
bded54dd 2004#endif
beecf6a1 2005
284f4730
JB
2006/* read a character from the keyboard; call the redisplay if needed */
2007/* commandflag 0 means do not do auto-saving, but do do redisplay.
2008 -1 means do not do redisplay, but do do autosaving.
2009 1 means do both. */
2010
7d6de002
RS
2011/* The arguments MAPS and NMAPS are for menu prompting.
2012 MAPS is an array of keymaps; NMAPS is the length of MAPS.
2013
2014 PREV_EVENT is the previous input event, or nil if we are reading
b638f328
RS
2015 the first event of a key sequence (or not reading a key sequence).
2016 If PREV_EVENT is t, that is a "magic" value that says
2017 not to run input methods, but in other respects to act as if
2018 not reading a key sequence.
7d6de002 2019
83d68044 2020 If USED_MOUSE_MENU is non-null, then we set *USED_MOUSE_MENU to 1
6569cc8d 2021 if we used a mouse menu to read the input, or zero otherwise. If
83d68044 2022 USED_MOUSE_MENU is null, we don't dereference it.
dcc408a0
RS
2023
2024 Value is t if we showed a menu and the user rejected it. */
7d6de002 2025
284f4730 2026Lisp_Object
7d6de002 2027read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
284f4730 2028 int commandflag;
7d6de002
RS
2029 int nmaps;
2030 Lisp_Object *maps;
2031 Lisp_Object prev_event;
2032 int *used_mouse_menu;
284f4730 2033{
8c907a56 2034 volatile Lisp_Object c;
284f4730 2035 int count;
410d4de9 2036 jmp_buf local_getcjmp;
284f4730 2037 jmp_buf save_jump;
8c907a56 2038 volatile int key_already_recorded = 0;
017c7cb6 2039 Lisp_Object tem, save;
8c907a56
GM
2040 volatile Lisp_Object previous_echo_area_message;
2041 volatile Lisp_Object also_record;
2042 volatile int reread;
d5eecefb 2043 struct gcpro gcpro1, gcpro2;
7c3bc944 2044
e4fe371d 2045 also_record = Qnil;
284f4730 2046
71918b75
RS
2047 before_command_key_count = this_command_key_count;
2048 before_command_echo_length = echo_length ();
ef6661f7 2049 c = Qnil;
7ee32cda 2050 previous_echo_area_message = Qnil;
71918b75 2051
7ee32cda 2052 GCPRO2 (c, previous_echo_area_message);
7c3bc944 2053
7f07d5ca
RS
2054 retry:
2055
7d18f9ae
RS
2056 reread = 0;
2057 if (CONSP (Vunread_post_input_method_events))
284f4730 2058 {
7539e11f 2059 c = XCAR (Vunread_post_input_method_events);
7d18f9ae 2060 Vunread_post_input_method_events
7539e11f 2061 = XCDR (Vunread_post_input_method_events);
284f4730 2062
2479e91e
RS
2063 /* Undo what read_char_x_menu_prompt did when it unread
2064 additional keys returned by Fx_popup_menu. */
2065 if (CONSP (c)
7539e11f
KR
2066 && (SYMBOLP (XCAR (c)) || INTEGERP (XCAR (c)))
2067 && NILP (XCDR (c)))
2068 c = XCAR (c);
2479e91e 2069
7d18f9ae
RS
2070 reread = 1;
2071 goto reread_first;
284f4730
JB
2072 }
2073
86e5706b
RS
2074 if (unread_command_char != -1)
2075 {
18cd2eeb 2076 XSETINT (c, unread_command_char);
86e5706b
RS
2077 unread_command_char = -1;
2078
7d18f9ae
RS
2079 reread = 1;
2080 goto reread_first;
2081 }
2082
2083 if (CONSP (Vunread_command_events))
2084 {
7539e11f
KR
2085 c = XCAR (Vunread_command_events);
2086 Vunread_command_events = XCDR (Vunread_command_events);
7d18f9ae
RS
2087
2088 /* Undo what read_char_x_menu_prompt did when it unread
2089 additional keys returned by Fx_popup_menu. */
2090 if (CONSP (c)
7539e11f
KR
2091 && (SYMBOLP (XCAR (c)) || INTEGERP (XCAR (c)))
2092 && NILP (XCDR (c)))
2093 c = XCAR (c);
7d18f9ae
RS
2094
2095 reread = 1;
2096 goto reread_for_input_method;
2097 }
2098
2099 if (CONSP (Vunread_input_method_events))
2100 {
7539e11f
KR
2101 c = XCAR (Vunread_input_method_events);
2102 Vunread_input_method_events = XCDR (Vunread_input_method_events);
7d18f9ae
RS
2103
2104 /* Undo what read_char_x_menu_prompt did when it unread
2105 additional keys returned by Fx_popup_menu. */
2106 if (CONSP (c)
7539e11f
KR
2107 && (SYMBOLP (XCAR (c)) || INTEGERP (XCAR (c)))
2108 && NILP (XCDR (c)))
2109 c = XCAR (c);
7d18f9ae
RS
2110 reread = 1;
2111 goto reread_for_input_method;
86e5706b
RS
2112 }
2113
71918b75
RS
2114 /* If there is no function key translated before
2115 reset-this-command-lengths takes effect, forget about it. */
2116 before_command_restore_flag = 0;
2117
284f4730
JB
2118 if (!NILP (Vexecuting_macro))
2119 {
fce33686
JB
2120 /* We set this to Qmacro; since that's not a frame, nobody will
2121 try to switch frames on us, and the selected window will
2122 remain unchanged.
2123
2124 Since this event came from a macro, it would be misleading to
eb8c3be9 2125 leave internal_last_event_frame set to wherever the last
3c370943
JB
2126 real event came from. Normally, a switch-frame event selects
2127 internal_last_event_frame after each command is read, but
2128 events read from a macro should never cause a new frame to be
2129 selected. */
4c52b668 2130 Vlast_event_frame = internal_last_event_frame = Qmacro;
fce33686 2131
663258f2
JB
2132 /* Exit the macro if we are at the end.
2133 Also, some things replace the macro with t
2134 to force an early exit. */
2135 if (EQ (Vexecuting_macro, Qt)
2136 || executing_macro_index >= XFASTINT (Flength (Vexecuting_macro)))
284f4730 2137 {
18cd2eeb 2138 XSETINT (c, -1);
7c3bc944 2139 RETURN_UNGCPRO (c);
284f4730 2140 }
df0f2ba1 2141
284f4730 2142 c = Faref (Vexecuting_macro, make_number (executing_macro_index));
8c18cbfb 2143 if (STRINGP (Vexecuting_macro)
86e5706b 2144 && (XINT (c) & 0x80))
bb9e9bed 2145 XSETFASTINT (c, CHAR_META | (XINT (c) & ~0x80));
86e5706b 2146
284f4730
JB
2147 executing_macro_index++;
2148
2149 goto from_macro;
2150 }
2151
cd21b839
JB
2152 if (!NILP (unread_switch_frame))
2153 {
2154 c = unread_switch_frame;
2155 unread_switch_frame = Qnil;
2156
2157 /* This event should make it into this_command_keys, and get echoed
7d18f9ae 2158 again, so we do not set `reread'. */
f4255cd1 2159 goto reread_first;
cd21b839
JB
2160 }
2161
adc1d5c8 2162 /* if redisplay was requested */
6e4e64a8
RS
2163 if (commandflag >= 0)
2164 {
adc1d5c8
RS
2165 /* If there is pending input, process any events which are not
2166 user-visible, such as X selection_request events. */
6e4e64a8
RS
2167 if (input_pending
2168 || detect_input_pending_run_timers (0))
adc1d5c8 2169 swallow_events (0); /* may clear input_pending */
6e4e64a8 2170
adc1d5c8
RS
2171 /* Redisplay if no pending input. */
2172 while (!input_pending)
2173 {
2174 redisplay ();
2175
2176 if (!input_pending)
2177 /* Normal case: no input arrived during redisplay. */
2178 break;
2179
2180 /* Input arrived and pre-empted redisplay.
2181 Process any events which are not user-visible. */
2182 swallow_events (0);
2183 /* If that cleared input_pending, try again to redisplay. */
2184 }
6e4e64a8 2185 }
e9bf89a0 2186
59a84f8e
GM
2187 /* Message turns off echoing unless more keystrokes turn it on again.
2188
2189 The code in 20.x for the condition was
2190
2191 1. echo_area_glyphs && *echo_area_glyphs
2192 2. && echo_area_glyphs != current_kboard->echobuf
2193 3. && ok_to_echo_at_next_pause != echo_area_glyphs
2194
2195 (1) means there's a current message displayed
2196
2197 (2) means it's not the message from echoing from the current
2198 kboard.
2199
2200 (3) There's only one place in 20.x where ok_to_echo_at_next_pause
2201 is set to a non-null value. This is done in read_char and it is
2202 set to echo_area_glyphs after a call to echo_char. That means
2203 ok_to_echo_at_next_pause is either null or
2204 current_kboard->echobuf with the appropriate current_kboard at
2205 that time.
2206
2207 So, condition (3) means in clear text ok_to_echo_at_next_pause
2208 must be either null, or the current message isn't from echoing at
2209 all, or it's from echoing from a different kboard than the
2210 current one. */
2211
2212 if (/* There currently something in the echo area */
985f9f66 2213 !NILP (echo_area_buffer[0])
59a84f8e
GM
2214 && (/* And it's either not from echoing. */
2215 !EQ (echo_area_buffer[0], echo_message_buffer)
2216 /* Or it's an echo from a different kboard. */
2217 || echo_kboard != current_kboard
2218 /* Or we explicitly allow overwriting whatever there is. */
2219 || ok_to_echo_at_next_pause == NULL))
7ee32cda 2220 cancel_echoing ();
410d4de9 2221 else
410d4de9 2222 echo_dash ();
59a84f8e 2223
410d4de9
RS
2224 /* Try reading a character via menu prompting in the minibuf.
2225 Try this before the sit-for, because the sit-for
2226 would do the wrong thing if we are supposed to do
2227 menu prompting. If EVENT_HAS_PARAMETERS then we are reading
2228 after a mouse event so don't try a minibuf menu. */
2229 c = Qnil;
2230 if (nmaps > 0 && INTERACTIVE
2231 && !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event)
2232 /* Don't bring up a menu if we already have another event. */
2233 && NILP (Vunread_command_events)
2234 && unread_command_char < 0
4ec4ed6a 2235 && !detect_input_pending_run_timers (0))
410d4de9
RS
2236 {
2237 c = read_char_minibuf_menu_prompt (commandflag, nmaps, maps);
2238 if (! NILP (c))
2239 {
2240 key_already_recorded = 1;
2241 goto non_reread_1;
2242 }
2243 }
284f4730 2244
410d4de9
RS
2245 /* Make a longjmp point for quits to use, but don't alter getcjmp just yet.
2246 We will do that below, temporarily for short sections of code,
2247 when appropriate. local_getcjmp must be in effect
2248 around any call to sit_for or kbd_buffer_get_event;
2249 it *must not* be in effect when we call redisplay. */
284f4730 2250
410d4de9 2251 if (_setjmp (local_getcjmp))
284f4730 2252 {
18cd2eeb 2253 XSETINT (c, quit_char);
788f89eb 2254 internal_last_event_frame = selected_frame;
4c52b668 2255 Vlast_event_frame = internal_last_event_frame;
04904c29
RS
2256 /* If we report the quit char as an event,
2257 don't do so more than once. */
2258 if (!NILP (Vinhibit_quit))
2259 Vquit_flag = Qnil;
284f4730 2260
c5fdd383 2261#ifdef MULTI_KBOARD
df0f2ba1 2262 {
788f89eb 2263 KBOARD *kb = FRAME_KBOARD (XFRAME (selected_frame));
c5fdd383 2264 if (kb != current_kboard)
df0f2ba1 2265 {
c5fdd383 2266 Lisp_Object *tailp = &kb->kbd_queue;
1e8bd3da
RS
2267 /* We shouldn't get here if we were in single-kboard mode! */
2268 if (single_kboard)
df0f2ba1
KH
2269 abort ();
2270 while (CONSP (*tailp))
7539e11f 2271 tailp = &XCDR (*tailp);
df0f2ba1
KH
2272 if (!NILP (*tailp))
2273 abort ();
2274 *tailp = Fcons (c, Qnil);
c5fdd383
KH
2275 kb->kbd_queue_has_data = 1;
2276 current_kboard = kb;
ef6661f7
RS
2277 /* This is going to exit from read_char
2278 so we had better get rid of this frame's stuff. */
2279 UNGCPRO;
c5fdd383 2280 longjmp (wrong_kboard_jmpbuf, 1);
df0f2ba1
KH
2281 }
2282 }
2283#endif
284f4730
JB
2284 goto non_reread;
2285 }
2286
d9d4c147
KH
2287 timer_start_idle ();
2288
284f4730
JB
2289 /* If in middle of key sequence and minibuffer not active,
2290 start echoing if enough time elapses. */
410d4de9 2291
7ee32cda
GM
2292 if (minibuf_level == 0
2293 && !current_kboard->immediate_echo
6c6083a9 2294 && this_command_key_count > 0
27203ead 2295 && ! noninteractive
f2647d04
DL
2296 && (FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
2297 && NILP (Fzerop (Vecho_keystrokes))
985f9f66
GM
2298 && (/* No message. */
2299 NILP (echo_area_buffer[0])
2300 /* Or empty message. */
2301 || (BUF_BEG (XBUFFER (echo_area_buffer[0]))
2302 == BUF_Z (XBUFFER (echo_area_buffer[0])))
2303 /* Or already echoing from same kboard. */
2304 || (echo_kboard && ok_to_echo_at_next_pause == echo_kboard)
2305 /* Or not echoing before and echoing allowed. */
2306 || (!echo_kboard && ok_to_echo_at_next_pause)))
284f4730
JB
2307 {
2308 Lisp_Object tem0;
985f9f66 2309
7d6de002
RS
2310 /* After a mouse event, start echoing right away.
2311 This is because we are probably about to display a menu,
2312 and we don't want to delay before doing so. */
dbc4e1c1 2313 if (EVENT_HAS_PARAMETERS (prev_event))
3dbd9ee4 2314 echo_now ();
7d6de002
RS
2315 else
2316 {
39aab679
DL
2317 int sec, usec;
2318 double duration = extract_float (Vecho_keystrokes);
2319 sec = (int) duration;
15fa88ab 2320 usec = (duration - sec) * 1000000;
410d4de9
RS
2321 save_getcjmp (save_jump);
2322 restore_getcjmp (local_getcjmp);
39aab679 2323 tem0 = sit_for (sec, usec, 1, 1, 0);
410d4de9 2324 restore_getcjmp (save_jump);
303b5b3f
RS
2325 if (EQ (tem0, Qt)
2326 && ! CONSP (Vunread_command_events))
3dbd9ee4 2327 echo_now ();
7d6de002 2328 }
284f4730
JB
2329 }
2330
410d4de9 2331 /* Maybe auto save due to number of keystrokes. */
284f4730
JB
2332
2333 if (commandflag != 0
2334 && auto_save_interval > 0
c43b1734 2335 && num_nonmacro_input_events - last_auto_save > max (auto_save_interval, 20)
4ec4ed6a 2336 && !detect_input_pending_run_timers (0))
284f4730 2337 {
284f4730 2338 Fdo_auto_save (Qnil, Qnil);
ef8fd672
RS
2339 /* Hooks can actually change some buffers in auto save. */
2340 redisplay ();
284f4730
JB
2341 }
2342
8150596a 2343 /* Try reading using an X menu.
24597608
RS
2344 This is never confused with reading using the minibuf
2345 because the recursive call of read_char in read_char_minibuf_menu_prompt
2346 does not pass on any keymaps. */
410d4de9 2347
24597608 2348 if (nmaps > 0 && INTERACTIVE
5a8d99e0
KH
2349 && !NILP (prev_event)
2350 && EVENT_HAS_PARAMETERS (prev_event)
7539e11f
KR
2351 && !EQ (XCAR (prev_event), Qmenu_bar)
2352 && !EQ (XCAR (prev_event), Qtool_bar)
24597608
RS
2353 /* Don't bring up a menu if we already have another event. */
2354 && NILP (Vunread_command_events)
b8556aee 2355 && unread_command_char < 0)
8eb4d8ef
RS
2356 {
2357 c = read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu);
2358
2359 /* Now that we have read an event, Emacs is not idle. */
2360 timer_stop_idle ();
2361
7c3bc944 2362 RETURN_UNGCPRO (c);
8eb4d8ef 2363 }
7d6de002 2364
410d4de9
RS
2365 /* Maybe autosave and/or garbage collect due to idleness. */
2366
26c1639e 2367 if (INTERACTIVE && NILP (c))
7d6de002
RS
2368 {
2369 int delay_level, buffer_size;
2370
410d4de9
RS
2371 /* Slow down auto saves logarithmically in size of current buffer,
2372 and garbage collect while we're at it. */
7d6de002
RS
2373 if (! MINI_WINDOW_P (XWINDOW (selected_window)))
2374 last_non_minibuf_size = Z - BEG;
2375 buffer_size = (last_non_minibuf_size >> 8) + 1;
2376 delay_level = 0;
2377 while (buffer_size > 64)
2378 delay_level++, buffer_size -= buffer_size >> 2;
2379 if (delay_level < 4) delay_level = 4;
2380 /* delay_level is 4 for files under around 50k, 7 at 100k,
2381 9 at 200k, 11 at 300k, and 12 at 500k. It is 15 at 1 meg. */
2382
2383 /* Auto save if enough time goes by without input. */
2384 if (commandflag != 0
c43b1734 2385 && num_nonmacro_input_events > last_auto_save
8c18cbfb 2386 && INTEGERP (Vauto_save_timeout)
7d6de002
RS
2387 && XINT (Vauto_save_timeout) > 0)
2388 {
2389 Lisp_Object tem0;
410d4de9
RS
2390
2391 save_getcjmp (save_jump);
2392 restore_getcjmp (local_getcjmp);
d9d4c147 2393 tem0 = sit_for (delay_level * XFASTINT (Vauto_save_timeout) / 4,
41365083 2394 0, 1, 1, 0);
410d4de9
RS
2395 restore_getcjmp (save_jump);
2396
303b5b3f
RS
2397 if (EQ (tem0, Qt)
2398 && ! CONSP (Vunread_command_events))
7d6de002 2399 {
7d6de002 2400 Fdo_auto_save (Qnil, Qnil);
7d6de002
RS
2401
2402 /* If we have auto-saved and there is still no input
2403 available, garbage collect if there has been enough
2404 consing going on to make it worthwhile. */
4ec4ed6a 2405 if (!detect_input_pending_run_timers (0)
7d6de002 2406 && consing_since_gc > gc_cons_threshold / 2)
ef8fd672 2407 Fgarbage_collect ();
410d4de9 2408
ef8fd672 2409 redisplay ();
7d6de002
RS
2410 }
2411 }
2412 }
284f4730 2413
303b5b3f
RS
2414 /* If this has become non-nil here, it has been set by a timer
2415 or sentinel or filter. */
2416 if (CONSP (Vunread_command_events))
2417 {
7539e11f
KR
2418 c = XCAR (Vunread_command_events);
2419 Vunread_command_events = XCDR (Vunread_command_events);
303b5b3f
RS
2420 }
2421
410d4de9
RS
2422 /* Read something from current KBOARD's side queue, if possible. */
2423
beecf6a1 2424 if (NILP (c))
1e12dd87 2425 {
c5fdd383 2426 if (current_kboard->kbd_queue_has_data)
beecf6a1 2427 {
c5fdd383 2428 if (!CONSP (current_kboard->kbd_queue))
4524b161 2429 abort ();
7539e11f 2430 c = XCAR (current_kboard->kbd_queue);
c5fdd383 2431 current_kboard->kbd_queue
7539e11f 2432 = XCDR (current_kboard->kbd_queue);
c5fdd383
KH
2433 if (NILP (current_kboard->kbd_queue))
2434 current_kboard->kbd_queue_has_data = 0;
d9d4c147 2435 input_pending = readable_events (0);
4c52b668
KH
2436 if (EVENT_HAS_PARAMETERS (c)
2437 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qswitch_frame))
7539e11f 2438 internal_last_event_frame = XCAR (XCDR (c));
4c52b668 2439 Vlast_event_frame = internal_last_event_frame;
beecf6a1 2440 }
1e8bd3da
RS
2441 }
2442
c5fdd383 2443#ifdef MULTI_KBOARD
1e8bd3da
RS
2444 /* If current_kboard's side queue is empty check the other kboards.
2445 If one of them has data that we have not yet seen here,
2446 switch to it and process the data waiting for it.
2447
2448 Note: if the events queued up for another kboard
2449 have already been seen here, and therefore are not a complete command,
2450 the kbd_queue_has_data field is 0, so we skip that kboard here.
2451 That's to avoid an infinite loop switching between kboards here. */
2452 if (NILP (c) && !single_kboard)
2453 {
2454 KBOARD *kb;
2455 for (kb = all_kboards; kb; kb = kb->next_kboard)
2456 if (kb->kbd_queue_has_data)
2457 {
2458 current_kboard = kb;
ef6661f7
RS
2459 /* This is going to exit from read_char
2460 so we had better get rid of this frame's stuff. */
2461 UNGCPRO;
1e8bd3da
RS
2462 longjmp (wrong_kboard_jmpbuf, 1);
2463 }
2464 }
df0f2ba1
KH
2465#endif
2466
410d4de9
RS
2467 wrong_kboard:
2468
2469 stop_polling ();
2470
1e8bd3da
RS
2471 /* Finally, we read from the main queue,
2472 and if that gives us something we can't use yet, we put it on the
2473 appropriate side queue and try again. */
410d4de9 2474
1e8bd3da
RS
2475 if (NILP (c))
2476 {
2477 KBOARD *kb;
2478
1e8bd3da 2479 /* Actually read a character, waiting if necessary. */
410d4de9
RS
2480 save_getcjmp (save_jump);
2481 restore_getcjmp (local_getcjmp);
83d68044 2482 c = kbd_buffer_get_event (&kb, used_mouse_menu);
410d4de9
RS
2483 restore_getcjmp (save_jump);
2484
c5fdd383 2485#ifdef MULTI_KBOARD
410d4de9 2486 if (! NILP (c) && (kb != current_kboard))
1e8bd3da
RS
2487 {
2488 Lisp_Object *tailp = &kb->kbd_queue;
2489 while (CONSP (*tailp))
7539e11f 2490 tailp = &XCDR (*tailp);
1e8bd3da
RS
2491 if (!NILP (*tailp))
2492 abort ();
2493 *tailp = Fcons (c, Qnil);
2494 kb->kbd_queue_has_data = 1;
46b84797 2495 c = Qnil;
1e8bd3da
RS
2496 if (single_kboard)
2497 goto wrong_kboard;
2498 current_kboard = kb;
ef6661f7
RS
2499 /* This is going to exit from read_char
2500 so we had better get rid of this frame's stuff. */
2501 UNGCPRO;
1e8bd3da 2502 longjmp (wrong_kboard_jmpbuf, 1);
df0f2ba1 2503 }
1e8bd3da 2504#endif
beecf6a1 2505 }
1e8bd3da 2506
284f4730 2507 /* Terminate Emacs in batch mode if at eof. */
8c18cbfb 2508 if (noninteractive && INTEGERP (c) && XINT (c) < 0)
284f4730
JB
2509 Fkill_emacs (make_number (1));
2510
8c18cbfb 2511 if (INTEGERP (c))
80645119
JB
2512 {
2513 /* Add in any extra modifiers, where appropriate. */
2514 if ((extra_keyboard_modifiers & CHAR_CTL)
2515 || ((extra_keyboard_modifiers & 0177) < ' '
2516 && (extra_keyboard_modifiers & 0177) != 0))
faf5e407 2517 XSETINT (c, make_ctrl_char (XINT (c)));
80645119
JB
2518
2519 /* Transfer any other modifier bits directly from
2520 extra_keyboard_modifiers to c. Ignore the actual character code
2521 in the low 16 bits of extra_keyboard_modifiers. */
b8d9050d 2522 XSETINT (c, XINT (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
80645119 2523 }
9fa4395d 2524
284f4730
JB
2525 non_reread:
2526
2fb9049e 2527 timer_stop_idle ();
d9d4c147 2528
284f4730
JB
2529 start_polling ();
2530
410d4de9
RS
2531 if (NILP (c))
2532 {
2533 if (commandflag >= 0
4ec4ed6a 2534 && !input_pending && !detect_input_pending_run_timers (0))
410d4de9
RS
2535 redisplay ();
2536
2537 goto wrong_kboard;
2538 }
2539
2540 non_reread_1:
2541
dfd11da7 2542 /* Buffer switch events are only for internal wakeups
7c3bc944
RS
2543 so don't show them to the user.
2544 Also, don't record a key if we already did. */
2545 if (BUFFERP (c) || key_already_recorded)
2546 RETURN_UNGCPRO (c);
a1341f75 2547
7f07d5ca
RS
2548 /* Process special events within read_char
2549 and loop around to read another event. */
017c7cb6
RS
2550 save = Vquit_flag;
2551 Vquit_flag = Qnil;
7f07d5ca
RS
2552 tem = get_keyelt (access_keymap (get_keymap_1 (Vspecial_event_map, 0, 0),
2553 c, 0, 0), 1);
017c7cb6 2554 Vquit_flag = save;
7f07d5ca
RS
2555
2556 if (!NILP (tem))
2557 {
ba8dfba8
RS
2558 int was_locked = single_kboard;
2559
7f07d5ca 2560 last_input_char = c;
158f7532 2561 Fcommand_execute (tem, Qnil, Fvector (1, &last_input_char), Qt);
ba8dfba8
RS
2562
2563 /* Resume allowing input from any kboard, if that was true before. */
2564 if (!was_locked)
2565 any_kboard_state ();
2566
7f07d5ca
RS
2567 goto retry;
2568 }
2569
284f4730 2570 /* Handle things that only apply to characters. */
8c18cbfb 2571 if (INTEGERP (c))
284f4730
JB
2572 {
2573 /* If kbd_buffer_get_event gave us an EOF, return that. */
86e5706b 2574 if (XINT (c) == -1)
7c3bc944 2575 RETURN_UNGCPRO (c);
284f4730 2576
301738ed
RS
2577 if ((STRINGP (Vkeyboard_translate_table)
2578 && XSTRING (Vkeyboard_translate_table)->size > (unsigned) XFASTINT (c))
2579 || (VECTORP (Vkeyboard_translate_table)
2580 && XVECTOR (Vkeyboard_translate_table)->size > (unsigned) XFASTINT (c))
2581 || (CHAR_TABLE_P (Vkeyboard_translate_table)
2582 && CHAR_TABLE_ORDINARY_SLOTS > (unsigned) XFASTINT (c)))
f9414d62
RS
2583 {
2584 Lisp_Object d;
2585 d = Faref (Vkeyboard_translate_table, c);
2586 /* nil in keyboard-translate-table means no translation. */
2587 if (!NILP (d))
2588 c = d;
2589 }
284f4730
JB
2590 }
2591
e4fe371d
RS
2592 /* If this event is a mouse click in the menu bar,
2593 return just menu-bar for now. Modify the mouse click event
2594 so we won't do this twice, then queue it up. */
2595 if (EVENT_HAS_PARAMETERS (c)
7539e11f 2596 && CONSP (XCDR (c))
e4fe371d 2597 && CONSP (EVENT_START (c))
7539e11f 2598 && CONSP (XCDR (EVENT_START (c))))
284f4730 2599 {
e4fe371d 2600 Lisp_Object posn;
284f4730 2601
e4fe371d
RS
2602 posn = POSN_BUFFER_POSN (EVENT_START (c));
2603 /* Handle menu-bar events:
2604 insert the dummy prefix event `menu-bar'. */
9ea173e8 2605 if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar))
e4fe371d
RS
2606 {
2607 /* Change menu-bar to (menu-bar) as the event "position". */
2608 POSN_BUFFER_POSN (EVENT_START (c)) = Fcons (posn, Qnil);
284f4730 2609
e4fe371d
RS
2610 also_record = c;
2611 Vunread_command_events = Fcons (c, Vunread_command_events);
2612 c = posn;
284f4730 2613 }
284f4730
JB
2614 }
2615
7d18f9ae
RS
2616 /* Store these characters into recent_keys, the dribble file if any,
2617 and the keyboard macro being defined, if any. */
e4fe371d
RS
2618 record_char (c);
2619 if (! NILP (also_record))
2620 record_char (also_record);
51172b6d 2621
d5eecefb
RS
2622 /* Wipe the echo area.
2623 But first, if we are about to use an input method,
2624 save the echo area contents for it to refer to. */
2625 if (INTEGERP (c)
2626 && ! NILP (Vinput_method_function)
2627 && (unsigned) XINT (c) >= ' '
8d769115
KH
2628 && (unsigned) XINT (c) != 127
2629 && (unsigned) XINT (c) < 256)
7ee32cda
GM
2630 {
2631 previous_echo_area_message = Fcurrent_message ();
2632 Vinput_method_previous_message = previous_echo_area_message;
2633 }
d5eecefb 2634
1172eb8d
GM
2635 /* Now wipe the echo area, except for help events which do their
2636 own stuff with the echo area. */
2637 if (!CONSP (c) || !(EQ (Qhelp_echo, XCAR (c))))
2638 {
2639 if (!NILP (echo_area_buffer[0]))
2640 safe_run_hooks (Qecho_area_clear_hook);
2641 clear_message (1, 0);
2642 }
d5eecefb 2643
7d18f9ae 2644 reread_for_input_method:
284f4730 2645 from_macro:
7d18f9ae 2646 /* Pass this to the input method, if appropriate. */
d5eecefb
RS
2647 if (INTEGERP (c)
2648 && ! NILP (Vinput_method_function)
b638f328
RS
2649 /* Don't run the input method within a key sequence,
2650 after the first event of the key sequence. */
2651 && NILP (prev_event)
d5eecefb 2652 && (unsigned) XINT (c) >= ' '
8d769115
KH
2653 && (unsigned) XINT (c) != 127
2654 && (unsigned) XINT (c) < 256)
d5eecefb
RS
2655 {
2656 Lisp_Object keys;
6e5742a0 2657 int key_count;
d5eecefb 2658 struct gcpro gcpro1;
b638f328 2659 int count = specpdl_ptr - specpdl;
d5eecefb 2660
6e5742a0
RS
2661 /* Save the echo status. */
2662 int saved_immediate_echo = current_kboard->immediate_echo;
985f9f66 2663 struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause;
6e5742a0
RS
2664 int saved_echo_after_prompt = current_kboard->echo_after_prompt;
2665
2666 if (before_command_restore_flag)
2667 {
2668 this_command_key_count = before_command_key_count_1;
2669 if (this_command_key_count < this_single_command_key_start)
2670 this_single_command_key_start = this_command_key_count;
2671 echo_truncate (before_command_echo_length_1);
2672 before_command_restore_flag = 0;
2673 }
2674
2675 /* Save the this_command_keys status. */
2676 key_count = this_command_key_count;
2677
2678 if (key_count > 0)
2679 keys = Fcopy_sequence (this_command_keys);
2680 else
2681 keys = Qnil;
d5eecefb 2682 GCPRO1 (keys);
6e5742a0
RS
2683
2684 /* Clear out this_command_keys. */
2685 this_command_key_count = 0;
2686
2687 /* Now wipe the echo area. */
985f9f66 2688 if (!NILP (echo_area_buffer[0]))
6e5742a0 2689 safe_run_hooks (Qecho_area_clear_hook);
985f9f66 2690 clear_message (1, 0);
6e5742a0
RS
2691 echo_truncate (0);
2692
b638f328
RS
2693 /* If we are not reading a key sequence,
2694 never use the echo area. */
2695 if (maps == 0)
2696 {
b638f328
RS
2697 specbind (Qinput_method_use_echo_area, Qt);
2698 }
2699
6e5742a0 2700 /* Call the input method. */
d5eecefb 2701 tem = call1 (Vinput_method_function, c);
b638f328
RS
2702
2703 tem = unbind_to (count, tem);
2704
6e5742a0
RS
2705 /* Restore the saved echoing state
2706 and this_command_keys state. */
2707 this_command_key_count = key_count;
2708 if (key_count > 0)
2709 this_command_keys = keys;
2710
2711 cancel_echoing ();
2712 ok_to_echo_at_next_pause = saved_ok_to_echo;
2713 current_kboard->echo_after_prompt = saved_echo_after_prompt;
2714 if (saved_immediate_echo)
2715 echo_now ();
2716
d5eecefb 2717 UNGCPRO;
6e5742a0 2718
d5eecefb
RS
2719 /* The input method can return no events. */
2720 if (! CONSP (tem))
7d18f9ae 2721 {
d5eecefb 2722 /* Bring back the previous message, if any. */
7ee32cda
GM
2723 if (! NILP (previous_echo_area_message))
2724 message_with_string ("%s", previous_echo_area_message, 0);
d5eecefb 2725 goto retry;
7d18f9ae 2726 }
d5eecefb 2727 /* It returned one event or more. */
7539e11f 2728 c = XCAR (tem);
d5eecefb 2729 Vunread_post_input_method_events
7539e11f 2730 = nconc2 (XCDR (tem), Vunread_post_input_method_events);
7d18f9ae 2731 }
7c3bc944 2732
7d18f9ae 2733 reread_first:
284f4730 2734
7ee32cda 2735 /* Display help if not echoing. */
1172eb8d 2736 if (CONSP (c) && EQ (XCAR (c), Qhelp_echo))
7ee32cda 2737 {
2190735a
GM
2738 /* (help-echo FRAME HELP WINDOW OBJECT POS). */
2739 Lisp_Object help, object, position, window;
8dfd92c9 2740 help = Fnth (make_number (2), c);
2190735a
GM
2741 window = Fnth (make_number (3), c);
2742 object = Fnth (make_number (4), c);
2743 position = Fnth (make_number (5), c);
2744 show_help_echo (help, window, object, position, 0);
7ee32cda
GM
2745 goto retry;
2746 }
2747
7d18f9ae 2748 if (this_command_key_count == 0 || ! reread)
e4fe371d 2749 {
7d18f9ae
RS
2750 before_command_key_count = this_command_key_count;
2751 before_command_echo_length = echo_length ();
2752
2753 /* Don't echo mouse motion events. */
f2647d04
DL
2754 if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
2755 && NILP (Fzerop (Vecho_keystrokes))
7d18f9ae
RS
2756 && ! (EVENT_HAS_PARAMETERS (c)
2757 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
2758 {
2759 echo_char (c);
2760 if (! NILP (also_record))
2761 echo_char (also_record);
2762 /* Once we reread a character, echoing can happen
2763 the next time we pause to read a new one. */
985f9f66 2764 ok_to_echo_at_next_pause = current_kboard;
7d18f9ae
RS
2765 }
2766
2767 /* Record this character as part of the current key. */
2768 add_command_key (c);
e4fe371d 2769 if (! NILP (also_record))
7d18f9ae 2770 add_command_key (also_record);
e4fe371d 2771 }
b8556aee 2772
284f4730 2773 last_input_char = c;
c43b1734 2774 num_input_events++;
284f4730
JB
2775
2776 /* Process the help character specially if enabled */
ecb7cb34 2777 if (!NILP (Vhelp_form) && help_char_p (c))
284f4730
JB
2778 {
2779 Lisp_Object tem0;
2780 count = specpdl_ptr - specpdl;
2781
2782 record_unwind_protect (Fset_window_configuration,
2783 Fcurrent_window_configuration (Qnil));
2784
2785 tem0 = Feval (Vhelp_form);
8c18cbfb 2786 if (STRINGP (tem0))
284f4730
JB
2787 internal_with_output_to_temp_buffer ("*Help*", print_help, tem0);
2788
2789 cancel_echoing ();
3cb81011
KH
2790 do
2791 c = read_char (0, 0, 0, Qnil, 0);
8c18cbfb 2792 while (BUFFERP (c));
ff11dfa1 2793 /* Remove the help from the frame */
284f4730 2794 unbind_to (count, Qnil);
410d4de9 2795
284f4730
JB
2796 redisplay ();
2797 if (EQ (c, make_number (040)))
2798 {
2799 cancel_echoing ();
3cb81011
KH
2800 do
2801 c = read_char (0, 0, 0, Qnil, 0);
8c18cbfb 2802 while (BUFFERP (c));
284f4730
JB
2803 }
2804 }
2805
7c3bc944 2806 RETURN_UNGCPRO (c);
284f4730
JB
2807}
2808
8eb4d8ef
RS
2809/* Record a key that came from a mouse menu.
2810 Record it for echoing, for this-command-keys, and so on. */
2811
2812static void
2813record_menu_key (c)
2814 Lisp_Object c;
2815{
2816 /* Wipe the echo area. */
985f9f66 2817 clear_message (1, 0);
8eb4d8ef
RS
2818
2819 record_char (c);
2820
2821 before_command_key_count = this_command_key_count;
2822 before_command_echo_length = echo_length ();
2823
2824 /* Don't echo mouse motion events. */
f2647d04
DL
2825 if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
2826 && NILP (Fzerop (Vecho_keystrokes)))
8eb4d8ef
RS
2827 {
2828 echo_char (c);
2829
2830 /* Once we reread a character, echoing can happen
2831 the next time we pause to read a new one. */
2832 ok_to_echo_at_next_pause = 0;
2833 }
2834
2835 /* Record this character as part of the current key. */
2836 add_command_key (c);
2837
2838 /* Re-reading in the middle of a command */
2839 last_input_char = c;
c43b1734 2840 num_input_events++;
8eb4d8ef
RS
2841}
2842
ecb7cb34
KH
2843/* Return 1 if should recognize C as "the help character". */
2844
2845int
2846help_char_p (c)
2847 Lisp_Object c;
2848{
2849 Lisp_Object tail;
2850
2851 if (EQ (c, Vhelp_char))
2852 return 1;
7539e11f
KR
2853 for (tail = Vhelp_event_list; CONSP (tail); tail = XCDR (tail))
2854 if (EQ (c, XCAR (tail)))
ecb7cb34
KH
2855 return 1;
2856 return 0;
2857}
2858
e4fe371d
RS
2859/* Record the input event C in various ways. */
2860
2861static void
2862record_char (c)
2863 Lisp_Object c;
2864{
2865 total_keys++;
2866 XVECTOR (recent_keys)->contents[recent_keys_index] = c;
2867 if (++recent_keys_index >= NUM_RECENT_KEYS)
2868 recent_keys_index = 0;
2869
2870 /* Write c to the dribble file. If c is a lispy event, write
2871 the event's symbol to the dribble file, in <brackets>. Bleaugh.
2872 If you, dear reader, have a better idea, you've got the source. :-) */
2873 if (dribble)
2874 {
2875 if (INTEGERP (c))
2876 {
2877 if (XUINT (c) < 0x100)
2878 putc (XINT (c), dribble);
2879 else
6de34814 2880 fprintf (dribble, " 0x%x", (int) XUINT (c));
e4fe371d
RS
2881 }
2882 else
2883 {
2884 Lisp_Object dribblee;
2885
2886 /* If it's a structured event, take the event header. */
2887 dribblee = EVENT_HEAD (c);
2888
2889 if (SYMBOLP (dribblee))
2890 {
2891 putc ('<', dribble);
2892 fwrite (XSYMBOL (dribblee)->name->data, sizeof (char),
fc932ac6 2893 STRING_BYTES (XSYMBOL (dribblee)->name),
e4fe371d
RS
2894 dribble);
2895 putc ('>', dribble);
2896 }
2897 }
2898
2899 fflush (dribble);
2900 }
2901
2902 store_kbd_macro_char (c);
2903
c43b1734 2904 num_nonmacro_input_events++;
e4fe371d
RS
2905}
2906
284f4730
JB
2907Lisp_Object
2908print_help (object)
2909 Lisp_Object object;
2910{
622de3e9 2911 struct buffer *old = current_buffer;
284f4730 2912 Fprinc (object, Qnil);
622de3e9
KH
2913 set_buffer_internal (XBUFFER (Vstandard_output));
2914 call0 (intern ("help-mode"));
2915 set_buffer_internal (old);
284f4730
JB
2916 return Qnil;
2917}
2918
2919/* Copy out or in the info on where C-g should throw to.
2920 This is used when running Lisp code from within get_char,
2921 in case get_char is called recursively.
2922 See read_process_output. */
2923
dfcf069d 2924static void
284f4730
JB
2925save_getcjmp (temp)
2926 jmp_buf temp;
2927{
2928 bcopy (getcjmp, temp, sizeof getcjmp);
2929}
2930
dfcf069d 2931static void
284f4730
JB
2932restore_getcjmp (temp)
2933 jmp_buf temp;
2934{
2935 bcopy (temp, getcjmp, sizeof getcjmp);
2936}
284f4730 2937\f
2eb6bfbe
RM
2938#ifdef HAVE_MOUSE
2939
284f4730
JB
2940/* Restore mouse tracking enablement. See Ftrack_mouse for the only use
2941 of this function. */
a9d77f1f 2942
284f4730
JB
2943static Lisp_Object
2944tracking_off (old_value)
2945 Lisp_Object old_value;
2946{
71edead1
RS
2947 do_mouse_tracking = old_value;
2948 if (NILP (old_value))
284f4730 2949 {
284f4730
JB
2950 /* Redisplay may have been preempted because there was input
2951 available, and it assumes it will be called again after the
2952 input has been processed. If the only input available was
2953 the sort that we have just disabled, then we need to call
2954 redisplay. */
d9d4c147 2955 if (!readable_events (1))
284f4730
JB
2956 {
2957 redisplay_preserve_echo_area ();
d9d4c147 2958 get_input_pending (&input_pending, 1);
284f4730
JB
2959 }
2960 }
30690496 2961 return Qnil;
284f4730
JB
2962}
2963
2964DEFUN ("track-mouse", Ftrack_mouse, Strack_mouse, 0, UNEVALLED, 0,
4bb994d1
JB
2965 "Evaluate BODY with mouse movement events enabled.\n\
2966Within a `track-mouse' form, mouse motion generates input events that\n\
2967you can read with `read-event'.\n\
2968Normally, mouse motion is ignored.")
284f4730
JB
2969 (args)
2970 Lisp_Object args;
2971{
2972 int count = specpdl_ptr - specpdl;
2973 Lisp_Object val;
2974
a9d77f1f 2975 record_unwind_protect (tracking_off, do_mouse_tracking);
284f4730 2976
f3253854 2977 do_mouse_tracking = Qt;
df0f2ba1 2978
284f4730
JB
2979 val = Fprogn (args);
2980 return unbind_to (count, val);
2981}
2eb6bfbe 2982
f3253854
KH
2983/* If mouse has moved on some frame, return one of those frames.
2984 Return 0 otherwise. */
2985
2986static FRAME_PTR
2987some_mouse_moved ()
2988{
2989 Lisp_Object tail, frame;
2990
2991 FOR_EACH_FRAME (tail, frame)
2992 {
2993 if (XFRAME (frame)->mouse_moved)
2994 return XFRAME (frame);
2995 }
2996
2997 return 0;
2998}
2999
2eb6bfbe 3000#endif /* HAVE_MOUSE */
a612e298
RS
3001\f
3002/* Low level keyboard/mouse input.
3003 kbd_buffer_store_event places events in kbd_buffer, and
0646c0dd 3004 kbd_buffer_get_event retrieves them. */
a612e298
RS
3005
3006/* Return true iff there are any events in the queue that read-char
3007 would return. If this returns false, a read-char would block. */
3008static int
d9d4c147
KH
3009readable_events (do_timers_now)
3010 int do_timers_now;
a612e298 3011{
4ec4ed6a
RS
3012 if (do_timers_now)
3013 timer_check (do_timers_now);
3014
beecf6a1
KH
3015 if (kbd_fetch_ptr != kbd_store_ptr)
3016 return 1;
3017#ifdef HAVE_MOUSE
f3253854 3018 if (!NILP (do_mouse_tracking) && some_mouse_moved ())
beecf6a1
KH
3019 return 1;
3020#endif
1e8bd3da 3021 if (single_kboard)
4c52b668 3022 {
c5fdd383 3023 if (current_kboard->kbd_queue_has_data)
4c52b668
KH
3024 return 1;
3025 }
3026 else
3027 {
c5fdd383
KH
3028 KBOARD *kb;
3029 for (kb = all_kboards; kb; kb = kb->next_kboard)
3030 if (kb->kbd_queue_has_data)
4c52b668
KH
3031 return 1;
3032 }
beecf6a1 3033 return 0;
a612e298
RS
3034}
3035
3036/* Set this for debugging, to have a way to get out */
3037int stop_character;
284f4730 3038
c5fdd383
KH
3039#ifdef MULTI_KBOARD
3040static KBOARD *
3041event_to_kboard (event)
5798cf15
KH
3042 struct input_event *event;
3043{
3044 Lisp_Object frame;
3045 frame = event->frame_or_window;
3046 if (CONSP (frame))
7539e11f 3047 frame = XCAR (frame);
5798cf15
KH
3048 else if (WINDOWP (frame))
3049 frame = WINDOW_FRAME (XWINDOW (frame));
3050
3051 /* There are still some events that don't set this field.
f5b56972
KH
3052 For now, just ignore the problem.
3053 Also ignore dead frames here. */
3054 if (!FRAMEP (frame) || !FRAME_LIVE_P (XFRAME (frame)))
5798cf15
KH
3055 return 0;
3056 else
c5fdd383 3057 return FRAME_KBOARD (XFRAME (frame));
5798cf15
KH
3058}
3059#endif
3060
284f4730
JB
3061/* Store an event obtained at interrupt level into kbd_buffer, fifo */
3062
3063void
3064kbd_buffer_store_event (event)
3065 register struct input_event *event;
3066{
3067 if (event->kind == no_event)
3068 abort ();
3069
3070 if (event->kind == ascii_keystroke)
3071 {
e9bf89a0 3072 register int c = event->code & 0377;
284f4730 3073
faf5e407
JB
3074 if (event->modifiers & ctrl_modifier)
3075 c = make_ctrl_char (c);
3076
9fd7d808
RS
3077 c |= (event->modifiers
3078 & (meta_modifier | alt_modifier
3079 | hyper_modifier | super_modifier));
3080
86e5706b 3081 if (c == quit_char)
284f4730 3082 {
3e51c7b7 3083 extern SIGTYPE interrupt_signal ();
c5fdd383
KH
3084#ifdef MULTI_KBOARD
3085 KBOARD *kb;
5798cf15
KH
3086 struct input_event *sp;
3087
1e8bd3da 3088 if (single_kboard
c5fdd383
KH
3089 && (kb = FRAME_KBOARD (XFRAME (event->frame_or_window)),
3090 kb != current_kboard))
5798cf15 3091 {
c5fdd383 3092 kb->kbd_queue
5798cf15
KH
3093 = Fcons (make_lispy_switch_frame (event->frame_or_window),
3094 Fcons (make_number (c), Qnil));
c5fdd383 3095 kb->kbd_queue_has_data = 1;
5798cf15
KH
3096 for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++)
3097 {
3098 if (sp == kbd_buffer + KBD_BUFFER_SIZE)
3099 sp = kbd_buffer;
3100
c5fdd383 3101 if (event_to_kboard (sp) == kb)
5798cf15
KH
3102 {
3103 sp->kind = no_event;
3104 sp->frame_or_window = Qnil;
da8f7368 3105 sp->arg = Qnil;
5798cf15
KH
3106 }
3107 }
3108 return;
3109 }
3110#endif
3e51c7b7 3111
284f4730 3112 /* If this results in a quit_char being returned to Emacs as
3c370943 3113 input, set Vlast_event_frame properly. If this doesn't
284f4730 3114 get returned to Emacs as an event, the next event read
ff11dfa1 3115 will set Vlast_event_frame again, so this is safe to do. */
4bb994d1 3116 {
9b8eb840 3117 Lisp_Object focus;
4bb994d1 3118
9b8eb840 3119 focus = FRAME_FOCUS_FRAME (XFRAME (event->frame_or_window));
4bb994d1 3120 if (NILP (focus))
beecf6a1 3121 focus = event->frame_or_window;
4c52b668
KH
3122 internal_last_event_frame = focus;
3123 Vlast_event_frame = focus;
4bb994d1 3124 }
3e51c7b7 3125
ffd56f97 3126 last_event_timestamp = event->timestamp;
284f4730
JB
3127 interrupt_signal ();
3128 return;
3129 }
3130
3131 if (c && c == stop_character)
3132 {
3133 sys_suspend ();
3134 return;
3135 }
284f4730 3136 }
3fe8e9a2
RS
3137 /* Don't insert two buffer_switch_event's in a row.
3138 Just ignore the second one. */
3139 else if (event->kind == buffer_switch_event
3140 && kbd_fetch_ptr != kbd_store_ptr
3141 && kbd_store_ptr->kind == buffer_switch_event)
3142 return;
284f4730 3143
beecf6a1
KH
3144 if (kbd_store_ptr - kbd_buffer == KBD_BUFFER_SIZE)
3145 kbd_store_ptr = kbd_buffer;
284f4730
JB
3146
3147 /* Don't let the very last slot in the buffer become full,
3148 since that would make the two pointers equal,
3149 and that is indistinguishable from an empty buffer.
3150 Discard the event if it would fill the last slot. */
beecf6a1 3151 if (kbd_fetch_ptr - 1 != kbd_store_ptr)
284f4730 3152 {
da8f7368
GM
3153 int idx;
3154
3155#if 0 /* The selection_request_event case looks bogus, and it's error
3156 prone to assign individual members for other events, in case
3157 the input_event structure is changed. --2000-07-13, gerd. */
7ee32cda 3158 struct input_event *sp = kbd_store_ptr;
612b78ef 3159 sp->kind = event->kind;
27203ead
RS
3160 if (event->kind == selection_request_event)
3161 {
3162 /* We must not use the ordinary copying code for this case,
3163 since `part' is an enum and copying it might not copy enough
3164 in this case. */
612b78ef 3165 bcopy (event, (char *) sp, sizeof (*event));
27203ead
RS
3166 }
3167 else
da8f7368 3168
27203ead 3169 {
612b78ef
KH
3170 sp->code = event->code;
3171 sp->part = event->part;
3172 sp->frame_or_window = event->frame_or_window;
da8f7368 3173 sp->arg = event->arg;
612b78ef
KH
3174 sp->modifiers = event->modifiers;
3175 sp->x = event->x;
3176 sp->y = event->y;
3177 sp->timestamp = event->timestamp;
27203ead 3178 }
da8f7368
GM
3179#else
3180 *kbd_store_ptr = *event;
3181#endif
284f4730 3182
da8f7368
GM
3183 idx = 2 * (kbd_store_ptr - kbd_buffer);
3184 ASET (kbd_buffer_gcpro, idx, event->frame_or_window);
3185 ASET (kbd_buffer_gcpro, idx + 1, event->arg);
3186 ++kbd_store_ptr;
284f4730
JB
3187 }
3188}
8dfd92c9
GM
3189
3190
f139e559 3191/* Generate HELP_EVENT input_events in BUFP which has room for
0bbfdc25
GM
3192 SIZE events. If there's not enough room in BUFP, ignore this
3193 event.
8dfd92c9
GM
3194
3195 HELP is the help form.
3196
3197 FRAME is the frame on which the help is generated. OBJECT is the
5b2ec2d0
GM
3198 Lisp object where the help was found (a buffer, a string, an
3199 overlay, or nil if neither from a string nor from a buffer. POS is
3200 the position within OBJECT where the help was found.
8dfd92c9
GM
3201
3202 Value is the number of input_events generated. */
3203
3204int
0bbfdc25 3205gen_help_event (bufp, size, help, frame, window, object, pos)
8dfd92c9 3206 struct input_event *bufp;
0bbfdc25 3207 int size;
2190735a 3208 Lisp_Object help, frame, object, window;
8dfd92c9
GM
3209 int pos;
3210{
0bbfdc25
GM
3211 int nevents_stored = 0;
3212
3213 if (size >= 2)
3214 {
3215 bufp->kind = HELP_EVENT;
3216 bufp->frame_or_window = frame;
3217 bufp->arg = object;
3218 bufp->x = make_number (pos);
3219 bufp->code = 0;
8dfd92c9 3220
0bbfdc25
GM
3221 ++bufp;
3222 bufp->kind = HELP_EVENT;
3223 bufp->frame_or_window = WINDOWP (window) ? window : frame;
3224 bufp->arg = help;
3225 bufp->code = 1;
3226 nevents_stored = 2;
3227 }
2190735a 3228
0bbfdc25 3229 return nevents_stored;
8dfd92c9
GM
3230}
3231
3232
3233/* Store HELP_EVENTs for HELP on FRAME in the input queue. */
3234
3235void
3236kbd_buffer_store_help_event (frame, help)
3237 Lisp_Object frame, help;
3238{
3239 struct input_event event;
3240
3241 event.kind = HELP_EVENT;
3242 event.frame_or_window = frame;
3243 event.arg = Qnil;
3244 event.x = make_number (0);
3245 event.code = 0;
3246 kbd_buffer_store_event (&event);
3247
3248 event.kind = HELP_EVENT;
3249 event.frame_or_window = frame;
3250 event.arg = help;
3251 event.x = make_number (0);
3252 event.code = 1;
3253 kbd_buffer_store_event (&event);
3254}
3255
a612e298 3256\f
07de30b9
GV
3257/* Discard any mouse events in the event buffer by setting them to
3258 no_event. */
3259void
3260discard_mouse_events ()
3261{
3262 struct input_event *sp;
3263 for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++)
3264 {
3265 if (sp == kbd_buffer + KBD_BUFFER_SIZE)
3266 sp = kbd_buffer;
3267
3268 if (sp->kind == mouse_click
3269#ifdef WINDOWSNT
3270 || sp->kind == w32_scroll_bar_click
3271#endif
3272 || sp->kind == scroll_bar_click)
3273 {
3274 sp->kind = no_event;
3275 }
3276 }
3277}
eeabfe76 3278
0bbfdc25
GM
3279
3280/* Return non-zero if there are any real events waiting in the event
3281 buffer, not counting `no_event's.
3282
3283 If DISCARD is non-zero, discard no_event events at the front of
3284 the input queue, possibly leaving the input queue empty if there
3285 are no real input events. */
3286
eeabfe76
EZ
3287int
3288kbd_buffer_events_waiting (discard)
3289 int discard;
3290{
3291 struct input_event *sp;
0bbfdc25
GM
3292
3293 for (sp = kbd_fetch_ptr;
3294 sp != kbd_store_ptr && sp->kind == no_event;
3295 ++sp)
eeabfe76
EZ
3296 {
3297 if (sp == kbd_buffer + KBD_BUFFER_SIZE)
3298 sp = kbd_buffer;
eeabfe76 3299 }
0bbfdc25 3300
eeabfe76
EZ
3301 if (discard)
3302 kbd_fetch_ptr = sp;
0bbfdc25
GM
3303
3304 return sp != kbd_store_ptr && sp->kind != no_event;
eeabfe76 3305}
0bbfdc25 3306
07de30b9 3307\f
0bbfdc25
GM
3308/* Clear input event EVENT. */
3309
3310static INLINE void
3311clear_event (event)
3312 struct input_event *event;
3313{
3314 int idx = 2 * (event - kbd_buffer);
3315 ASET (kbd_buffer_gcpro, idx, Qnil);
3316 ASET (kbd_buffer_gcpro, idx + 1, Qnil);
3317 event->kind = no_event;
3318}
3319
3320
a612e298
RS
3321/* Read one event from the event buffer, waiting if necessary.
3322 The value is a Lisp object representing the event.
3323 The value is nil for an event that should be ignored,
3324 or that was handled here.
3325 We always read and discard one event. */
284f4730
JB
3326
3327static Lisp_Object
83d68044 3328kbd_buffer_get_event (kbp, used_mouse_menu)
410d4de9 3329 KBOARD **kbp;
83d68044 3330 int *used_mouse_menu;
284f4730
JB
3331{
3332 register int c;
3333 Lisp_Object obj;
3334
3335 if (noninteractive)
3336 {
3337 c = getchar ();
18cd2eeb 3338 XSETINT (obj, c);
f5b56972 3339 *kbp = current_kboard;
284f4730
JB
3340 return obj;
3341 }
3342
3343 /* Wait until there is input available. */
3344 for (;;)
3345 {
beecf6a1
KH
3346 if (kbd_fetch_ptr != kbd_store_ptr)
3347 break;
3348#ifdef HAVE_MOUSE
f3253854 3349 if (!NILP (do_mouse_tracking) && some_mouse_moved ())
284f4730 3350 break;
beecf6a1 3351#endif
284f4730
JB
3352
3353 /* If the quit flag is set, then read_char will return
3354 quit_char, so that counts as "available input." */
3355 if (!NILP (Vquit_flag))
3356 quit_throw_to_read_char ();
3357
3358 /* One way or another, wait until input is available; then, if
3359 interrupt handlers have not read it, read it now. */
3360
3361#ifdef OLDVMS
3362 wait_for_kbd_input ();
3363#else
3364/* Note SIGIO has been undef'd if FIONREAD is missing. */
3365#ifdef SIGIO
3366 gobble_input (0);
3367#endif /* SIGIO */
beecf6a1
KH
3368 if (kbd_fetch_ptr != kbd_store_ptr)
3369 break;
3370#ifdef HAVE_MOUSE
f3253854 3371 if (!NILP (do_mouse_tracking) && some_mouse_moved ())
beecf6a1
KH
3372 break;
3373#endif
3374 {
3375 Lisp_Object minus_one;
f76475ad 3376
beecf6a1 3377 XSETINT (minus_one, -1);
d9d4c147 3378 wait_reading_process_input (0, 0, minus_one, 1);
284f4730 3379
beecf6a1
KH
3380 if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr)
3381 /* Pass 1 for EXPECT since we just waited to have input. */
3382 read_avail_input (1);
3383 }
284f4730
JB
3384#endif /* not VMS */
3385 }
3386
303b5b3f
RS
3387 if (CONSP (Vunread_command_events))
3388 {
3389 Lisp_Object first;
7539e11f
KR
3390 first = XCAR (Vunread_command_events);
3391 Vunread_command_events = XCDR (Vunread_command_events);
303b5b3f
RS
3392 *kbp = current_kboard;
3393 return first;
3394 }
3395
284f4730
JB
3396 /* At this point, we know that there is a readable event available
3397 somewhere. If the event queue is empty, then there must be a
3398 mouse movement enabled and available. */
beecf6a1 3399 if (kbd_fetch_ptr != kbd_store_ptr)
284f4730 3400 {
cd21b839 3401 struct input_event *event;
3e51c7b7 3402
beecf6a1
KH
3403 event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE)
3404 ? kbd_fetch_ptr
3405 : kbd_buffer);
3e51c7b7 3406
cd21b839 3407 last_event_timestamp = event->timestamp;
cd21b839 3408
c5fdd383
KH
3409#ifdef MULTI_KBOARD
3410 *kbp = event_to_kboard (event);
3411 if (*kbp == 0)
3412 *kbp = current_kboard; /* Better than returning null ptr? */
5798cf15 3413#else
c5fdd383 3414 *kbp = &the_only_kboard;
5798cf15 3415#endif
beecf6a1 3416
4bb994d1
JB
3417 obj = Qnil;
3418
48e416d4 3419 /* These two kinds of events get special handling
a612e298
RS
3420 and don't actually appear to the command loop.
3421 We return nil for them. */
48e416d4
RS
3422 if (event->kind == selection_request_event)
3423 {
598a9fa7 3424#ifdef HAVE_X11
1e8bd3da
RS
3425 struct input_event copy;
3426
4581e928
RS
3427 /* Remove it from the buffer before processing it,
3428 since otherwise swallow_events will see it
3429 and process it again. */
1e8bd3da 3430 copy = *event;
beecf6a1 3431 kbd_fetch_ptr = event + 1;
d9d4c147 3432 input_pending = readable_events (0);
4581e928 3433 x_handle_selection_request (&copy);
598a9fa7
JB
3434#else
3435 /* We're getting selection request events, but we don't have
3436 a window system. */
3437 abort ();
3438#endif
48e416d4
RS
3439 }
3440
1e12dd87 3441 else if (event->kind == selection_clear_event)
48e416d4 3442 {
598a9fa7 3443#ifdef HAVE_X11
e0301c07
RS
3444 struct input_event copy;
3445
3446 /* Remove it from the buffer before processing it. */
3447 copy = *event;
beecf6a1 3448 kbd_fetch_ptr = event + 1;
d9d4c147 3449 input_pending = readable_events (0);
90c2bb0c 3450 x_handle_selection_clear (&copy);
598a9fa7
JB
3451#else
3452 /* We're getting selection request events, but we don't have
3453 a window system. */
3454 abort ();
3455#endif
48e416d4 3456 }
e98a93eb 3457#if defined (HAVE_X11) || defined (HAVE_NTGUI)
990acea3
RS
3458 else if (event->kind == delete_window_event)
3459 {
bbdc2092
RS
3460 /* Make an event (delete-frame (FRAME)). */
3461 obj = Fcons (event->frame_or_window, Qnil);
af17bd2b 3462 obj = Fcons (Qdelete_frame, Fcons (obj, Qnil));
beecf6a1 3463 kbd_fetch_ptr = event + 1;
af17bd2b
KH
3464 }
3465 else if (event->kind == iconify_event)
3466 {
3467 /* Make an event (iconify-frame (FRAME)). */
3468 obj = Fcons (event->frame_or_window, Qnil);
3469 obj = Fcons (Qiconify_frame, Fcons (obj, Qnil));
beecf6a1 3470 kbd_fetch_ptr = event + 1;
af17bd2b
KH
3471 }
3472 else if (event->kind == deiconify_event)
3473 {
3474 /* Make an event (make-frame-visible (FRAME)). */
3475 obj = Fcons (event->frame_or_window, Qnil);
3476 obj = Fcons (Qmake_frame_visible, Fcons (obj, Qnil));
beecf6a1 3477 kbd_fetch_ptr = event + 1;
990acea3
RS
3478 }
3479#endif
a8015ab5
KH
3480 else if (event->kind == buffer_switch_event)
3481 {
3482 /* The value doesn't matter here; only the type is tested. */
18cd2eeb 3483 XSETBUFFER (obj, current_buffer);
beecf6a1 3484 kbd_fetch_ptr = event + 1;
a8015ab5 3485 }
07de30b9 3486#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
099787c1
RS
3487 else if (event->kind == menu_bar_activate_event)
3488 {
3489 kbd_fetch_ptr = event + 1;
d9d4c147 3490 input_pending = readable_events (0);
e649d076
RS
3491 if (FRAME_LIVE_P (XFRAME (event->frame_or_window)))
3492 x_activate_menubar (XFRAME (event->frame_or_window));
099787c1 3493 }
1161d367
GV
3494#endif
3495#ifdef WINDOWSNT
3496 else if (event->kind == language_change_event)
3497 {
3498 /* Make an event (language-change (FRAME CHARSET LCID)). */
3499 obj = Fcons (event->modifiers, Qnil);
3500 obj = Fcons (event->code, Qnil);
3501 obj = Fcons (event->frame_or_window, obj);
3502 obj = Fcons (Qlanguage_change, Fcons (obj, Qnil));
3503 kbd_fetch_ptr = event + 1;
3504 }
099787c1 3505#endif
a612e298 3506 /* Just discard these, by returning nil.
c5fdd383 3507 With MULTI_KBOARD, these events are used as placeholders
5798cf15
KH
3508 when we need to randomly delete events from the queue.
3509 (They shouldn't otherwise be found in the buffer,
3510 but on some machines it appears they do show up
c5fdd383 3511 even without MULTI_KBOARD.) */
07de30b9
GV
3512 /* On Windows NT/9X, no_event is used to delete extraneous
3513 mouse events during a popup-menu call. */
a612e298 3514 else if (event->kind == no_event)
beecf6a1 3515 kbd_fetch_ptr = event + 1;
7ee32cda
GM
3516 else if (event->kind == HELP_EVENT)
3517 {
e4457b09 3518 /* There are always two HELP_EVENTs in the input queue. */
2190735a 3519 Lisp_Object object, position, help, frame, window;
e4457b09 3520
8dfd92c9
GM
3521 xassert (event->code == 0);
3522 frame = event->frame_or_window;
3523 object = event->arg;
3524 position = event->x;
0bbfdc25 3525 clear_event (event);
e4457b09
GM
3526
3527 kbd_fetch_ptr = event + 1;
3528 event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE)
3529 ? kbd_fetch_ptr
3530 : kbd_buffer);
3531 xassert (event->code == 1);
3532 help = event->arg;
3533 window = event->frame_or_window;
2190735a
GM
3534 if (!WINDOWP (window))
3535 window = Qnil;
3536 obj = Fcons (Qhelp_echo,
3537 list5 (frame, help, window, object, position));
0bbfdc25 3538 clear_event (event);
e4457b09 3539 kbd_fetch_ptr = event + 1;
7ee32cda 3540 }
c51c7093
GM
3541 else if (event->kind == FOCUS_IN_EVENT)
3542 {
3543 /* Notification of a FocusIn event. The frame receiving the
3544 focus is in event->frame_or_window. Generate a
3545 switch-frame event if necessary. */
3546 Lisp_Object frame, focus;
3547
3548 frame = event->frame_or_window;
3549 focus = FRAME_FOCUS_FRAME (XFRAME (frame));
3550 if (FRAMEP (focus))
3551 frame = focus;
3552
3553 if (!EQ (frame, internal_last_event_frame)
3554 && !EQ (frame, selected_frame))
3555 obj = make_lispy_switch_frame (frame);
3556 internal_last_event_frame = frame;
3557 kbd_fetch_ptr = event + 1;
3558 }
1e12dd87
RS
3559 else
3560 {
c51c7093
GM
3561 /* If this event is on a different frame, return a switch-frame this
3562 time, and leave the event in the queue for next time. */
9b8eb840 3563 Lisp_Object frame;
1e12dd87 3564 Lisp_Object focus;
7b4aedb9 3565
9b8eb840 3566 frame = event->frame_or_window;
2470a66f 3567 if (CONSP (frame))
7539e11f 3568 frame = XCAR (frame);
2470a66f 3569 else if (WINDOWP (frame))
1e12dd87 3570 frame = WINDOW_FRAME (XWINDOW (frame));
4bb994d1 3571
1e12dd87
RS
3572 focus = FRAME_FOCUS_FRAME (XFRAME (frame));
3573 if (! NILP (focus))
3574 frame = focus;
07d2b8de 3575
4c52b668 3576 if (! EQ (frame, internal_last_event_frame)
788f89eb 3577 && !EQ (frame, selected_frame))
1e12dd87 3578 obj = make_lispy_switch_frame (frame);
4c52b668 3579 internal_last_event_frame = frame;
4bb994d1 3580
1e12dd87
RS
3581 /* If we didn't decide to make a switch-frame event, go ahead
3582 and build a real event from the queue entry. */
cd21b839 3583
1e12dd87
RS
3584 if (NILP (obj))
3585 {
da8f7368
GM
3586 int idx;
3587
1e12dd87 3588 obj = make_lispy_event (event);
da8f7368 3589
e98a93eb 3590#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
83d68044
KH
3591 /* If this was a menu selection, then set the flag to inhibit
3592 writing to last_nonmenu_event. Don't do this if the event
3593 we're returning is (menu-bar), though; that indicates the
3594 beginning of the menu sequence, and we might as well leave
3595 that as the `event with parameters' for this selection. */
da8f7368
GM
3596 if (used_mouse_menu
3597 && !EQ (event->frame_or_window, event->arg)
3598 && (event->kind == MENU_BAR_EVENT
3599 || event->kind == TOOL_BAR_EVENT))
83d68044
KH
3600 *used_mouse_menu = 1;
3601#endif
1e12dd87
RS
3602
3603 /* Wipe out this event, to catch bugs. */
0bbfdc25 3604 clear_event (event);
beecf6a1 3605 kbd_fetch_ptr = event + 1;
1e12dd87 3606 }
4bb994d1 3607 }
284f4730 3608 }
2eb6bfbe 3609#ifdef HAVE_MOUSE
a612e298 3610 /* Try generating a mouse motion event. */
f3253854 3611 else if (!NILP (do_mouse_tracking) && some_mouse_moved ())
284f4730 3612 {
f3253854 3613 FRAME_PTR f = some_mouse_moved ();
7b4aedb9 3614 Lisp_Object bar_window;
3c370943 3615 enum scroll_bar_part part;
e5d77022
JB
3616 Lisp_Object x, y;
3617 unsigned long time;
284f4730 3618
c5fdd383 3619 *kbp = current_kboard;
e177ac3a
RS
3620 /* Note that this uses F to determine which display to look at.
3621 If there is no valid info, it does not store anything
3622 so x remains nil. */
3623 x = Qnil;
dd26ab75 3624 (*mouse_position_hook) (&f, 0, &bar_window, &part, &x, &y, &time);
4bb994d1
JB
3625
3626 obj = Qnil;
284f4730 3627
4bb994d1
JB
3628 /* Decide if we should generate a switch-frame event. Don't
3629 generate switch-frame events for motion outside of all Emacs
3630 frames. */
e177ac3a 3631 if (!NILP (x) && f)
cd21b839 3632 {
9b8eb840 3633 Lisp_Object frame;
4bb994d1 3634
9b8eb840 3635 frame = FRAME_FOCUS_FRAME (f);
4bb994d1 3636 if (NILP (frame))
18cd2eeb 3637 XSETFRAME (frame, f);
4bb994d1 3638
4c52b668 3639 if (! EQ (frame, internal_last_event_frame)
788f89eb 3640 && !EQ (frame, selected_frame))
764cb3f9 3641 obj = make_lispy_switch_frame (frame);
4c52b668 3642 internal_last_event_frame = frame;
cd21b839 3643 }
4bb994d1 3644
df0f2ba1 3645 /* If we didn't decide to make a switch-frame event, go ahead and
4bb994d1 3646 return a mouse-motion event. */
e177ac3a 3647 if (!NILP (x) && NILP (obj))
7b4aedb9 3648 obj = make_lispy_movement (f, bar_window, part, x, y, time);
6cbff1cb 3649 }
2eb6bfbe 3650#endif /* HAVE_MOUSE */
284f4730
JB
3651 else
3652 /* We were promised by the above while loop that there was
3653 something for us to read! */
3654 abort ();
3655
d9d4c147 3656 input_pending = readable_events (0);
284f4730 3657
4c52b668 3658 Vlast_event_frame = internal_last_event_frame;
3c370943 3659
284f4730
JB
3660 return (obj);
3661}
a612e298
RS
3662\f
3663/* Process any events that are not user-visible,
3664 then return, without reading any user-visible events. */
3a3b9632
RS
3665
3666void
d9d4c147
KH
3667swallow_events (do_display)
3668 int do_display;
3a3b9632 3669{
87dd9b9b
RS
3670 int old_timers_run;
3671
beecf6a1 3672 while (kbd_fetch_ptr != kbd_store_ptr)
3a3b9632
RS
3673 {
3674 struct input_event *event;
3675
beecf6a1
KH
3676 event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE)
3677 ? kbd_fetch_ptr
3678 : kbd_buffer);
3a3b9632
RS
3679
3680 last_event_timestamp = event->timestamp;
3681
3682 /* These two kinds of events get special handling
3683 and don't actually appear to the command loop. */
3684 if (event->kind == selection_request_event)
3685 {
3686#ifdef HAVE_X11
4581e928 3687 struct input_event copy;
e0301c07
RS
3688
3689 /* Remove it from the buffer before processing it,
3690 since otherwise swallow_events called recursively could see it
3691 and process it again. */
4581e928 3692 copy = *event;
beecf6a1 3693 kbd_fetch_ptr = event + 1;
d9d4c147 3694 input_pending = readable_events (0);
4581e928 3695 x_handle_selection_request (&copy);
3a3b9632
RS
3696#else
3697 /* We're getting selection request events, but we don't have
3698 a window system. */
3699 abort ();
3700#endif
3701 }
3702
3703 else if (event->kind == selection_clear_event)
3704 {
3705#ifdef HAVE_X11
e0301c07
RS
3706 struct input_event copy;
3707
3708 /* Remove it from the buffer before processing it, */
3709 copy = *event;
3710
beecf6a1 3711 kbd_fetch_ptr = event + 1;
d9d4c147 3712 input_pending = readable_events (0);
90c2bb0c 3713 x_handle_selection_clear (&copy);
3a3b9632
RS
3714#else
3715 /* We're getting selection request events, but we don't have
3716 a window system. */
3717 abort ();
3718#endif
3719 }
3720 else
3721 break;
3722 }
3723
87dd9b9b 3724 old_timers_run = timers_run;
d9d4c147 3725 get_input_pending (&input_pending, 1);
87dd9b9b
RS
3726
3727 if (timers_run != old_timers_run && do_display)
3728 redisplay_preserve_echo_area ();
3a3b9632 3729}
a612e298 3730\f
d9d4c147
KH
3731static EMACS_TIME timer_idleness_start_time;
3732
3733/* Record the start of when Emacs is idle,
3734 for the sake of running idle-time timers. */
3735
07a59269 3736void
d9d4c147
KH
3737timer_start_idle ()
3738{
3739 Lisp_Object timers;
3740
3741 /* If we are already in the idle state, do nothing. */
3742 if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
3743 return;
3744
3745 EMACS_GET_TIME (timer_idleness_start_time);
3746
3747 /* Mark all idle-time timers as once again candidates for running. */
7539e11f 3748 for (timers = Vtimer_idle_list; CONSP (timers); timers = XCDR (timers))
d9d4c147
KH
3749 {
3750 Lisp_Object timer;
3751
7539e11f 3752 timer = XCAR (timers);
d9d4c147
KH
3753
3754 if (!VECTORP (timer) || XVECTOR (timer)->size != 8)
3755 continue;
3756 XVECTOR (timer)->contents[0] = Qnil;
3757 }
3758}
3759
3760/* Record that Emacs is no longer idle, so stop running idle-time timers. */
3761
07a59269 3762void
d9d4c147
KH
3763timer_stop_idle ()
3764{
3765 EMACS_SET_SECS_USECS (timer_idleness_start_time, -1, -1);
3766}
3767
e044e87c
RS
3768/* This is only for debugging. */
3769struct input_event last_timer_event;
3770
c04cbc3b
RS
3771/* Check whether a timer has fired. To prevent larger problems we simply
3772 disregard elements that are not proper timers. Do not make a circular
3773 timer list for the time being.
3774
3775 Returns the number of seconds to wait until the next timer fires. If a
3776 timer is triggering now, return zero seconds.
3777 If no timer is active, return -1 seconds.
3778
4ec4ed6a
RS
3779 If a timer is ripe, we run it, with quitting turned off.
3780
3781 DO_IT_NOW is now ignored. It used to mean that we should
3782 run the timer directly instead of queueing a timer-event.
3783 Now we always run timers directly. */
c04cbc3b
RS
3784
3785EMACS_TIME
3786timer_check (do_it_now)
3787 int do_it_now;
3788{
3789 EMACS_TIME nexttime;
9291c072
RS
3790 EMACS_TIME now, idleness_now;
3791 Lisp_Object timers, idle_timers, chosen_timer;
9291c072 3792 struct gcpro gcpro1, gcpro2, gcpro3;
c04cbc3b 3793
c04cbc3b
RS
3794 EMACS_SET_SECS (nexttime, -1);
3795 EMACS_SET_USECS (nexttime, -1);
3796
9291c072 3797 /* Always consider the ordinary timers. */
7ea13e12 3798 timers = Vtimer_list;
9291c072
RS
3799 /* Consider the idle timers only if Emacs is idle. */
3800 if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
3801 idle_timers = Vtimer_idle_list;
3802 else
3803 idle_timers = Qnil;
3804 chosen_timer = Qnil;
3805 GCPRO3 (timers, idle_timers, chosen_timer);
7ea13e12 3806
9291c072 3807 if (CONSP (timers) || CONSP (idle_timers))
c04cbc3b 3808 {
9291c072
RS
3809 EMACS_GET_TIME (now);
3810 if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
3811 EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time);
3812 }
c04cbc3b 3813
9291c072
RS
3814 while (CONSP (timers) || CONSP (idle_timers))
3815 {
9291c072 3816 Lisp_Object *vector;
8c907a56 3817 Lisp_Object timer = Qnil, idle_timer = Qnil;
9291c072
RS
3818 EMACS_TIME timer_time, idle_timer_time;
3819 EMACS_TIME difference, timer_difference, idle_timer_difference;
3820
3821 /* Skip past invalid timers and timers already handled. */
3822 if (!NILP (timers))
c04cbc3b 3823 {
7539e11f 3824 timer = XCAR (timers);
9291c072
RS
3825 if (!VECTORP (timer) || XVECTOR (timer)->size != 8)
3826 {
7539e11f 3827 timers = XCDR (timers);
9291c072
RS
3828 continue;
3829 }
3830 vector = XVECTOR (timer)->contents;
d9d4c147 3831
9291c072
RS
3832 if (!INTEGERP (vector[1]) || !INTEGERP (vector[2])
3833 || !INTEGERP (vector[3])
3834 || ! NILP (vector[0]))
3835 {
7539e11f 3836 timers = XCDR (timers);
9291c072
RS
3837 continue;
3838 }
3839 }
3840 if (!NILP (idle_timers))
3841 {
7539e11f 3842 timer = XCAR (idle_timers);
d9d4c147 3843 if (!VECTORP (timer) || XVECTOR (timer)->size != 8)
9291c072 3844 {
7539e11f 3845 idle_timers = XCDR (idle_timers);
9291c072
RS
3846 continue;
3847 }
d9d4c147
KH
3848 vector = XVECTOR (timer)->contents;
3849
3850 if (!INTEGERP (vector[1]) || !INTEGERP (vector[2])
9291c072
RS
3851 || !INTEGERP (vector[3])
3852 || ! NILP (vector[0]))
3853 {
7539e11f 3854 idle_timers = XCDR (idle_timers);
9291c072
RS
3855 continue;
3856 }
3857 }
d9d4c147 3858
9291c072
RS
3859 /* Set TIMER, TIMER_TIME and TIMER_DIFFERENCE
3860 based on the next ordinary timer.
3861 TIMER_DIFFERENCE is the distance in time from NOW to when
3862 this timer becomes ripe (negative if it's already ripe). */
3863 if (!NILP (timers))
3864 {
7539e11f 3865 timer = XCAR (timers);
9291c072 3866 vector = XVECTOR (timer)->contents;
d9d4c147
KH
3867 EMACS_SET_SECS (timer_time,
3868 (XINT (vector[1]) << 16) | (XINT (vector[2])));
3869 EMACS_SET_USECS (timer_time, XINT (vector[3]));
9291c072
RS
3870 EMACS_SUB_TIME (timer_difference, timer_time, now);
3871 }
ba8dfba8 3872
9291c072
RS
3873 /* Set IDLE_TIMER, IDLE_TIMER_TIME and IDLE_TIMER_DIFFERENCE
3874 based on the next idle timer. */
3875 if (!NILP (idle_timers))
3876 {
7539e11f 3877 idle_timer = XCAR (idle_timers);
9291c072
RS
3878 vector = XVECTOR (idle_timer)->contents;
3879 EMACS_SET_SECS (idle_timer_time,
3880 (XINT (vector[1]) << 16) | (XINT (vector[2])));
3881 EMACS_SET_USECS (idle_timer_time, XINT (vector[3]));
3882 EMACS_SUB_TIME (idle_timer_difference, idle_timer_time, idleness_now);
3883 }
ba8dfba8 3884
9291c072
RS
3885 /* Decide which timer is the next timer,
3886 and set CHOSEN_TIMER, VECTOR and DIFFERENCE accordingly.
3887 Also step down the list where we found that timer. */
d9d4c147 3888
9291c072
RS
3889 if (! NILP (timers) && ! NILP (idle_timers))
3890 {
3891 EMACS_TIME temp;
3892 EMACS_SUB_TIME (temp, timer_difference, idle_timer_difference);
3893 if (EMACS_TIME_NEG_P (temp))
3894 {
3895 chosen_timer = timer;
7539e11f 3896 timers = XCDR (timers);
9291c072 3897 difference = timer_difference;
c04cbc3b 3898 }
d9d4c147 3899 else
d9d4c147 3900 {
9291c072 3901 chosen_timer = idle_timer;
7539e11f 3902 idle_timers = XCDR (idle_timers);
9291c072 3903 difference = idle_timer_difference;
d9d4c147 3904 }
7ea13e12 3905 }
9291c072
RS
3906 else if (! NILP (timers))
3907 {
3908 chosen_timer = timer;
7539e11f 3909 timers = XCDR (timers);
9291c072
RS
3910 difference = timer_difference;
3911 }
3912 else
3913 {
3914 chosen_timer = idle_timer;
7539e11f 3915 idle_timers = XCDR (idle_timers);
9291c072
RS
3916 difference = idle_timer_difference;
3917 }
3918 vector = XVECTOR (chosen_timer)->contents;
3919
bd55b860 3920 /* If timer is ripe, run it if it hasn't been run. */
9291c072
RS
3921 if (EMACS_TIME_NEG_P (difference)
3922 || (EMACS_SECS (difference) == 0
3923 && EMACS_USECS (difference) == 0))
3924 {
3925 if (NILP (vector[0]))
3926 {
d925fb39
RS
3927 int was_locked = single_kboard;
3928 int count = specpdl_ptr - specpdl;
3929
9291c072
RS
3930 /* Mark the timer as triggered to prevent problems if the lisp
3931 code fails to reschedule it right. */
3932 vector[0] = Qt;
3933
d925fb39 3934 specbind (Qinhibit_quit, Qt);
9291c072 3935
d925fb39
RS
3936 call1 (Qtimer_event_handler, chosen_timer);
3937 timers_run++;
9291c072 3938
d925fb39 3939 unbind_to (count, Qnil);
4ec4ed6a 3940
d925fb39
RS
3941 /* Resume allowing input from any kboard, if that was true before. */
3942 if (!was_locked)
3943 any_kboard_state ();
9291c072 3944
d925fb39
RS
3945 /* Since we have handled the event,
3946 we don't need to tell the caller to wake up and do it. */
9291c072
RS
3947 }
3948 }
3949 else
3950 /* When we encounter a timer that is still waiting,
3951 return the amount of time to wait before it is ripe. */
3952 {
3953 UNGCPRO;
9291c072
RS
3954 return difference;
3955 }
c04cbc3b 3956 }
9291c072 3957
7ea13e12
RS
3958 /* No timers are pending in the future. */
3959 /* Return 0 if we generated an event, and -1 if not. */
3960 UNGCPRO;
c04cbc3b
RS
3961 return nexttime;
3962}
3963\f
284f4730 3964/* Caches for modify_event_symbol. */
e9bf89a0 3965static Lisp_Object accent_key_syms;
284f4730
JB
3966static Lisp_Object func_key_syms;
3967static Lisp_Object mouse_syms;
07de30b9
GV
3968#ifdef WINDOWSNT
3969static Lisp_Object mouse_wheel_syms;
3970#endif
a24dc617 3971static Lisp_Object drag_n_drop_syms;
284f4730 3972
e9bf89a0
RS
3973/* This is a list of keysym codes for special "accent" characters.
3974 It parallels lispy_accent_keys. */
3975
3976static int lispy_accent_codes[] =
3977{
79a7046c 3978#ifdef XK_dead_circumflex
e9bf89a0 3979 XK_dead_circumflex,
79a7046c
RS
3980#else
3981 0,
3982#endif
3983#ifdef XK_dead_grave
e9bf89a0 3984 XK_dead_grave,
79a7046c
RS
3985#else
3986 0,
3987#endif
3988#ifdef XK_dead_tilde
e9bf89a0 3989 XK_dead_tilde,
79a7046c
RS
3990#else
3991 0,
3992#endif
3993#ifdef XK_dead_diaeresis
e9bf89a0 3994 XK_dead_diaeresis,
79a7046c
RS
3995#else
3996 0,
3997#endif
3998#ifdef XK_dead_macron
e9bf89a0 3999 XK_dead_macron,
79a7046c
RS
4000#else
4001 0,
4002#endif
4003#ifdef XK_dead_degree
e9bf89a0 4004 XK_dead_degree,
79a7046c
RS
4005#else
4006 0,
4007#endif
4008#ifdef XK_dead_acute
e9bf89a0 4009 XK_dead_acute,
79a7046c
RS
4010#else
4011 0,
4012#endif
4013#ifdef XK_dead_cedilla
e9bf89a0 4014 XK_dead_cedilla,
79a7046c
RS
4015#else
4016 0,
4017#endif
4018#ifdef XK_dead_breve
e9bf89a0 4019 XK_dead_breve,
79a7046c
RS
4020#else
4021 0,
4022#endif
4023#ifdef XK_dead_ogonek
e9bf89a0 4024 XK_dead_ogonek,
79a7046c
RS
4025#else
4026 0,
4027#endif
4028#ifdef XK_dead_caron
e9bf89a0 4029 XK_dead_caron,
79a7046c
RS
4030#else
4031 0,
4032#endif
4033#ifdef XK_dead_doubleacute
e9bf89a0 4034 XK_dead_doubleacute,
79a7046c
RS
4035#else
4036 0,
4037#endif
4038#ifdef XK_dead_abovedot
e9bf89a0 4039 XK_dead_abovedot,
79a7046c
RS
4040#else
4041 0,
4042#endif
e9bf89a0
RS
4043};
4044
4045/* This is a list of Lisp names for special "accent" characters.
4046 It parallels lispy_accent_codes. */
4047
4048static char *lispy_accent_keys[] =
4049{
4050 "dead-circumflex",
4051 "dead-grave",
4052 "dead-tilde",
4053 "dead-diaeresis",
4054 "dead-macron",
4055 "dead-degree",
4056 "dead-acute",
4057 "dead-cedilla",
4058 "dead-breve",
4059 "dead-ogonek",
4060 "dead-caron",
4061 "dead-doubleacute",
4062 "dead-abovedot",
4063};
4064
e98a93eb
GV
4065#ifdef HAVE_NTGUI
4066#define FUNCTION_KEY_OFFSET 0x0
4067
4068char *lispy_function_keys[] =
4069 {
4070 0, /* 0 */
4071
4072 0, /* VK_LBUTTON 0x01 */
4073 0, /* VK_RBUTTON 0x02 */
4074 "cancel", /* VK_CANCEL 0x03 */
4075 0, /* VK_MBUTTON 0x04 */
4076
4077 0, 0, 0, /* 0x05 .. 0x07 */
4078
4079 "backspace", /* VK_BACK 0x08 */
4080 "tab", /* VK_TAB 0x09 */
4081
4082 0, 0, /* 0x0A .. 0x0B */
4083
4084 "clear", /* VK_CLEAR 0x0C */
4085 "return", /* VK_RETURN 0x0D */
4086
4087 0, 0, /* 0x0E .. 0x0F */
4088
1161d367
GV
4089 0, /* VK_SHIFT 0x10 */
4090 0, /* VK_CONTROL 0x11 */
4091 0, /* VK_MENU 0x12 */
e98a93eb 4092 "pause", /* VK_PAUSE 0x13 */
1161d367 4093 "capslock", /* VK_CAPITAL 0x14 */
e98a93eb
GV
4094
4095 0, 0, 0, 0, 0, 0, /* 0x15 .. 0x1A */
4096
1161d367 4097 "escape", /* VK_ESCAPE 0x1B */
e98a93eb
GV
4098
4099 0, 0, 0, 0, /* 0x1C .. 0x1F */
4100
4101 0, /* VK_SPACE 0x20 */
4102 "prior", /* VK_PRIOR 0x21 */
4103 "next", /* VK_NEXT 0x22 */
4104 "end", /* VK_END 0x23 */
4105 "home", /* VK_HOME 0x24 */
4106 "left", /* VK_LEFT 0x25 */
4107 "up", /* VK_UP 0x26 */
4108 "right", /* VK_RIGHT 0x27 */
4109 "down", /* VK_DOWN 0x28 */
4110 "select", /* VK_SELECT 0x29 */
4111 "print", /* VK_PRINT 0x2A */
4112 "execute", /* VK_EXECUTE 0x2B */
4113 "snapshot", /* VK_SNAPSHOT 0x2C */
4114 "insert", /* VK_INSERT 0x2D */
4115 "delete", /* VK_DELETE 0x2E */
4116 "help", /* VK_HELP 0x2F */
4117
4118 /* VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */
4119
4120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4121
4122 0, 0, 0, 0, 0, 0, 0, /* 0x3A .. 0x40 */
4123
4124 /* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */
4125
4126 0, 0, 0, 0, 0, 0, 0, 0, 0,
4127 0, 0, 0, 0, 0, 0, 0, 0, 0,
4128 0, 0, 0, 0, 0, 0, 0, 0,
4129
e376f90d
RS
4130 "lwindow", /* VK_LWIN 0x5B */
4131 "rwindow", /* VK_RWIN 0x5C */
4132 "apps", /* VK_APPS 0x5D */
e98a93eb
GV
4133
4134 0, 0, /* 0x5E .. 0x5F */
4135
4136 "kp-0", /* VK_NUMPAD0 0x60 */
4137 "kp-1", /* VK_NUMPAD1 0x61 */
4138 "kp-2", /* VK_NUMPAD2 0x62 */
4139 "kp-3", /* VK_NUMPAD3 0x63 */
4140 "kp-4", /* VK_NUMPAD4 0x64 */
4141 "kp-5", /* VK_NUMPAD5 0x65 */
4142 "kp-6", /* VK_NUMPAD6 0x66 */
4143 "kp-7", /* VK_NUMPAD7 0x67 */
4144 "kp-8", /* VK_NUMPAD8 0x68 */
4145 "kp-9", /* VK_NUMPAD9 0x69 */
4146 "kp-multiply", /* VK_MULTIPLY 0x6A */
4147 "kp-add", /* VK_ADD 0x6B */
4148 "kp-separator", /* VK_SEPARATOR 0x6C */
4149 "kp-subtract", /* VK_SUBTRACT 0x6D */
4150 "kp-decimal", /* VK_DECIMAL 0x6E */
4151 "kp-divide", /* VK_DIVIDE 0x6F */
4152 "f1", /* VK_F1 0x70 */
4153 "f2", /* VK_F2 0x71 */
4154 "f3", /* VK_F3 0x72 */
4155 "f4", /* VK_F4 0x73 */
4156 "f5", /* VK_F5 0x74 */
4157 "f6", /* VK_F6 0x75 */
4158 "f7", /* VK_F7 0x76 */
4159 "f8", /* VK_F8 0x77 */
4160 "f9", /* VK_F9 0x78 */
4161 "f10", /* VK_F10 0x79 */
4162 "f11", /* VK_F11 0x7A */
4163 "f12", /* VK_F12 0x7B */
4164 "f13", /* VK_F13 0x7C */
4165 "f14", /* VK_F14 0x7D */
4166 "f15", /* VK_F15 0x7E */
4167 "f16", /* VK_F16 0x7F */
4168 "f17", /* VK_F17 0x80 */
4169 "f18", /* VK_F18 0x81 */
4170 "f19", /* VK_F19 0x82 */
4171 "f20", /* VK_F20 0x83 */
4172 "f21", /* VK_F21 0x84 */
4173 "f22", /* VK_F22 0x85 */
4174 "f23", /* VK_F23 0x86 */
4175 "f24", /* VK_F24 0x87 */
4176
4177 0, 0, 0, 0, /* 0x88 .. 0x8B */
4178 0, 0, 0, 0, /* 0x8C .. 0x8F */
4179
4180 "kp-numlock", /* VK_NUMLOCK 0x90 */
4181 "scroll", /* VK_SCROLL 0x91 */
4182
e376f90d
RS
4183 "kp-space", /* VK_NUMPAD_CLEAR 0x92 */
4184 "kp-enter", /* VK_NUMPAD_ENTER 0x93 */
4185 "kp-prior", /* VK_NUMPAD_PRIOR 0x94 */
4186 "kp-next", /* VK_NUMPAD_NEXT 0x95 */
4187 "kp-end", /* VK_NUMPAD_END 0x96 */
4188 "kp-home", /* VK_NUMPAD_HOME 0x97 */
4189 "kp-left", /* VK_NUMPAD_LEFT 0x98 */
4190 "kp-up", /* VK_NUMPAD_UP 0x99 */
4191 "kp-right", /* VK_NUMPAD_RIGHT 0x9A */
4192 "kp-down", /* VK_NUMPAD_DOWN 0x9B */
4193 "kp-insert", /* VK_NUMPAD_INSERT 0x9C */
4194 "kp-delete", /* VK_NUMPAD_DELETE 0x9D */
4195
4196 0, 0, /* 0x9E .. 0x9F */
4197
e98a93eb
GV
4198 /*
4199 * VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys.
e8886a1d 4200 * Used only as parameters to GetAsyncKeyState and GetKeyState.
e98a93eb
GV
4201 * No other API or message will distinguish left and right keys this way.
4202 */
4203 /* 0xA0 .. 0xEF */
4204
4205 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4206 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4207 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4208 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4209 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4210
4211 /* 0xF0 .. 0xF5 */
4212
4213 0, 0, 0, 0, 0, 0,
4214
4215 "attn", /* VK_ATTN 0xF6 */
4216 "crsel", /* VK_CRSEL 0xF7 */
4217 "exsel", /* VK_EXSEL 0xF8 */
4218 "ereof", /* VK_EREOF 0xF9 */
4219 "play", /* VK_PLAY 0xFA */
4220 "zoom", /* VK_ZOOM 0xFB */
4221 "noname", /* VK_NONAME 0xFC */
4222 "pa1", /* VK_PA1 0xFD */
4223 "oem_clear", /* VK_OEM_CLEAR 0xFE */
1161d367 4224 0 /* 0xFF */
e98a93eb
GV
4225 };
4226
04f215f0 4227#else /* not HAVE_NTGUI */
e98a93eb 4228
37cd9f30
KH
4229#ifdef XK_kana_A
4230static char *lispy_kana_keys[] =
4231 {
4232 /* X Keysym value */
4233 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x400 .. 0x40f */
4234 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x410 .. 0x41f */
4235 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x420 .. 0x42f */
4236 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x430 .. 0x43f */
4237 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x440 .. 0x44f */
4238 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x450 .. 0x45f */
4239 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x460 .. 0x46f */
4240 0,0,0,0,0,0,0,0,0,0,0,0,0,0,"overline",0,
4241 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x480 .. 0x48f */
4242 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x490 .. 0x49f */
4243 0, "kana-fullstop", "kana-openingbracket", "kana-closingbracket",
4244 "kana-comma", "kana-conjunctive", "kana-WO", "kana-a",
4245 "kana-i", "kana-u", "kana-e", "kana-o",
4246 "kana-ya", "kana-yu", "kana-yo", "kana-tsu",
4247 "prolongedsound", "kana-A", "kana-I", "kana-U",
4248 "kana-E", "kana-O", "kana-KA", "kana-KI",
4249 "kana-KU", "kana-KE", "kana-KO", "kana-SA",
4250 "kana-SHI", "kana-SU", "kana-SE", "kana-SO",
4251 "kana-TA", "kana-CHI", "kana-TSU", "kana-TE",
4252 "kana-TO", "kana-NA", "kana-NI", "kana-NU",
4253 "kana-NE", "kana-NO", "kana-HA", "kana-HI",
4254 "kana-FU", "kana-HE", "kana-HO", "kana-MA",
4255 "kana-MI", "kana-MU", "kana-ME", "kana-MO",
4256 "kana-YA", "kana-YU", "kana-YO", "kana-RA",
4257 "kana-RI", "kana-RU", "kana-RE", "kana-RO",
4258 "kana-WA", "kana-N", "voicedsound", "semivoicedsound",
4259 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x4e0 .. 0x4ef */
4260 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x4f0 .. 0x4ff */
4261 };
4262#endif /* XK_kana_A */
4263
04f215f0
RS
4264#define FUNCTION_KEY_OFFSET 0xff00
4265
284f4730
JB
4266/* You'll notice that this table is arranged to be conveniently
4267 indexed by X Windows keysym values. */
4268static char *lispy_function_keys[] =
4269 {
4270 /* X Keysym value */
4271
75045dcb
RS
4272 0, 0, 0, 0, 0, 0, 0, 0, /* 0xff00...0f */
4273 "backspace", "tab", "linefeed", "clear",
4274 0, "return", 0, 0,
4275 0, 0, 0, "pause", /* 0xff10...1f */
4276 0, 0, 0, 0, 0, 0, 0, "escape",
86e5706b 4277 0, 0, 0, 0,
75045dcb
RS
4278 0, "kanji", "muhenkan", "henkan", /* 0xff20...2f */
4279 "romaji", "hiragana", "katakana", "hiragana-katakana",
4280 "zenkaku", "hankaku", "zenkaku-hankaku", "touroku",
4281 "massyo", "kana-lock", "kana-shift", "eisu-shift",
4282 "eisu-toggle", /* 0xff30...3f */
4283 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
86e5706b
RS
4284 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xff40...4f */
4285
75045dcb
RS
4286 "home", "left", "up", "right", /* 0xff50 */ /* IsCursorKey */
4287 "down", "prior", "next", "end",
4288 "begin", 0, 0, 0, 0, 0, 0, 0,
284f4730
JB
4289 "select", /* 0xff60 */ /* IsMiscFunctionKey */
4290 "print",
4291 "execute",
4292 "insert",
4293 0, /* 0xff64 */
4294 "undo",
4295 "redo",
4296 "menu",
4297 "find",
4298 "cancel",
4299 "help",
4300 "break", /* 0xff6b */
4301
75045dcb
RS
4302 0, 0, 0, 0,
4303 0, 0, 0, 0, "backtab", 0, 0, 0, /* 0xff70... */
4304 0, 0, 0, 0, 0, 0, 0, "kp-numlock", /* 0xff78... */
284f4730
JB
4305 "kp-space", /* 0xff80 */ /* IsKeypadKey */
4306 0, 0, 0, 0, 0, 0, 0, 0,
4307 "kp-tab", /* 0xff89 */
4308 0, 0, 0,
4309 "kp-enter", /* 0xff8d */
4310 0, 0, 0,
4311 "kp-f1", /* 0xff91 */
4312 "kp-f2",
4313 "kp-f3",
4314 "kp-f4",
872157e7
RS
4315 "kp-home", /* 0xff95 */
4316 "kp-left",
4317 "kp-up",
4318 "kp-right",
4319 "kp-down",
4320 "kp-prior", /* kp-page-up */
4321 "kp-next", /* kp-page-down */
4322 "kp-end",
4323 "kp-begin",
4324 "kp-insert",
4325 "kp-delete",
4326 0, /* 0xffa0 */
4327 0, 0, 0, 0, 0, 0, 0, 0, 0,
284f4730
JB
4328 "kp-multiply", /* 0xffaa */
4329 "kp-add",
4330 "kp-separator",
4331 "kp-subtract",
4332 "kp-decimal",
4333 "kp-divide", /* 0xffaf */
4334 "kp-0", /* 0xffb0 */
4335 "kp-1", "kp-2", "kp-3", "kp-4", "kp-5", "kp-6", "kp-7", "kp-8", "kp-9",
4336 0, /* 0xffba */
4337 0, 0,
4338 "kp-equal", /* 0xffbd */
4339 "f1", /* 0xffbe */ /* IsFunctionKey */
86e5706b
RS
4340 "f2",
4341 "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", /* 0xffc0 */
4342 "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18",
4343 "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", /* 0xffd0 */
4344 "f27", "f28", "f29", "f30", "f31", "f32", "f33", "f34",
4345 "f35", 0, 0, 0, 0, 0, 0, 0, /* 0xffe0 */
4346 0, 0, 0, 0, 0, 0, 0, 0,
4347 0, 0, 0, 0, 0, 0, 0, 0, /* 0xfff0 */
4348 0, 0, 0, 0, 0, 0, 0, "delete"
04f215f0 4349 };
284f4730 4350
04f215f0
RS
4351/* ISO 9995 Function and Modifier Keys; the first byte is 0xFE. */
4352#define ISO_FUNCTION_KEY_OFFSET 0xfe00
4353
4354static char *iso_lispy_function_keys[] =
4355 {
4356 0, 0, 0, 0, 0, 0, 0, 0, /* 0xfe00 */
4357 0, 0, 0, 0, 0, 0, 0, 0, /* 0xfe08 */
4358 0, 0, 0, 0, 0, 0, 0, 0, /* 0xfe10 */
4359 0, 0, 0, 0, 0, 0, 0, 0, /* 0xfe18 */
4360 "iso-lefttab", /* 0xfe20 */
4361 "iso-move-line-up", "iso-move-line-down",
4362 "iso-partial-line-up", "iso-partial-line-down",
4363 "iso-partial-space-left", "iso-partial-space-right",
4364 "iso-set-margin-left", "iso-set-margin-right", /* 0xffe27, 28 */
4365 "iso-release-margin-left", "iso-release-margin-right",
4366 "iso-release-both-margins",
4367 "iso-fast-cursor-left", "iso-fast-cursor-right",
4368 "iso-fast-cursor-up", "iso-fast-cursor-down",
4369 "iso-continuous-underline", "iso-discontinuous-underline", /* 0xfe30, 31 */
4370 "iso-emphasize", "iso-center-object", "iso-enter", /* ... 0xfe34 */
4371 };
4372
4373#endif /* not HAVE_NTGUI */
e98a93eb 4374
8e1e4240 4375Lisp_Object Vlispy_mouse_stem;
284f4730 4376
07de30b9
GV
4377#ifdef WINDOWSNT
4378/* mouse-wheel events are generated by the wheel on devices such as
4379 the MS Intellimouse. The wheel sits in between the left and right
4380 mouse buttons, and is typically used to scroll or zoom the window
4381 underneath the pointer. mouse-wheel events specify the object on
4382 which they operate, and a delta corresponding to the amount and
4383 direction that the wheel is rotated. Clicking the mouse-wheel
4384 generates a mouse-2 event. */
4385static char *lispy_mouse_wheel_names[] =
4386{
4387 "mouse-wheel"
4388};
a24dc617 4389
07de30b9
GV
4390#endif /* WINDOWSNT */
4391
a24dc617
RS
4392/* drag-n-drop events are generated when a set of selected files are
4393 dragged from another application and dropped onto an Emacs window. */
4394static char *lispy_drag_n_drop_names[] =
4395{
4396 "drag-n-drop"
4397};
4398
3c370943 4399/* Scroll bar parts. */
4bb994d1 4400Lisp_Object Qabove_handle, Qhandle, Qbelow_handle;
7ee32cda 4401Lisp_Object Qup, Qdown, Qbottom, Qend_scroll;
eef28553 4402Lisp_Object Qtop, Qratio;
4bb994d1 4403
3c370943
JB
4404/* An array of scroll bar parts, indexed by an enum scroll_bar_part value. */
4405Lisp_Object *scroll_bar_parts[] = {
db08707d 4406 &Qabove_handle, &Qhandle, &Qbelow_handle,
eef28553 4407 &Qup, &Qdown, &Qtop, &Qbottom, &Qend_scroll, &Qratio
4bb994d1
JB
4408};
4409
5bf68f6e
AS
4410/* User signal events. */
4411Lisp_Object Qusr1_signal, Qusr2_signal;
4412
4413Lisp_Object *lispy_user_signals[] =
4414{
4415 &Qusr1_signal, &Qusr2_signal
4416};
4417
4bb994d1 4418
7b4aedb9 4419/* A vector, indexed by button number, giving the down-going location
3c370943 4420 of currently depressed buttons, both scroll bar and non-scroll bar.
7b4aedb9
JB
4421
4422 The elements have the form
4423 (BUTTON-NUMBER MODIFIER-MASK . REST)
4424 where REST is the cdr of a position as it would be reported in the event.
4425
4426 The make_lispy_event function stores positions here to tell the
4427 difference between click and drag events, and to store the starting
4428 location to be included in drag events. */
4429
4430static Lisp_Object button_down_location;
88cb0656 4431
fbcd35bd
JB
4432/* Information about the most recent up-going button event: Which
4433 button, what location, and what time. */
4434
559f9d04
RS
4435static int last_mouse_button;
4436static int last_mouse_x;
4437static int last_mouse_y;
4438static unsigned long button_down_time;
fbcd35bd 4439
564dc952
JB
4440/* The maximum time between clicks to make a double-click,
4441 or Qnil to disable double-click detection,
4442 or Qt for no time limit. */
4443Lisp_Object Vdouble_click_time;
fbcd35bd
JB
4444
4445/* The number of clicks in this multiple-click. */
4446
4447int double_click_count;
4448
284f4730
JB
4449/* Given a struct input_event, build the lisp event which represents
4450 it. If EVENT is 0, build a mouse movement event from the mouse
88cb0656
JB
4451 movement buffer, which should have a movement event in it.
4452
4453 Note that events must be passed to this function in the order they
4454 are received; this function stores the location of button presses
4455 in order to build drag events when the button is released. */
284f4730
JB
4456
4457static Lisp_Object
4458make_lispy_event (event)
4459 struct input_event *event;
4460{
79a7046c
RS
4461 int i;
4462
0220c518 4463 switch (SWITCH_ENUM_CAST (event->kind))
284f4730 4464 {
284f4730
JB
4465 /* A simple keystroke. */
4466 case ascii_keystroke:
86e5706b 4467 {
9343ab07 4468 Lisp_Object lispy_c;
e9bf89a0 4469 int c = event->code & 0377;
5a1c6df8
JB
4470 /* Turn ASCII characters into control characters
4471 when proper. */
4472 if (event->modifiers & ctrl_modifier)
d205953b
JB
4473 c = make_ctrl_char (c);
4474
4475 /* Add in the other modifier bits. We took care of ctrl_modifier
4476 just above, and the shift key was taken care of by the X code,
4477 and applied to control characters by make_ctrl_char. */
86e5706b
RS
4478 c |= (event->modifiers
4479 & (meta_modifier | alt_modifier
4480 | hyper_modifier | super_modifier));
32454a9f
RS
4481 /* Distinguish Shift-SPC from SPC. */
4482 if ((event->code & 0377) == 040
4483 && event->modifiers & shift_modifier)
4484 c |= shift_modifier;
559f9d04 4485 button_down_time = 0;
bb9e9bed 4486 XSETFASTINT (lispy_c, c);
9343ab07 4487 return lispy_c;
86e5706b 4488 }
284f4730 4489
a50e723f
KH
4490 case multibyte_char_keystroke:
4491 {
4492 Lisp_Object lispy_c;
4493
4494 XSETFASTINT (lispy_c, event->code);
4495 return lispy_c;
4496 }
4497
284f4730
JB
4498 /* A function key. The symbol may need to have modifier prefixes
4499 tacked onto it. */
4500 case non_ascii_keystroke:
559f9d04 4501 button_down_time = 0;
e9bf89a0
RS
4502
4503 for (i = 0; i < sizeof (lispy_accent_codes) / sizeof (int); i++)
4504 if (event->code == lispy_accent_codes[i])
4505 return modify_event_symbol (i,
4506 event->modifiers,
80e4aa30 4507 Qfunction_key, Qnil,
e9bf89a0
RS
4508 lispy_accent_keys, &accent_key_syms,
4509 (sizeof (lispy_accent_keys)
4510 / sizeof (lispy_accent_keys[0])));
4511
270a208f 4512 /* Handle system-specific keysyms. */
80e4aa30
RS
4513 if (event->code & (1 << 28))
4514 {
4515 /* We need to use an alist rather than a vector as the cache
4516 since we can't make a vector long enuf. */
142e6c73
KH
4517 if (NILP (current_kboard->system_key_syms))
4518 current_kboard->system_key_syms = Fcons (Qnil, Qnil);
2c834fb3 4519 return modify_event_symbol (event->code,
80e4aa30 4520 event->modifiers,
7c97ffdc
KH
4521 Qfunction_key,
4522 current_kboard->Vsystem_key_alist,
142e6c73
KH
4523 0, &current_kboard->system_key_syms,
4524 (unsigned)-1);
80e4aa30
RS
4525 }
4526
37cd9f30
KH
4527#ifdef XK_kana_A
4528 if (event->code >= 0x400 && event->code < 0x500)
4529 return modify_event_symbol (event->code - 0x400,
4530 event->modifiers & ~shift_modifier,
4531 Qfunction_key, Qnil,
4532 lispy_kana_keys, &func_key_syms,
4533 (sizeof (lispy_kana_keys)
4534 / sizeof (lispy_kana_keys[0])));
4535#endif /* XK_kana_A */
4536
111c4138 4537#ifdef ISO_FUNCTION_KEY_OFFSET
04f215f0
RS
4538 if (event->code < FUNCTION_KEY_OFFSET
4539 && event->code >= ISO_FUNCTION_KEY_OFFSET)
4540 return modify_event_symbol (event->code - ISO_FUNCTION_KEY_OFFSET,
4541 event->modifiers,
4542 Qfunction_key, Qnil,
4543 iso_lispy_function_keys, &func_key_syms,
4544 (sizeof (iso_lispy_function_keys)
4545 / sizeof (iso_lispy_function_keys[0])));
4546 else
111c4138 4547#endif
04f215f0
RS
4548 return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET,
4549 event->modifiers,
4550 Qfunction_key, Qnil,
4551 lispy_function_keys, &func_key_syms,
4552 (sizeof (lispy_function_keys)
4553 / sizeof (lispy_function_keys[0])));
284f4730 4554
514354e9 4555#ifdef HAVE_MOUSE
df0f2ba1 4556 /* A mouse click. Figure out where it is, decide whether it's
88cb0656 4557 a press, click or drag, and build the appropriate structure. */
284f4730 4558 case mouse_click:
7ee32cda 4559#ifndef USE_TOOLKIT_SCROLL_BARS
3c370943 4560 case scroll_bar_click:
7ee32cda 4561#endif
284f4730 4562 {
e9bf89a0 4563 int button = event->code;
559f9d04 4564 int is_double;
7b4aedb9 4565 Lisp_Object position;
dbc4e1c1
JB
4566 Lisp_Object *start_pos_ptr;
4567 Lisp_Object start_pos;
284f4730 4568
8c907a56
GM
4569 position = Qnil;
4570
7b4aedb9
JB
4571 /* Build the position as appropriate for this mouse click. */
4572 if (event->kind == mouse_click)
284f4730 4573 {
7b4aedb9 4574 int part;
598a9fa7 4575 FRAME_PTR f = XFRAME (event->frame_or_window);
0aafc975 4576 Lisp_Object window;
7b4aedb9 4577 Lisp_Object posn;
7ee32cda 4578 Lisp_Object string_info = Qnil;
9e20143a
RS
4579 int row, column;
4580
5da3133a
RS
4581 /* Ignore mouse events that were made on frame that
4582 have been deleted. */
4583 if (! FRAME_LIVE_P (f))
4584 return Qnil;
4585
7ee32cda
GM
4586 /* EVENT->x and EVENT->y are frame-relative pixel
4587 coordinates at this place. Under old redisplay, COLUMN
4588 and ROW are set to frame relative glyph coordinates
4589 which are then used to determine whether this click is
4590 in a menu (non-toolkit version). */
4591 pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
4592 &column, &row, NULL, 1);
7b4aedb9 4593
eef045bf
RS
4594#ifndef USE_X_TOOLKIT
4595 /* In the non-toolkit version, clicks on the menu bar
4596 are ordinary button events in the event buffer.
4597 Distinguish them, and invoke the menu.
4598
4599 (In the toolkit version, the toolkit handles the menu bar
4600 and Emacs doesn't know about it until after the user
4601 makes a selection.) */
2ee250ec
RS
4602 if (row >= 0 && row < FRAME_MENU_BAR_LINES (f)
4603 && (event->modifiers & down_modifier))
bb936752 4604 {
b7c49376 4605 Lisp_Object items, item;
0a0e8fe6
RS
4606 int hpos;
4607 int i;
4608
2ee250ec 4609#if 0
0a0e8fe6
RS
4610 /* Activate the menu bar on the down event. If the
4611 up event comes in before the menu code can deal with it,
4612 just ignore it. */
4613 if (! (event->modifiers & down_modifier))
4614 return Qnil;
2ee250ec 4615#endif
0aafc975 4616
7ee32cda 4617 /* Find the menu bar item under `column'. */
f2ae6b3f 4618 item = Qnil;
5ec75a55 4619 items = FRAME_MENU_BAR_ITEMS (f);
35b3402f 4620 for (i = 0; i < XVECTOR (items)->size; i += 4)
5ec75a55
RS
4621 {
4622 Lisp_Object pos, string;
b7c49376 4623 string = XVECTOR (items)->contents[i + 1];
35b3402f 4624 pos = XVECTOR (items)->contents[i + 3];
b7c49376
RS
4625 if (NILP (string))
4626 break;
9e20143a
RS
4627 if (column >= XINT (pos)
4628 && column < XINT (pos) + XSTRING (string)->size)
b7c49376
RS
4629 {
4630 item = XVECTOR (items)->contents[i];
4631 break;
4632 }
5ec75a55 4633 }
9e20143a 4634
7ee32cda
GM
4635 /* ELisp manual 2.4b says (x y) are window relative but
4636 code says they are frame-relative. */
5ec75a55
RS
4637 position
4638 = Fcons (event->frame_or_window,
4639 Fcons (Qmenu_bar,
4640 Fcons (Fcons (event->x, event->y),
4641 Fcons (make_number (event->timestamp),
4642 Qnil))));
4643
b7c49376 4644 return Fcons (item, Fcons (position, Qnil));
5ec75a55 4645 }
eef045bf 4646#endif /* not USE_X_TOOLKIT */
0aafc975 4647
7ee32cda
GM
4648 /* Set `window' to the window under frame pixel coordinates
4649 event->x/event->y. */
4650 window = window_from_coordinates (f, XINT (event->x),
4651 XINT (event->y), &part, 0);
0aafc975 4652
8c18cbfb 4653 if (!WINDOWP (window))
78ced549
RS
4654 {
4655 window = event->frame_or_window;
4656 posn = Qnil;
4657 }
284f4730 4658 else
7b4aedb9 4659 {
7ee32cda
GM
4660 /* It's a click in window window at frame coordinates
4661 event->x/ event->y. */
4662 struct window *w = XWINDOW (window);
4663
4664 /* Get window relative coordinates. Original code
4665 `rounded' this to glyph boundaries. */
4666 int wx = FRAME_TO_WINDOW_PIXEL_X (w, XINT (event->x));
4667 int wy = FRAME_TO_WINDOW_PIXEL_Y (w, XINT (event->y));
4668
4669 /* Set event coordinates to window-relative coordinates
4670 for constructing the Lisp event below. */
4671 XSETINT (event->x, wx);
4672 XSETINT (event->y, wy);
4673
4674 if (part == 1 || part == 3)
4675 {
4676 /* Mode line or top line. Look for a string under
4677 the mouse that may have a `local-map' property. */
4678 Lisp_Object string;
4679 int charpos;
4680
045dee35 4681 posn = part == 1 ? Qmode_line : Qheader_line;
7ee32cda
GM
4682 string = mode_line_string (w, wx, wy, part == 1, &charpos);
4683 if (STRINGP (string))
4684 string_info = Fcons (string, make_number (charpos));
4685 }
7b4aedb9
JB
4686 else if (part == 2)
4687 posn = Qvertical_line;
4688 else
7ee32cda 4689 XSETINT (posn, buffer_posn_from_coords (w, &wx, &wy));
7b4aedb9
JB
4690 }
4691
5ec75a55
RS
4692 position
4693 = Fcons (window,
4694 Fcons (posn,
4695 Fcons (Fcons (event->x, event->y),
4696 Fcons (make_number (event->timestamp),
7ee32cda
GM
4697 (NILP (string_info)
4698 ? Qnil
4699 : Fcons (string_info, Qnil))))));
284f4730 4700 }
7ee32cda 4701#ifndef USE_TOOLKIT_SCROLL_BARS
7b4aedb9 4702 else
88cb0656 4703 {
7ee32cda 4704 /* It's a scrollbar click. */
9e20143a
RS
4705 Lisp_Object window;
4706 Lisp_Object portion_whole;
4707 Lisp_Object part;
4708
4709 window = event->frame_or_window;
4710 portion_whole = Fcons (event->x, event->y);
4711 part = *scroll_bar_parts[(int) event->part];
7b4aedb9 4712
db08707d
RS
4713 position
4714 = Fcons (window,
4715 Fcons (Qvertical_scroll_bar,
4716 Fcons (portion_whole,
4717 Fcons (make_number (event->timestamp),
4718 Fcons (part, Qnil)))));
88cb0656 4719 }
7ee32cda 4720#endif /* not USE_TOOLKIT_SCROLL_BARS */
88cb0656 4721
8e1e4240
GM
4722 if (button >= XVECTOR (button_down_location)->size)
4723 {
4724 button_down_location = larger_vector (button_down_location,
4725 button + 1, Qnil);
4726 mouse_syms = larger_vector (mouse_syms, button + 1, Qnil);
4727 }
4728
dbc4e1c1
JB
4729 start_pos_ptr = &XVECTOR (button_down_location)->contents[button];
4730
4731 start_pos = *start_pos_ptr;
4732 *start_pos_ptr = Qnil;
7b4aedb9 4733
559f9d04
RS
4734 is_double = (button == last_mouse_button
4735 && XINT (event->x) == last_mouse_x
4736 && XINT (event->y) == last_mouse_y
4737 && button_down_time != 0
4738 && (EQ (Vdouble_click_time, Qt)
4739 || (INTEGERP (Vdouble_click_time)
4740 && ((int)(event->timestamp - button_down_time)
4741 < XINT (Vdouble_click_time)))));
4742 last_mouse_button = button;
4743 last_mouse_x = XINT (event->x);
4744 last_mouse_y = XINT (event->y);
4745
7b4aedb9
JB
4746 /* If this is a button press, squirrel away the location, so
4747 we can decide later whether it was a click or a drag. */
4748 if (event->modifiers & down_modifier)
559f9d04
RS
4749 {
4750 if (is_double)
4751 {
4752 double_click_count++;
4753 event->modifiers |= ((double_click_count > 2)
4754 ? triple_modifier
4755 : double_modifier);
4756 }
4757 else
4758 double_click_count = 1;
4759 button_down_time = event->timestamp;
4760 *start_pos_ptr = Fcopy_alist (position);
4761 }
7b4aedb9 4762
88cb0656 4763 /* Now we're releasing a button - check the co-ordinates to
7b4aedb9 4764 see if this was a click or a drag. */
88cb0656
JB
4765 else if (event->modifiers & up_modifier)
4766 {
48e416d4
RS
4767 /* If we did not see a down before this up,
4768 ignore the up. Probably this happened because
4769 the down event chose a menu item.
4770 It would be an annoyance to treat the release
4771 of the button that chose the menu item
4772 as a separate event. */
4773
8c18cbfb 4774 if (!CONSP (start_pos))
48e416d4
RS
4775 return Qnil;
4776
88cb0656 4777 event->modifiers &= ~up_modifier;
48e416d4 4778#if 0 /* Formerly we treated an up with no down as a click event. */
8c18cbfb 4779 if (!CONSP (start_pos))
dbc4e1c1
JB
4780 event->modifiers |= click_modifier;
4781 else
48e416d4 4782#endif
dbc4e1c1
JB
4783 {
4784 /* The third element of every position should be the (x,y)
4785 pair. */
9b8eb840 4786 Lisp_Object down;
dbc4e1c1 4787
9b8eb840 4788 down = Fnth (make_number (2), start_pos);
7539e11f
KR
4789 if (EQ (event->x, XCAR (down))
4790 && EQ (event->y, XCDR (down)))
fbcd35bd 4791 {
bc536d84 4792 event->modifiers |= click_modifier;
fbcd35bd
JB
4793 }
4794 else
4795 {
559f9d04 4796 button_down_time = 0;
fbcd35bd
JB
4797 event->modifiers |= drag_modifier;
4798 }
bc536d84
RS
4799 /* Don't check is_double; treat this as multiple
4800 if the down-event was multiple. */
4801 if (double_click_count > 1)
4802 event->modifiers |= ((double_click_count > 2)
4803 ? triple_modifier
4804 : double_modifier);
dbc4e1c1 4805 }
88cb0656
JB
4806 }
4807 else
4808 /* Every mouse event should either have the down_modifier or
7b4aedb9 4809 the up_modifier set. */
88cb0656
JB
4810 abort ();
4811
88cb0656 4812 {
7b4aedb9 4813 /* Get the symbol we should use for the mouse click. */
9b8eb840
KH
4814 Lisp_Object head;
4815
4816 head = modify_event_symbol (button,
4817 event->modifiers,
8e1e4240
GM
4818 Qmouse_click, Vlispy_mouse_stem,
4819 NULL,
4820 &mouse_syms,
4821 XVECTOR (mouse_syms)->size);
88cb0656 4822 if (event->modifiers & drag_modifier)
dbc4e1c1
JB
4823 return Fcons (head,
4824 Fcons (start_pos,
4825 Fcons (position,
4826 Qnil)));
fbcd35bd
JB
4827 else if (event->modifiers & (double_modifier | triple_modifier))
4828 return Fcons (head,
4829 Fcons (position,
4830 Fcons (make_number (double_click_count),
4831 Qnil)));
88cb0656
JB
4832 else
4833 return Fcons (head,
7b4aedb9 4834 Fcons (position,
88cb0656
JB
4835 Qnil));
4836 }
284f4730 4837 }
db08707d 4838
7ee32cda
GM
4839#if USE_TOOLKIT_SCROLL_BARS
4840
4841 /* We don't have down and up events if using toolkit scroll bars,
4842 so make this always a click event. Store in the `part' of
4843 the Lisp event a symbol which maps to the following actions:
4844
4845 `above_handle' page up
4846 `below_handle' page down
4847 `up' line up
4848 `down' line down
4849 `top' top of buffer
4850 `bottom' bottom of buffer
4851 `handle' thumb has been dragged.
4852 `end-scroll' end of interaction with scroll bar
4853
4854 The incoming input_event contains in its `part' member an
4855 index of type `enum scroll_bar_part' which we can use as an
4856 index in scroll_bar_parts to get the appropriate symbol. */
4857
4858 case scroll_bar_click:
4859 {
4860 Lisp_Object position, head, window, portion_whole, part;
4861
4862 window = event->frame_or_window;
4863 portion_whole = Fcons (event->x, event->y);
4864 part = *scroll_bar_parts[(int) event->part];
4865
4866 position
4867 = Fcons (window,
4868 Fcons (Qvertical_scroll_bar,
4869 Fcons (portion_whole,
4870 Fcons (make_number (event->timestamp),
4871 Fcons (part, Qnil)))));
4872
4873 /* Always treat scroll bar events as clicks. */
4874 event->modifiers |= click_modifier;
4875
4876 /* Get the symbol we should use for the mouse click. */
4877 head = modify_event_symbol (event->code,
4878 event->modifiers,
8e1e4240
GM
4879 Qmouse_click,
4880 Vlispy_mouse_stem,
4881 NULL, &mouse_syms,
4882 XVECTOR (mouse_syms)->size);
7ee32cda
GM
4883 return Fcons (head, Fcons (position, Qnil));
4884 }
4885
4886#endif /* USE_TOOLKIT_SCROLL_BARS */
4887
db08707d 4888#ifdef WINDOWSNT
fbd6baed 4889 case w32_scroll_bar_click:
db08707d
RS
4890 {
4891 int button = event->code;
4892 int is_double;
4893 Lisp_Object position;
4894 Lisp_Object *start_pos_ptr;
4895 Lisp_Object start_pos;
4896
db08707d
RS
4897 {
4898 Lisp_Object window;
4899 Lisp_Object portion_whole;
4900 Lisp_Object part;
4901
4902 window = event->frame_or_window;
4903 portion_whole = Fcons (event->x, event->y);
4904 part = *scroll_bar_parts[(int) event->part];
4905
e8886a1d
RS
4906 position
4907 = Fcons (window,
4908 Fcons (Qvertical_scroll_bar,
4909 Fcons (portion_whole,
4910 Fcons (make_number (event->timestamp),
4911 Fcons (part, Qnil)))));
db08707d
RS
4912 }
4913
fbd6baed 4914 /* Always treat W32 scroll bar events as clicks. */
db08707d
RS
4915 event->modifiers |= click_modifier;
4916
4917 {
4918 /* Get the symbol we should use for the mouse click. */
4919 Lisp_Object head;
4920
4921 head = modify_event_symbol (button,
4922 event->modifiers,
8e1e4240
GM
4923 Qmouse_click,
4924 Vlispy_mouse_stem,
4925 NULL, &mouse_syms,
4926 XVECTOR (mouse_syms)->size);
db08707d
RS
4927 return Fcons (head,
4928 Fcons (position,
4929 Qnil));
4930 }
4931 }
07de30b9
GV
4932 case mouse_wheel:
4933 {
4934 int part;
4935 FRAME_PTR f = XFRAME (event->frame_or_window);
4936 Lisp_Object window;
4937 Lisp_Object posn;
4938 Lisp_Object head, position;
4939 int row, column;
4940
4941 /* Ignore mouse events that were made on frame that
4942 have been deleted. */
4943 if (! FRAME_LIVE_P (f))
4944 return Qnil;
4945 pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
4946 &column, &row, NULL, 1);
7ee32cda 4947 window = window_from_coordinates (f, column, row, &part, 0);
07de30b9
GV
4948
4949 if (!WINDOWP (window))
4950 {
4951 window = event->frame_or_window;
4952 posn = Qnil;
4953 }
4954 else
4955 {
4956 int pixcolumn, pixrow;
4957 column -= XINT (XWINDOW (window)->left);
4958 row -= XINT (XWINDOW (window)->top);
e1bfeab2
JR
4959 glyph_to_pixel_coords (XWINDOW(window), column, row,
4960 &pixcolumn, &pixrow);
07de30b9
GV
4961 XSETINT (event->x, pixcolumn);
4962 XSETINT (event->y, pixrow);
4963
4964 if (part == 1)
4965 posn = Qmode_line;
4966 else if (part == 2)
4967 posn = Qvertical_line;
7ee32cda 4968 else if (part == 3)
045dee35 4969 posn = Qheader_line;
07de30b9
GV
4970 else
4971 XSETINT (posn,
4972 buffer_posn_from_coords (XWINDOW (window),
3cd2f327 4973 &column, &row));
07de30b9 4974 }
db08707d 4975
07de30b9
GV
4976 {
4977 Lisp_Object head, position;
4978
4979 position
4980 = Fcons (window,
4981 Fcons (posn,
4982 Fcons (Fcons (event->x, event->y),
4983 Fcons (make_number (event->timestamp),
4984 Qnil))));
4985
4986 head = modify_event_symbol (0, event->modifiers,
4987 Qmouse_wheel, Qnil,
4988 lispy_mouse_wheel_names,
4989 &mouse_wheel_syms, 1);
4990 return Fcons (head,
4991 Fcons (position,
4992 Fcons (make_number (event->code),
4993 Qnil)));
4994 }
4995 }
4996#endif /* WINDOWSNT */
a24dc617
RS
4997
4998 case drag_n_drop:
4999 {
5000 int part;
5001 FRAME_PTR f;
5002 Lisp_Object window;
5003 Lisp_Object posn;
a24dc617
RS
5004 Lisp_Object files;
5005 int row, column;
5006
5007 /* The frame_or_window field should be a cons of the frame in
5008 which the event occurred and a list of the filenames
5009 dropped. */
5010 if (! CONSP (event->frame_or_window))
5011 abort ();
5012
7539e11f
KR
5013 f = XFRAME (XCAR (event->frame_or_window));
5014 files = XCDR (event->frame_or_window);
a24dc617
RS
5015
5016 /* Ignore mouse events that were made on frames that
5017 have been deleted. */
5018 if (! FRAME_LIVE_P (f))
5019 return Qnil;
5020 pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
5021 &column, &row, NULL, 1);
7ee32cda 5022 window = window_from_coordinates (f, column, row, &part, 0);
a24dc617
RS
5023
5024 if (!WINDOWP (window))
5025 {
7539e11f 5026 window = XCAR (event->frame_or_window);
a24dc617
RS
5027 posn = Qnil;
5028 }
5029 else
5030 {
7ee32cda
GM
5031 /* It's an event in window `window' at frame coordinates
5032 event->x/ event->y. */
5033 struct window *w = XWINDOW (window);
5034
5035 /* Get window relative coordinates. */
5036 int wx = FRAME_TO_WINDOW_PIXEL_X (w, XINT (event->x));
5037 int wy = FRAME_TO_WINDOW_PIXEL_Y (w, XINT (event->y));
5038
5039 /* Set event coordinates to window-relative coordinates
5040 for constructing the Lisp event below. */
5041 XSETINT (event->x, wx);
5042 XSETINT (event->y, wy);
a24dc617
RS
5043
5044 if (part == 1)
5045 posn = Qmode_line;
5046 else if (part == 2)
5047 posn = Qvertical_line;
7ee32cda 5048 else if (part == 3)
045dee35 5049 posn = Qheader_line;
a24dc617 5050 else
7ee32cda 5051 XSETINT (posn, buffer_posn_from_coords (w, &wx, &wy));
a24dc617
RS
5052 }
5053
5054 {
5055 Lisp_Object head, position;
5056
5057 position
5058 = Fcons (window,
5059 Fcons (posn,
5060 Fcons (Fcons (event->x, event->y),
5061 Fcons (make_number (event->timestamp),
5062 Qnil))));
5063
5064 head = modify_event_symbol (0, event->modifiers,
5065 Qdrag_n_drop, Qnil,
5066 lispy_drag_n_drop_names,
5067 &drag_n_drop_syms, 1);
5068 return Fcons (head,
5069 Fcons (position,
5070 Fcons (files,
5071 Qnil)));
5072 }
5073 }
514354e9 5074#endif /* HAVE_MOUSE */
284f4730 5075
e98a93eb 5076#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
da8f7368
GM
5077 case MENU_BAR_EVENT:
5078 if (EQ (event->arg, event->frame_or_window))
5079 /* This is the prefix key. We translate this to
5080 `(menu_bar)' because the code in keyboard.c for menu
5081 events, which we use, relies on this. */
5082 return Fcons (Qmenu_bar, Qnil);
5083 return event->arg;
2470a66f
KH
5084#endif
5085
9ea173e8 5086 case TOOL_BAR_EVENT:
da8f7368
GM
5087 if (EQ (event->arg, event->frame_or_window))
5088 /* This is the prefix key. We translate this to
5089 `(tool_bar)' because the code in keyboard.c for menu
5090 events, which we use, relies on this. */
5091 return Fcons (Qtool_bar, Qnil);
5092 else if (SYMBOLP (event->arg))
5093 return apply_modifiers (event->modifiers, event->arg);
5094 return event->arg;
5095
5096 case USER_SIGNAL_EVENT:
5bf68f6e
AS
5097 /* A user signal. */
5098 return *lispy_user_signals[event->code];
5099
284f4730
JB
5100 /* The 'kind' field of the event is something we don't recognize. */
5101 default:
48e416d4 5102 abort ();
284f4730
JB
5103 }
5104}
5105
514354e9 5106#ifdef HAVE_MOUSE
6cbff1cb 5107
284f4730 5108static Lisp_Object
7b4aedb9 5109make_lispy_movement (frame, bar_window, part, x, y, time)
ff11dfa1 5110 FRAME_PTR frame;
7b4aedb9 5111 Lisp_Object bar_window;
3c370943 5112 enum scroll_bar_part part;
284f4730 5113 Lisp_Object x, y;
e5d77022 5114 unsigned long time;
284f4730 5115{
3c370943 5116 /* Is it a scroll bar movement? */
7b4aedb9 5117 if (frame && ! NILP (bar_window))
4bb994d1 5118 {
9b8eb840 5119 Lisp_Object part_sym;
4bb994d1 5120
9b8eb840 5121 part_sym = *scroll_bar_parts[(int) part];
3c370943 5122 return Fcons (Qscroll_bar_movement,
7b4aedb9 5123 (Fcons (Fcons (bar_window,
3c370943 5124 Fcons (Qvertical_scroll_bar,
4bb994d1
JB
5125 Fcons (Fcons (x, y),
5126 Fcons (make_number (time),
cb5df6ae 5127 Fcons (part_sym,
4bb994d1
JB
5128 Qnil))))),
5129 Qnil)));
5130 }
5131
5132 /* Or is it an ordinary mouse movement? */
284f4730
JB
5133 else
5134 {
4bb994d1 5135 int area;
9e20143a 5136 Lisp_Object window;
4bb994d1 5137 Lisp_Object posn;
9e20143a 5138
9e20143a 5139 if (frame)
7ee32cda
GM
5140 /* It's in a frame; which window on that frame? */
5141 window = window_from_coordinates (frame, XINT (x), XINT (y), &area, 0);
9e20143a
RS
5142 else
5143 window = Qnil;
4bb994d1 5144
8c18cbfb 5145 if (WINDOWP (window))
4bb994d1 5146 {
7ee32cda 5147 struct window *w = XWINDOW (window);
7ee32cda 5148 int wx, wy;
7ee32cda
GM
5149
5150 /* Get window relative coordinates. */
5151 wx = FRAME_TO_WINDOW_PIXEL_X (w, XINT (x));
5152 wy = FRAME_TO_WINDOW_PIXEL_Y (w, XINT (y));
5153 XSETINT (x, wx);
5154 XSETINT (y, wy);
5155
4bb994d1
JB
5156 if (area == 1)
5157 posn = Qmode_line;
5158 else if (area == 2)
5159 posn = Qvertical_line;
7ee32cda 5160 else if (area == 3)
045dee35 5161 posn = Qheader_line;
4bb994d1 5162 else
7ee32cda 5163 XSETINT (posn, buffer_posn_from_coords (w, &wx, &wy));
4bb994d1 5164 }
e9bf89a0
RS
5165 else if (frame != 0)
5166 {
18cd2eeb 5167 XSETFRAME (window, frame);
e9bf89a0
RS
5168 posn = Qnil;
5169 }
284f4730 5170 else
4bb994d1
JB
5171 {
5172 window = Qnil;
5173 posn = Qnil;
bb9e9bed
KH
5174 XSETFASTINT (x, 0);
5175 XSETFASTINT (y, 0);
4bb994d1 5176 }
284f4730 5177
4bb994d1
JB
5178 return Fcons (Qmouse_movement,
5179 Fcons (Fcons (window,
5180 Fcons (posn,
5181 Fcons (Fcons (x, y),
5182 Fcons (make_number (time),
5183 Qnil)))),
5184 Qnil));
5185 }
284f4730
JB
5186}
5187
514354e9 5188#endif /* HAVE_MOUSE */
6cbff1cb 5189
cd21b839
JB
5190/* Construct a switch frame event. */
5191static Lisp_Object
5192make_lispy_switch_frame (frame)
5193 Lisp_Object frame;
5194{
5195 return Fcons (Qswitch_frame, Fcons (frame, Qnil));
5196}
0a7f1fc0
JB
5197\f
5198/* Manipulating modifiers. */
284f4730 5199
0a7f1fc0 5200/* Parse the name of SYMBOL, and return the set of modifiers it contains.
284f4730 5201
0a7f1fc0
JB
5202 If MODIFIER_END is non-zero, set *MODIFIER_END to the position in
5203 SYMBOL's name of the end of the modifiers; the string from this
5204 position is the unmodified symbol name.
284f4730 5205
0a7f1fc0 5206 This doesn't use any caches. */
6da3dd3a 5207
0a7f1fc0
JB
5208static int
5209parse_modifiers_uncached (symbol, modifier_end)
284f4730 5210 Lisp_Object symbol;
0a7f1fc0 5211 int *modifier_end;
284f4730
JB
5212{
5213 struct Lisp_String *name;
5214 int i;
5215 int modifiers;
284f4730
JB
5216
5217 CHECK_SYMBOL (symbol, 1);
df0f2ba1 5218
284f4730
JB
5219 modifiers = 0;
5220 name = XSYMBOL (symbol)->name;
5221
fc932ac6 5222 for (i = 0; i+2 <= STRING_BYTES (name); )
6da3dd3a
RS
5223 {
5224 int this_mod_end = 0;
5225 int this_mod = 0;
284f4730 5226
6da3dd3a
RS
5227 /* See if the name continues with a modifier word.
5228 Check that the word appears, but don't check what follows it.
5229 Set this_mod and this_mod_end to record what we find. */
fce33686 5230
6da3dd3a
RS
5231 switch (name->data[i])
5232 {
5233#define SINGLE_LETTER_MOD(BIT) \
5234 (this_mod_end = i + 1, this_mod = BIT)
5235
6da3dd3a
RS
5236 case 'A':
5237 SINGLE_LETTER_MOD (alt_modifier);
5238 break;
284f4730 5239
6da3dd3a
RS
5240 case 'C':
5241 SINGLE_LETTER_MOD (ctrl_modifier);
5242 break;
284f4730 5243
6da3dd3a
RS
5244 case 'H':
5245 SINGLE_LETTER_MOD (hyper_modifier);
5246 break;
5247
6da3dd3a
RS
5248 case 'M':
5249 SINGLE_LETTER_MOD (meta_modifier);
5250 break;
5251
6da3dd3a
RS
5252 case 'S':
5253 SINGLE_LETTER_MOD (shift_modifier);
5254 break;
5255
5256 case 's':
6da3dd3a
RS
5257 SINGLE_LETTER_MOD (super_modifier);
5258 break;
5259
0a7f1fc0 5260#undef SINGLE_LETTER_MOD
6da3dd3a
RS
5261 }
5262
5263 /* If we found no modifier, stop looking for them. */
5264 if (this_mod_end == 0)
5265 break;
5266
5267 /* Check there is a dash after the modifier, so that it
5268 really is a modifier. */
fc932ac6
RS
5269 if (this_mod_end >= STRING_BYTES (name)
5270 || name->data[this_mod_end] != '-')
6da3dd3a
RS
5271 break;
5272
5273 /* This modifier is real; look for another. */
5274 modifiers |= this_mod;
5275 i = this_mod_end + 1;
5276 }
284f4730 5277
0a7f1fc0 5278 /* Should we include the `click' modifier? */
fbcd35bd
JB
5279 if (! (modifiers & (down_modifier | drag_modifier
5280 | double_modifier | triple_modifier))
fc932ac6 5281 && i + 7 == STRING_BYTES (name)
4bb994d1 5282 && strncmp (name->data + i, "mouse-", 6) == 0
6569cc8d 5283 && ('0' <= name->data[i + 6] && name->data[i + 6] <= '9'))
0a7f1fc0
JB
5284 modifiers |= click_modifier;
5285
5286 if (modifier_end)
5287 *modifier_end = i;
5288
5289 return modifiers;
5290}
5291
0a7f1fc0
JB
5292/* Return a symbol whose name is the modifier prefixes for MODIFIERS
5293 prepended to the string BASE[0..BASE_LEN-1].
5294 This doesn't use any caches. */
5295static Lisp_Object
301738ed 5296apply_modifiers_uncached (modifiers, base, base_len, base_len_byte)
0a7f1fc0
JB
5297 int modifiers;
5298 char *base;
301738ed 5299 int base_len, base_len_byte;
0a7f1fc0
JB
5300{
5301 /* Since BASE could contain nulls, we can't use intern here; we have
5302 to use Fintern, which expects a genuine Lisp_String, and keeps a
5303 reference to it. */
301738ed
RS
5304 char *new_mods
5305 = (char *) alloca (sizeof ("A-C-H-M-S-s-down-drag-double-triple-"));
0a7f1fc0 5306 int mod_len;
284f4730 5307
284f4730 5308 {
0a7f1fc0
JB
5309 char *p = new_mods;
5310
5311 /* Only the event queue may use the `up' modifier; it should always
5312 be turned into a click or drag event before presented to lisp code. */
5313 if (modifiers & up_modifier)
5314 abort ();
5315
5316 if (modifiers & alt_modifier) { *p++ = 'A'; *p++ = '-'; }
5317 if (modifiers & ctrl_modifier) { *p++ = 'C'; *p++ = '-'; }
5318 if (modifiers & hyper_modifier) { *p++ = 'H'; *p++ = '-'; }
5319 if (modifiers & meta_modifier) { *p++ = 'M'; *p++ = '-'; }
5320 if (modifiers & shift_modifier) { *p++ = 'S'; *p++ = '-'; }
86e5706b 5321 if (modifiers & super_modifier) { *p++ = 's'; *p++ = '-'; }
fbcd35bd
JB
5322 if (modifiers & double_modifier) { strcpy (p, "double-"); p += 7; }
5323 if (modifiers & triple_modifier) { strcpy (p, "triple-"); p += 7; }
559f9d04
RS
5324 if (modifiers & down_modifier) { strcpy (p, "down-"); p += 5; }
5325 if (modifiers & drag_modifier) { strcpy (p, "drag-"); p += 5; }
0a7f1fc0
JB
5326 /* The click modifier is denoted by the absence of other modifiers. */
5327
5328 *p = '\0';
5329
5330 mod_len = p - new_mods;
5331 }
284f4730 5332
0a7f1fc0 5333 {
9b8eb840 5334 Lisp_Object new_name;
df0f2ba1 5335
301738ed
RS
5336 new_name = make_uninit_multibyte_string (mod_len + base_len,
5337 mod_len + base_len_byte);
0a7f1fc0 5338 bcopy (new_mods, XSTRING (new_name)->data, mod_len);
301738ed 5339 bcopy (base, XSTRING (new_name)->data + mod_len, base_len_byte);
284f4730
JB
5340
5341 return Fintern (new_name, Qnil);
5342 }
5343}
5344
5345
0a7f1fc0
JB
5346static char *modifier_names[] =
5347{
fbcd35bd 5348 "up", "down", "drag", "click", "double", "triple", 0, 0,
f335fabe 5349 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
86e5706b 5350 0, 0, "alt", "super", "hyper", "shift", "control", "meta"
0a7f1fc0 5351};
80645119 5352#define NUM_MOD_NAMES (sizeof (modifier_names) / sizeof (modifier_names[0]))
0a7f1fc0
JB
5353
5354static Lisp_Object modifier_symbols;
5355
5356/* Return the list of modifier symbols corresponding to the mask MODIFIERS. */
5357static Lisp_Object
5358lispy_modifier_list (modifiers)
5359 int modifiers;
5360{
5361 Lisp_Object modifier_list;
5362 int i;
5363
5364 modifier_list = Qnil;
80645119 5365 for (i = 0; (1<<i) <= modifiers && i < NUM_MOD_NAMES; i++)
0a7f1fc0 5366 if (modifiers & (1<<i))
80645119
JB
5367 modifier_list = Fcons (XVECTOR (modifier_symbols)->contents[i],
5368 modifier_list);
0a7f1fc0
JB
5369
5370 return modifier_list;
5371}
5372
5373
5374/* Parse the modifiers on SYMBOL, and return a list like (UNMODIFIED MASK),
5375 where UNMODIFIED is the unmodified form of SYMBOL,
5376 MASK is the set of modifiers present in SYMBOL's name.
5377 This is similar to parse_modifiers_uncached, but uses the cache in
5378 SYMBOL's Qevent_symbol_element_mask property, and maintains the
5379 Qevent_symbol_elements property. */
3d31316f 5380
1161d367 5381Lisp_Object
0a7f1fc0
JB
5382parse_modifiers (symbol)
5383 Lisp_Object symbol;
5384{
9b8eb840 5385 Lisp_Object elements;
0a7f1fc0 5386
9b8eb840 5387 elements = Fget (symbol, Qevent_symbol_element_mask);
0a7f1fc0
JB
5388 if (CONSP (elements))
5389 return elements;
5390 else
5391 {
5392 int end;
ec0faad2 5393 int modifiers = parse_modifiers_uncached (symbol, &end);
9b8eb840 5394 Lisp_Object unmodified;
0a7f1fc0
JB
5395 Lisp_Object mask;
5396
9b8eb840 5397 unmodified = Fintern (make_string (XSYMBOL (symbol)->name->data + end,
fc932ac6 5398 STRING_BYTES (XSYMBOL (symbol)->name) - end),
9b8eb840
KH
5399 Qnil);
5400
ec0faad2 5401 if (modifiers & ~(((EMACS_INT)1 << VALBITS) - 1))
734fef94 5402 abort ();
bb9e9bed 5403 XSETFASTINT (mask, modifiers);
0a7f1fc0
JB
5404 elements = Fcons (unmodified, Fcons (mask, Qnil));
5405
5406 /* Cache the parsing results on SYMBOL. */
5407 Fput (symbol, Qevent_symbol_element_mask,
5408 elements);
5409 Fput (symbol, Qevent_symbol_elements,
5410 Fcons (unmodified, lispy_modifier_list (modifiers)));
5411
5412 /* Since we know that SYMBOL is modifiers applied to unmodified,
5413 it would be nice to put that in unmodified's cache.
5414 But we can't, since we're not sure that parse_modifiers is
5415 canonical. */
5416
5417 return elements;
5418 }
5419}
5420
5421/* Apply the modifiers MODIFIERS to the symbol BASE.
5422 BASE must be unmodified.
5423
5424 This is like apply_modifiers_uncached, but uses BASE's
5425 Qmodifier_cache property, if present. It also builds
cd21b839
JB
5426 Qevent_symbol_elements properties, since it has that info anyway.
5427
5428 apply_modifiers copies the value of BASE's Qevent_kind property to
5429 the modified symbol. */
0a7f1fc0
JB
5430static Lisp_Object
5431apply_modifiers (modifiers, base)
5432 int modifiers;
5433 Lisp_Object base;
5434{
7b4aedb9 5435 Lisp_Object cache, index, entry, new_symbol;
0a7f1fc0 5436
80645119 5437 /* Mask out upper bits. We don't know where this value's been. */
ec0faad2 5438 modifiers &= ((EMACS_INT)1 << VALBITS) - 1;
80645119 5439
0a7f1fc0 5440 /* The click modifier never figures into cache indices. */
0a7f1fc0 5441 cache = Fget (base, Qmodifier_cache);
bb9e9bed 5442 XSETFASTINT (index, (modifiers & ~click_modifier));
697e4895 5443 entry = assq_no_quit (index, cache);
0a7f1fc0
JB
5444
5445 if (CONSP (entry))
7539e11f 5446 new_symbol = XCDR (entry);
7b4aedb9
JB
5447 else
5448 {
df0f2ba1 5449 /* We have to create the symbol ourselves. */
7b4aedb9
JB
5450 new_symbol = apply_modifiers_uncached (modifiers,
5451 XSYMBOL (base)->name->data,
301738ed 5452 XSYMBOL (base)->name->size,
fc932ac6 5453 STRING_BYTES (XSYMBOL (base)->name));
7b4aedb9
JB
5454
5455 /* Add the new symbol to the base's cache. */
5456 entry = Fcons (index, new_symbol);
5457 Fput (base, Qmodifier_cache, Fcons (entry, cache));
5458
5459 /* We have the parsing info now for free, so add it to the caches. */
bb9e9bed 5460 XSETFASTINT (index, modifiers);
7b4aedb9
JB
5461 Fput (new_symbol, Qevent_symbol_element_mask,
5462 Fcons (base, Fcons (index, Qnil)));
5463 Fput (new_symbol, Qevent_symbol_elements,
5464 Fcons (base, lispy_modifier_list (modifiers)));
5465 }
0a7f1fc0 5466
df0f2ba1 5467 /* Make sure this symbol is of the same kind as BASE.
7b4aedb9
JB
5468
5469 You'd think we could just set this once and for all when we
5470 intern the symbol above, but reorder_modifiers may call us when
5471 BASE's property isn't set right; we can't assume that just
80645119
JB
5472 because it has a Qmodifier_cache property it must have its
5473 Qevent_kind set right as well. */
7b4aedb9
JB
5474 if (NILP (Fget (new_symbol, Qevent_kind)))
5475 {
9b8eb840 5476 Lisp_Object kind;
7b4aedb9 5477
9b8eb840 5478 kind = Fget (base, Qevent_kind);
7b4aedb9
JB
5479 if (! NILP (kind))
5480 Fput (new_symbol, Qevent_kind, kind);
5481 }
5482
5483 return new_symbol;
0a7f1fc0
JB
5484}
5485
5486
5487/* Given a symbol whose name begins with modifiers ("C-", "M-", etc),
5488 return a symbol with the modifiers placed in the canonical order.
5489 Canonical order is alphabetical, except for down and drag, which
5490 always come last. The 'click' modifier is never written out.
5491
5492 Fdefine_key calls this to make sure that (for example) C-M-foo
5493 and M-C-foo end up being equivalent in the keymap. */
5494
5495Lisp_Object
5496reorder_modifiers (symbol)
5497 Lisp_Object symbol;
5498{
5499 /* It's hopefully okay to write the code this way, since everything
5500 will soon be in caches, and no consing will be done at all. */
9b8eb840 5501 Lisp_Object parsed;
0a7f1fc0 5502
9b8eb840 5503 parsed = parse_modifiers (symbol);
7539e11f
KR
5504 return apply_modifiers ((int) XINT (XCAR (XCDR (parsed))),
5505 XCAR (parsed));
0a7f1fc0
JB
5506}
5507
5508
284f4730
JB
5509/* For handling events, we often want to produce a symbol whose name
5510 is a series of modifier key prefixes ("M-", "C-", etcetera) attached
5511 to some base, like the name of a function key or mouse button.
5512 modify_event_symbol produces symbols of this sort.
5513
5514 NAME_TABLE should point to an array of strings, such that NAME_TABLE[i]
5515 is the name of the i'th symbol. TABLE_SIZE is the number of elements
5516 in the table.
5517
8e1e4240
GM
5518 Alternatively, NAME_ALIST_OR_STEM is either an alist mapping codes
5519 into symbol names, or a string specifying a name stem used to
a50e723f 5520 construct a symbol name or the form `STEM-N', where N is the decimal
8e1e4240
GM
5521 representation of SYMBOL_NUM. NAME_ALIST_OR_STEM is used if it is
5522 non-nil; otherwise NAME_TABLE is used.
80e4aa30 5523
284f4730
JB
5524 SYMBOL_TABLE should be a pointer to a Lisp_Object whose value will
5525 persist between calls to modify_event_symbol that it can use to
5526 store a cache of the symbols it's generated for this NAME_TABLE
80e4aa30 5527 before. The object stored there may be a vector or an alist.
284f4730
JB
5528
5529 SYMBOL_NUM is the number of the base name we want from NAME_TABLE.
df0f2ba1 5530
284f4730
JB
5531 MODIFIERS is a set of modifier bits (as given in struct input_events)
5532 whose prefixes should be applied to the symbol name.
5533
5534 SYMBOL_KIND is the value to be placed in the event_kind property of
df0f2ba1 5535 the returned symbol.
88cb0656
JB
5536
5537 The symbols we create are supposed to have an
eb8c3be9 5538 `event-symbol-elements' property, which lists the modifiers present
88cb0656
JB
5539 in the symbol's name. */
5540
284f4730 5541static Lisp_Object
8e1e4240 5542modify_event_symbol (symbol_num, modifiers, symbol_kind, name_alist_or_stem,
80e4aa30 5543 name_table, symbol_table, table_size)
284f4730
JB
5544 int symbol_num;
5545 unsigned modifiers;
5546 Lisp_Object symbol_kind;
8e1e4240 5547 Lisp_Object name_alist_or_stem;
284f4730
JB
5548 char **name_table;
5549 Lisp_Object *symbol_table;
2c834fb3 5550 unsigned int table_size;
284f4730 5551{
80e4aa30
RS
5552 Lisp_Object value;
5553 Lisp_Object symbol_int;
5554
2c834fb3
KH
5555 /* Get rid of the "vendor-specific" bit here. */
5556 XSETINT (symbol_int, symbol_num & 0xffffff);
284f4730
JB
5557
5558 /* Is this a request for a valid symbol? */
88cb0656 5559 if (symbol_num < 0 || symbol_num >= table_size)
0c2611c5 5560 return Qnil;
284f4730 5561
80e4aa30
RS
5562 if (CONSP (*symbol_table))
5563 value = Fcdr (assq_no_quit (symbol_int, *symbol_table));
5564
0a7f1fc0 5565 /* If *symbol_table doesn't seem to be initialized properly, fix that.
88cb0656 5566 *symbol_table should be a lisp vector TABLE_SIZE elements long,
4bb994d1
JB
5567 where the Nth element is the symbol for NAME_TABLE[N], or nil if
5568 we've never used that symbol before. */
80e4aa30 5569 else
88cb0656 5570 {
80e4aa30
RS
5571 if (! VECTORP (*symbol_table)
5572 || XVECTOR (*symbol_table)->size != table_size)
5573 {
5574 Lisp_Object size;
0a7f1fc0 5575
bb9e9bed 5576 XSETFASTINT (size, table_size);
80e4aa30
RS
5577 *symbol_table = Fmake_vector (size, Qnil);
5578 }
284f4730 5579
80e4aa30
RS
5580 value = XVECTOR (*symbol_table)->contents[symbol_num];
5581 }
284f4730 5582
0a7f1fc0 5583 /* Have we already used this symbol before? */
80e4aa30 5584 if (NILP (value))
284f4730 5585 {
0a7f1fc0 5586 /* No; let's create it. */
8e1e4240
GM
5587 if (CONSP (name_alist_or_stem))
5588 value = Fcdr_safe (Fassq (symbol_int, name_alist_or_stem));
5589 else if (STRINGP (name_alist_or_stem))
5590 {
5591 int len = STRING_BYTES (XSTRING (name_alist_or_stem));
5592 char *buf = (char *) alloca (len + 50);
5593 sprintf (buf, "%s-%d", XSTRING (name_alist_or_stem)->data,
5594 XINT (symbol_int) + 1);
5595 value = intern (buf);
5596 }
2ff6714d 5597 else if (name_table != 0 && name_table[symbol_num])
80e4aa30 5598 value = intern (name_table[symbol_num]);
b64b4075 5599
e98a93eb 5600#ifdef HAVE_WINDOW_SYSTEM
2c834fb3
KH
5601 if (NILP (value))
5602 {
5603 char *name = x_get_keysym_name (symbol_num);
5604 if (name)
5605 value = intern (name);
5606 }
5607#endif
5608
b64b4075 5609 if (NILP (value))
d1f50460
RS
5610 {
5611 char buf[20];
5612 sprintf (buf, "key-%d", symbol_num);
80e4aa30 5613 value = intern (buf);
d1f50460 5614 }
0a7f1fc0 5615
80e4aa30 5616 if (CONSP (*symbol_table))
4205cb08 5617 *symbol_table = Fcons (Fcons (symbol_int, value), *symbol_table);
80e4aa30
RS
5618 else
5619 XVECTOR (*symbol_table)->contents[symbol_num] = value;
5620
df0f2ba1 5621 /* Fill in the cache entries for this symbol; this also
0a7f1fc0
JB
5622 builds the Qevent_symbol_elements property, which the user
5623 cares about. */
80e4aa30
RS
5624 apply_modifiers (modifiers & click_modifier, value);
5625 Fput (value, Qevent_kind, symbol_kind);
284f4730 5626 }
88cb0656 5627
0a7f1fc0 5628 /* Apply modifiers to that symbol. */
80e4aa30 5629 return apply_modifiers (modifiers, value);
284f4730 5630}
6da3dd3a
RS
5631\f
5632/* Convert a list that represents an event type,
5633 such as (ctrl meta backspace), into the usual representation of that
5634 event type as a number or a symbol. */
5635
a1706c30 5636DEFUN ("event-convert-list", Fevent_convert_list, Sevent_convert_list, 1, 1, 0,
e57d8fd8
EN
5637 "Convert the event description list EVENT-DESC to an event type.\n\
5638EVENT-DESC should contain one base event type (a character or symbol)\n\
a1706c30 5639and zero or more modifier names (control, meta, hyper, super, shift, alt,\n\
377f24f5 5640drag, down, double or triple). The base must be last.\n\
a1706c30
KH
5641The return value is an event type (a character or symbol) which\n\
5642has the same base event type and all the specified modifiers.")
e57d8fd8
EN
5643 (event_desc)
5644 Lisp_Object event_desc;
6da3dd3a
RS
5645{
5646 Lisp_Object base;
5647 int modifiers = 0;
5648 Lisp_Object rest;
5649
5650 base = Qnil;
e57d8fd8 5651 rest = event_desc;
6da3dd3a
RS
5652 while (CONSP (rest))
5653 {
5654 Lisp_Object elt;
5655 int this = 0;
5656
7539e11f
KR
5657 elt = XCAR (rest);
5658 rest = XCDR (rest);
6da3dd3a 5659
3d31316f 5660 /* Given a symbol, see if it is a modifier name. */
377f24f5 5661 if (SYMBOLP (elt) && CONSP (rest))
3d31316f 5662 this = parse_solitary_modifier (elt);
6da3dd3a
RS
5663
5664 if (this != 0)
5665 modifiers |= this;
5666 else if (!NILP (base))
5667 error ("Two bases given in one event");
5668 else
5669 base = elt;
5670
6da3dd3a
RS
5671 }
5672
3d31316f
RS
5673 /* Let the symbol A refer to the character A. */
5674 if (SYMBOLP (base) && XSYMBOL (base)->name->size == 1)
5675 XSETINT (base, XSYMBOL (base)->name->data[0]);
5676
6da3dd3a
RS
5677 if (INTEGERP (base))
5678 {
3d31316f
RS
5679 /* Turn (shift a) into A. */
5680 if ((modifiers & shift_modifier) != 0
5681 && (XINT (base) >= 'a' && XINT (base) <= 'z'))
5682 {
5683 XSETINT (base, XINT (base) - ('a' - 'A'));
5684 modifiers &= ~shift_modifier;
5685 }
5686
5687 /* Turn (control a) into C-a. */
6da3dd3a 5688 if (modifiers & ctrl_modifier)
3d31316f 5689 return make_number ((modifiers & ~ctrl_modifier)
6da3dd3a
RS
5690 | make_ctrl_char (XINT (base)));
5691 else
5692 return make_number (modifiers | XINT (base));
5693 }
5694 else if (SYMBOLP (base))
5695 return apply_modifiers (modifiers, base);
5696 else
8c907a56
GM
5697 {
5698 error ("Invalid base event");
5699 return Qnil;
5700 }
6da3dd3a
RS
5701}
5702
3d31316f
RS
5703/* Try to recognize SYMBOL as a modifier name.
5704 Return the modifier flag bit, or 0 if not recognized. */
5705
5706static int
5707parse_solitary_modifier (symbol)
5708 Lisp_Object symbol;
5709{
5710 struct Lisp_String *name = XSYMBOL (symbol)->name;
5711
5712 switch (name->data[0])
5713 {
5714#define SINGLE_LETTER_MOD(BIT) \
fc932ac6 5715 if (STRING_BYTES (name) == 1) \
3d31316f
RS
5716 return BIT;
5717
5718#define MULTI_LETTER_MOD(BIT, NAME, LEN) \
fc932ac6 5719 if (LEN == STRING_BYTES (name) \
3d31316f
RS
5720 && ! strncmp (name->data, NAME, LEN)) \
5721 return BIT;
5722
5723 case 'A':
5724 SINGLE_LETTER_MOD (alt_modifier);
5725 break;
5726
5727 case 'a':
5728 MULTI_LETTER_MOD (alt_modifier, "alt", 3);
5729 break;
5730
5731 case 'C':
5732 SINGLE_LETTER_MOD (ctrl_modifier);
5733 break;
5734
5735 case 'c':
5736 MULTI_LETTER_MOD (ctrl_modifier, "ctrl", 4);
5737 MULTI_LETTER_MOD (ctrl_modifier, "control", 7);
5738 break;
5739
5740 case 'H':
5741 SINGLE_LETTER_MOD (hyper_modifier);
5742 break;
5743
5744 case 'h':
5745 MULTI_LETTER_MOD (hyper_modifier, "hyper", 5);
5746 break;
5747
5748 case 'M':
5749 SINGLE_LETTER_MOD (meta_modifier);
5750 break;
5751
5752 case 'm':
5753 MULTI_LETTER_MOD (meta_modifier, "meta", 4);
5754 break;
5755
5756 case 'S':
5757 SINGLE_LETTER_MOD (shift_modifier);
5758 break;
5759
5760 case 's':
5761 MULTI_LETTER_MOD (shift_modifier, "shift", 5);
5762 MULTI_LETTER_MOD (super_modifier, "super", 5);
5763 SINGLE_LETTER_MOD (super_modifier);
5764 break;
5765
5766 case 'd':
5767 MULTI_LETTER_MOD (drag_modifier, "drag", 4);
5768 MULTI_LETTER_MOD (down_modifier, "down", 4);
5769 MULTI_LETTER_MOD (double_modifier, "double", 6);
5770 break;
5771
5772 case 't':
5773 MULTI_LETTER_MOD (triple_modifier, "triple", 6);
5774 break;
5775
5776#undef SINGLE_LETTER_MOD
5777#undef MULTI_LETTER_MOD
5778 }
5779
5780 return 0;
5781}
5782
6da3dd3a
RS
5783/* Return 1 if EVENT is a list whose elements are all integers or symbols.
5784 Such a list is not valid as an event,
5785 but it can be a Lucid-style event type list. */
5786
5787int
5788lucid_event_type_list_p (object)
5789 Lisp_Object object;
5790{
5791 Lisp_Object tail;
5792
5793 if (! CONSP (object))
5794 return 0;
5795
7539e11f 5796 for (tail = object; CONSP (tail); tail = XCDR (tail))
6da3dd3a
RS
5797 {
5798 Lisp_Object elt;
7539e11f 5799 elt = XCAR (tail);
6da3dd3a
RS
5800 if (! (INTEGERP (elt) || SYMBOLP (elt)))
5801 return 0;
5802 }
5803
5804 return NILP (tail);
5805}
284f4730 5806\f
284f4730
JB
5807/* Store into *addr a value nonzero if terminal input chars are available.
5808 Serves the purpose of ioctl (0, FIONREAD, addr)
5809 but works even if FIONREAD does not exist.
d9d4c147
KH
5810 (In fact, this may actually read some input.)
5811
5812 If DO_TIMERS_NOW is nonzero, actually run timer events that are ripe. */
284f4730
JB
5813
5814static void
d9d4c147 5815get_input_pending (addr, do_timers_now)
284f4730 5816 int *addr;
d9d4c147 5817 int do_timers_now;
284f4730
JB
5818{
5819 /* First of all, have we already counted some input? */
d9d4c147 5820 *addr = !NILP (Vquit_flag) || readable_events (do_timers_now);
284f4730
JB
5821
5822 /* If input is being read as it arrives, and we have none, there is none. */
5823 if (*addr > 0 || (interrupt_input && ! interrupts_deferred))
5824 return;
5825
5826 /* Try to read some input and see how much we get. */
5827 gobble_input (0);
d9d4c147 5828 *addr = !NILP (Vquit_flag) || readable_events (do_timers_now);
284f4730
JB
5829}
5830
81931ba1 5831/* Interface to read_avail_input, blocking SIGIO or SIGALRM if necessary. */
284f4730 5832
07a59269 5833void
284f4730
JB
5834gobble_input (expected)
5835 int expected;
5836{
5837#ifndef VMS
5838#ifdef SIGIO
5839 if (interrupt_input)
5840 {
32676c08 5841 SIGMASKTYPE mask;
4f8aaa74 5842 mask = sigblock (sigmask (SIGIO));
284f4730 5843 read_avail_input (expected);
e065a56e 5844 sigsetmask (mask);
284f4730
JB
5845 }
5846 else
81931ba1
RS
5847#ifdef POLL_FOR_INPUT
5848 if (read_socket_hook && !interrupt_input && poll_suppress_count == 0)
5849 {
5850 SIGMASKTYPE mask;
4f8aaa74 5851 mask = sigblock (sigmask (SIGALRM));
81931ba1
RS
5852 read_avail_input (expected);
5853 sigsetmask (mask);
5854 }
5855 else
87485d6f 5856#endif
284f4730
JB
5857#endif
5858 read_avail_input (expected);
5859#endif
5860}
a8015ab5 5861
241ceaf7
RS
5862/* Put a buffer_switch_event in the buffer
5863 so that read_key_sequence will notice the new current buffer. */
5864
07a59269 5865void
a8015ab5
KH
5866record_asynch_buffer_change ()
5867{
5868 struct input_event event;
a30f0615
RS
5869 Lisp_Object tem;
5870
a8015ab5
KH
5871 event.kind = buffer_switch_event;
5872 event.frame_or_window = Qnil;
da8f7368 5873 event.arg = Qnil;
241ceaf7 5874
f65e6f7d 5875#ifdef subprocesses
a30f0615
RS
5876 /* We don't need a buffer-switch event unless Emacs is waiting for input.
5877 The purpose of the event is to make read_key_sequence look up the
5878 keymaps again. If we aren't in read_key_sequence, we don't need one,
5879 and the event could cause trouble by messing up (input-pending-p). */
5880 tem = Fwaiting_for_user_input_p ();
5881 if (NILP (tem))
5882 return;
f65e6f7d
RS
5883#else
5884 /* We never need these events if we have no asynchronous subprocesses. */
5885 return;
5886#endif
a30f0615 5887
241ceaf7
RS
5888 /* Make sure no interrupt happens while storing the event. */
5889#ifdef SIGIO
5890 if (interrupt_input)
5891 {
5892 SIGMASKTYPE mask;
4f8aaa74 5893 mask = sigblock (sigmask (SIGIO));
241ceaf7
RS
5894 kbd_buffer_store_event (&event);
5895 sigsetmask (mask);
5896 }
5897 else
5898#endif
5899 {
5900 stop_polling ();
5901 kbd_buffer_store_event (&event);
5902 start_polling ();
5903 }
a8015ab5 5904}
284f4730
JB
5905\f
5906#ifndef VMS
5907
5908/* Read any terminal input already buffered up by the system
5909 into the kbd_buffer, but do not wait.
5910
5911 EXPECTED should be nonzero if the caller knows there is some input.
5912
5913 Except on VMS, all input is read by this function.
5914 If interrupt_input is nonzero, this function MUST be called
5915 only when SIGIO is blocked.
5916
5917 Returns the number of keyboard chars read, or -1 meaning
5918 this is a bad time to try to read input. */
5919
5920static int
5921read_avail_input (expected)
5922 int expected;
5923{
5924 struct input_event buf[KBD_BUFFER_SIZE];
5925 register int i;
5926 int nread;
5927
5928 if (read_socket_hook)
5929 /* No need for FIONREAD or fcntl; just say don't wait. */
33e19c6e 5930 nread = (*read_socket_hook) (input_fd, buf, KBD_BUFFER_SIZE, expected);
284f4730
JB
5931 else
5932 {
17270835
RS
5933 /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
5934 the kbd_buffer can really hold. That may prevent loss
5935 of characters on some systems when input is stuffed at us. */
5936 unsigned char cbuf[KBD_BUFFER_SIZE - 1];
58788063 5937 int n_to_read;
284f4730 5938
58788063 5939 /* Determine how many characters we should *try* to read. */
bc536d84
RS
5940#ifdef WINDOWSNT
5941 return 0;
5942#else /* not WINDOWSNT */
80e4aa30 5943#ifdef MSDOS
58788063
RS
5944 n_to_read = dos_keysns ();
5945 if (n_to_read == 0)
5946 return 0;
c3a2738c 5947#else /* not MSDOS */
284f4730
JB
5948#ifdef FIONREAD
5949 /* Find out how much input is available. */
437f6112 5950 if (ioctl (input_fd, FIONREAD, &n_to_read) < 0)
284f4730
JB
5951 /* Formerly simply reported no input, but that sometimes led to
5952 a failure of Emacs to terminate.
5953 SIGHUP seems appropriate if we can't reach the terminal. */
e4535288
RS
5954 /* ??? Is it really right to send the signal just to this process
5955 rather than to the whole process group?
5956 Perhaps on systems with FIONREAD Emacs is alone in its group. */
284f4730 5957 kill (getpid (), SIGHUP);
58788063 5958 if (n_to_read == 0)
284f4730 5959 return 0;
58788063
RS
5960 if (n_to_read > sizeof cbuf)
5961 n_to_read = sizeof cbuf;
284f4730 5962#else /* no FIONREAD */
0c04a67e 5963#if defined (USG) || defined (DGUX)
284f4730 5964 /* Read some input if available, but don't wait. */
58788063 5965 n_to_read = sizeof cbuf;
437f6112 5966 fcntl (input_fd, F_SETFL, O_NDELAY);
284f4730
JB
5967#else
5968 you lose;
5969#endif
5970#endif
80e4aa30 5971#endif /* not MSDOS */
bc536d84 5972#endif /* not WINDOWSNT */
284f4730 5973
58788063
RS
5974 /* Now read; for one reason or another, this will not block.
5975 NREAD is set to the number of chars read. */
9134775b 5976 do
284f4730 5977 {
80e4aa30 5978#ifdef MSDOS
0c04a67e 5979 cbuf[0] = dos_keyread ();
80e4aa30
RS
5980 nread = 1;
5981#else
68c45bf0 5982 nread = emacs_read (input_fd, cbuf, n_to_read);
80e4aa30 5983#endif
49854566
RS
5984 /* POSIX infers that processes which are not in the session leader's
5985 process group won't get SIGHUP's at logout time. BSDI adheres to
e8886a1d 5986 this part standard and returns -1 from read (0) with errno==EIO
49854566
RS
5987 when the control tty is taken away.
5988 Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
5989 if (nread == -1 && errno == EIO)
5990 kill (0, SIGHUP);
762f2b92 5991#if defined (AIX) && (! defined (aix386) && defined (_BSD))
284f4730
JB
5992 /* The kernel sometimes fails to deliver SIGHUP for ptys.
5993 This looks incorrect, but it isn't, because _BSD causes
5994 O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
5995 and that causes a value other than 0 when there is no input. */
854f3a54 5996 if (nread == 0)
80e4aa30 5997 kill (0, SIGHUP);
284f4730 5998#endif
9134775b 5999 }
791587ee
KH
6000 while (
6001 /* We used to retry the read if it was interrupted.
6002 But this does the wrong thing when O_NDELAY causes
6003 an EAGAIN error. Does anybody know of a situation
6004 where a retry is actually needed? */
6005#if 0
6006 nread < 0 && (errno == EAGAIN
6aec06f5 6007#ifdef EFAULT
9134775b 6008 || errno == EFAULT
80e4aa30 6009#endif
284f4730 6010#ifdef EBADSLT
9134775b 6011 || errno == EBADSLT
284f4730 6012#endif
791587ee
KH
6013 )
6014#else
6015 0
6016#endif
6017 );
284f4730
JB
6018
6019#ifndef FIONREAD
02c2c53f 6020#if defined (USG) || defined (DGUX)
437f6112 6021 fcntl (input_fd, F_SETFL, 0);
02c2c53f 6022#endif /* USG or DGUX */
284f4730
JB
6023#endif /* no FIONREAD */
6024 for (i = 0; i < nread; i++)
6025 {
6026 buf[i].kind = ascii_keystroke;
86e5706b 6027 buf[i].modifiers = 0;
b04904fb 6028 if (meta_key == 1 && (cbuf[i] & 0x80))
86e5706b 6029 buf[i].modifiers = meta_modifier;
b04904fb
RS
6030 if (meta_key != 2)
6031 cbuf[i] &= ~0x80;
f3e59d5e
KH
6032
6033 buf[i].code = cbuf[i];
788f89eb 6034 buf[i].frame_or_window = selected_frame;
da8f7368 6035 buf[i].arg = Qnil;
284f4730
JB
6036 }
6037 }
6038
6039 /* Scan the chars for C-g and store them in kbd_buffer. */
6040 for (i = 0; i < nread; i++)
6041 {
6042 kbd_buffer_store_event (&buf[i]);
6043 /* Don't look at input that follows a C-g too closely.
6044 This reduces lossage due to autorepeat on C-g. */
6045 if (buf[i].kind == ascii_keystroke
9343ab07 6046 && buf[i].code == quit_char)
284f4730
JB
6047 break;
6048 }
6049
6050 return nread;
6051}
6052#endif /* not VMS */
6053\f
6054#ifdef SIGIO /* for entire page */
6055/* Note SIGIO has been undef'd if FIONREAD is missing. */
6056
2ce30ea2 6057SIGTYPE
284f4730
JB
6058input_available_signal (signo)
6059 int signo;
6060{
6061 /* Must preserve main program's value of errno. */
6062 int old_errno = errno;
6063#ifdef BSD4_1
6064 extern int select_alarmed;
6065#endif
6066
5970a8cb 6067#if defined (USG) && !defined (POSIX_SIGNALS)
284f4730
JB
6068 /* USG systems forget handlers when they are used;
6069 must reestablish each time */
6070 signal (signo, input_available_signal);
6071#endif /* USG */
6072
6073#ifdef BSD4_1
6074 sigisheld (SIGIO);
6075#endif
6076
ffd56f97
JB
6077 if (input_available_clear_time)
6078 EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
284f4730
JB
6079
6080 while (1)
6081 {
6082 int nread;
6083 nread = read_avail_input (1);
6084 /* -1 means it's not ok to read the input now.
6085 UNBLOCK_INPUT will read it later; now, avoid infinite loop.
6086 0 means there was no keyboard input available. */
6087 if (nread <= 0)
6088 break;
6089
6090#ifdef BSD4_1
6091 select_alarmed = 1; /* Force the select emulator back to life */
6092#endif
6093 }
6094
6095#ifdef BSD4_1
6096 sigfree ();
6097#endif
6098 errno = old_errno;
6099}
6100#endif /* SIGIO */
ad163903
JB
6101
6102/* Send ourselves a SIGIO.
6103
6104 This function exists so that the UNBLOCK_INPUT macro in
6105 blockinput.h can have some way to take care of input we put off
6106 dealing with, without assuming that every file which uses
6107 UNBLOCK_INPUT also has #included the files necessary to get SIGIO. */
6108void
6109reinvoke_input_signal ()
6110{
df0f2ba1 6111#ifdef SIGIO
87dd9b9b 6112 kill (getpid (), SIGIO);
ad163903
JB
6113#endif
6114}
6115
6116
284f4730
JB
6117\f
6118/* Return the prompt-string of a sparse keymap.
6119 This is the first element which is a string.
6120 Return nil if there is none. */
6121
6122Lisp_Object
6123map_prompt (map)
6124 Lisp_Object map;
6125{
6126 while (CONSP (map))
6127 {
6128 register Lisp_Object tem;
6129 tem = Fcar (map);
8c18cbfb 6130 if (STRINGP (tem))
284f4730
JB
6131 return tem;
6132 map = Fcdr (map);
6133 }
6134 return Qnil;
6135}
6136
b7c49376
RS
6137static void menu_bar_item ();
6138static void menu_bar_one_keymap ();
6139
6140/* These variables hold the vector under construction within
6141 menu_bar_items and its subroutines, and the current index
6142 for storing into that vector. */
6143static Lisp_Object menu_bar_items_vector;
9343ab07 6144static int menu_bar_items_index;
5ec75a55 6145
b7c49376
RS
6146/* Return a vector of menu items for a menu bar, appropriate
6147 to the current buffer. Each item has three elements in the vector:
f5e09c8b 6148 KEY STRING MAPLIST.
b7c49376
RS
6149
6150 OLD is an old vector we can optionally reuse, or nil. */
5ec75a55
RS
6151
6152Lisp_Object
b7c49376
RS
6153menu_bar_items (old)
6154 Lisp_Object old;
5ec75a55
RS
6155{
6156 /* The number of keymaps we're scanning right now, and the number of
6157 keymaps we have allocated space for. */
6158 int nmaps;
6159
6160 /* maps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1]
6161 in the current keymaps, or nil where it is not a prefix. */
6162 Lisp_Object *maps;
6163
9f9c0e27 6164 Lisp_Object def, tem, tail;
5ec75a55
RS
6165
6166 Lisp_Object result;
6167
6168 int mapno;
47d319aa 6169 Lisp_Object oquit;
5ec75a55 6170
b7c49376
RS
6171 int i;
6172
6173 struct gcpro gcpro1;
6174
db60d856
JB
6175 /* In order to build the menus, we need to call the keymap
6176 accessors. They all call QUIT. But this function is called
6177 during redisplay, during which a quit is fatal. So inhibit
47d319aa
RS
6178 quitting while building the menus.
6179 We do this instead of specbind because (1) errors will clear it anyway
6180 and (2) this avoids risk of specpdl overflow. */
6181 oquit = Vinhibit_quit;
df0f2ba1 6182 Vinhibit_quit = Qt;
db60d856 6183
b7c49376
RS
6184 if (!NILP (old))
6185 menu_bar_items_vector = old;
6186 else
6187 menu_bar_items_vector = Fmake_vector (make_number (24), Qnil);
6188 menu_bar_items_index = 0;
6189
6190 GCPRO1 (menu_bar_items_vector);
6191
5ec75a55
RS
6192 /* Build our list of keymaps.
6193 If we recognize a function key and replace its escape sequence in
6194 keybuf with its symbol, or if the sequence starts with a mouse
6195 click and we need to switch buffers, we jump back here to rebuild
6196 the initial keymaps from the current buffer. */
df0f2ba1 6197 {
5ec75a55
RS
6198 Lisp_Object *tmaps;
6199
217258d5 6200 /* Should overriding-terminal-local-map and overriding-local-map apply? */
d0a49716 6201 if (!NILP (Voverriding_local_map_menu_flag))
9dd3131c 6202 {
217258d5
KH
6203 /* Yes, use them (if non-nil) as well as the global map. */
6204 maps = (Lisp_Object *) alloca (3 * sizeof (maps[0]));
6205 nmaps = 0;
6206 if (!NILP (current_kboard->Voverriding_terminal_local_map))
6207 maps[nmaps++] = current_kboard->Voverriding_terminal_local_map;
6208 if (!NILP (Voverriding_local_map))
6209 maps[nmaps++] = Voverriding_local_map;
9dd3131c
RS
6210 }
6211 else
6212 {
30690496
DL
6213 /* No, so use major and minor mode keymaps and keymap property. */
6214 int extra_maps = 2;
6215 Lisp_Object map = get_local_map (PT, current_buffer, keymap);
6216 if (!NILP (map))
6217 extra_maps = 3;
217258d5 6218 nmaps = current_minor_maps (NULL, &tmaps);
30690496
DL
6219 maps = (Lisp_Object *) alloca ((nmaps + extra_maps)
6220 * sizeof (maps[0]));
217258d5 6221 bcopy (tmaps, maps, nmaps * sizeof (maps[0]));
30690496 6222 if (!NILP (map))
9f83cf0b 6223 maps[nmaps++] = map;
30690496 6224 maps[nmaps++] = get_local_map (PT, current_buffer, local_map);
9dd3131c 6225 }
217258d5 6226 maps[nmaps++] = current_global_map;
5ec75a55
RS
6227 }
6228
6229 /* Look up in each map the dummy prefix key `menu-bar'. */
6230
6231 result = Qnil;
6232
e58aa385 6233 for (mapno = nmaps - 1; mapno >= 0; mapno--)
5ec75a55
RS
6234 {
6235 if (! NILP (maps[mapno]))
c6a67acd 6236 def = get_keyelt (access_keymap (maps[mapno], Qmenu_bar, 1, 0), 0);
5ec75a55
RS
6237 else
6238 def = Qnil;
6239
6240 tem = Fkeymapp (def);
6241 if (!NILP (tem))
b7c49376 6242 menu_bar_one_keymap (def);
5ec75a55
RS
6243 }
6244
b7c49376
RS
6245 /* Move to the end those items that should be at the end. */
6246
7539e11f 6247 for (tail = Vmenu_bar_final_items; CONSP (tail); tail = XCDR (tail))
9f9c0e27 6248 {
b7c49376
RS
6249 int i;
6250 int end = menu_bar_items_index;
6251
35b3402f 6252 for (i = 0; i < end; i += 4)
7539e11f 6253 if (EQ (XCAR (tail), XVECTOR (menu_bar_items_vector)->contents[i]))
b7c49376 6254 {
35b3402f 6255 Lisp_Object tem0, tem1, tem2, tem3;
0301268e
RS
6256 /* Move the item at index I to the end,
6257 shifting all the others forward. */
6258 tem0 = XVECTOR (menu_bar_items_vector)->contents[i + 0];
6259 tem1 = XVECTOR (menu_bar_items_vector)->contents[i + 1];
6260 tem2 = XVECTOR (menu_bar_items_vector)->contents[i + 2];
35b3402f
RS
6261 tem3 = XVECTOR (menu_bar_items_vector)->contents[i + 3];
6262 if (end > i + 4)
6263 bcopy (&XVECTOR (menu_bar_items_vector)->contents[i + 4],
0301268e 6264 &XVECTOR (menu_bar_items_vector)->contents[i],
35b3402f
RS
6265 (end - i - 4) * sizeof (Lisp_Object));
6266 XVECTOR (menu_bar_items_vector)->contents[end - 4] = tem0;
6267 XVECTOR (menu_bar_items_vector)->contents[end - 3] = tem1;
6268 XVECTOR (menu_bar_items_vector)->contents[end - 2] = tem2;
6269 XVECTOR (menu_bar_items_vector)->contents[end - 1] = tem3;
0301268e 6270 break;
b7c49376
RS
6271 }
6272 }
9f9c0e27 6273
0c9071cd 6274 /* Add nil, nil, nil, nil at the end. */
b7c49376 6275 i = menu_bar_items_index;
35b3402f 6276 if (i + 4 > XVECTOR (menu_bar_items_vector)->size)
b7c49376
RS
6277 {
6278 Lisp_Object tem;
b7c49376
RS
6279 tem = Fmake_vector (make_number (2 * i), Qnil);
6280 bcopy (XVECTOR (menu_bar_items_vector)->contents,
6281 XVECTOR (tem)->contents, i * sizeof (Lisp_Object));
6282 menu_bar_items_vector = tem;
9f9c0e27 6283 }
b7c49376
RS
6284 /* Add this item. */
6285 XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil;
6286 XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil;
6287 XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil;
35b3402f 6288 XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil;
b7c49376 6289 menu_bar_items_index = i;
a73c5e29 6290
47d319aa 6291 Vinhibit_quit = oquit;
b7c49376
RS
6292 UNGCPRO;
6293 return menu_bar_items_vector;
5ec75a55
RS
6294}
6295\f
6296/* Scan one map KEYMAP, accumulating any menu items it defines
f5e09c8b 6297 in menu_bar_items_vector. */
5ec75a55 6298
759860a6
RS
6299static Lisp_Object menu_bar_one_keymap_changed_items;
6300
b7c49376
RS
6301static void
6302menu_bar_one_keymap (keymap)
6303 Lisp_Object keymap;
5ec75a55 6304{
03cee6ae 6305 Lisp_Object tail, item;
5ec75a55 6306
759860a6
RS
6307 menu_bar_one_keymap_changed_items = Qnil;
6308
5ec75a55 6309 /* Loop over all keymap entries that have menu strings. */
7539e11f 6310 for (tail = keymap; CONSP (tail); tail = XCDR (tail))
5ec75a55 6311 {
7539e11f 6312 item = XCAR (tail);
8c18cbfb 6313 if (CONSP (item))
7539e11f 6314 menu_bar_item (XCAR (item), XCDR (item));
8c18cbfb 6315 else if (VECTORP (item))
5ec75a55
RS
6316 {
6317 /* Loop over the char values represented in the vector. */
6318 int len = XVECTOR (item)->size;
6319 int c;
6320 for (c = 0; c < len; c++)
6321 {
6322 Lisp_Object character;
bb9e9bed 6323 XSETFASTINT (character, c);
e8886a1d 6324 menu_bar_item (character, XVECTOR (item)->contents[c]);
5ec75a55
RS
6325 }
6326 }
6327 }
5ec75a55
RS
6328}
6329
f5e09c8b
RS
6330/* Add one item to menu_bar_items_vector, for KEY, ITEM_STRING and DEF.
6331 If there's already an item for KEY, add this DEF to it. */
6332
e8886a1d
RS
6333Lisp_Object item_properties;
6334
b7c49376 6335static void
e8886a1d
RS
6336menu_bar_item (key, item)
6337 Lisp_Object key, item;
5ec75a55 6338{
e8886a1d 6339 struct gcpro gcpro1;
b7c49376 6340 int i;
759860a6 6341 Lisp_Object tem;
5ec75a55 6342
e8886a1d 6343 if (EQ (item, Qundefined))
e58aa385 6344 {
f5e09c8b 6345 /* If a map has an explicit `undefined' as definition,
e58aa385 6346 discard any previously made menu bar item. */
b7c49376 6347
35b3402f 6348 for (i = 0; i < menu_bar_items_index; i += 4)
b7c49376
RS
6349 if (EQ (key, XVECTOR (menu_bar_items_vector)->contents[i]))
6350 {
35b3402f
RS
6351 if (menu_bar_items_index > i + 4)
6352 bcopy (&XVECTOR (menu_bar_items_vector)->contents[i + 4],
b7c49376 6353 &XVECTOR (menu_bar_items_vector)->contents[i],
35b3402f
RS
6354 (menu_bar_items_index - i - 4) * sizeof (Lisp_Object));
6355 menu_bar_items_index -= 4;
b7c49376 6356 }
e58aa385
RS
6357 }
6358
759860a6
RS
6359 /* If this keymap has already contributed to this KEY,
6360 don't contribute to it a second time. */
6361 tem = Fmemq (key, menu_bar_one_keymap_changed_items);
9cd2ced7 6362 if (!NILP (tem) || NILP (item))
759860a6
RS
6363 return;
6364
6365 menu_bar_one_keymap_changed_items
6366 = Fcons (key, menu_bar_one_keymap_changed_items);
6367
9cd2ced7
SM
6368 /* We add to menu_bar_one_keymap_changed_items before doing the
6369 parse_menu_item, so that if it turns out it wasn't a menu item,
6370 it still correctly hides any further menu item. */
6371 GCPRO1 (key);
6372 i = parse_menu_item (item, 0, 1);
6373 UNGCPRO;
6374 if (!i)
6375 return;
6376
e8886a1d
RS
6377 item = XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF];
6378
f5e09c8b 6379 /* Find any existing item for this KEY. */
35b3402f 6380 for (i = 0; i < menu_bar_items_index; i += 4)
b7c49376
RS
6381 if (EQ (key, XVECTOR (menu_bar_items_vector)->contents[i]))
6382 break;
6383
f5e09c8b 6384 /* If we did not find this KEY, add it at the end. */
b7c49376
RS
6385 if (i == menu_bar_items_index)
6386 {
6387 /* If vector is too small, get a bigger one. */
35b3402f 6388 if (i + 4 > XVECTOR (menu_bar_items_vector)->size)
b7c49376
RS
6389 {
6390 Lisp_Object tem;
b7c49376
RS
6391 tem = Fmake_vector (make_number (2 * i), Qnil);
6392 bcopy (XVECTOR (menu_bar_items_vector)->contents,
6393 XVECTOR (tem)->contents, i * sizeof (Lisp_Object));
6394 menu_bar_items_vector = tem;
6395 }
e8886a1d 6396
b7c49376
RS
6397 /* Add this item. */
6398 XVECTOR (menu_bar_items_vector)->contents[i++] = key;
e8886a1d
RS
6399 XVECTOR (menu_bar_items_vector)->contents[i++]
6400 = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
6401 XVECTOR (menu_bar_items_vector)->contents[i++] = Fcons (item, Qnil);
35b3402f 6402 XVECTOR (menu_bar_items_vector)->contents[i++] = make_number (0);
b7c49376
RS
6403 menu_bar_items_index = i;
6404 }
e8886a1d 6405 /* We did find an item for this KEY. Add ITEM to its list of maps. */
f5e09c8b
RS
6406 else
6407 {
6408 Lisp_Object old;
6409 old = XVECTOR (menu_bar_items_vector)->contents[i + 2];
e8886a1d 6410 XVECTOR (menu_bar_items_vector)->contents[i + 2] = Fcons (item, old);
f5e09c8b 6411 }
5ec75a55
RS
6412}
6413\f
e8886a1d
RS
6414 /* This is used as the handler when calling menu_item_eval_property. */
6415static Lisp_Object
6416menu_item_eval_property_1 (arg)
6417 Lisp_Object arg;
6418{
6419 /* If we got a quit from within the menu computation,
6420 quit all the way out of it. This takes care of C-] in the debugger. */
7539e11f 6421 if (CONSP (arg) && EQ (XCAR (arg), Qquit))
e8886a1d
RS
6422 Fsignal (Qquit, Qnil);
6423
6424 return Qnil;
6425}
6426
6427/* Evaluate an expression and return the result (or nil if something
6428 went wrong). Used to evaluate dynamic parts of menu items. */
7ee32cda 6429Lisp_Object
e8886a1d
RS
6430menu_item_eval_property (sexpr)
6431 Lisp_Object sexpr;
6432{
44e553a3 6433 int count = specpdl_ptr - specpdl;
e8886a1d 6434 Lisp_Object val;
44e553a3 6435 specbind (Qinhibit_redisplay, Qt);
e8886a1d
RS
6436 val = internal_condition_case_1 (Feval, sexpr, Qerror,
6437 menu_item_eval_property_1);
44e553a3 6438 return unbind_to (count, val);
e8886a1d
RS
6439}
6440
6441/* This function parses a menu item and leaves the result in the
6442 vector item_properties.
6443 ITEM is a key binding, a possible menu item.
6444 If NOTREAL is nonzero, only check for equivalent key bindings, don't
6445 evaluate dynamic expressions in the menu item.
fd3613d7 6446 INMENUBAR is > 0 when this is considered for an entry in a menu bar
e8886a1d 6447 top level.
fd3613d7 6448 INMENUBAR is < 0 when this is considered for an entry in a keyboard menu.
e8886a1d
RS
6449 parse_menu_item returns true if the item is a menu item and false
6450 otherwise. */
6451
6452int
6453parse_menu_item (item, notreal, inmenubar)
6454 Lisp_Object item;
6455 int notreal, inmenubar;
6456{
adc1d5c8 6457 Lisp_Object def, tem, item_string, start;
07ba902e
RS
6458 Lisp_Object cachelist;
6459 Lisp_Object filter;
6460 Lisp_Object keyhint;
e8886a1d 6461 int i;
74c1de23
RS
6462 int newcache = 0;
6463
07ba902e
RS
6464 cachelist = Qnil;
6465 filter = Qnil;
6466 keyhint = Qnil;
6467
e8886a1d
RS
6468 if (!CONSP (item))
6469 return 0;
6470
e8886a1d
RS
6471 /* Create item_properties vector if necessary. */
6472 if (NILP (item_properties))
6473 item_properties
6474 = Fmake_vector (make_number (ITEM_PROPERTY_ENABLE + 1), Qnil);
6475
6476 /* Initialize optional entries. */
6477 for (i = ITEM_PROPERTY_DEF; i < ITEM_PROPERTY_ENABLE; i++)
6478 XVECTOR (item_properties)->contents[i] = Qnil;
6479 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE] = Qt;
6480
6481 /* Save the item here to protect it from GC. */
6482 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ITEM] = item;
6483
7539e11f 6484 item_string = XCAR (item);
e8886a1d
RS
6485
6486 start = item;
7539e11f 6487 item = XCDR (item);
e8886a1d
RS
6488 if (STRINGP (item_string))
6489 {
6490 /* Old format menu item. */
6491 XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME] = item_string;
6492
6493 /* Maybe help string. */
7539e11f 6494 if (CONSP (item) && STRINGP (XCAR (item)))
e8886a1d
RS
6495 {
6496 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]
7539e11f 6497 = XCAR (item);
e8886a1d 6498 start = item;
7539e11f 6499 item = XCDR (item);
e8886a1d
RS
6500 }
6501
31f84d03 6502 /* Maybe key binding cache. */
7539e11f
KR
6503 if (CONSP (item) && CONSP (XCAR (item))
6504 && (NILP (XCAR (XCAR (item)))
6505 || VECTORP (XCAR (XCAR (item)))))
e8886a1d 6506 {
7539e11f
KR
6507 cachelist = XCAR (item);
6508 item = XCDR (item);
e8886a1d
RS
6509 }
6510
6511 /* This is the real definition--the function to run. */
6512 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF] = item;
6513
6514 /* Get enable property, if any. */
6515 if (SYMBOLP (item))
6516 {
6517 tem = Fget (item, Qmenu_enable);
6518 if (!NILP (tem))
6519 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE] = tem;
6520 }
6521 }
6522 else if (EQ (item_string, Qmenu_item) && CONSP (item))
6523 {
6524 /* New format menu item. */
6525 XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME]
7539e11f
KR
6526 = XCAR (item);
6527 start = XCDR (item);
e8886a1d
RS
6528 if (CONSP (start))
6529 {
6530 /* We have a real binding. */
6531 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF]
7539e11f 6532 = XCAR (start);
e8886a1d 6533
7539e11f 6534 item = XCDR (start);
e8886a1d 6535 /* Is there a cache list with key equivalences. */
7539e11f 6536 if (CONSP (item) && CONSP (XCAR (item)))
e8886a1d 6537 {
7539e11f
KR
6538 cachelist = XCAR (item);
6539 item = XCDR (item);
e8886a1d
RS
6540 }
6541
6542 /* Parse properties. */
7539e11f 6543 while (CONSP (item) && CONSP (XCDR (item)))
e8886a1d 6544 {
7539e11f
KR
6545 tem = XCAR (item);
6546 item = XCDR (item);
e8886a1d
RS
6547
6548 if (EQ (tem, QCenable))
6549 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE]
7539e11f 6550 = XCAR (item);
e8886a1d
RS
6551 else if (EQ (tem, QCvisible) && !notreal)
6552 {
6553 /* If got a visible property and that evaluates to nil
6554 then ignore this item. */
7539e11f 6555 tem = menu_item_eval_property (XCAR (item));
e8886a1d 6556 if (NILP (tem))
adc1d5c8 6557 return 0;
e8886a1d
RS
6558 }
6559 else if (EQ (tem, QChelp))
6560 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]
7539e11f 6561 = XCAR (item);
e8886a1d 6562 else if (EQ (tem, QCfilter))
74c1de23
RS
6563 filter = item;
6564 else if (EQ (tem, QCkey_sequence))
6565 {
7539e11f 6566 tem = XCAR (item);
74c1de23
RS
6567 if (NILP (cachelist)
6568 && (SYMBOLP (tem) || STRINGP (tem) || VECTORP (tem)))
6569 /* Be GC protected. Set keyhint to item instead of tem. */
6570 keyhint = item;
6571 }
6572 else if (EQ (tem, QCkeys))
6573 {
7539e11f 6574 tem = XCAR (item);
03cee6ae 6575 if (CONSP (tem) || (STRINGP (tem) && NILP (cachelist)))
74c1de23
RS
6576 XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ]
6577 = tem;
6578 }
7539e11f 6579 else if (EQ (tem, QCbutton) && CONSP (XCAR (item)))
e8886a1d 6580 {
74c1de23 6581 Lisp_Object type;
7539e11f
KR
6582 tem = XCAR (item);
6583 type = XCAR (tem);
e8886a1d
RS
6584 if (EQ (type, QCtoggle) || EQ (type, QCradio))
6585 {
6586 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED]
7539e11f 6587 = XCDR (tem);
e8886a1d
RS
6588 XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE]
6589 = type;
6590 }
6591 }
7539e11f 6592 item = XCDR (item);
e8886a1d
RS
6593 }
6594 }
6595 else if (inmenubar || !NILP (start))
adc1d5c8 6596 return 0;
e8886a1d
RS
6597 }
6598 else
adc1d5c8 6599 return 0; /* not a menu item */
e8886a1d
RS
6600
6601 /* If item string is not a string, evaluate it to get string.
6602 If we don't get a string, skip this item. */
6603 item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
6604 if (!(STRINGP (item_string) || notreal))
6605 {
6606 item_string = menu_item_eval_property (item_string);
6607 if (!STRINGP (item_string))
adc1d5c8 6608 return 0;
e8886a1d
RS
6609 XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME] = item_string;
6610 }
6611
6612 /* If got a filter apply it on definition. */
6613 def = XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF];
6614 if (!NILP (filter))
6615 {
7539e11f 6616 def = menu_item_eval_property (list2 (XCAR (filter),
c5c5a6f8
RS
6617 list2 (Qquote, def)));
6618
e8886a1d
RS
6619 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF] = def;
6620 }
6621
6622 /* If we got no definition, this item is just unselectable text which
74c1de23 6623 is OK in a submenu but not in the menubar. */
e8886a1d 6624 if (NILP (def))
adc1d5c8 6625 return (inmenubar ? 0 : 1);
e8886a1d
RS
6626
6627 /* Enable or disable selection of item. */
6628 tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE];
6629 if (!EQ (tem, Qt))
6630 {
6631 if (notreal)
6632 tem = Qt;
6633 else
6634 tem = menu_item_eval_property (tem);
6635 if (inmenubar && NILP (tem))
adc1d5c8 6636 return 0; /* Ignore disabled items in menu bar. */
e8886a1d
RS
6637 XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE] = tem;
6638 }
6639
6640 /* See if this is a separate pane or a submenu. */
74c1de23 6641 def = XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF];
e8886a1d 6642 tem = get_keymap_1 (def, 0, 1);
9ac425d1 6643 /* For a subkeymap, just record its details and exit. */
e8886a1d
RS
6644 if (!NILP (tem))
6645 {
6646 XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP] = tem;
6647 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF] = tem;
e8886a1d
RS
6648 return 1;
6649 }
9ac425d1
RS
6650 /* At the top level in the menu bar, do likewise for commands also.
6651 The menu bar does not display equivalent key bindings anyway.
6652 ITEM_PROPERTY_DEF is already set up properly. */
6653 if (inmenubar > 0)
6654 return 1;
e8886a1d
RS
6655
6656 /* This is a command. See if there is an equivalent key binding. */
6657 if (NILP (cachelist))
6658 {
74c1de23 6659 /* We have to create a cachelist. */
e8886a1d 6660 CHECK_IMPURE (start);
7539e11f
KR
6661 XCDR (start) = Fcons (Fcons (Qnil, Qnil), XCDR (start));
6662 cachelist = XCAR (XCDR (start));
74c1de23
RS
6663 newcache = 1;
6664 tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ];
6665 if (!NILP (keyhint))
6666 {
7539e11f 6667 XCAR (cachelist) = XCAR (keyhint);
74c1de23
RS
6668 newcache = 0;
6669 }
6670 else if (STRINGP (tem))
6671 {
7539e11f
KR
6672 XCDR (cachelist) = Fsubstitute_command_keys (tem);
6673 XCAR (cachelist) = Qt;
74c1de23
RS
6674 }
6675 }
7539e11f 6676 tem = XCAR (cachelist);
74c1de23
RS
6677 if (!EQ (tem, Qt))
6678 {
6679 int chkcache = 0;
6680 Lisp_Object prefix;
6681
6682 if (!NILP (tem))
6683 tem = Fkey_binding (tem, Qnil);
6684
6685 prefix = XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ];
6686 if (CONSP (prefix))
6687 {
7539e11f
KR
6688 def = XCAR (prefix);
6689 prefix = XCDR (prefix);
74c1de23 6690 }
e8886a1d 6691 else
74c1de23
RS
6692 def = XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF];
6693
7539e11f 6694 if (NILP (XCAR (cachelist))) /* Have no saved key. */
74c1de23
RS
6695 {
6696 if (newcache /* Always check first time. */
6697 /* Should we check everything when precomputing key
6698 bindings? */
6699 /* || notreal */
6700 /* If something had no key binding before, don't recheck it
6701 because that is too slow--except if we have a list of
6702 rebound commands in Vdefine_key_rebound_commands, do
6703 recheck any command that appears in that list. */
6704 || (CONSP (Vdefine_key_rebound_commands)
6705 && !NILP (Fmemq (def, Vdefine_key_rebound_commands))))
6706 chkcache = 1;
6707 }
6708 /* We had a saved key. Is it still bound to the command? */
6709 else if (NILP (tem)
03cee6ae
GM
6710 || (!EQ (tem, def)
6711 /* If the command is an alias for another
6712 (such as lmenu.el set it up), check if the
6713 original command matches the cached command. */
6714 && !(SYMBOLP (def) && EQ (tem, XSYMBOL (def)->function))))
74c1de23
RS
6715 chkcache = 1; /* Need to recompute key binding. */
6716
6717 if (chkcache)
6718 {
6719 /* Recompute equivalent key binding. If the command is an alias
6720 for another (such as lmenu.el set it up), see if the original
6721 command name has equivalent keys. Otherwise look up the
6722 specified command itself. We don't try both, because that
6723 makes lmenu menus slow. */
6724 if (SYMBOLP (def) && SYMBOLP (XSYMBOL (def)->function)
6725 && ! NILP (Fget (def, Qmenu_alias)))
6726 def = XSYMBOL (def)->function;
6727 tem = Fwhere_is_internal (def, Qnil, Qt, Qnil);
7539e11f 6728 XCAR (cachelist) = tem;
74c1de23
RS
6729 if (NILP (tem))
6730 {
7539e11f 6731 XCDR (cachelist) = Qnil;
74c1de23
RS
6732 chkcache = 0;
6733 }
6734 }
7539e11f 6735 else if (!NILP (keyhint) && !NILP (XCAR (cachelist)))
74c1de23 6736 {
7539e11f 6737 tem = XCAR (cachelist);
74c1de23
RS
6738 chkcache = 1;
6739 }
6740
6741 newcache = chkcache;
6742 if (chkcache)
6743 {
6744 tem = Fkey_description (tem);
6745 if (CONSP (prefix))
6746 {
7539e11f
KR
6747 if (STRINGP (XCAR (prefix)))
6748 tem = concat2 (XCAR (prefix), tem);
6749 if (STRINGP (XCDR (prefix)))
6750 tem = concat2 (tem, XCDR (prefix));
74c1de23 6751 }
7539e11f 6752 XCDR (cachelist) = tem;
74c1de23
RS
6753 }
6754 }
6755
7539e11f 6756 tem = XCDR (cachelist);
74c1de23 6757 if (newcache && !NILP (tem))
e8886a1d 6758 {
74c1de23 6759 tem = concat3 (build_string (" ("), tem, build_string (")"));
7539e11f 6760 XCDR (cachelist) = tem;
e8886a1d
RS
6761 }
6762
6763 /* If we only want to precompute equivalent key bindings, stop here. */
6764 if (notreal)
adc1d5c8 6765 return 1;
e8886a1d
RS
6766
6767 /* If we have an equivalent key binding, use that. */
adc1d5c8
RS
6768 XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ] = tem;
6769
6770 /* Include this when menu help is implemented.
6771 tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP];
6772 if (!(NILP (tem) || STRINGP (tem)))
6773 {
6774 tem = menu_item_eval_property (tem);
6775 if (!STRINGP (tem))
6776 tem = Qnil;
6777 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP] = tem;
6778 }
e8886a1d
RS
6779 */
6780
6781 /* Handle radio buttons or toggle boxes. */
6782 tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED];
6783 if (!NILP (tem))
6784 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED]
6785 = menu_item_eval_property (tem);
6786
e8886a1d
RS
6787 return 1;
6788}
7ee32cda
GM
6789
6790
6791\f
6792/***********************************************************************
6793 Tool-bars
6794 ***********************************************************************/
6795
9ea173e8
GM
6796/* A vector holding tool bar items while they are parsed in function
6797 tool_bar_items runs Each item occupies TOOL_BAR_ITEM_NSCLOTS elements
6798 in the vector. */
7ee32cda 6799
9ea173e8 6800static Lisp_Object tool_bar_items_vector;
7ee32cda 6801
9ea173e8
GM
6802/* A vector holding the result of parse_tool_bar_item. Layout is like
6803 the one for a single item in tool_bar_items_vector. */
7ee32cda 6804
9ea173e8 6805static Lisp_Object tool_bar_item_properties;
7ee32cda 6806
9ea173e8 6807/* Next free index in tool_bar_items_vector. */
7ee32cda 6808
9ea173e8 6809static int ntool_bar_items;
7ee32cda 6810
9ea173e8 6811/* The symbols `tool-bar', and `:image'. */
7ee32cda 6812
9ea173e8 6813extern Lisp_Object Qtool_bar;
7ee32cda
GM
6814Lisp_Object QCimage;
6815
6816/* Function prototypes. */
6817
9ea173e8
GM
6818static void init_tool_bar_items P_ ((Lisp_Object));
6819static void process_tool_bar_item P_ ((Lisp_Object, Lisp_Object));
6820static int parse_tool_bar_item P_ ((Lisp_Object, Lisp_Object));
6821static void append_tool_bar_item P_ ((void));
7ee32cda
GM
6822
6823
9ea173e8 6824/* Return a vector of tool bar items for keymaps currently in effect.
7ee32cda 6825 Reuse vector REUSE if non-nil. Return in *NITEMS the number of
9ea173e8 6826 tool bar items found. */
7ee32cda
GM
6827
6828Lisp_Object
9ea173e8 6829tool_bar_items (reuse, nitems)
7ee32cda
GM
6830 Lisp_Object reuse;
6831 int *nitems;
6832{
6833 Lisp_Object *maps;
6834 int nmaps, i;
6835 Lisp_Object oquit;
6836 Lisp_Object *tmaps;
6837 extern Lisp_Object Voverriding_local_map_menu_flag;
6838 extern Lisp_Object Voverriding_local_map;
6839
6840 *nitems = 0;
6841
6842 /* In order to build the menus, we need to call the keymap
6843 accessors. They all call QUIT. But this function is called
6844 during redisplay, during which a quit is fatal. So inhibit
6845 quitting while building the menus. We do this instead of
6846 specbind because (1) errors will clear it anyway and (2) this
6847 avoids risk of specpdl overflow. */
6848 oquit = Vinhibit_quit;
6849 Vinhibit_quit = Qt;
6850
9ea173e8
GM
6851 /* Initialize tool_bar_items_vector and protect it from GC. */
6852 init_tool_bar_items (reuse);
7ee32cda
GM
6853
6854 /* Build list of keymaps in maps. Set nmaps to the number of maps
6855 to process. */
6856
6857 /* Should overriding-terminal-local-map and overriding-local-map apply? */
6858 if (!NILP (Voverriding_local_map_menu_flag))
6859 {
6860 /* Yes, use them (if non-nil) as well as the global map. */
6861 maps = (Lisp_Object *) alloca (3 * sizeof (maps[0]));
6862 nmaps = 0;
6863 if (!NILP (current_kboard->Voverriding_terminal_local_map))
6864 maps[nmaps++] = current_kboard->Voverriding_terminal_local_map;
6865 if (!NILP (Voverriding_local_map))
6866 maps[nmaps++] = Voverriding_local_map;
6867 }
6868 else
6869 {
30690496
DL
6870 /* No, so use major and minor mode keymaps and keymap property. */
6871 int extra_maps = 2;
6872 Lisp_Object map = get_local_map (PT, current_buffer, keymap);
6873 if (!NILP (map))
6874 extra_maps = 3;
7ee32cda 6875 nmaps = current_minor_maps (NULL, &tmaps);
30690496
DL
6876 maps = (Lisp_Object *) alloca ((nmaps + extra_maps)
6877 * sizeof (maps[0]));
7ee32cda 6878 bcopy (tmaps, maps, nmaps * sizeof (maps[0]));
30690496 6879 if (!NILP (map))
9f83cf0b 6880 maps[nmaps++] = map;
30690496 6881 maps[nmaps++] = get_local_map (PT, current_buffer, local_map);
7ee32cda
GM
6882 }
6883
6884 /* Add global keymap at the end. */
6885 maps[nmaps++] = current_global_map;
6886
6887 /* Process maps in reverse order and look up in each map the prefix
9ea173e8 6888 key `tool-bar'. */
7ee32cda
GM
6889 for (i = nmaps - 1; i >= 0; --i)
6890 if (!NILP (maps[i]))
6891 {
6892 Lisp_Object keymap;
6893
9ea173e8 6894 keymap = get_keyelt (access_keymap (maps[i], Qtool_bar, 1, 1), 0);
7ee32cda
GM
6895 if (!NILP (Fkeymapp (keymap)))
6896 {
6897 Lisp_Object tail;
6898
6899 /* KEYMAP is a list `(keymap (KEY . BINDING) ...)'. */
7539e11f 6900 for (tail = keymap; CONSP (tail); tail = XCDR (tail))
7ee32cda
GM
6901 {
6902 Lisp_Object keydef = XCAR (tail);
6903 if (CONSP (keydef))
9ea173e8 6904 process_tool_bar_item (XCAR (keydef), XCDR (keydef));
7ee32cda
GM
6905 }
6906 }
6907 }
6908
6909 Vinhibit_quit = oquit;
9ea173e8
GM
6910 *nitems = ntool_bar_items / TOOL_BAR_ITEM_NSLOTS;
6911 return tool_bar_items_vector;
7ee32cda
GM
6912}
6913
6914
6915/* Process the definition of KEY which is DEF. */
6916
6917static void
9ea173e8 6918process_tool_bar_item (key, def)
7ee32cda
GM
6919 Lisp_Object key, def;
6920{
6921 int i;
6922 extern Lisp_Object Qundefined;
6923 struct gcpro gcpro1, gcpro2;
6924
9ea173e8 6925 /* Protect KEY and DEF from GC because parse_tool_bar_item may call
7ee32cda
GM
6926 eval. */
6927 GCPRO2 (key, def);
6928
6929 if (EQ (def, Qundefined))
6930 {
6931 /* If a map has an explicit `undefined' as definition,
6932 discard any previously made item. */
9ea173e8 6933 for (i = 0; i < ntool_bar_items; i += TOOL_BAR_ITEM_NSLOTS)
7ee32cda 6934 {
9ea173e8 6935 Lisp_Object *v = XVECTOR (tool_bar_items_vector)->contents + i;
7ee32cda 6936
9ea173e8 6937 if (EQ (key, v[TOOL_BAR_ITEM_KEY]))
7ee32cda 6938 {
9ea173e8
GM
6939 if (ntool_bar_items > i + TOOL_BAR_ITEM_NSLOTS)
6940 bcopy (v + TOOL_BAR_ITEM_NSLOTS, v,
6941 ((ntool_bar_items - i - TOOL_BAR_ITEM_NSLOTS)
7ee32cda 6942 * sizeof (Lisp_Object)));
9ea173e8 6943 ntool_bar_items -= TOOL_BAR_ITEM_NSLOTS;
7ee32cda
GM
6944 break;
6945 }
6946 }
6947 }
9ea173e8
GM
6948 else if (parse_tool_bar_item (key, def))
6949 /* Append a new tool bar item to tool_bar_items_vector. Accept
7ee32cda 6950 more than one definition for the same key. */
9ea173e8 6951 append_tool_bar_item ();
7ee32cda
GM
6952
6953 UNGCPRO;
6954}
6955
6956
9ea173e8
GM
6957/* Parse a tool bar item specification ITEM for key KEY and return the
6958 result in tool_bar_item_properties. Value is zero if ITEM is
7ee32cda
GM
6959 invalid.
6960
6961 ITEM is a list `(menu-item CAPTION BINDING PROPS...)'.
6962
6963 CAPTION is the caption of the item, If it's not a string, it is
6964 evaluated to get a string.
6965
9ea173e8 6966 BINDING is the tool bar item's binding. Tool-bar items with keymaps
7ee32cda
GM
6967 as binding are currently ignored.
6968
6969 The following properties are recognized:
6970
6971 - `:enable FORM'.
6972
9ea173e8
GM
6973 FORM is evaluated and specifies whether the tool bar item is
6974 enabled or disabled.
7ee32cda
GM
6975
6976 - `:visible FORM'
6977
9ea173e8 6978 FORM is evaluated and specifies whether the tool bar item is visible.
7ee32cda
GM
6979
6980 - `:filter FUNCTION'
6981
6982 FUNCTION is invoked with one parameter `(quote BINDING)'. Its
6983 result is stored as the new binding.
6984
6985 - `:button (TYPE SELECTED)'
6986
6987 TYPE must be one of `:radio' or `:toggle'. SELECTED is evaluated
6988 and specifies whether the button is selected (pressed) or not.
6989
6990 - `:image IMAGES'
6991
6992 IMAGES is either a single image specification or a vector of four
9ea173e8 6993 image specifications. See enum tool_bar_item_images.
7ee32cda
GM
6994
6995 - `:help HELP-STRING'.
6996
9ea173e8 6997 Gives a help string to display for the tool bar item. */
7ee32cda
GM
6998
6999static int
9ea173e8 7000parse_tool_bar_item (key, item)
7ee32cda
GM
7001 Lisp_Object key, item;
7002{
9ea173e8
GM
7003 /* Access slot with index IDX of vector tool_bar_item_properties. */
7004#define PROP(IDX) XVECTOR (tool_bar_item_properties)->contents[IDX]
7ee32cda
GM
7005
7006 Lisp_Object filter = Qnil;
7007 Lisp_Object caption;
7008 extern Lisp_Object QCenable, QCvisible, QChelp, QCfilter;
7009 extern Lisp_Object QCbutton, QCtoggle, QCradio;
7010 int i;
7ee32cda 7011
8c907a56
GM
7012 /* Defininition looks like `(menu-item CAPTION BINDING PROPS...)'.
7013 Rule out items that aren't lists, don't start with
7014 `menu-item' or whose rest following `tool-bar-item' is not a
7ee32cda
GM
7015 list. */
7016 if (!CONSP (item)
7017 || !EQ (XCAR (item), Qmenu_item)
7018 || (item = XCDR (item),
7019 !CONSP (item)))
7020 return 0;
7021
9ea173e8 7022 /* Create tool_bar_item_properties vector if necessary. Reset it to
7ee32cda 7023 defaults. */
9ea173e8 7024 if (VECTORP (tool_bar_item_properties))
7ee32cda 7025 {
9ea173e8 7026 for (i = 0; i < TOOL_BAR_ITEM_NSLOTS; ++i)
7ee32cda
GM
7027 PROP (i) = Qnil;
7028 }
7029 else
9ea173e8
GM
7030 tool_bar_item_properties
7031 = Fmake_vector (make_number (TOOL_BAR_ITEM_NSLOTS), Qnil);
7ee32cda
GM
7032
7033 /* Set defaults. */
9ea173e8
GM
7034 PROP (TOOL_BAR_ITEM_KEY) = key;
7035 PROP (TOOL_BAR_ITEM_ENABLED_P) = Qt;
7ee32cda
GM
7036
7037 /* Get the caption of the item. If the caption is not a string,
7038 evaluate it to get a string. If we don't get a string, skip this
7039 item. */
7040 caption = XCAR (item);
7041 if (!STRINGP (caption))
7042 {
7043 caption = menu_item_eval_property (caption);
7044 if (!STRINGP (caption))
7045 return 0;
7046 }
9ea173e8 7047 PROP (TOOL_BAR_ITEM_CAPTION) = caption;
7ee32cda
GM
7048
7049 /* Give up if rest following the caption is not a list. */
7050 item = XCDR (item);
7051 if (!CONSP (item))
7052 return 0;
7053
7054 /* Store the binding. */
9ea173e8 7055 PROP (TOOL_BAR_ITEM_BINDING) = XCAR (item);
7ee32cda
GM
7056 item = XCDR (item);
7057
8c907a56
GM
7058 /* Ignore cached key binding, if any. */
7059 if (CONSP (item) && CONSP (XCAR (item)))
7060 item = XCDR (item);
7061
7ee32cda
GM
7062 /* Process the rest of the properties. */
7063 for (; CONSP (item) && CONSP (XCDR (item)); item = XCDR (XCDR (item)))
7064 {
7065 Lisp_Object key, value;
7066
7067 key = XCAR (item);
7068 value = XCAR (XCDR (item));
7069
7070 if (EQ (key, QCenable))
7071 /* `:enable FORM'. */
9ea173e8 7072 PROP (TOOL_BAR_ITEM_ENABLED_P) = value;
7ee32cda
GM
7073 else if (EQ (key, QCvisible))
7074 {
7075 /* `:visible FORM'. If got a visible property and that
7076 evaluates to nil then ignore this item. */
7077 if (NILP (menu_item_eval_property (value)))
7078 return 0;
7079 }
7080 else if (EQ (key, QChelp))
7081 /* `:help HELP-STRING'. */
9ea173e8 7082 PROP (TOOL_BAR_ITEM_HELP) = value;
7ee32cda
GM
7083 else if (EQ (key, QCfilter))
7084 /* ':filter FORM'. */
7085 filter = value;
7086 else if (EQ (key, QCbutton) && CONSP (value))
7087 {
7088 /* `:button (TYPE . SELECTED)'. */
7089 Lisp_Object type, selected;
7090
7091 type = XCAR (value);
7092 selected = XCDR (value);
7093 if (EQ (type, QCtoggle) || EQ (type, QCradio))
7094 {
9ea173e8
GM
7095 PROP (TOOL_BAR_ITEM_SELECTED_P) = selected;
7096 PROP (TOOL_BAR_ITEM_TYPE) = type;
7ee32cda
GM
7097 }
7098 }
7099 else if (EQ (key, QCimage)
7100 && (CONSP (value)
7101 || (VECTORP (value) && XVECTOR (value)->size == 4)))
7102 /* Value is either a single image specification or a vector
7103 of 4 such specifications for the different buttion states. */
9ea173e8 7104 PROP (TOOL_BAR_ITEM_IMAGES) = value;
7ee32cda
GM
7105 }
7106
7107 /* If got a filter apply it on binding. */
7108 if (!NILP (filter))
9ea173e8 7109 PROP (TOOL_BAR_ITEM_BINDING)
7ee32cda
GM
7110 = menu_item_eval_property (list2 (filter,
7111 list2 (Qquote,
9ea173e8 7112 PROP (TOOL_BAR_ITEM_BINDING))));
7ee32cda
GM
7113
7114 /* See if the binding is a keymap. Give up if it is. */
9ea173e8 7115 if (!NILP (get_keymap_1 (PROP (TOOL_BAR_ITEM_BINDING), 0, 1)))
7ee32cda
GM
7116 return 0;
7117
7118 /* Enable or disable selection of item. */
9ea173e8
GM
7119 if (!EQ (PROP (TOOL_BAR_ITEM_ENABLED_P), Qt))
7120 PROP (TOOL_BAR_ITEM_ENABLED_P)
7121 = menu_item_eval_property (PROP (TOOL_BAR_ITEM_ENABLED_P));
7ee32cda
GM
7122
7123 /* Handle radio buttons or toggle boxes. */
9ea173e8
GM
7124 if (!NILP (PROP (TOOL_BAR_ITEM_SELECTED_P)))
7125 PROP (TOOL_BAR_ITEM_SELECTED_P)
7126 = menu_item_eval_property (PROP (TOOL_BAR_ITEM_SELECTED_P));
7ee32cda
GM
7127
7128 return 1;
7129
7130#undef PROP
7131}
7132
7133
9ea173e8
GM
7134/* Initialize tool_bar_items_vector. REUSE, if non-nil, is a vector
7135 that can be reused. */
7ee32cda
GM
7136
7137static void
9ea173e8 7138init_tool_bar_items (reuse)
7ee32cda
GM
7139 Lisp_Object reuse;
7140{
7141 if (VECTORP (reuse))
9ea173e8 7142 tool_bar_items_vector = reuse;
7ee32cda 7143 else
9ea173e8
GM
7144 tool_bar_items_vector = Fmake_vector (make_number (64), Qnil);
7145 ntool_bar_items = 0;
7ee32cda
GM
7146}
7147
7148
9ea173e8
GM
7149/* Append parsed tool bar item properties from
7150 tool_bar_item_properties */
7ee32cda
GM
7151
7152static void
9ea173e8 7153append_tool_bar_item ()
7ee32cda
GM
7154{
7155 Lisp_Object *to, *from;
7156
9ea173e8
GM
7157 /* Enlarge tool_bar_items_vector if necessary. */
7158 if (ntool_bar_items + TOOL_BAR_ITEM_NSLOTS
7159 >= XVECTOR (tool_bar_items_vector)->size)
7ee32cda
GM
7160 {
7161 Lisp_Object new_vector;
9ea173e8 7162 int old_size = XVECTOR (tool_bar_items_vector)->size;
7ee32cda
GM
7163
7164 new_vector = Fmake_vector (make_number (2 * old_size), Qnil);
9ea173e8 7165 bcopy (XVECTOR (tool_bar_items_vector)->contents,
7ee32cda
GM
7166 XVECTOR (new_vector)->contents,
7167 old_size * sizeof (Lisp_Object));
9ea173e8 7168 tool_bar_items_vector = new_vector;
7ee32cda
GM
7169 }
7170
9ea173e8
GM
7171 /* Append entries from tool_bar_item_properties to the end of
7172 tool_bar_items_vector. */
7173 to = XVECTOR (tool_bar_items_vector)->contents + ntool_bar_items;
7174 from = XVECTOR (tool_bar_item_properties)->contents;
7175 bcopy (from, to, TOOL_BAR_ITEM_NSLOTS * sizeof *to);
7176 ntool_bar_items += TOOL_BAR_ITEM_NSLOTS;
7ee32cda
GM
7177}
7178
7179
7180
7181
e8886a1d 7182\f
dcc408a0
RS
7183/* Read a character using menus based on maps in the array MAPS.
7184 NMAPS is the length of MAPS. Return nil if there are no menus in the maps.
7185 Return t if we displayed a menu but the user rejected it.
7d6de002
RS
7186
7187 PREV_EVENT is the previous input event, or nil if we are reading
7188 the first event of a key sequence.
7189
83d68044 7190 If USED_MOUSE_MENU is non-null, then we set *USED_MOUSE_MENU to 1
6569cc8d 7191 if we used a mouse menu to read the input, or zero otherwise. If
83d68044 7192 USED_MOUSE_MENU is null, we don't dereference it.
284f4730
JB
7193
7194 The prompting is done based on the prompt-string of the map
df0f2ba1 7195 and the strings associated with various map elements.
8150596a
RS
7196
7197 This can be done with X menus or with menus put in the minibuf.
7198 These are done in different ways, depending on how the input will be read.
7199 Menus using X are done after auto-saving in read-char, getting the input
7200 event from Fx_popup_menu; menus using the minibuf use read_char recursively
7201 and do auto-saving in the inner call of read_char. */
284f4730 7202
7617111f 7203static Lisp_Object
8150596a 7204read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu)
7d6de002
RS
7205 int nmaps;
7206 Lisp_Object *maps;
7207 Lisp_Object prev_event;
7208 int *used_mouse_menu;
284f4730 7209{
7d6de002
RS
7210 int mapno;
7211 register Lisp_Object name;
7d6de002 7212
6569cc8d
JB
7213 if (used_mouse_menu)
7214 *used_mouse_menu = 0;
284f4730
JB
7215
7216 /* Use local over global Menu maps */
7217
7d6de002
RS
7218 if (! menu_prompting)
7219 return Qnil;
7220
03361bcc
RS
7221 /* Optionally disregard all but the global map. */
7222 if (inhibit_local_menu_bar_menus)
7223 {
7224 maps += (nmaps - 1);
7225 nmaps = 1;
7226 }
7227
7d6de002
RS
7228 /* Get the menu name from the first map that has one (a prompt string). */
7229 for (mapno = 0; mapno < nmaps; mapno++)
7230 {
7231 name = map_prompt (maps[mapno]);
7232 if (!NILP (name))
7233 break;
7234 }
284f4730 7235
7d6de002 7236 /* If we don't have any menus, just read a character normally. */
dbc4e1c1 7237 if (mapno >= nmaps)
7d6de002
RS
7238 return Qnil;
7239
1f5b1641 7240#ifdef HAVE_MENUS
7d6de002
RS
7241 /* If we got to this point via a mouse click,
7242 use a real menu for mouse selection. */
5a8d99e0 7243 if (EVENT_HAS_PARAMETERS (prev_event)
7539e11f
KR
7244 && !EQ (XCAR (prev_event), Qmenu_bar)
7245 && !EQ (XCAR (prev_event), Qtool_bar))
7d6de002
RS
7246 {
7247 /* Display the menu and get the selection. */
7248 Lisp_Object *realmaps
7249 = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object));
7250 Lisp_Object value;
7251 int nmaps1 = 0;
7252
7253 /* Use the maps that are not nil. */
7254 for (mapno = 0; mapno < nmaps; mapno++)
7255 if (!NILP (maps[mapno]))
7256 realmaps[nmaps1++] = maps[mapno];
7257
7258 value = Fx_popup_menu (prev_event, Flist (nmaps1, realmaps));
663258f2
JB
7259 if (CONSP (value))
7260 {
68f297c5
RS
7261 Lisp_Object tem;
7262
7539e11f 7263 record_menu_key (XCAR (value));
8eb4d8ef 7264
68f297c5
RS
7265 /* If we got multiple events, unread all but
7266 the first.
7267 There is no way to prevent those unread events
7268 from showing up later in last_nonmenu_event.
7269 So turn symbol and integer events into lists,
7270 to indicate that they came from a mouse menu,
7271 so that when present in last_nonmenu_event
7272 they won't confuse things. */
7539e11f
KR
7273 for (tem = XCDR (value); !NILP (tem);
7274 tem = XCDR (tem))
8eb4d8ef 7275 {
7539e11f
KR
7276 record_menu_key (XCAR (tem));
7277 if (SYMBOLP (XCAR (tem))
7278 || INTEGERP (XCAR (tem)))
7279 XCAR (tem)
7280 = Fcons (XCAR (tem), Qnil);
8eb4d8ef 7281 }
68f297c5 7282
663258f2
JB
7283 /* If we got more than one event, put all but the first
7284 onto this list to be read later.
7285 Return just the first event now. */
24597608 7286 Vunread_command_events
7539e11f
KR
7287 = nconc2 (XCDR (value), Vunread_command_events);
7288 value = XCAR (value);
663258f2 7289 }
1c90c381 7290 else if (NILP (value))
dcc408a0 7291 value = Qt;
6569cc8d
JB
7292 if (used_mouse_menu)
7293 *used_mouse_menu = 1;
7d6de002
RS
7294 return value;
7295 }
1f5b1641 7296#endif /* HAVE_MENUS */
8150596a
RS
7297 return Qnil ;
7298}
7299
68e0de82
RS
7300/* Buffer in use so far for the minibuf prompts for menu keymaps.
7301 We make this bigger when necessary, and never free it. */
7302static char *read_char_minibuf_menu_text;
7303/* Size of that buffer. */
7304static int read_char_minibuf_menu_width;
7305
8150596a 7306static Lisp_Object
24597608 7307read_char_minibuf_menu_prompt (commandflag, nmaps, maps)
8150596a
RS
7308 int commandflag ;
7309 int nmaps;
7310 Lisp_Object *maps;
7311{
7312 int mapno;
7313 register Lisp_Object name;
7314 int nlength;
788f89eb 7315 int width = FRAME_WIDTH (SELECTED_FRAME ()) - 4;
8150596a 7316 int idx = -1;
9fdbfdf8 7317 int nobindings = 1;
8150596a 7318 Lisp_Object rest, vector;
68e0de82 7319 char *menu;
8150596a 7320
8c907a56
GM
7321 vector = Qnil;
7322
8150596a
RS
7323 if (! menu_prompting)
7324 return Qnil;
7325
68e0de82
RS
7326 /* Make sure we have a big enough buffer for the menu text. */
7327 if (read_char_minibuf_menu_text == 0)
7328 {
7329 read_char_minibuf_menu_width = width + 4;
7330 read_char_minibuf_menu_text = (char *) xmalloc (width + 4);
7331 }
7332 else if (width + 4 > read_char_minibuf_menu_width)
7333 {
7334 read_char_minibuf_menu_width = width + 4;
7335 read_char_minibuf_menu_text
7336 = (char *) xrealloc (read_char_minibuf_menu_text, width + 4);
7337 }
7338 menu = read_char_minibuf_menu_text;
7339
8150596a
RS
7340 /* Get the menu name from the first map that has one (a prompt string). */
7341 for (mapno = 0; mapno < nmaps; mapno++)
7342 {
7343 name = map_prompt (maps[mapno]);
7344 if (!NILP (name))
7345 break;
7346 }
7347
7348 /* If we don't have any menus, just read a character normally. */
7349 if (mapno >= nmaps)
7350 return Qnil;
284f4730
JB
7351
7352 /* Prompt string always starts with map's prompt, and a space. */
7353 strcpy (menu, XSTRING (name)->data);
fc932ac6 7354 nlength = STRING_BYTES (XSTRING (name));
7d6de002 7355 menu[nlength++] = ':';
284f4730
JB
7356 menu[nlength++] = ' ';
7357 menu[nlength] = 0;
7358
7d6de002
RS
7359 /* Start prompting at start of first map. */
7360 mapno = 0;
7361 rest = maps[mapno];
284f4730
JB
7362
7363 /* Present the documented bindings, a line at a time. */
7364 while (1)
7365 {
7366 int notfirst = 0;
7367 int i = nlength;
7368 Lisp_Object obj;
7369 int ch;
8066f1a1 7370 Lisp_Object orig_defn_macro;
284f4730 7371
284f4730 7372 /* Loop over elements of map. */
7d6de002 7373 while (i < width)
284f4730 7374 {
fd3613d7 7375 Lisp_Object elt;
284f4730 7376
7d6de002
RS
7377 /* If reached end of map, start at beginning of next map. */
7378 if (NILP (rest))
7379 {
7380 mapno++;
7381 /* At end of last map, wrap around to first map if just starting,
7382 or end this line if already have something on it. */
7383 if (mapno == nmaps)
284f4730 7384 {
8150596a 7385 mapno = 0;
40932d1a 7386 if (notfirst || nobindings) break;
284f4730 7387 }
7d6de002 7388 rest = maps[mapno];
284f4730 7389 }
7d6de002
RS
7390
7391 /* Look at the next element of the map. */
7392 if (idx >= 0)
7393 elt = XVECTOR (vector)->contents[idx];
284f4730 7394 else
7d6de002
RS
7395 elt = Fcar_safe (rest);
7396
8c18cbfb 7397 if (idx < 0 && VECTORP (elt))
284f4730 7398 {
7d6de002
RS
7399 /* If we found a dense table in the keymap,
7400 advanced past it, but start scanning its contents. */
7401 rest = Fcdr_safe (rest);
7402 vector = elt;
7403 idx = 0;
284f4730 7404 }
7d6de002
RS
7405 else
7406 {
7407 /* An ordinary element. */
fd3613d7 7408 Lisp_Object event, tem;
0a2ea221
KH
7409
7410 if (idx < 0)
7411 {
fd3613d7
RS
7412 event = Fcar_safe (elt); /* alist */
7413 elt = Fcdr_safe (elt);
0a2ea221 7414 }
8150596a 7415 else
7d6de002 7416 {
fd3613d7 7417 XSETINT (event, idx); /* vector */
0a2ea221
KH
7418 }
7419
7420 /* Ignore the element if it has no prompt string. */
fd3613d7 7421 if (INTEGERP (event) && parse_menu_item (elt, 0, -1))
0a2ea221
KH
7422 {
7423 /* 1 if the char to type matches the string. */
7424 int char_matches;
7425 Lisp_Object upcased_event, downcased_event;
8c907a56 7426 Lisp_Object desc = Qnil;
fd3613d7
RS
7427 Lisp_Object s
7428 = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
0a2ea221
KH
7429
7430 upcased_event = Fupcase (event);
7431 downcased_event = Fdowncase (event);
7432 char_matches = (XINT (upcased_event) == XSTRING (s)->data[0]
7433 || XINT (downcased_event) == XSTRING (s)->data[0]);
7434 if (! char_matches)
efff6e49 7435 desc = Fsingle_key_description (event, Qnil);
0a2ea221 7436
fd3613d7
RS
7437 tem
7438 = XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ];
7439 if (!NILP (tem))
7440 /* Insert equivalent keybinding. */
7441 s = concat2 (s, tem);
7442
7443 tem
7444 = XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE];
7445 if (EQ (tem, QCradio) || EQ (tem, QCtoggle))
7446 {
7447 /* Insert button prefix. */
7448 Lisp_Object selected
7449 = XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED];
7450 if (EQ (tem, QCradio))
7451 tem = build_string (NILP (selected) ? "(*) " : "( ) ");
7452 else
7453 tem = build_string (NILP (selected) ? "[X] " : "[ ] ");
7454 s = concat2 (tem, s);
7455 }
7456
7457
0a2ea221
KH
7458 /* If we have room for the prompt string, add it to this line.
7459 If this is the first on the line, always add it. */
7460 if ((XSTRING (s)->size + i + 2
7461 + (char_matches ? 0 : XSTRING (desc)->size + 3))
7462 < width
7463 || !notfirst)
7464 {
7465 int thiswidth;
7466
7467 /* Punctuate between strings. */
7468 if (notfirst)
7469 {
7470 strcpy (menu + i, ", ");
7471 i += 2;
7472 }
7473 notfirst = 1;
7474 nobindings = 0 ;
284f4730 7475
0a2ea221
KH
7476 /* If the char to type doesn't match the string's
7477 first char, explicitly show what char to type. */
7478 if (! char_matches)
7479 {
7480 /* Add as much of string as fits. */
7481 thiswidth = XSTRING (desc)->size;
7482 if (thiswidth + i > width)
7483 thiswidth = width - i;
7484 bcopy (XSTRING (desc)->data, menu + i, thiswidth);
7485 i += thiswidth;
7486 strcpy (menu + i, " = ");
7487 i += 3;
7488 }
7489
7490 /* Add as much of string as fits. */
7491 thiswidth = XSTRING (s)->size;
7492 if (thiswidth + i > width)
7493 thiswidth = width - i;
7494 bcopy (XSTRING (s)->data, menu + i, thiswidth);
7495 i += thiswidth;
7496 menu[i] = 0;
7497 }
7498 else
7d6de002 7499 {
0a2ea221
KH
7500 /* If this element does not fit, end the line now,
7501 and save the element for the next line. */
7502 strcpy (menu + i, "...");
7503 break;
7d6de002 7504 }
7d6de002
RS
7505 }
7506
7507 /* Move past this element. */
8150596a 7508 if (idx >= 0 && idx + 1 >= XVECTOR (vector)->size)
7d6de002
RS
7509 /* Handle reaching end of dense table. */
7510 idx = -1;
7511 if (idx >= 0)
7512 idx++;
7513 else
7514 rest = Fcdr_safe (rest);
7515 }
284f4730
JB
7516 }
7517
7518 /* Prompt with that and read response. */
301738ed
RS
7519 message2_nolog (menu, strlen (menu),
7520 ! NILP (current_buffer->enable_multibyte_characters));
8150596a 7521
df0f2ba1 7522 /* Make believe its not a keyboard macro in case the help char
8150596a
RS
7523 is pressed. Help characters are not recorded because menu prompting
7524 is not used on replay.
7525 */
c5fdd383
KH
7526 orig_defn_macro = current_kboard->defining_kbd_macro;
7527 current_kboard->defining_kbd_macro = Qnil;
3cb81011 7528 do
7735786b 7529 obj = read_char (commandflag, 0, 0, Qt, 0);
8c18cbfb 7530 while (BUFFERP (obj));
c5fdd383 7531 current_kboard->defining_kbd_macro = orig_defn_macro;
284f4730 7532
8c18cbfb 7533 if (!INTEGERP (obj))
284f4730
JB
7534 return obj;
7535 else
7536 ch = XINT (obj);
7537
f4255cd1 7538 if (! EQ (obj, menu_prompt_more_char)
8c18cbfb 7539 && (!INTEGERP (menu_prompt_more_char)
f4255cd1 7540 || ! EQ (obj, make_number (Ctl (XINT (menu_prompt_more_char))))))
8150596a 7541 {
c5fdd383 7542 if (!NILP (current_kboard->defining_kbd_macro))
8066f1a1 7543 store_kbd_macro_char (obj);
8150596a
RS
7544 return obj;
7545 }
7546 /* Help char - go round again */
284f4730
JB
7547 }
7548}
284f4730
JB
7549\f
7550/* Reading key sequences. */
7551
7552/* Follow KEY in the maps in CURRENT[0..NMAPS-1], placing its bindings
7553 in DEFS[0..NMAPS-1]. Set NEXT[i] to DEFS[i] if DEFS[i] is a
7554 keymap, or nil otherwise. Return the index of the first keymap in
7555 which KEY has any binding, or NMAPS if no map has a binding.
7556
7557 If KEY is a meta ASCII character, treat it like meta-prefix-char
7558 followed by the corresponding non-meta character. Keymaps in
7559 CURRENT with non-prefix bindings for meta-prefix-char become nil in
7560 NEXT.
7561
88cb0656
JB
7562 If KEY has no bindings in any of the CURRENT maps, NEXT is left
7563 unmodified.
7564
569871d2 7565 NEXT may be the same array as CURRENT. */
284f4730
JB
7566
7567static int
4e50f26a 7568follow_key (key, nmaps, current, defs, next)
284f4730
JB
7569 Lisp_Object key;
7570 Lisp_Object *current, *defs, *next;
7571 int nmaps;
7572{
7573 int i, first_binding;
569871d2 7574 int did_meta = 0;
284f4730
JB
7575
7576 /* If KEY is a meta ASCII character, treat it like meta-prefix-char
569871d2
RS
7577 followed by the corresponding non-meta character.
7578 Put the results into DEFS, since we are going to alter that anyway.
7579 Do not alter CURRENT or NEXT. */
ebdb31e4 7580 if (INTEGERP (key) && (XUINT (key) & CHAR_META))
284f4730
JB
7581 {
7582 for (i = 0; i < nmaps; i++)
7583 if (! NILP (current[i]))
7584 {
569871d2
RS
7585 Lisp_Object def;
7586 def = get_keyelt (access_keymap (current[i],
c6a67acd 7587 meta_prefix_char, 1, 0), 0);
284f4730
JB
7588
7589 /* Note that since we pass the resulting bindings through
7590 get_keymap_1, non-prefix bindings for meta-prefix-char
7591 disappear. */
569871d2 7592 defs[i] = get_keymap_1 (def, 0, 1);
284f4730
JB
7593 }
7594 else
569871d2 7595 defs[i] = Qnil;
284f4730 7596
569871d2 7597 did_meta = 1;
18cd2eeb 7598 XSETINT (key, XFASTINT (key) & ~CHAR_META);
284f4730
JB
7599 }
7600
7601 first_binding = nmaps;
7602 for (i = nmaps - 1; i >= 0; i--)
7603 {
7604 if (! NILP (current[i]))
7605 {
569871d2
RS
7606 Lisp_Object map;
7607 if (did_meta)
7608 map = defs[i];
7609 else
7610 map = current[i];
7611
31f84d03 7612 defs[i] = get_keyelt (access_keymap (map, key, 1, 0), 1);
284f4730
JB
7613 if (! NILP (defs[i]))
7614 first_binding = i;
7615 }
7616 else
7617 defs[i] = Qnil;
7618 }
7619
284f4730 7620 /* Given the set of bindings we've found, produce the next set of maps. */
0a7f1fc0
JB
7621 if (first_binding < nmaps)
7622 for (i = 0; i < nmaps; i++)
f4255cd1 7623 next[i] = NILP (defs[i]) ? Qnil : get_keymap_1 (defs[i], 0, 1);
284f4730
JB
7624
7625 return first_binding;
7626}
7627
df0f2ba1 7628/* Read a sequence of keys that ends with a non prefix character,
f4255cd1
JB
7629 storing it in KEYBUF, a buffer of size BUFSIZE.
7630 Prompt with PROMPT.
284f4730 7631 Return the length of the key sequence stored.
dcc408a0 7632 Return -1 if the user rejected a command menu.
284f4730 7633
f4255cd1
JB
7634 Echo starting immediately unless `prompt' is 0.
7635
7636 Where a key sequence ends depends on the currently active keymaps.
7637 These include any minor mode keymaps active in the current buffer,
7638 the current buffer's local map, and the global map.
7639
7640 If a key sequence has no other bindings, we check Vfunction_key_map
7641 to see if some trailing subsequence might be the beginning of a
7642 function key's sequence. If so, we try to read the whole function
7643 key, and substitute its symbolic name into the key sequence.
7644
fbcd35bd
JB
7645 We ignore unbound `down-' mouse clicks. We turn unbound `drag-' and
7646 `double-' events into similar click events, if that would make them
7647 bound. We try to turn `triple-' events first into `double-' events,
7648 then into clicks.
f4255cd1
JB
7649
7650 If we get a mouse click in a mode line, vertical divider, or other
7651 non-text area, we treat the click as if it were prefixed by the
7652 symbol denoting that area - `mode-line', `vertical-line', or
7653 whatever.
7654
7655 If the sequence starts with a mouse click, we read the key sequence
7656 with respect to the buffer clicked on, not the current buffer.
284f4730 7657
f4255cd1
JB
7658 If the user switches frames in the midst of a key sequence, we put
7659 off the switch-frame event until later; the next call to
f571ae0d
RS
7660 read_char will return it.
7661
7662 If FIX_CURRENT_BUFFER is nonzero, we restore current_buffer
7663 from the selected window's buffer. */
48e416d4 7664
284f4730 7665static int
ce98e608 7666read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
f571ae0d 7667 can_return_switch_frame, fix_current_buffer)
284f4730
JB
7668 Lisp_Object *keybuf;
7669 int bufsize;
84d91fda 7670 Lisp_Object prompt;
309b0fc8 7671 int dont_downcase_last;
ce98e608 7672 int can_return_switch_frame;
f571ae0d 7673 int fix_current_buffer;
284f4730 7674{
8c907a56 7675 volatile int count = specpdl_ptr - specpdl;
f4255cd1 7676
284f4730 7677 /* How many keys there are in the current key sequence. */
8c907a56 7678 volatile int t;
284f4730 7679
284f4730
JB
7680 /* The length of the echo buffer when we started reading, and
7681 the length of this_command_keys when we started reading. */
8c907a56
GM
7682 volatile int echo_start;
7683 volatile int keys_start;
284f4730
JB
7684
7685 /* The number of keymaps we're scanning right now, and the number of
7686 keymaps we have allocated space for. */
8c907a56
GM
7687 volatile int nmaps;
7688 volatile int nmaps_allocated = 0;
284f4730 7689
284f4730
JB
7690 /* defs[0..nmaps-1] are the definitions of KEYBUF[0..t-1] in
7691 the current keymaps. */
8c907a56 7692 Lisp_Object *volatile defs = NULL;
284f4730 7693
f4255cd1
JB
7694 /* submaps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1]
7695 in the current keymaps, or nil where it is not a prefix. */
8c907a56 7696 Lisp_Object *volatile submaps = NULL;
f4255cd1 7697
e0dff5f6 7698 /* The local map to start out with at start of key sequence. */
8c907a56 7699 volatile Lisp_Object orig_local_map;
e0dff5f6 7700
30690496
DL
7701 /* The map from the `keymap' property to start out with at start of
7702 key sequence. */
8c907a56 7703 volatile Lisp_Object orig_keymap;
30690496 7704
e0dff5f6
RS
7705 /* 1 if we have already considered switching to the local-map property
7706 of the place where a mouse click occurred. */
8c907a56 7707 volatile int localized_local_map = 0;
e0dff5f6 7708
f4255cd1
JB
7709 /* The index in defs[] of the first keymap that has a binding for
7710 this key sequence. In other words, the lowest i such that
7711 defs[i] is non-nil. */
8c907a56 7712 volatile int first_binding;
284f4730 7713
f4255cd1 7714 /* If t < mock_input, then KEYBUF[t] should be read as the next
253598e4
JB
7715 input key.
7716
7717 We use this to recover after recognizing a function key. Once we
7718 realize that a suffix of the current key sequence is actually a
7719 function key's escape sequence, we replace the suffix with the
7720 function key's binding from Vfunction_key_map. Now keybuf
f4255cd1
JB
7721 contains a new and different key sequence, so the echo area,
7722 this_command_keys, and the submaps and defs arrays are wrong. In
7723 this situation, we set mock_input to t, set t to 0, and jump to
7724 restart_sequence; the loop will read keys from keybuf up until
7725 mock_input, thus rebuilding the state; and then it will resume
7726 reading characters from the keyboard. */
8c907a56 7727 volatile int mock_input = 0;
284f4730 7728
253598e4 7729 /* If the sequence is unbound in submaps[], then
f4255cd1
JB
7730 keybuf[fkey_start..fkey_end-1] is a prefix in Vfunction_key_map,
7731 and fkey_map is its binding.
253598e4 7732
f4255cd1
JB
7733 These might be > t, indicating that all function key scanning
7734 should hold off until t reaches them. We do this when we've just
7735 recognized a function key, to avoid searching for the function
7736 key's again in Vfunction_key_map. */
8c907a56
GM
7737 volatile int fkey_start = 0, fkey_end = 0;
7738 volatile Lisp_Object fkey_map;
284f4730 7739
a612e298 7740 /* Likewise, for key_translation_map. */
8c907a56
GM
7741 volatile int keytran_start = 0, keytran_end = 0;
7742 volatile Lisp_Object keytran_map;
a612e298 7743
cd21b839
JB
7744 /* If we receive a ``switch-frame'' event in the middle of a key sequence,
7745 we put it off for later. While we're reading, we keep the event here. */
8c907a56 7746 volatile Lisp_Object delayed_switch_frame;
cd21b839 7747
51763820
BF
7748 /* See the comment below... */
7749#if defined (GOBBLE_FIRST_EVENT)
4efda7dd 7750 Lisp_Object first_event;
51763820 7751#endif
4efda7dd 7752
8c907a56
GM
7753 volatile Lisp_Object original_uppercase;
7754 volatile int original_uppercase_position = -1;
309b0fc8 7755
bc536d84 7756 /* Gets around Microsoft compiler limitations. */
309b0fc8 7757 int dummyflag = 0;
bc536d84 7758
3b9189f8
RS
7759 struct buffer *starting_buffer;
7760
e9bf89a0
RS
7761 /* Nonzero if we seem to have got the beginning of a binding
7762 in function_key_map. */
8c907a56
GM
7763 volatile int function_key_possible = 0;
7764 volatile int key_translation_possible = 0;
e9bf89a0 7765
3fe8e9a2
RS
7766 /* Save the status of key translation before each step,
7767 so that we can restore this after downcasing. */
7768 Lisp_Object prev_fkey_map;
3fdfceb3
RS
7769 int prev_fkey_start;
7770 int prev_fkey_end;
3fe8e9a2
RS
7771
7772 Lisp_Object prev_keytran_map;
3fdfceb3
RS
7773 int prev_keytran_start;
7774 int prev_keytran_end;
3fe8e9a2 7775
03cee6ae 7776#if defined (GOBBLE_FIRST_EVENT)
4efda7dd 7777 int junk;
03cee6ae 7778#endif
4efda7dd 7779
7d18f9ae
RS
7780 raw_keybuf_count = 0;
7781
4efda7dd
RS
7782 last_nonmenu_event = Qnil;
7783
7784 delayed_switch_frame = Qnil;
7785 fkey_map = Vfunction_key_map;
a612e298 7786 keytran_map = Vkey_translation_map;
f4255cd1 7787
a612e298 7788 /* If there is no function-key-map, turn off function key scanning. */
f4255cd1
JB
7789 if (NILP (Fkeymapp (Vfunction_key_map)))
7790 fkey_start = fkey_end = bufsize + 1;
7791
a612e298
RS
7792 /* If there is no key-translation-map, turn off scanning. */
7793 if (NILP (Fkeymapp (Vkey_translation_map)))
7794 keytran_start = keytran_end = bufsize + 1;
7795
284f4730
JB
7796 if (INTERACTIVE)
7797 {
84d91fda
RS
7798 if (!NILP (prompt))
7799 echo_prompt (XSTRING (prompt)->data);
f2647d04
DL
7800 else if (cursor_in_echo_area
7801 && (FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
7802 && NILP (Fzerop (Vecho_keystrokes)))
284f4730
JB
7803 /* This doesn't put in a dash if the echo buffer is empty, so
7804 you don't always see a dash hanging out in the minibuffer. */
7805 echo_dash ();
284f4730
JB
7806 }
7807
f4255cd1
JB
7808 /* Record the initial state of the echo area and this_command_keys;
7809 we will need to restore them if we replay a key sequence. */
0a7f1fc0 7810 if (INTERACTIVE)
df0f2ba1 7811 echo_start = echo_length ();
f4255cd1 7812 keys_start = this_command_key_count;
6321824f 7813 this_single_command_key_start = keys_start;
0a7f1fc0 7814
51763820
BF
7815#if defined (GOBBLE_FIRST_EVENT)
7816 /* This doesn't quite work, because some of the things that read_char
7817 does cannot safely be bypassed. It seems too risky to try to make
df0f2ba1 7818 this work right. */
51763820 7819
4efda7dd
RS
7820 /* Read the first char of the sequence specially, before setting
7821 up any keymaps, in case a filter runs and switches buffers on us. */
84d91fda 7822 first_event = read_char (NILP (prompt), 0, submaps, last_nonmenu_event,
4efda7dd 7823 &junk);
51763820 7824#endif /* GOBBLE_FIRST_EVENT */
4efda7dd 7825
30690496
DL
7826 orig_local_map = get_local_map (PT, current_buffer, local_map);
7827 orig_keymap = get_local_map (PT, current_buffer, keymap);
e0dff5f6 7828
7b4aedb9
JB
7829 /* We jump here when the key sequence has been thoroughly changed, and
7830 we need to rescan it starting from the beginning. When we jump here,
7831 keybuf[0..mock_input] holds the sequence we should reread. */
07d2b8de 7832 replay_sequence:
7b4aedb9 7833
3b9189f8 7834 starting_buffer = current_buffer;
e9bf89a0 7835 function_key_possible = 0;
00a78037 7836 key_translation_possible = 0;
3b9189f8 7837
f4255cd1 7838 /* Build our list of keymaps.
07d2b8de
JB
7839 If we recognize a function key and replace its escape sequence in
7840 keybuf with its symbol, or if the sequence starts with a mouse
7841 click and we need to switch buffers, we jump back here to rebuild
7842 the initial keymaps from the current buffer. */
df0f2ba1 7843 {
284f4730
JB
7844 Lisp_Object *maps;
7845
217258d5
KH
7846 if (!NILP (current_kboard->Voverriding_terminal_local_map)
7847 || !NILP (Voverriding_local_map))
284f4730 7848 {
217258d5 7849 if (3 > nmaps_allocated)
9dd3131c 7850 {
217258d5
KH
7851 submaps = (Lisp_Object *) alloca (3 * sizeof (submaps[0]));
7852 defs = (Lisp_Object *) alloca (3 * sizeof (defs[0]));
7853 nmaps_allocated = 3;
9dd3131c 7854 }
217258d5
KH
7855 nmaps = 0;
7856 if (!NILP (current_kboard->Voverriding_terminal_local_map))
7857 submaps[nmaps++] = current_kboard->Voverriding_terminal_local_map;
7858 if (!NILP (Voverriding_local_map))
7859 submaps[nmaps++] = Voverriding_local_map;
284f4730 7860 }
9dd3131c
RS
7861 else
7862 {
30690496 7863 int extra_maps = 2;
217258d5 7864 nmaps = current_minor_maps (0, &maps);
30690496
DL
7865 if (!NILP (orig_keymap))
7866 extra_maps = 3;
7867 if (nmaps + extra_maps > nmaps_allocated)
9dd3131c 7868 {
30690496
DL
7869 submaps = (Lisp_Object *) alloca ((nmaps+extra_maps)
7870 * sizeof (submaps[0]));
7871 defs = (Lisp_Object *) alloca ((nmaps+extra_maps)
7872 * sizeof (defs[0]));
7873 nmaps_allocated = nmaps + extra_maps;
9dd3131c 7874 }
8c907a56 7875 bcopy (maps, (void *) submaps, nmaps * sizeof (submaps[0]));
30690496
DL
7876 if (!NILP (orig_keymap))
7877 submaps[nmaps++] = orig_keymap;
217258d5 7878 submaps[nmaps++] = orig_local_map;
9dd3131c 7879 }
217258d5 7880 submaps[nmaps++] = current_global_map;
284f4730
JB
7881 }
7882
7883 /* Find an accurate initial value for first_binding. */
7884 for (first_binding = 0; first_binding < nmaps; first_binding++)
253598e4 7885 if (! NILP (submaps[first_binding]))
284f4730
JB
7886 break;
7887
3b9189f8 7888 /* Start from the beginning in keybuf. */
f4255cd1
JB
7889 t = 0;
7890
7891 /* These are no-ops the first time through, but if we restart, they
7892 revert the echo area and this_command_keys to their original state. */
7893 this_command_key_count = keys_start;
df0f2ba1 7894 if (INTERACTIVE && t < mock_input)
f4255cd1
JB
7895 echo_truncate (echo_start);
7896
cca310da
JB
7897 /* If the best binding for the current key sequence is a keymap, or
7898 we may be looking at a function key's escape sequence, keep on
7899 reading. */
253598e4 7900 while ((first_binding < nmaps && ! NILP (submaps[first_binding]))
cca310da
JB
7901 || (first_binding >= nmaps
7902 && fkey_start < t
7903 /* mock input is never part of a function key's sequence. */
a612e298 7904 && mock_input <= fkey_start)
0d882d52
KH
7905 || (first_binding >= nmaps
7906 && keytran_start < t && key_translation_possible)
e9bf89a0
RS
7907 /* Don't return in the middle of a possible function key sequence,
7908 if the only bindings we found were via case conversion.
7909 Thus, if ESC O a has a function-key-map translation
7910 and ESC o has a binding, don't return after ESC O,
7911 so that we can translate ESC O plus the next character. */
4e50f26a 7912 )
284f4730
JB
7913 {
7914 Lisp_Object key;
7d6de002 7915 int used_mouse_menu = 0;
284f4730 7916
7b4aedb9
JB
7917 /* Where the last real key started. If we need to throw away a
7918 key that has expanded into more than one element of keybuf
7919 (say, a mouse click on the mode line which is being treated
7920 as [mode-line (mouse-...)], then we backtrack to this point
7921 of keybuf. */
8c907a56 7922 volatile int last_real_key_start;
7b4aedb9 7923
0a7f1fc0
JB
7924 /* These variables are analogous to echo_start and keys_start;
7925 while those allow us to restart the entire key sequence,
7926 echo_local_start and keys_local_start allow us to throw away
7927 just one key. */
8c907a56 7928 volatile int echo_local_start, keys_local_start, local_first_binding;
f4255cd1 7929
284f4730 7930 if (t >= bufsize)
3fe8e9a2 7931 error ("Key sequence too long");
284f4730 7932
f4255cd1
JB
7933 if (INTERACTIVE)
7934 echo_local_start = echo_length ();
7935 keys_local_start = this_command_key_count;
7936 local_first_binding = first_binding;
df0f2ba1 7937
f4255cd1 7938 replay_key:
0a7f1fc0 7939 /* These are no-ops, unless we throw away a keystroke below and
f4255cd1
JB
7940 jumped back up to replay_key; in that case, these restore the
7941 variables to their original state, allowing us to replay the
0a7f1fc0 7942 loop. */
40932d1a 7943 if (INTERACTIVE && t < mock_input)
f4255cd1 7944 echo_truncate (echo_local_start);
0a7f1fc0
JB
7945 this_command_key_count = keys_local_start;
7946 first_binding = local_first_binding;
7947
7e85b935
RS
7948 /* By default, assume each event is "real". */
7949 last_real_key_start = t;
7950
f4255cd1 7951 /* Does mock_input indicate that we are re-reading a key sequence? */
284f4730
JB
7952 if (t < mock_input)
7953 {
7954 key = keybuf[t];
7955 add_command_key (key);
f2647d04
DL
7956 if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
7957 && NILP (Fzerop (Vecho_keystrokes)))
a98ea3f9 7958 echo_char (key);
284f4730 7959 }
253598e4
JB
7960
7961 /* If not, we should actually read a character. */
284f4730
JB
7962 else
7963 {
beecf6a1 7964 {
c5fdd383
KH
7965#ifdef MULTI_KBOARD
7966 KBOARD *interrupted_kboard = current_kboard;
788f89eb 7967 struct frame *interrupted_frame = SELECTED_FRAME ();
c5fdd383 7968 if (setjmp (wrong_kboard_jmpbuf))
beecf6a1 7969 {
5798cf15
KH
7970 if (!NILP (delayed_switch_frame))
7971 {
c5fdd383 7972 interrupted_kboard->kbd_queue
5798cf15 7973 = Fcons (delayed_switch_frame,
c5fdd383 7974 interrupted_kboard->kbd_queue);
5798cf15
KH
7975 delayed_switch_frame = Qnil;
7976 }
beecf6a1 7977 while (t > 0)
c5fdd383
KH
7978 interrupted_kboard->kbd_queue
7979 = Fcons (keybuf[--t], interrupted_kboard->kbd_queue);
5798cf15
KH
7980
7981 /* If the side queue is non-empty, ensure it begins with a
7982 switch-frame, so we'll replay it in the right context. */
c5fdd383 7983 if (CONSP (interrupted_kboard->kbd_queue)
7539e11f 7984 && (key = XCAR (interrupted_kboard->kbd_queue),
5798cf15
KH
7985 !(EVENT_HAS_PARAMETERS (key)
7986 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (key)),
7987 Qswitch_frame))))
df0f2ba1
KH
7988 {
7989 Lisp_Object frame;
7990 XSETFRAME (frame, interrupted_frame);
c5fdd383 7991 interrupted_kboard->kbd_queue
df0f2ba1 7992 = Fcons (make_lispy_switch_frame (frame),
c5fdd383 7993 interrupted_kboard->kbd_queue);
df0f2ba1 7994 }
beecf6a1 7995 mock_input = 0;
30690496
DL
7996 orig_local_map = get_local_map (PT, current_buffer, local_map);
7997 orig_keymap = get_local_map (PT, current_buffer, keymap);
beecf6a1
KH
7998 goto replay_sequence;
7999 }
bded54dd 8000#endif
8c907a56
GM
8001 key = read_char (NILP (prompt), nmaps,
8002 (Lisp_Object *) submaps, last_nonmenu_event,
beecf6a1
KH
8003 &used_mouse_menu);
8004 }
284f4730 8005
dcc408a0
RS
8006 /* read_char returns t when it shows a menu and the user rejects it.
8007 Just return -1. */
8008 if (EQ (key, Qt))
7d18f9ae
RS
8009 {
8010 unbind_to (count, Qnil);
8011 return -1;
8012 }
dcc408a0 8013
f4255cd1 8014 /* read_char returns -1 at the end of a macro.
284f4730
JB
8015 Emacs 18 handles this by returning immediately with a
8016 zero, so that's what we'll do. */
8c18cbfb 8017 if (INTEGERP (key) && XINT (key) == -1)
cd21b839 8018 {
f4255cd1 8019 t = 0;
bc536d84
RS
8020 /* The Microsoft C compiler can't handle the goto that
8021 would go here. */
309b0fc8 8022 dummyflag = 1;
bc536d84 8023 break;
cd21b839 8024 }
df0f2ba1 8025
3cb81011
KH
8026 /* If the current buffer has been changed from under us, the
8027 keymap may have changed, so replay the sequence. */
8c18cbfb 8028 if (BUFFERP (key))
3cb81011
KH
8029 {
8030 mock_input = t;
f571ae0d
RS
8031 /* Reset the current buffer from the selected window
8032 in case something changed the former and not the latter.
8033 This is to be more consistent with the behavior
8034 of the command_loop_1. */
8035 if (fix_current_buffer)
a94a4335 8036 {
788f89eb 8037 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
a94a4335
KH
8038 Fkill_emacs (Qnil);
8039 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
8040 Fset_buffer (XWINDOW (selected_window)->buffer);
8041 }
f571ae0d 8042
30690496
DL
8043 orig_local_map = get_local_map (PT, current_buffer, local_map);
8044 orig_keymap = get_local_map (PT, current_buffer, keymap);
3cb81011
KH
8045 goto replay_sequence;
8046 }
8047
3b9189f8
RS
8048 /* If we have a quit that was typed in another frame, and
8049 quit_throw_to_read_char switched buffers,
8050 replay to get the right keymap. */
9343ab07 8051 if (XINT (key) == quit_char && current_buffer != starting_buffer)
3b9189f8 8052 {
7d18f9ae
RS
8053 GROW_RAW_KEYBUF;
8054 XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key;
3b9189f8
RS
8055 keybuf[t++] = key;
8056 mock_input = t;
8057 Vquit_flag = Qnil;
30690496
DL
8058 orig_local_map = get_local_map (PT, current_buffer, local_map);
8059 orig_keymap = get_local_map (PT, current_buffer, keymap);
3b9189f8
RS
8060 goto replay_sequence;
8061 }
3cb81011 8062
284f4730 8063 Vquit_flag = Qnil;
7d18f9ae
RS
8064
8065 if (EVENT_HAS_PARAMETERS (key)
8066 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (key)), Qswitch_frame))
8067 {
8068 /* If we're at the beginning of a key sequence, and the caller
8069 says it's okay, go ahead and return this event. If we're
8070 in the midst of a key sequence, delay it until the end. */
8071 if (t > 0 || !can_return_switch_frame)
8072 {
8073 delayed_switch_frame = key;
8074 goto replay_key;
8075 }
8076 }
8077
8078 GROW_RAW_KEYBUF;
8079 XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key;
7e85b935 8080 }
284f4730 8081
df0f2ba1 8082 /* Clicks in non-text areas get prefixed by the symbol
7e85b935
RS
8083 in their CHAR-ADDRESS field. For example, a click on
8084 the mode line is prefixed by the symbol `mode-line'.
8085
8086 Furthermore, key sequences beginning with mouse clicks
8087 are read using the keymaps of the buffer clicked on, not
8088 the current buffer. So we may have to switch the buffer
8089 here.
8090
8091 When we turn one event into two events, we must make sure
8092 that neither of the two looks like the original--so that,
8093 if we replay the events, they won't be expanded again.
8094 If not for this, such reexpansion could happen either here
8095 or when user programs play with this-command-keys. */
8096 if (EVENT_HAS_PARAMETERS (key))
8097 {
9b8eb840 8098 Lisp_Object kind;
cca310da 8099
9b8eb840 8100 kind = EVENT_HEAD_KIND (EVENT_HEAD (key));
7e85b935 8101 if (EQ (kind, Qmouse_click))
0a7f1fc0 8102 {
9b8eb840 8103 Lisp_Object window, posn;
f4255cd1 8104
9b8eb840
KH
8105 window = POSN_WINDOW (EVENT_START (key));
8106 posn = POSN_BUFFER_POSN (EVENT_START (key));
7ee32cda 8107
8c18cbfb 8108 if (CONSP (posn))
0a7f1fc0 8109 {
7e85b935
RS
8110 /* We're looking at the second event of a
8111 sequence which we expanded before. Set
8112 last_real_key_start appropriately. */
8113 if (t > 0)
8114 last_real_key_start = t - 1;
cd21b839 8115 }
7e85b935
RS
8116
8117 /* Key sequences beginning with mouse clicks are
8118 read using the keymaps in the buffer clicked on,
8119 not the current buffer. If we're at the
8120 beginning of a key sequence, switch buffers. */
8121 if (last_real_key_start == 0
8c18cbfb
KH
8122 && WINDOWP (window)
8123 && BUFFERP (XWINDOW (window)->buffer)
7e85b935 8124 && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
cd21b839 8125 {
7d18f9ae 8126 XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key;
7e85b935
RS
8127 keybuf[t] = key;
8128 mock_input = t + 1;
8129
8130 /* Arrange to go back to the original buffer once we're
8131 done reading the key sequence. Note that we can't
8132 use save_excursion_{save,restore} here, because they
8133 save point as well as the current buffer; we don't
8134 want to save point, because redisplay may change it,
8135 to accommodate a Fset_window_start or something. We
8136 don't want to do this at the top of the function,
8137 because we may get input from a subprocess which
8138 wants to change the selected window and stuff (say,
8139 emacsclient). */
8140 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
8141
788f89eb 8142 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
a94a4335 8143 Fkill_emacs (Qnil);
30690496
DL
8144 set_buffer_internal (XBUFFER (XWINDOW
8145 (window)->buffer)
8146);
8147 orig_local_map = get_local_map (PT, current_buffer,
8148 local_map);
8149 orig_keymap = get_local_map (PT, current_buffer, keymap);
7e85b935 8150 goto replay_sequence;
0a7f1fc0 8151 }
7ee32cda 8152
e0dff5f6
RS
8153 /* For a mouse click, get the local text-property keymap
8154 of the place clicked on, rather than point. */
7ee32cda 8155 if (last_real_key_start == 0
7539e11f 8156 && CONSP (XCDR (key))
e0dff5f6 8157 && ! localized_local_map)
5ec75a55 8158 {
e0dff5f6
RS
8159 Lisp_Object map_here, start, pos;
8160
8161 localized_local_map = 1;
8162 start = EVENT_START (key);
7ee32cda 8163
7539e11f 8164 if (CONSP (start) && CONSP (XCDR (start)))
e0dff5f6
RS
8165 {
8166 pos = POSN_BUFFER_POSN (start);
b78ce8fb
RS
8167 if (INTEGERP (pos)
8168 && XINT (pos) >= BEG && XINT (pos) <= Z)
e0dff5f6 8169 {
30690496
DL
8170 map_here = get_local_map (XINT (pos),
8171 current_buffer, local_map);
e0dff5f6
RS
8172 if (!EQ (map_here, orig_local_map))
8173 {
8174 orig_local_map = map_here;
8175 keybuf[t] = key;
8176 mock_input = t + 1;
5ec75a55 8177
30690496
DL
8178 goto replay_sequence;
8179 }
8180 map_here = get_local_map (XINT (pos),
8181 current_buffer, keymap);
8182 if (!EQ (map_here, orig_keymap))
8183 {
8184 orig_keymap = map_here;
8185 keybuf[t] = key;
8186 mock_input = t + 1;
8187
e0dff5f6
RS
8188 goto replay_sequence;
8189 }
8190 }
8191 }
8192 }
8193
8194 /* Expand mode-line and scroll-bar events into two events:
8195 use posn as a fake prefix key. */
8196 if (SYMBOLP (posn))
8197 {
7e85b935 8198 if (t + 1 >= bufsize)
3fe8e9a2 8199 error ("Key sequence too long");
7e85b935
RS
8200 keybuf[t] = posn;
8201 keybuf[t+1] = key;
8202 mock_input = t + 2;
7ee32cda 8203
7e85b935
RS
8204 /* Zap the position in key, so we know that we've
8205 expanded it, and don't try to do so again. */
8206 POSN_BUFFER_POSN (EVENT_START (key))
8207 = Fcons (posn, Qnil);
7ee32cda
GM
8208
8209 /* If on a mode line string with a local keymap,
8210 reconsider the key sequence with that keymap. */
8211 if (CONSP (POSN_STRING (EVENT_START (key))))
8212 {
30690496 8213 Lisp_Object string, pos, map, map2;
7ee32cda
GM
8214
8215 string = POSN_STRING (EVENT_START (key));
8216 pos = XCDR (string);
8217 string = XCAR (string);
52e386c2
KR
8218 if (XINT (pos) >= 0
8219 && XINT (pos) < XSTRING (string)->size)
30690496
DL
8220 {
8221 map = Fget_text_property (pos, Qlocal_map, string);
8222 if (!NILP (map))
8223 orig_local_map = map;
8224 map2 = Fget_text_property (pos, Qkeymap, string);
8225 if (!NILP (map2))
8226 orig_keymap = map2;
8227 if (!NILP (map) || !NILP (map2))
8228 goto replay_sequence;
8229 }
7ee32cda
GM
8230 }
8231
7e85b935 8232 goto replay_key;
5ec75a55 8233 }
0a7f1fc0 8234 }
7539e11f 8235 else if (CONSP (XCDR (key))
7a80a6f6 8236 && CONSP (EVENT_START (key))
7539e11f 8237 && CONSP (XCDR (EVENT_START (key))))
7e85b935 8238 {
9b8eb840 8239 Lisp_Object posn;
7e85b935 8240
9b8eb840 8241 posn = POSN_BUFFER_POSN (EVENT_START (key));
7e85b935
RS
8242 /* Handle menu-bar events:
8243 insert the dummy prefix event `menu-bar'. */
9ea173e8 8244 if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar))
7e85b935
RS
8245 {
8246 if (t + 1 >= bufsize)
3fe8e9a2 8247 error ("Key sequence too long");
7e85b935
RS
8248 keybuf[t] = posn;
8249 keybuf[t+1] = key;
8250
8251 /* Zap the position in key, so we know that we've
8252 expanded it, and don't try to do so again. */
8253 POSN_BUFFER_POSN (EVENT_START (key))
8254 = Fcons (posn, Qnil);
8255
8256 mock_input = t + 2;
8257 goto replay_sequence;
8258 }
8c18cbfb 8259 else if (CONSP (posn))
7e85b935
RS
8260 {
8261 /* We're looking at the second event of a
8262 sequence which we expanded before. Set
8263 last_real_key_start appropriately. */
8264 if (last_real_key_start == t && t > 0)
8265 last_real_key_start = t - 1;
8266 }
a6d53864 8267 }
284f4730 8268 }
f4255cd1
JB
8269
8270 /* We have finally decided that KEY is something we might want
8271 to look up. */
284f4730
JB
8272 first_binding = (follow_key (key,
8273 nmaps - first_binding,
253598e4 8274 submaps + first_binding,
284f4730 8275 defs + first_binding,
4e50f26a 8276 submaps + first_binding)
284f4730 8277 + first_binding);
0a7f1fc0 8278
f4255cd1 8279 /* If KEY wasn't bound, we'll try some fallbacks. */
0a7f1fc0
JB
8280 if (first_binding >= nmaps)
8281 {
9b8eb840 8282 Lisp_Object head;
0a7f1fc0 8283
9b8eb840 8284 head = EVENT_HEAD (key);
24736fbc 8285 if (help_char_p (head) && t > 0)
7e85b935
RS
8286 {
8287 read_key_sequence_cmd = Vprefix_help_command;
8288 keybuf[t++] = key;
8289 last_nonmenu_event = key;
bc536d84
RS
8290 /* The Microsoft C compiler can't handle the goto that
8291 would go here. */
309b0fc8 8292 dummyflag = 1;
0d882d52 8293 break;
7e85b935
RS
8294 }
8295
8c18cbfb 8296 if (SYMBOLP (head))
0a7f1fc0 8297 {
9b8eb840
KH
8298 Lisp_Object breakdown;
8299 int modifiers;
0a7f1fc0 8300
9b8eb840 8301 breakdown = parse_modifiers (head);
7539e11f 8302 modifiers = XINT (XCAR (XCDR (breakdown)));
559f9d04
RS
8303 /* Attempt to reduce an unbound mouse event to a simpler
8304 event that is bound:
8305 Drags reduce to clicks.
8306 Double-clicks reduce to clicks.
8307 Triple-clicks reduce to double-clicks, then to clicks.
8308 Down-clicks are eliminated.
8309 Double-downs reduce to downs, then are eliminated.
8310 Triple-downs reduce to double-downs, then to downs,
8311 then are eliminated. */
8312 if (modifiers & (down_modifier | drag_modifier
8313 | double_modifier | triple_modifier))
0a7f1fc0 8314 {
559f9d04
RS
8315 while (modifiers & (down_modifier | drag_modifier
8316 | double_modifier | triple_modifier))
fbcd35bd
JB
8317 {
8318 Lisp_Object new_head, new_click;
8319 if (modifiers & triple_modifier)
8320 modifiers ^= (double_modifier | triple_modifier);
bc536d84
RS
8321 else if (modifiers & double_modifier)
8322 modifiers &= ~double_modifier;
8323 else if (modifiers & drag_modifier)
8324 modifiers &= ~drag_modifier;
559f9d04
RS
8325 else
8326 {
8327 /* Dispose of this `down' event by simply jumping
8328 back to replay_key, to get another event.
8329
8330 Note that if this event came from mock input,
8331 then just jumping back to replay_key will just
8332 hand it to us again. So we have to wipe out any
8333 mock input.
8334
8335 We could delete keybuf[t] and shift everything
8336 after that to the left by one spot, but we'd also
8337 have to fix up any variable that points into
8338 keybuf, and shifting isn't really necessary
8339 anyway.
8340
8341 Adding prefixes for non-textual mouse clicks
8342 creates two characters of mock input, and both
8343 must be thrown away. If we're only looking at
8344 the prefix now, we can just jump back to
8345 replay_key. On the other hand, if we've already
8346 processed the prefix, and now the actual click
8347 itself is giving us trouble, then we've lost the
8348 state of the keymaps we want to backtrack to, and
8349 we need to replay the whole sequence to rebuild
8350 it.
8351
8352 Beyond that, only function key expansion could
8353 create more than two keys, but that should never
8354 generate mouse events, so it's okay to zero
8355 mock_input in that case too.
8356
8357 Isn't this just the most wonderful code ever? */
8358 if (t == last_real_key_start)
8359 {
8360 mock_input = 0;
8361 goto replay_key;
8362 }
8363 else
8364 {
8365 mock_input = last_real_key_start;
8366 goto replay_sequence;
8367 }
8368 }
8369
27203ead 8370 new_head
7539e11f 8371 = apply_modifiers (modifiers, XCAR (breakdown));
27203ead
RS
8372 new_click
8373 = Fcons (new_head, Fcons (EVENT_START (key), Qnil));
fbcd35bd
JB
8374
8375 /* Look for a binding for this new key. follow_key
8376 promises that it didn't munge submaps the
8377 last time we called it, since key was unbound. */
27203ead
RS
8378 first_binding
8379 = (follow_key (new_click,
8380 nmaps - local_first_binding,
8381 submaps + local_first_binding,
8382 defs + local_first_binding,
4e50f26a 8383 submaps + local_first_binding)
27203ead 8384 + local_first_binding);
fbcd35bd
JB
8385
8386 /* If that click is bound, go for it. */
8387 if (first_binding < nmaps)
8388 {
8389 key = new_click;
8390 break;
8391 }
8392 /* Otherwise, we'll leave key set to the drag event. */
8393 }
0a7f1fc0
JB
8394 }
8395 }
8396 }
8397
284f4730 8398 keybuf[t++] = key;
7d6de002
RS
8399 /* Normally, last_nonmenu_event gets the previous key we read.
8400 But when a mouse popup menu is being used,
8401 we don't update last_nonmenu_event; it continues to hold the mouse
8402 event that preceded the first level of menu. */
8403 if (!used_mouse_menu)
8404 last_nonmenu_event = key;
284f4730 8405
6321824f
RS
8406 /* Record what part of this_command_keys is the current key sequence. */
8407 this_single_command_key_start = this_command_key_count - t;
8408
3fe8e9a2
RS
8409 prev_fkey_map = fkey_map;
8410 prev_fkey_start = fkey_start;
8411 prev_fkey_end = fkey_end;
8412
8413 prev_keytran_map = keytran_map;
8414 prev_keytran_start = keytran_start;
8415 prev_keytran_end = keytran_end;
8416
284f4730 8417 /* If the sequence is unbound, see if we can hang a function key
253598e4
JB
8418 off the end of it. We only want to scan real keyboard input
8419 for function key sequences, so if mock_input says that we're
f4255cd1 8420 re-reading old events, don't examine it. */
4e50f26a 8421 if (first_binding >= nmaps
253598e4 8422 && t >= mock_input)
284f4730
JB
8423 {
8424 Lisp_Object fkey_next;
8425
e9bf89a0
RS
8426 /* Continue scan from fkey_end until we find a bound suffix.
8427 If we fail, increment fkey_start
8428 and start fkey_end from there. */
284f4730
JB
8429 while (fkey_end < t)
8430 {
f4255cd1
JB
8431 Lisp_Object key;
8432
8433 key = keybuf[fkey_end++];
067ffa38
JB
8434 /* Look up meta-characters by prefixing them
8435 with meta_prefix_char. I hate this. */
140c4ac6 8436 if (INTEGERP (key) && XUINT (key) & meta_modifier)
f4255cd1 8437 {
e74fbc70
RS
8438 fkey_next
8439 = get_keymap_1
f4255cd1 8440 (get_keyelt
c6a67acd 8441 (access_keymap (fkey_map, meta_prefix_char, 1, 0), 0),
f4255cd1 8442 0, 1);
bb9e9bed 8443 XSETFASTINT (key, XFASTINT (key) & ~meta_modifier);
f4255cd1 8444 }
067ffa38
JB
8445 else
8446 fkey_next = fkey_map;
8447
e74fbc70 8448 fkey_next
c700c260
RS
8449 = get_keyelt (access_keymap (fkey_next, key, 1, 0), 1);
8450
8451 /* Handle symbol with autoload definition. */
0afc861b
RS
8452 if (SYMBOLP (fkey_next) && ! NILP (Ffboundp (fkey_next))
8453 && CONSP (XSYMBOL (fkey_next)->function)
7539e11f 8454 && EQ (XCAR (XSYMBOL (fkey_next)->function), Qautoload))
0afc861b
RS
8455 do_autoload (XSYMBOL (fkey_next)->function,
8456 fkey_next);
c700c260
RS
8457
8458 /* Handle a symbol whose function definition is a keymap
8459 or an array. */
0afc861b
RS
8460 if (SYMBOLP (fkey_next) && ! NILP (Ffboundp (fkey_next))
8461 && (!NILP (Farrayp (XSYMBOL (fkey_next)->function))
8462 || !NILP (Fkeymapp (XSYMBOL (fkey_next)->function))))
8463 fkey_next = XSYMBOL (fkey_next)->function;
067ffa38 8464
7a80a6f6
RS
8465#if 0 /* I didn't turn this on, because it might cause trouble
8466 for the mapping of return into C-m and tab into C-i. */
8467 /* Optionally don't map function keys into other things.
8468 This enables the user to redefine kp- keys easily. */
8469 if (SYMBOLP (key) && !NILP (Vinhibit_function_key_mapping))
8470 fkey_next = Qnil;
8471#endif
8472
1abe6abe
RS
8473 /* If the function key map gives a function, not an
8474 array, then call the function with no args and use
8475 its value instead. */
8476 if (SYMBOLP (fkey_next) && ! NILP (Ffboundp (fkey_next))
8477 && fkey_end == t)
8478 {
8479 struct gcpro gcpro1, gcpro2, gcpro3;
8480 Lisp_Object tem;
8481 tem = fkey_next;
8482
8483 GCPRO3 (fkey_map, keytran_map, delayed_switch_frame);
84d91fda 8484 fkey_next = call1 (fkey_next, prompt);
1abe6abe
RS
8485 UNGCPRO;
8486 /* If the function returned something invalid,
8487 barf--don't ignore it.
df0f2ba1 8488 (To ignore it safely, we would need to gcpro a bunch of
1abe6abe
RS
8489 other variables.) */
8490 if (! (VECTORP (fkey_next) || STRINGP (fkey_next)))
6321824f 8491 error ("Function in key-translation-map returns invalid key sequence");
1abe6abe
RS
8492 }
8493
e9bf89a0
RS
8494 function_key_possible = ! NILP (fkey_next);
8495
85bc5181 8496 /* If keybuf[fkey_start..fkey_end] is bound in the
a764a753 8497 function key map and it's a suffix of the current
85bc5181 8498 sequence (i.e. fkey_end == t), replace it with
a764a753 8499 the binding and restart with fkey_start at the end. */
f5ea6163 8500 if ((VECTORP (fkey_next) || STRINGP (fkey_next))
284f4730
JB
8501 && fkey_end == t)
8502 {
2e864a76 8503 int len = XFASTINT (Flength (fkey_next));
f5ea6163
JB
8504
8505 t = fkey_start + len;
284f4730 8506 if (t >= bufsize)
3fe8e9a2 8507 error ("Key sequence too long");
284f4730 8508
f5ea6163
JB
8509 if (VECTORP (fkey_next))
8510 bcopy (XVECTOR (fkey_next)->contents,
8511 keybuf + fkey_start,
8512 (t - fkey_start) * sizeof (keybuf[0]));
8513 else if (STRINGP (fkey_next))
8514 {
8515 int i;
8516
8517 for (i = 0; i < len; i++)
bb9e9bed
KH
8518 XSETFASTINT (keybuf[fkey_start + i],
8519 XSTRING (fkey_next)->data[i]);
f5ea6163 8520 }
df0f2ba1 8521
284f4730
JB
8522 mock_input = t;
8523 fkey_start = fkey_end = t;
32e6d806 8524 fkey_map = Vfunction_key_map;
284f4730 8525
3bd0dffb
KH
8526 /* Do pass the results through key-translation-map.
8527 But don't retranslate what key-translation-map
8528 has already translated. */
8529 keytran_end = keytran_start;
00a78037
RS
8530 keytran_map = Vkey_translation_map;
8531
f4255cd1 8532 goto replay_sequence;
284f4730 8533 }
df0f2ba1 8534
f4255cd1 8535 fkey_map = get_keymap_1 (fkey_next, 0, 1);
284f4730 8536
df0f2ba1 8537 /* If we no longer have a bound suffix, try a new positions for
a764a753 8538 fkey_start. */
284f4730
JB
8539 if (NILP (fkey_map))
8540 {
8541 fkey_end = ++fkey_start;
8542 fkey_map = Vfunction_key_map;
e9bf89a0 8543 function_key_possible = 0;
284f4730
JB
8544 }
8545 }
8546 }
a612e298
RS
8547
8548 /* Look for this sequence in key-translation-map. */
8549 {
8550 Lisp_Object keytran_next;
8551
8552 /* Scan from keytran_end until we find a bound suffix. */
8553 while (keytran_end < t)
8554 {
8555 Lisp_Object key;
8556
8557 key = keybuf[keytran_end++];
8558 /* Look up meta-characters by prefixing them
8559 with meta_prefix_char. I hate this. */
140c4ac6 8560 if (INTEGERP (key) && XUINT (key) & meta_modifier)
a612e298
RS
8561 {
8562 keytran_next
8563 = get_keymap_1
8564 (get_keyelt
c6a67acd 8565 (access_keymap (keytran_map, meta_prefix_char, 1, 0), 0),
a612e298 8566 0, 1);
bb9e9bed 8567 XSETFASTINT (key, XFASTINT (key) & ~meta_modifier);
a612e298
RS
8568 }
8569 else
8570 keytran_next = keytran_map;
8571
8572 keytran_next
e83f6bb0 8573 = get_keyelt (access_keymap (keytran_next, key, 1, 0), 1);
a612e298 8574
c700c260 8575 /* Handle symbol with autoload definition. */
e83f6bb0
RS
8576 if (SYMBOLP (keytran_next) && ! NILP (Ffboundp (keytran_next))
8577 && CONSP (XSYMBOL (keytran_next)->function)
7539e11f 8578 && EQ (XCAR (XSYMBOL (keytran_next)->function), Qautoload))
e83f6bb0
RS
8579 do_autoload (XSYMBOL (keytran_next)->function,
8580 keytran_next);
8581
c700c260
RS
8582 /* Handle a symbol whose function definition is a keymap
8583 or an array. */
e83f6bb0 8584 if (SYMBOLP (keytran_next) && ! NILP (Ffboundp (keytran_next))
c700c260
RS
8585 && (!NILP (Farrayp (XSYMBOL (keytran_next)->function))
8586 || !NILP (Fkeymapp (XSYMBOL (keytran_next)->function))))
e83f6bb0
RS
8587 keytran_next = XSYMBOL (keytran_next)->function;
8588
1abe6abe 8589 /* If the key translation map gives a function, not an
e83f6bb0 8590 array, then call the function with one arg and use
1abe6abe
RS
8591 its value instead. */
8592 if (SYMBOLP (keytran_next) && ! NILP (Ffboundp (keytran_next))
8593 && keytran_end == t)
8594 {
8595 struct gcpro gcpro1, gcpro2, gcpro3;
8596 Lisp_Object tem;
8597 tem = keytran_next;
8598
40932d1a 8599 GCPRO3 (fkey_map, keytran_map, delayed_switch_frame);
84d91fda 8600 keytran_next = call1 (keytran_next, prompt);
1abe6abe
RS
8601 UNGCPRO;
8602 /* If the function returned something invalid,
8603 barf--don't ignore it.
df0f2ba1 8604 (To ignore it safely, we would need to gcpro a bunch of
1abe6abe
RS
8605 other variables.) */
8606 if (! (VECTORP (keytran_next) || STRINGP (keytran_next)))
40932d1a 8607 error ("Function in key-translation-map returns invalid key sequence");
1abe6abe
RS
8608 }
8609
00a78037
RS
8610 key_translation_possible = ! NILP (keytran_next);
8611
a612e298 8612 /* If keybuf[keytran_start..keytran_end] is bound in the
1abe6abe 8613 key translation map and it's a suffix of the current
a612e298
RS
8614 sequence (i.e. keytran_end == t), replace it with
8615 the binding and restart with keytran_start at the end. */
8616 if ((VECTORP (keytran_next) || STRINGP (keytran_next))
8617 && keytran_end == t)
8618 {
2e864a76 8619 int len = XFASTINT (Flength (keytran_next));
a612e298
RS
8620
8621 t = keytran_start + len;
8622 if (t >= bufsize)
3fe8e9a2 8623 error ("Key sequence too long");
a612e298
RS
8624
8625 if (VECTORP (keytran_next))
8626 bcopy (XVECTOR (keytran_next)->contents,
8627 keybuf + keytran_start,
8628 (t - keytran_start) * sizeof (keybuf[0]));
8629 else if (STRINGP (keytran_next))
8630 {
8631 int i;
8632
8633 for (i = 0; i < len; i++)
bb9e9bed
KH
8634 XSETFASTINT (keybuf[keytran_start + i],
8635 XSTRING (keytran_next)->data[i]);
a612e298
RS
8636 }
8637
8638 mock_input = t;
8639 keytran_start = keytran_end = t;
8640 keytran_map = Vkey_translation_map;
8641
00a78037
RS
8642 /* Don't pass the results of key-translation-map
8643 through function-key-map. */
8644 fkey_start = fkey_end = t;
3bd0dffb 8645 fkey_map = Vfunction_key_map;
00a78037 8646
a612e298
RS
8647 goto replay_sequence;
8648 }
8649
8650 keytran_map = get_keymap_1 (keytran_next, 0, 1);
8651
df0f2ba1 8652 /* If we no longer have a bound suffix, try a new positions for
a612e298
RS
8653 keytran_start. */
8654 if (NILP (keytran_map))
8655 {
8656 keytran_end = ++keytran_start;
8657 keytran_map = Vkey_translation_map;
00a78037 8658 key_translation_possible = 0;
a612e298
RS
8659 }
8660 }
8661 }
4e50f26a
RS
8662
8663 /* If KEY is not defined in any of the keymaps,
8664 and cannot be part of a function key or translation,
8665 and is an upper case letter
8666 use the corresponding lower-case letter instead. */
8667 if (first_binding == nmaps && ! function_key_possible
00a78037 8668 && ! key_translation_possible
8c18cbfb 8669 && INTEGERP (key)
4e50f26a 8670 && ((((XINT (key) & 0x3ffff)
301738ed 8671 < XCHAR_TABLE (current_buffer->downcase_table)->size)
4e50f26a
RS
8672 && UPPERCASEP (XINT (key) & 0x3ffff))
8673 || (XINT (key) & shift_modifier)))
8674 {
569871d2 8675 Lisp_Object new_key;
569871d2 8676
309b0fc8
RS
8677 original_uppercase = key;
8678 original_uppercase_position = t - 1;
8679
831f35a2 8680 if (XINT (key) & shift_modifier)
569871d2 8681 XSETINT (new_key, XINT (key) & ~shift_modifier);
4e50f26a 8682 else
569871d2
RS
8683 XSETINT (new_key, (DOWNCASE (XINT (key) & 0x3ffff)
8684 | (XINT (key) & ~0x3ffff)));
8685
3fe8e9a2
RS
8686 /* We have to do this unconditionally, regardless of whether
8687 the lower-case char is defined in the keymaps, because they
8688 might get translated through function-key-map. */
8689 keybuf[t - 1] = new_key;
8690 mock_input = t;
8691
8692 fkey_map = prev_fkey_map;
8693 fkey_start = prev_fkey_start;
8694 fkey_end = prev_fkey_end;
8695
8696 keytran_map = prev_keytran_map;
8697 keytran_start = prev_keytran_start;
8698 keytran_end = prev_keytran_end;
8699
8700 goto replay_sequence;
4e50f26a 8701 }
ef8fd672
RS
8702 /* If KEY is not defined in any of the keymaps,
8703 and cannot be part of a function key or translation,
8704 and is a shifted function key,
8705 use the corresponding unshifted function key instead. */
8706 if (first_binding == nmaps && ! function_key_possible
8707 && ! key_translation_possible
8708 && SYMBOLP (key))
8709 {
8710 Lisp_Object breakdown;
8711 int modifiers;
8712
8713 breakdown = parse_modifiers (key);
7539e11f 8714 modifiers = XINT (XCAR (XCDR (breakdown)));
ef8fd672
RS
8715 if (modifiers & shift_modifier)
8716 {
569871d2 8717 Lisp_Object new_key;
3fe8e9a2
RS
8718
8719 original_uppercase = key;
8720 original_uppercase_position = t - 1;
ef8fd672 8721
569871d2
RS
8722 modifiers &= ~shift_modifier;
8723 new_key = apply_modifiers (modifiers,
7539e11f 8724 XCAR (breakdown));
569871d2 8725
3fe8e9a2
RS
8726 keybuf[t - 1] = new_key;
8727 mock_input = t;
8728
8729 fkey_map = prev_fkey_map;
8730 fkey_start = prev_fkey_start;
8731 fkey_end = prev_fkey_end;
8732
8733 keytran_map = prev_keytran_map;
8734 keytran_start = prev_keytran_start;
8735 keytran_end = prev_keytran_end;
8736
8737 goto replay_sequence;
ef8fd672
RS
8738 }
8739 }
284f4730
JB
8740 }
8741
309b0fc8 8742 if (!dummyflag)
bc536d84
RS
8743 read_key_sequence_cmd = (first_binding < nmaps
8744 ? defs[first_binding]
8745 : Qnil);
284f4730 8746
cd21b839 8747 unread_switch_frame = delayed_switch_frame;
f4255cd1 8748 unbind_to (count, Qnil);
07f76a14 8749
3fe8e9a2
RS
8750 /* Don't downcase the last character if the caller says don't.
8751 Don't downcase it if the result is undefined, either. */
8752 if ((dont_downcase_last || first_binding >= nmaps)
8753 && t - 1 == original_uppercase_position)
309b0fc8
RS
8754 keybuf[t - 1] = original_uppercase;
8755
07f76a14
JB
8756 /* Occasionally we fabricate events, perhaps by expanding something
8757 according to function-key-map, or by adding a prefix symbol to a
8758 mouse click in the scroll bar or modeline. In this cases, return
8759 the entire generated key sequence, even if we hit an unbound
8760 prefix or a definition before the end. This means that you will
8761 be able to push back the event properly, and also means that
8762 read-key-sequence will always return a logical unit.
8763
8764 Better ideas? */
cca310da
JB
8765 for (; t < mock_input; t++)
8766 {
f2647d04
DL
8767 if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
8768 && NILP (Fzerop (Vecho_keystrokes)))
a98ea3f9 8769 echo_char (keybuf[t]);
cca310da
JB
8770 add_command_key (keybuf[t]);
8771 }
07f76a14 8772
7d18f9ae
RS
8773
8774
284f4730
JB
8775 return t;
8776}
8777
a612e298
RS
8778#if 0 /* This doc string is too long for some compilers.
8779 This commented-out definition serves for DOC. */
ce98e608 8780DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 4, 0,
284f4730
JB
8781 "Read a sequence of keystrokes and return as a string or vector.\n\
8782The sequence is sufficient to specify a non-prefix command in the\n\
8783current local and global maps.\n\
8784\n\
c0a58692
RS
8785First arg PROMPT is a prompt string. If nil, do not prompt specially.\n\
8786Second (optional) arg CONTINUE-ECHO, if non-nil, means this key echos\n\
8787as a continuation of the previous key.\n\
284f4730 8788\n\
309b0fc8
RS
8789The third (optional) arg DONT-DOWNCASE-LAST, if non-nil, means do not\n\
8790convert the last event to lower case. (Normally any upper case event\n\
8791is converted to lower case if the original event is undefined and the lower\n\
8792case equivalent is defined.) A non-nil value is appropriate for reading\n\
8793a key sequence to be defined.\n\
8794\n\
cb5df6ae
JB
8795A C-g typed while in this function is treated like any other character,\n\
8796and `quit-flag' is not set.\n\
8797\n\
8798If the key sequence starts with a mouse click, then the sequence is read\n\
8799using the keymaps of the buffer of the window clicked in, not the buffer\n\
8800of the selected window as normal.\n\
ede41463 8801""\n\
cb5df6ae
JB
8802`read-key-sequence' drops unbound button-down events, since you normally\n\
8803only care about the click or drag events which follow them. If a drag\n\
fbcd35bd
JB
8804or multi-click event is unbound, but the corresponding click event would\n\
8805be bound, `read-key-sequence' turns the event into a click event at the\n\
cb5df6ae 8806drag's starting position. This means that you don't have to distinguish\n\
fbcd35bd 8807between click and drag, double, or triple events unless you want to.\n\
cb5df6ae
JB
8808\n\
8809`read-key-sequence' prefixes mouse events on mode lines, the vertical\n\
3c370943
JB
8810lines separating windows, and scroll bars with imaginary keys\n\
8811`mode-line', `vertical-line', and `vertical-scroll-bar'.\n\
cb5df6ae 8812\n\
ce98e608
KH
8813Optional fourth argument CAN-RETURN-SWITCH-FRAME non-nil means that this\n\
8814function will process a switch-frame event if the user switches frames\n\
8815before typing anything. If the user switches frames in the middle of a\n\
8816key sequence, or at the start of the sequence but CAN-RETURN-SWITCH-FRAME\n\
8817is nil, then the event will be put off until after the current key sequence.\n\
cb5df6ae
JB
8818\n\
8819`read-key-sequence' checks `function-key-map' for function key\n\
8820sequences, where they wouldn't conflict with ordinary bindings. See\n\
d5eecefb
RS
8821`function-key-map' for more details.\n\
8822\n\
8823The optional fifth argument COMMAND-LOOP, if non-nil, means\n\
8824that this key sequence is being read by something that will\n\
8825read commands one after another. It should be nil if the caller\n\
8826will read just one key sequence.")
b638f328 8827 (prompt, continue_echo, dont_downcase_last, can_return_switch_frame, command-loop)
a612e298
RS
8828#endif
8829
d5eecefb 8830DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 5, 0,
a612e298 8831 0)
d5eecefb
RS
8832 (prompt, continue_echo, dont_downcase_last, can_return_switch_frame,
8833 command_loop)
309b0fc8 8834 Lisp_Object prompt, continue_echo, dont_downcase_last;
d5eecefb 8835 Lisp_Object can_return_switch_frame, command_loop;
284f4730
JB
8836{
8837 Lisp_Object keybuf[30];
8838 register int i;
03cee6ae 8839 struct gcpro gcpro1;
d5eecefb 8840 int count = specpdl_ptr - specpdl;
284f4730
JB
8841
8842 if (!NILP (prompt))
8843 CHECK_STRING (prompt, 0);
8844 QUIT;
8845
d5eecefb
RS
8846 specbind (Qinput_method_exit_on_first_char,
8847 (NILP (command_loop) ? Qt : Qnil));
8848 specbind (Qinput_method_use_echo_area,
8849 (NILP (command_loop) ? Qt : Qnil));
8850
284f4730
JB
8851 bzero (keybuf, sizeof keybuf);
8852 GCPRO1 (keybuf[0]);
8853 gcpro1.nvars = (sizeof keybuf/sizeof (keybuf[0]));
8854
daa37602 8855 if (NILP (continue_echo))
6321824f
RS
8856 {
8857 this_command_key_count = 0;
8858 this_single_command_key_start = 0;
8859 }
c0a58692 8860
d0c48478
GM
8861#ifdef HAVE_X_WINDOWS
8862 if (display_busy_cursor_p)
8863 cancel_busy_cursor ();
8864#endif
8865
309b0fc8 8866 i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])),
ce98e608 8867 prompt, ! NILP (dont_downcase_last),
f571ae0d 8868 ! NILP (can_return_switch_frame), 0);
284f4730 8869
d0c48478
GM
8870#ifdef HAVE_X_WINDOWS
8871 if (display_busy_cursor_p)
8872 start_busy_cursor ();
8873#endif
8874
dcc408a0
RS
8875 if (i == -1)
8876 {
8877 Vquit_flag = Qt;
8878 QUIT;
8879 }
284f4730 8880 UNGCPRO;
d5eecefb 8881 return unbind_to (count, make_event_array (i, keybuf));
284f4730 8882}
e39da3d7
RS
8883
8884DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector,
d5eecefb 8885 Sread_key_sequence_vector, 1, 5, 0,
e39da3d7 8886 "Like `read-key-sequence' but always return a vector.")
d5eecefb
RS
8887 (prompt, continue_echo, dont_downcase_last, can_return_switch_frame,
8888 command_loop)
e39da3d7 8889 Lisp_Object prompt, continue_echo, dont_downcase_last;
d5eecefb 8890 Lisp_Object can_return_switch_frame, command_loop;
e39da3d7
RS
8891{
8892 Lisp_Object keybuf[30];
8893 register int i;
03cee6ae 8894 struct gcpro gcpro1;
d5eecefb 8895 int count = specpdl_ptr - specpdl;
e39da3d7
RS
8896
8897 if (!NILP (prompt))
8898 CHECK_STRING (prompt, 0);
8899 QUIT;
8900
d5eecefb
RS
8901 specbind (Qinput_method_exit_on_first_char,
8902 (NILP (command_loop) ? Qt : Qnil));
8903 specbind (Qinput_method_use_echo_area,
8904 (NILP (command_loop) ? Qt : Qnil));
8905
e39da3d7
RS
8906 bzero (keybuf, sizeof keybuf);
8907 GCPRO1 (keybuf[0]);
8908 gcpro1.nvars = (sizeof keybuf/sizeof (keybuf[0]));
8909
8910 if (NILP (continue_echo))
8911 {
8912 this_command_key_count = 0;
8913 this_single_command_key_start = 0;
8914 }
8915
d0c48478
GM
8916#ifdef HAVE_X_WINDOWS
8917 if (display_busy_cursor_p)
8918 cancel_busy_cursor ();
8919#endif
8920
e39da3d7
RS
8921 i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])),
8922 prompt, ! NILP (dont_downcase_last),
8923 ! NILP (can_return_switch_frame), 0);
8924
d0c48478
GM
8925#ifdef HAVE_X_WINDOWS
8926 if (display_busy_cursor_p)
8927 start_busy_cursor ();
8928#endif
8929
e39da3d7
RS
8930 if (i == -1)
8931 {
8932 Vquit_flag = Qt;
8933 QUIT;
8934 }
8935 UNGCPRO;
d5eecefb 8936 return unbind_to (count, Fvector (i, keybuf));
e39da3d7 8937}
284f4730 8938\f
158f7532 8939DEFUN ("command-execute", Fcommand_execute, Scommand_execute, 1, 4, 0,
284f4730
JB
8940 "Execute CMD as an editor command.\n\
8941CMD must be a symbol that satisfies the `commandp' predicate.\n\
8942Optional second arg RECORD-FLAG non-nil\n\
8943means unconditionally put this command in `command-history'.\n\
aaf2ead7
RS
8944Otherwise, that is done only if an arg is read using the minibuffer.\n\
8945The argument KEYS specifies the value to use instead of (this-command-keys)\n\
6321824f 8946when reading the arguments; if it is nil, (this-command-keys) is used.\n\
158f7532
RS
8947The argument SPECIAL, if non-nil, means that this command is executing\n\
8948a special event, so ignore the prefix argument and don't clear it.")
8949 (cmd, record_flag, keys, special)
8950 Lisp_Object cmd, record_flag, keys, special;
284f4730
JB
8951{
8952 register Lisp_Object final;
8953 register Lisp_Object tem;
8954 Lisp_Object prefixarg;
8955 struct backtrace backtrace;
8956 extern int debug_on_next_call;
8957
284f4730
JB
8958 debug_on_next_call = 0;
8959
158f7532
RS
8960 if (NILP (special))
8961 {
8962 prefixarg = current_kboard->Vprefix_arg;
8963 Vcurrent_prefix_arg = prefixarg;
8964 current_kboard->Vprefix_arg = Qnil;
8965 }
8966 else
8967 prefixarg = Qnil;
8968
8c18cbfb 8969 if (SYMBOLP (cmd))
284f4730
JB
8970 {
8971 tem = Fget (cmd, Qdisabled);
88ce066e 8972 if (!NILP (tem) && !NILP (Vrun_hooks))
b78ce8fb
RS
8973 {
8974 tem = Fsymbol_value (Qdisabled_command_hook);
8975 if (!NILP (tem))
8976 return call1 (Vrun_hooks, Qdisabled_command_hook);
8977 }
284f4730
JB
8978 }
8979
01e26217 8980 while (1)
284f4730 8981 {
ffd56f97 8982 final = Findirect_function (cmd);
284f4730
JB
8983
8984 if (CONSP (final) && (tem = Fcar (final), EQ (tem, Qautoload)))
b516a185
RS
8985 {
8986 struct gcpro gcpro1, gcpro2;
8987
8988 GCPRO2 (cmd, prefixarg);
8989 do_autoload (final, cmd);
8990 UNGCPRO;
8991 }
284f4730
JB
8992 else
8993 break;
8994 }
8995
8c18cbfb 8996 if (STRINGP (final) || VECTORP (final))
284f4730
JB
8997 {
8998 /* If requested, place the macro in the command history. For
8999 other sorts of commands, call-interactively takes care of
9000 this. */
e57d8fd8 9001 if (!NILP (record_flag))
f4385381
RS
9002 {
9003 Vcommand_history
9004 = Fcons (Fcons (Qexecute_kbd_macro,
9005 Fcons (final, Fcons (prefixarg, Qnil))),
9006 Vcommand_history);
9007
9008 /* Don't keep command history around forever. */
9009 if (NUMBERP (Vhistory_length) && XINT (Vhistory_length) > 0)
9010 {
9011 tem = Fnthcdr (Vhistory_length, Vcommand_history);
9012 if (CONSP (tem))
7539e11f 9013 XCDR (tem) = Qnil;
f4385381
RS
9014 }
9015 }
284f4730
JB
9016
9017 return Fexecute_kbd_macro (final, prefixarg);
9018 }
f4385381 9019
8c18cbfb 9020 if (CONSP (final) || SUBRP (final) || COMPILEDP (final))
284f4730
JB
9021 {
9022 backtrace.next = backtrace_list;
9023 backtrace_list = &backtrace;
9024 backtrace.function = &Qcall_interactively;
9025 backtrace.args = &cmd;
9026 backtrace.nargs = 1;
9027 backtrace.evalargs = 0;
9028
e57d8fd8 9029 tem = Fcall_interactively (cmd, record_flag, keys);
284f4730
JB
9030
9031 backtrace_list = backtrace.next;
9032 return tem;
9033 }
9034 return Qnil;
9035}
9036\f
284f4730
JB
9037DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_command,
9038 1, 1, "P",
9039 "Read function name, then read its arguments and call it.")
9040 (prefixarg)
9041 Lisp_Object prefixarg;
9042{
9043 Lisp_Object function;
9044 char buf[40];
9045 Lisp_Object saved_keys;
5434fce6 9046 Lisp_Object bindings, value;
214360e9 9047 struct gcpro gcpro1, gcpro2;
284f4730 9048
b0f2a7bf
KH
9049 saved_keys = Fvector (this_command_key_count,
9050 XVECTOR (this_command_keys)->contents);
284f4730 9051 buf[0] = 0;
fde7aff8 9052 GCPRO2 (saved_keys, prefixarg);
284f4730
JB
9053
9054 if (EQ (prefixarg, Qminus))
9055 strcpy (buf, "- ");
7539e11f 9056 else if (CONSP (prefixarg) && XINT (XCAR (prefixarg)) == 4)
284f4730 9057 strcpy (buf, "C-u ");
7539e11f 9058 else if (CONSP (prefixarg) && INTEGERP (XCAR (prefixarg)))
5d5b907f
RS
9059 {
9060 if (sizeof (int) == sizeof (EMACS_INT))
7539e11f 9061 sprintf (buf, "%d ", XINT (XCAR (prefixarg)));
5d5b907f 9062 else if (sizeof (long) == sizeof (EMACS_INT))
7539e11f 9063 sprintf (buf, "%ld ", (long) XINT (XCAR (prefixarg)));
5d5b907f
RS
9064 else
9065 abort ();
9066 }
8c18cbfb 9067 else if (INTEGERP (prefixarg))
5d5b907f
RS
9068 {
9069 if (sizeof (int) == sizeof (EMACS_INT))
9070 sprintf (buf, "%d ", XINT (prefixarg));
9071 else if (sizeof (long) == sizeof (EMACS_INT))
03cee6ae 9072 sprintf (buf, "%ld ", (long) XINT (prefixarg));
5d5b907f
RS
9073 else
9074 abort ();
9075 }
284f4730
JB
9076
9077 /* This isn't strictly correct if execute-extended-command
9078 is bound to anything else. Perhaps it should use
9079 this_command_keys? */
9080 strcat (buf, "M-x ");
9081
9082 /* Prompt with buf, and then read a string, completing from and
9083 restricting to the set of all defined commands. Don't provide
51763820 9084 any initial input. Save the command read on the extended-command
03b4122a 9085 history list. */
284f4730
JB
9086 function = Fcompleting_read (build_string (buf),
9087 Vobarray, Qcommandp,
4328577a
KH
9088 Qt, Qnil, Qextended_command_history, Qnil,
9089 Qnil);
284f4730 9090
1f5b1641
RS
9091 if (STRINGP (function) && XSTRING (function)->size == 0)
9092 error ("No command name given");
9093
1113d9db
JB
9094 /* Set this_command_keys to the concatenation of saved_keys and
9095 function, followed by a RET. */
284f4730 9096 {
1113d9db 9097 struct Lisp_String *str;
b0f2a7bf 9098 Lisp_Object *keys;
284f4730 9099 int i;
284f4730 9100
1113d9db 9101 this_command_key_count = 0;
6321824f 9102 this_single_command_key_start = 0;
1113d9db 9103
b0f2a7bf
KH
9104 keys = XVECTOR (saved_keys)->contents;
9105 for (i = 0; i < XVECTOR (saved_keys)->size; i++)
9106 add_command_key (keys[i]);
1113d9db
JB
9107
9108 str = XSTRING (function);
9109 for (i = 0; i < str->size; i++)
301738ed 9110 add_command_key (Faref (function, make_number (i)));
1113d9db 9111
301738ed 9112 add_command_key (make_number ('\015'));
284f4730
JB
9113 }
9114
9115 UNGCPRO;
9116
0a7f1fc0 9117 function = Fintern (function, Qnil);
d8bcf58e 9118 current_kboard->Vprefix_arg = prefixarg;
d5eecefb
RS
9119 Vthis_command = function;
9120 real_this_command = function;
284f4730 9121
6526ab49
RS
9122 /* If enabled, show which key runs this command. */
9123 if (!NILP (Vsuggest_key_bindings)
71012575 9124 && NILP (Vexecuting_macro)
6526ab49 9125 && SYMBOLP (function))
5434fce6
RS
9126 bindings = Fwhere_is_internal (function, Voverriding_local_map,
9127 Qt, Qnil);
9128 else
9129 bindings = Qnil;
6526ab49 9130
5434fce6
RS
9131 value = Qnil;
9132 GCPRO2 (bindings, value);
9133 value = Fcommand_execute (function, Qt, Qnil, Qnil);
6526ab49 9134
5434fce6 9135 /* If the command has a key binding, print it now. */
3ababa60 9136 if (!NILP (bindings)
ee112567
KH
9137 && ! (VECTORP (bindings) && EQ (Faref (bindings, make_number (0)),
9138 Qmouse_movement)))
5434fce6
RS
9139 {
9140 /* But first wait, and skip the message if there is input. */
426939cc 9141 int delay_time;
985f9f66 9142 if (!NILP (echo_area_buffer[0]))
426939cc
RS
9143 /* This command displayed something in the echo area;
9144 so wait a few seconds, then display our suggestion message. */
9145 delay_time = (NUMBERP (Vsuggest_key_bindings)
9146 ? XINT (Vsuggest_key_bindings) : 2);
9147 else
9148 /* This command left the echo area empty,
9149 so display our message immediately. */
9150 delay_time = 0;
9151
9152 if (!NILP (Fsit_for (make_number (delay_time), Qnil, Qnil))
303b5b3f 9153 && ! CONSP (Vunread_command_events))
6526ab49 9154 {
5434fce6
RS
9155 Lisp_Object binding;
9156 char *newmessage;
985f9f66 9157 int message_p = push_message ();
5434fce6
RS
9158
9159 binding = Fkey_description (bindings);
9160
9161 newmessage
9162 = (char *) alloca (XSYMBOL (function)->name->size
fc932ac6 9163 + STRING_BYTES (XSTRING (binding))
5434fce6 9164 + 100);
3ababa60 9165 sprintf (newmessage, "You can run the command `%s' with %s",
6526ab49 9166 XSYMBOL (function)->name->data,
5434fce6 9167 XSTRING (binding)->data);
301738ed
RS
9168 message2_nolog (newmessage,
9169 strlen (newmessage),
9170 STRING_MULTIBYTE (binding));
5434fce6
RS
9171 if (!NILP (Fsit_for ((NUMBERP (Vsuggest_key_bindings)
9172 ? Vsuggest_key_bindings : make_number (2)),
985f9f66
GM
9173 Qnil, Qnil))
9174 && message_p)
9175 restore_message ();
9176
9177 pop_message ();
6526ab49
RS
9178 }
9179 }
9180
5434fce6 9181 RETURN_UNGCPRO (value);
284f4730 9182}
6526ab49
RS
9183
9184/* Find the set of keymaps now active.
9185 Store into *MAPS_P a vector holding the various maps
9186 and return the number of them. The vector was malloc'd
9187 and the caller should free it. */
9188
9189int
9190current_active_maps (maps_p)
9191 Lisp_Object **maps_p;
9192{
9193 Lisp_Object *tmaps, *maps;
9194 int nmaps;
9195
9196 /* Should overriding-terminal-local-map and overriding-local-map apply? */
9197 if (!NILP (Voverriding_local_map_menu_flag))
9198 {
9199 /* Yes, use them (if non-nil) as well as the global map. */
9200 maps = (Lisp_Object *) xmalloc (3 * sizeof (maps[0]));
9201 nmaps = 0;
9202 if (!NILP (current_kboard->Voverriding_terminal_local_map))
9203 maps[nmaps++] = current_kboard->Voverriding_terminal_local_map;
9204 if (!NILP (Voverriding_local_map))
9205 maps[nmaps++] = Voverriding_local_map;
9206 }
9207 else
9208 {
30690496
DL
9209 /* No, so use major and minor mode keymaps and keymap property. */
9210 int extra_maps = 2;
9211 Lisp_Object map = get_local_map (PT, current_buffer, keymap);
9212 if (!NILP (map))
9213 extra_maps = 3;
6526ab49 9214 nmaps = current_minor_maps (NULL, &tmaps);
30690496
DL
9215 maps = (Lisp_Object *) alloca ((nmaps + extra_maps)
9216 * sizeof (maps[0]));
6526ab49 9217 bcopy (tmaps, maps, nmaps * sizeof (maps[0]));
30690496 9218 if (!NILP (map))
9f83cf0b 9219 maps[nmaps++] = map;
30690496 9220 maps[nmaps++] = get_local_map (PT, current_buffer, local_map);
6526ab49
RS
9221 }
9222 maps[nmaps++] = current_global_map;
9223
9224 *maps_p = maps;
9225 return nmaps;
9226}
284f4730 9227\f
d9d4c147 9228/* Return nonzero if input events are pending. */
284f4730 9229
dfcf069d 9230int
284f4730
JB
9231detect_input_pending ()
9232{
9233 if (!input_pending)
d9d4c147
KH
9234 get_input_pending (&input_pending, 0);
9235
9236 return input_pending;
9237}
9238
b1878f45 9239/* Return nonzero if input events are pending, and run any pending timers. */
d9d4c147 9240
dfcf069d 9241int
87dd9b9b
RS
9242detect_input_pending_run_timers (do_display)
9243 int do_display;
d9d4c147 9244{
87dd9b9b
RS
9245 int old_timers_run = timers_run;
9246
d9d4c147
KH
9247 if (!input_pending)
9248 get_input_pending (&input_pending, 1);
284f4730 9249
87dd9b9b 9250 if (old_timers_run != timers_run && do_display)
7ee32cda
GM
9251 {
9252 redisplay_preserve_echo_area ();
9253 /* The following fixes a bug when using lazy-lock with
9254 lazy-lock-defer-on-the-fly set to t, i.e. when fontifying
9255 from an idle timer function. The symptom of the bug is that
9256 the cursor sometimes doesn't become visible until the next X
9257 event is processed. --gerd. */
9258 if (rif)
9259 rif->flush_display (NULL);
9260 }
87dd9b9b 9261
284f4730
JB
9262 return input_pending;
9263}
9264
ffd56f97
JB
9265/* This is called in some cases before a possible quit.
9266 It cases the next call to detect_input_pending to recompute input_pending.
9267 So calling this function unnecessarily can't do any harm. */
07a59269
KH
9268
9269void
ffd56f97
JB
9270clear_input_pending ()
9271{
9272 input_pending = 0;
9273}
9274
b1878f45
RS
9275/* Return nonzero if there are pending requeued events.
9276 This isn't used yet. The hope is to make wait_reading_process_input
9277 call it, and return return if it runs Lisp code that unreads something.
9278 The problem is, kbd_buffer_get_event needs to be fixed to know what
9279 to do in that case. It isn't trivial. */
9280
dfcf069d 9281int
b1878f45
RS
9282requeued_events_pending_p ()
9283{
9284 return (!NILP (Vunread_command_events) || unread_command_char != -1);
9285}
9286
9287
284f4730
JB
9288DEFUN ("input-pending-p", Finput_pending_p, Sinput_pending_p, 0, 0, 0,
9289 "T if command input is currently available with no waiting.\n\
9290Actually, the value is nil only if we can be sure that no input is available.")
9291 ()
9292{
24597608 9293 if (!NILP (Vunread_command_events) || unread_command_char != -1)
284f4730
JB
9294 return (Qt);
9295
d9d4c147
KH
9296 get_input_pending (&input_pending, 1);
9297 return input_pending > 0 ? Qt : Qnil;
284f4730
JB
9298}
9299
9300DEFUN ("recent-keys", Frecent_keys, Srecent_keys, 0, 0, 0,
22d7cb89 9301 "Return vector of last 100 events, not counting those from keyboard macros.")
284f4730
JB
9302 ()
9303{
5160df46 9304 Lisp_Object *keys = XVECTOR (recent_keys)->contents;
284f4730
JB
9305 Lisp_Object val;
9306
9307 if (total_keys < NUM_RECENT_KEYS)
5160df46 9308 return Fvector (total_keys, keys);
284f4730
JB
9309 else
9310 {
5160df46
JB
9311 val = Fvector (NUM_RECENT_KEYS, keys);
9312 bcopy (keys + recent_keys_index,
284f4730
JB
9313 XVECTOR (val)->contents,
9314 (NUM_RECENT_KEYS - recent_keys_index) * sizeof (Lisp_Object));
5160df46 9315 bcopy (keys,
284f4730
JB
9316 XVECTOR (val)->contents + NUM_RECENT_KEYS - recent_keys_index,
9317 recent_keys_index * sizeof (Lisp_Object));
9318 return val;
9319 }
9320}
9321
9322DEFUN ("this-command-keys", Fthis_command_keys, Sthis_command_keys, 0, 0, 0,
e5f920d7
RS
9323 "Return the key sequence that invoked this command.\n\
9324The value is a string or a vector.")
284f4730
JB
9325 ()
9326{
86e5706b
RS
9327 return make_event_array (this_command_key_count,
9328 XVECTOR (this_command_keys)->contents);
284f4730
JB
9329}
9330
e39da3d7
RS
9331DEFUN ("this-command-keys-vector", Fthis_command_keys_vector, Sthis_command_keys_vector, 0, 0, 0,
9332 "Return the key sequence that invoked this command, as a vector.")
9333 ()
9334{
9335 return Fvector (this_command_key_count,
9336 XVECTOR (this_command_keys)->contents);
9337}
9338
6321824f
RS
9339DEFUN ("this-single-command-keys", Fthis_single_command_keys,
9340 Sthis_single_command_keys, 0, 0, 0,
9341 "Return the key sequence that invoked this command.\n\
9342Unlike `this-command-keys', this function's value\n\
9343does not include prefix arguments.\n\
e39da3d7 9344The value is always a vector.")
6321824f
RS
9345 ()
9346{
e39da3d7
RS
9347 return Fvector (this_command_key_count
9348 - this_single_command_key_start,
9349 (XVECTOR (this_command_keys)->contents
9350 + this_single_command_key_start));
6321824f
RS
9351}
9352
7d18f9ae
RS
9353DEFUN ("this-single-command-raw-keys", Fthis_single_command_raw_keys,
9354 Sthis_single_command_raw_keys, 0, 0, 0,
9355 "Return the raw events that were read for this command.\n\
9356Unlike `this-single-command-keys', this function's value\n\
9357shows the events before all translations (except for input methods).\n\
9358The value is always a vector.")
9359 ()
9360{
9361 return Fvector (raw_keybuf_count,
9362 (XVECTOR (raw_keybuf)->contents));
9363}
9364
71918b75
RS
9365DEFUN ("reset-this-command-lengths", Freset_this_command_lengths,
9366 Sreset_this_command_lengths, 0, 0, 0,
9367 "Used for complicated reasons in `universal-argument-other-key'.\n\
9368\n\
9369`universal-argument-other-key' rereads the event just typed.\n\
9370It then gets translated through `function-key-map'.\n\
9371The translated event gets included in the echo area and in\n\
9372the value of `this-command-keys' in addition to the raw original event.\n\
9373That is not right.\n\
9374\n\
9375Calling this function directs the translated event to replace\n\
9376the original event, so that only one version of the event actually\n\
9377appears in the echo area and in the value of `this-command-keys.'.")
9378 ()
9379{
9380 before_command_restore_flag = 1;
9381 before_command_key_count_1 = before_command_key_count;
9382 before_command_echo_length_1 = before_command_echo_length;
6e5742a0 9383 return Qnil;
71918b75
RS
9384}
9385
82e6e5af
RS
9386DEFUN ("clear-this-command-keys", Fclear_this_command_keys,
9387 Sclear_this_command_keys, 0, 0, 0,
e27b53f6
GM
9388 "Clear out the vector that `this-command-keys' returns.\n\
9389Clear vector containing last 100 events.")
82e6e5af
RS
9390 ()
9391{
fb0dde6c
GM
9392 int i;
9393
82e6e5af 9394 this_command_key_count = 0;
fb0dde6c
GM
9395
9396 for (i = 0; i < XVECTOR (recent_keys)->size; ++i)
9397 XVECTOR (recent_keys)->contents[i] = Qnil;
9398 total_keys = 0;
9399 recent_keys_index = 0;
82e6e5af
RS
9400 return Qnil;
9401}
9402
284f4730
JB
9403DEFUN ("recursion-depth", Frecursion_depth, Srecursion_depth, 0, 0, 0,
9404 "Return the current depth in recursive edits.")
9405 ()
9406{
9407 Lisp_Object temp;
bb9e9bed 9408 XSETFASTINT (temp, command_loop_level + minibuf_level);
284f4730
JB
9409 return temp;
9410}
9411
9412DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1,
9413 "FOpen dribble file: ",
9b2471df
RS
9414 "Start writing all keyboard characters to a dribble file called FILE.\n\
9415If FILE is nil, close any open dribble file.")
284f4730
JB
9416 (file)
9417 Lisp_Object file;
9418{
6cb52def 9419 if (dribble)
284f4730 9420 {
6cb52def
KH
9421 fclose (dribble);
9422 dribble = 0;
284f4730 9423 }
6cb52def 9424 if (!NILP (file))
284f4730
JB
9425 {
9426 file = Fexpand_file_name (file, Qnil);
9427 dribble = fopen (XSTRING (file)->data, "w");
ab6ca1de
KH
9428 if (dribble == 0)
9429 report_file_error ("Opening dribble", Fcons (file, Qnil));
284f4730
JB
9430 }
9431 return Qnil;
9432}
9433
9434DEFUN ("discard-input", Fdiscard_input, Sdiscard_input, 0, 0, 0,
9435 "Discard the contents of the terminal input buffer.\n\
9436Also cancel any kbd macro being defined.")
9437 ()
9438{
c5fdd383 9439 current_kboard->defining_kbd_macro = Qnil;
284f4730
JB
9440 update_mode_lines++;
9441
24597608 9442 Vunread_command_events = Qnil;
86e5706b 9443 unread_command_char = -1;
284f4730
JB
9444
9445 discard_tty_input ();
9446
7ee32cda 9447 kbd_fetch_ptr = kbd_store_ptr;
da8f7368 9448 Ffillarray (kbd_buffer_gcpro, Qnil);
284f4730
JB
9449 input_pending = 0;
9450
9451 return Qnil;
9452}
9453\f
9454DEFUN ("suspend-emacs", Fsuspend_emacs, Ssuspend_emacs, 0, 1, "",
9455 "Stop Emacs and return to superior process. You can resume later.\n\
8026024c
KH
9456If `cannot-suspend' is non-nil, or if the system doesn't support job\n\
9457control, run a subshell instead.\n\n\
284f4730 9458If optional arg STUFFSTRING is non-nil, its characters are stuffed\n\
b7d2ebbf
RS
9459to be read as terminal input by Emacs's parent, after suspension.\n\
9460\n\
bbdc2092
RS
9461Before suspending, run the normal hook `suspend-hook'.\n\
9462After resumption run the normal hook `suspend-resume-hook'.\n\
284f4730
JB
9463\n\
9464Some operating systems cannot stop the Emacs process and resume it later.\n\
b7d2ebbf 9465On such systems, Emacs starts a subshell instead of suspending.")
284f4730
JB
9466 (stuffstring)
9467 Lisp_Object stuffstring;
9468{
284f4730
JB
9469 int count = specpdl_ptr - specpdl;
9470 int old_height, old_width;
9471 int width, height;
03cee6ae 9472 struct gcpro gcpro1;
284f4730
JB
9473
9474 if (!NILP (stuffstring))
9475 CHECK_STRING (stuffstring, 0);
284f4730 9476
1e95ed28
JB
9477 /* Run the functions in suspend-hook. */
9478 if (!NILP (Vrun_hooks))
9479 call1 (Vrun_hooks, intern ("suspend-hook"));
284f4730 9480
b7d2ebbf 9481 GCPRO1 (stuffstring);
ff11dfa1 9482 get_frame_size (&old_width, &old_height);
284f4730
JB
9483 reset_sys_modes ();
9484 /* sys_suspend can get an error if it tries to fork a subshell
9485 and the system resources aren't available for that. */
91a0da02 9486 record_unwind_protect ((Lisp_Object (*) P_ ((Lisp_Object))) init_sys_modes,
d52a7a92 9487 Qnil);
284f4730 9488 stuff_buffered_input (stuffstring);
8026024c
KH
9489 if (cannot_suspend)
9490 sys_subshell ();
9491 else
9492 sys_suspend ();
284f4730
JB
9493 unbind_to (count, Qnil);
9494
9495 /* Check if terminal/window size has changed.
9496 Note that this is not useful when we are running directly
9497 with a window system; but suspend should be disabled in that case. */
ff11dfa1 9498 get_frame_size (&width, &height);
284f4730 9499 if (width != old_width || height != old_height)
788f89eb 9500 change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);
284f4730 9501
1e95ed28 9502 /* Run suspend-resume-hook. */
284f4730
JB
9503 if (!NILP (Vrun_hooks))
9504 call1 (Vrun_hooks, intern ("suspend-resume-hook"));
df0f2ba1 9505
284f4730
JB
9506 UNGCPRO;
9507 return Qnil;
9508}
9509
9510/* If STUFFSTRING is a string, stuff its contents as pending terminal input.
eb8c3be9 9511 Then in any case stuff anything Emacs has read ahead and not used. */
284f4730 9512
07a59269 9513void
284f4730
JB
9514stuff_buffered_input (stuffstring)
9515 Lisp_Object stuffstring;
9516{
284f4730 9517/* stuff_char works only in BSD, versions 4.2 and up. */
6df54671 9518#ifdef BSD_SYSTEM
284f4730 9519#ifndef BSD4_1
612b78ef 9520 register unsigned char *p;
612b78ef 9521
8c18cbfb 9522 if (STRINGP (stuffstring))
284f4730
JB
9523 {
9524 register int count;
9525
9526 p = XSTRING (stuffstring)->data;
fc932ac6 9527 count = STRING_BYTES (XSTRING (stuffstring));
284f4730
JB
9528 while (count-- > 0)
9529 stuff_char (*p++);
9530 stuff_char ('\n');
9531 }
da8f7368 9532
284f4730 9533 /* Anything we have read ahead, put back for the shell to read. */
beecf6a1 9534 /* ?? What should this do when we have multiple keyboards??
c5fdd383 9535 Should we ignore anything that was typed in at the "wrong" kboard? */
beecf6a1 9536 for (; kbd_fetch_ptr != kbd_store_ptr; kbd_fetch_ptr++)
284f4730 9537 {
da8f7368
GM
9538 int idx;
9539
beecf6a1
KH
9540 if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
9541 kbd_fetch_ptr = kbd_buffer;
9542 if (kbd_fetch_ptr->kind == ascii_keystroke)
9543 stuff_char (kbd_fetch_ptr->code);
da8f7368 9544
beecf6a1 9545 kbd_fetch_ptr->kind = no_event;
da8f7368
GM
9546 idx = 2 * (kbd_fetch_ptr - kbd_buffer);
9547 ASET (kbd_buffer_gcpro, idx, Qnil);
9548 ASET (kbd_buffer_gcpro, idx + 1, Qnil);
284f4730 9549 }
da8f7368 9550
284f4730
JB
9551 input_pending = 0;
9552#endif
6df54671 9553#endif /* BSD_SYSTEM and not BSD4_1 */
284f4730
JB
9554}
9555\f
dfcf069d 9556void
ffd56f97
JB
9557set_waiting_for_input (time_to_clear)
9558 EMACS_TIME *time_to_clear;
284f4730 9559{
ffd56f97 9560 input_available_clear_time = time_to_clear;
284f4730
JB
9561
9562 /* Tell interrupt_signal to throw back to read_char, */
9563 waiting_for_input = 1;
9564
9565 /* If interrupt_signal was called before and buffered a C-g,
9566 make it run again now, to avoid timing error. */
9567 if (!NILP (Vquit_flag))
9568 quit_throw_to_read_char ();
284f4730
JB
9569}
9570
07a59269 9571void
284f4730
JB
9572clear_waiting_for_input ()
9573{
9574 /* Tell interrupt_signal not to throw back to read_char, */
9575 waiting_for_input = 0;
ffd56f97 9576 input_available_clear_time = 0;
284f4730
JB
9577}
9578
9579/* This routine is called at interrupt level in response to C-G.
d4e68eea
GM
9580
9581 If interrupt_input, this is the handler for SIGINT. Otherwise, it
9582 is called from kbd_buffer_store_event, in handling SIGIO or
9583 SIGTINT.
284f4730 9584
d4e68eea
GM
9585 If `waiting_for_input' is non zero, then unless `echoing' is
9586 nonzero, immediately throw back to read_char.
284f4730 9587
d4e68eea
GM
9588 Otherwise it sets the Lisp variable quit-flag not-nil. This causes
9589 eval to throw, when it gets a chance. If quit-flag is already
9590 non-nil, it stops the job right away. */
284f4730
JB
9591
9592SIGTYPE
91c049d4
RS
9593interrupt_signal (signalnum) /* If we don't have an argument, */
9594 int signalnum; /* some compilers complain in signal calls. */
284f4730
JB
9595{
9596 char c;
9597 /* Must preserve main program's value of errno. */
9598 int old_errno = errno;
788f89eb 9599 struct frame *sf = SELECTED_FRAME ();
284f4730 9600
5970a8cb 9601#if defined (USG) && !defined (POSIX_SIGNALS)
7a80a6f6
RS
9602 if (!read_socket_hook && NILP (Vwindow_system))
9603 {
9604 /* USG systems forget handlers when they are used;
9605 must reestablish each time */
9606 signal (SIGINT, interrupt_signal);
9607 signal (SIGQUIT, interrupt_signal);
9608 }
284f4730
JB
9609#endif /* USG */
9610
9611 cancel_echoing ();
9612
31e4e97b 9613 if (!NILP (Vquit_flag)
788f89eb 9614 && (FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf)))
284f4730 9615 {
31e4e97b
EZ
9616 /* If SIGINT isn't blocked, don't let us be interrupted by
9617 another SIGINT, it might be harmful due to non-reentrancy
9618 in I/O functions. */
9619 sigblock (sigmask (SIGINT));
9620
284f4730
JB
9621 fflush (stdout);
9622 reset_sys_modes ();
31e4e97b 9623
284f4730
JB
9624#ifdef SIGTSTP /* Support possible in later USG versions */
9625/*
9626 * On systems which can suspend the current process and return to the original
9627 * shell, this command causes the user to end up back at the shell.
9628 * The "Auto-save" and "Abort" questions are not asked until
9629 * the user elects to return to emacs, at which point he can save the current
9630 * job and either dump core or continue.
9631 */
9632 sys_suspend ();
9633#else
9634#ifdef VMS
9635 if (sys_suspend () == -1)
9636 {
9637 printf ("Not running as a subprocess;\n");
9638 printf ("you can continue or abort.\n");
9639 }
9640#else /* not VMS */
9641 /* Perhaps should really fork an inferior shell?
9642 But that would not provide any way to get back
9643 to the original shell, ever. */
9644 printf ("No support for stopping a process on this operating system;\n");
9645 printf ("you can continue or abort.\n");
9646#endif /* not VMS */
9647#endif /* not SIGTSTP */
80e4aa30
RS
9648#ifdef MSDOS
9649 /* We must remain inside the screen area when the internal terminal
9650 is used. Note that [Enter] is not echoed by dos. */
9651 cursor_to (0, 0);
9652#endif
118d6ca9
RS
9653 /* It doesn't work to autosave while GC is in progress;
9654 the code used for auto-saving doesn't cope with the mark bit. */
9655 if (!gc_in_progress)
9fd7d808 9656 {
118d6ca9
RS
9657 printf ("Auto-save? (y or n) ");
9658 fflush (stdout);
9659 if (((c = getchar ()) & ~040) == 'Y')
9660 {
9661 Fdo_auto_save (Qt, Qnil);
80e4aa30 9662#ifdef MSDOS
118d6ca9 9663 printf ("\r\nAuto-save done");
80e4aa30 9664#else /* not MSDOS */
118d6ca9 9665 printf ("Auto-save done\n");
80e4aa30 9666#endif /* not MSDOS */
118d6ca9
RS
9667 }
9668 while (c != '\n') c = getchar ();
9fd7d808 9669 }
118d6ca9
RS
9670 else
9671 {
9672 /* During GC, it must be safe to reenable quitting again. */
9673 Vinhibit_quit = Qnil;
9674#ifdef MSDOS
9675 printf ("\r\n");
9676#endif /* not MSDOS */
9677 printf ("Garbage collection in progress; cannot auto-save now\r\n");
9678 printf ("but will instead do a real quit after garbage collection ends\r\n");
9679 fflush (stdout);
9680 }
9681
80e4aa30
RS
9682#ifdef MSDOS
9683 printf ("\r\nAbort? (y or n) ");
9684#else /* not MSDOS */
284f4730
JB
9685#ifdef VMS
9686 printf ("Abort (and enter debugger)? (y or n) ");
9687#else /* not VMS */
9688 printf ("Abort (and dump core)? (y or n) ");
9689#endif /* not VMS */
80e4aa30 9690#endif /* not MSDOS */
284f4730
JB
9691 fflush (stdout);
9692 if (((c = getchar ()) & ~040) == 'Y')
9693 abort ();
9694 while (c != '\n') c = getchar ();
80e4aa30
RS
9695#ifdef MSDOS
9696 printf ("\r\nContinuing...\r\n");
9697#else /* not MSDOS */
284f4730 9698 printf ("Continuing...\n");
80e4aa30 9699#endif /* not MSDOS */
284f4730
JB
9700 fflush (stdout);
9701 init_sys_modes ();
31e4e97b 9702 sigfree ();
284f4730
JB
9703 }
9704 else
9705 {
9706 /* If executing a function that wants to be interrupted out of
9707 and the user has not deferred quitting by binding `inhibit-quit'
9708 then quit right away. */
9709 if (immediate_quit && NILP (Vinhibit_quit))
9710 {
e39da3d7
RS
9711 struct gl_state_s saved;
9712 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9713
284f4730
JB
9714 immediate_quit = 0;
9715 sigfree ();
e39da3d7
RS
9716 saved = gl_state;
9717 GCPRO4 (saved.object, saved.global_code,
9718 saved.current_syntax_table, saved.old_prop);
284f4730 9719 Fsignal (Qquit, Qnil);
e39da3d7
RS
9720 gl_state = saved;
9721 UNGCPRO;
284f4730
JB
9722 }
9723 else
9724 /* Else request quit when it's safe */
9725 Vquit_flag = Qt;
9726 }
9727
9728 if (waiting_for_input && !echoing)
9729 quit_throw_to_read_char ();
9730
9731 errno = old_errno;
9732}
9733
9734/* Handle a C-g by making read_char return C-g. */
9735
07a59269 9736void
284f4730
JB
9737quit_throw_to_read_char ()
9738{
284f4730
JB
9739 sigfree ();
9740 /* Prevent another signal from doing this before we finish. */
f76475ad 9741 clear_waiting_for_input ();
284f4730
JB
9742 input_pending = 0;
9743
24597608 9744 Vunread_command_events = Qnil;
86e5706b 9745 unread_command_char = -1;
284f4730 9746
087feab3
RS
9747#if 0 /* Currently, sit_for is called from read_char without turning
9748 off polling. And that can call set_waiting_for_input.
9749 It seems to be harmless. */
e6b01c14
JB
9750#ifdef POLL_FOR_INPUT
9751 /* May be > 1 if in recursive minibuffer. */
9752 if (poll_suppress_count == 0)
9753 abort ();
9754#endif
087feab3 9755#endif
4c52b668 9756 if (FRAMEP (internal_last_event_frame)
788f89eb 9757 && !EQ (internal_last_event_frame, selected_frame))
719191cf
RS
9758 do_switch_frame (make_lispy_switch_frame (internal_last_event_frame),
9759 Qnil, 0);
e6b01c14 9760
284f4730
JB
9761 _longjmp (getcjmp, 1);
9762}
9763\f
9764DEFUN ("set-input-mode", Fset_input_mode, Sset_input_mode, 3, 4, 0,
9765 "Set mode of reading keyboard input.\n\
464f8898
RS
9766First arg INTERRUPT non-nil means use input interrupts;\n\
9767 nil means use CBREAK mode.\n\
9768Second arg FLOW non-nil means use ^S/^Q flow control for output to terminal\n\
284f4730 9769 (no effect except in CBREAK mode).\n\
b04904fb
RS
9770Third arg META t means accept 8-bit input (for a Meta key).\n\
9771 META nil means ignore the top bit, on the assumption it is parity.\n\
9772 Otherwise, accept 8-bit input and don't use the top bit for Meta.\n\
a8ee7ef9
RS
9773Optional fourth arg QUIT if non-nil specifies character to use for quitting.\n\
9774See also `current-input-mode'.")
284f4730
JB
9775 (interrupt, flow, meta, quit)
9776 Lisp_Object interrupt, flow, meta, quit;
9777{
9778 if (!NILP (quit)
8c18cbfb 9779 && (!INTEGERP (quit) || XINT (quit) < 0 || XINT (quit) > 0400))
34f04431
RS
9780 error ("set-input-mode: QUIT must be an ASCII character");
9781
9782#ifdef POLL_FOR_INPUT
9783 stop_polling ();
9784#endif
284f4730 9785
07de30b9 9786#ifndef DOS_NT
2ee250ec 9787 /* this causes startup screen to be restored and messes with the mouse */
284f4730 9788 reset_sys_modes ();
2ee250ec
RS
9789#endif
9790
284f4730
JB
9791#ifdef SIGIO
9792/* Note SIGIO has been undef'd if FIONREAD is missing. */
284f4730 9793 if (read_socket_hook)
9a0f60bb
KH
9794 {
9795 /* When using X, don't give the user a real choice,
9796 because we haven't implemented the mechanisms to support it. */
9797#ifdef NO_SOCK_SIGIO
9798 interrupt_input = 0;
9799#else /* not NO_SOCK_SIGIO */
9800 interrupt_input = 1;
284f4730 9801#endif /* NO_SOCK_SIGIO */
9a0f60bb
KH
9802 }
9803 else
284f4730
JB
9804 interrupt_input = !NILP (interrupt);
9805#else /* not SIGIO */
9806 interrupt_input = 0;
9807#endif /* not SIGIO */
9a0f60bb 9808
284f4730
JB
9809/* Our VMS input only works by interrupts, as of now. */
9810#ifdef VMS
9811 interrupt_input = 1;
9812#endif
9a0f60bb 9813
284f4730 9814 flow_control = !NILP (flow);
b04904fb
RS
9815 if (NILP (meta))
9816 meta_key = 0;
9817 else if (EQ (meta, Qt))
9818 meta_key = 1;
9819 else
9820 meta_key = 2;
284f4730
JB
9821 if (!NILP (quit))
9822 /* Don't let this value be out of range. */
9823 quit_char = XINT (quit) & (meta_key ? 0377 : 0177);
9824
07de30b9 9825#ifndef DOS_NT
284f4730 9826 init_sys_modes ();
2ee250ec 9827#endif
34f04431
RS
9828
9829#ifdef POLL_FOR_INPUT
9830 poll_suppress_count = 1;
9831 start_polling ();
9832#endif
284f4730
JB
9833 return Qnil;
9834}
80645119
JB
9835
9836DEFUN ("current-input-mode", Fcurrent_input_mode, Scurrent_input_mode, 0, 0, 0,
9837 "Return information about the way Emacs currently reads keyboard input.\n\
9838The value is a list of the form (INTERRUPT FLOW META QUIT), where\n\
9839 INTERRUPT is non-nil if Emacs is using interrupt-driven input; if\n\
9840 nil, Emacs is using CBREAK mode.\n\
9841 FLOW is non-nil if Emacs uses ^S/^Q flow control for output to the\n\
9842 terminal; this does not apply if Emacs uses interrupt-driven input.\n\
a8ee7ef9
RS
9843 META is t if accepting 8-bit input with 8th bit as Meta flag.\n\
9844 META nil means ignoring the top bit, on the assumption it is parity.\n\
9845 META is neither t nor nil if accepting 8-bit input and using\n\
9846 all 8 bits as the character code.\n\
80645119
JB
9847 QUIT is the character Emacs currently uses to quit.\n\
9848The elements of this list correspond to the arguments of\n\
a8ee7ef9 9849`set-input-mode'.")
80645119
JB
9850 ()
9851{
9852 Lisp_Object val[4];
9853
9854 val[0] = interrupt_input ? Qt : Qnil;
9855 val[1] = flow_control ? Qt : Qnil;
a8ee7ef9 9856 val[2] = meta_key == 2 ? make_number (0) : meta_key == 1 ? Qt : Qnil;
bb9e9bed 9857 XSETFASTINT (val[3], quit_char);
80645119 9858
bf673a7a 9859 return Flist (sizeof (val) / sizeof (val[0]), val);
80645119
JB
9860}
9861
284f4730 9862\f
6c6083a9 9863/*
c5fdd383 9864 * Set up a new kboard object with reasonable initial values.
6c6083a9
KH
9865 */
9866void
c5fdd383
KH
9867init_kboard (kb)
9868 KBOARD *kb;
6c6083a9 9869{
217258d5 9870 kb->Voverriding_terminal_local_map = Qnil;
6c7178b9 9871 kb->Vlast_command = Qnil;
75045dcb 9872 kb->Vreal_last_command = Qnil;
d8bcf58e 9873 kb->Vprefix_arg = Qnil;
75045dcb 9874 kb->Vlast_prefix_arg = Qnil;
c5fdd383
KH
9875 kb->kbd_queue = Qnil;
9876 kb->kbd_queue_has_data = 0;
9877 kb->immediate_echo = 0;
9878 kb->echoptr = kb->echobuf;
9879 kb->echo_after_prompt = -1;
9880 kb->kbd_macro_buffer = 0;
9881 kb->kbd_macro_bufsize = 0;
9882 kb->defining_kbd_macro = Qnil;
9883 kb->Vlast_kbd_macro = Qnil;
9884 kb->reference_count = 0;
7c97ffdc 9885 kb->Vsystem_key_alist = Qnil;
142e6c73 9886 kb->system_key_syms = Qnil;
9ba47203 9887 kb->Vdefault_minibuffer_frame = Qnil;
6c6083a9
KH
9888}
9889
9890/*
c5fdd383 9891 * Destroy the contents of a kboard object, but not the object itself.
8e6208c5 9892 * We use this just before deleting it, or if we're going to initialize
6c6083a9
KH
9893 * it a second time.
9894 */
e50b8090 9895static void
c5fdd383
KH
9896wipe_kboard (kb)
9897 KBOARD *kb;
6c6083a9 9898{
c5fdd383
KH
9899 if (kb->kbd_macro_buffer)
9900 xfree (kb->kbd_macro_buffer);
6c6083a9
KH
9901}
9902
e50b8090
KH
9903#ifdef MULTI_KBOARD
9904void
9905delete_kboard (kb)
9906 KBOARD *kb;
9907{
9908 KBOARD **kbp;
9909 for (kbp = &all_kboards; *kbp != kb; kbp = &(*kbp)->next_kboard)
9910 if (*kbp == NULL)
9911 abort ();
9912 *kbp = kb->next_kboard;
9913 wipe_kboard (kb);
9914 xfree (kb);
9915}
9916#endif
9917
dfcf069d 9918void
284f4730
JB
9919init_keyboard ()
9920{
284f4730
JB
9921 /* This is correct before outermost invocation of the editor loop */
9922 command_loop_level = -1;
9923 immediate_quit = 0;
9924 quit_char = Ctl ('g');
24597608 9925 Vunread_command_events = Qnil;
86e5706b 9926 unread_command_char = -1;
87dd9b9b 9927 EMACS_SET_SECS_USECS (timer_idleness_start_time, -1, -1);
284f4730 9928 total_keys = 0;
9deb415a 9929 recent_keys_index = 0;
beecf6a1
KH
9930 kbd_fetch_ptr = kbd_buffer;
9931 kbd_store_ptr = kbd_buffer;
da8f7368 9932 kbd_buffer_gcpro = Fmake_vector (make_number (2 * KBD_BUFFER_SIZE), Qnil);
2eb6bfbe 9933#ifdef HAVE_MOUSE
a9d77f1f 9934 do_mouse_tracking = Qnil;
2eb6bfbe 9935#endif
284f4730
JB
9936 input_pending = 0;
9937
4c52b668
KH
9938 /* This means that command_loop_1 won't try to select anything the first
9939 time through. */
9940 internal_last_event_frame = Qnil;
9941 Vlast_event_frame = internal_last_event_frame;
4c52b668 9942
c5fdd383 9943#ifdef MULTI_KBOARD
aaca43a1 9944 current_kboard = initial_kboard;
6c6083a9 9945#endif
aaca43a1 9946 wipe_kboard (current_kboard);
c5fdd383 9947 init_kboard (current_kboard);
07d2b8de 9948
7a80a6f6 9949 if (!noninteractive && !read_socket_hook && NILP (Vwindow_system))
284f4730
JB
9950 {
9951 signal (SIGINT, interrupt_signal);
cb5df6ae 9952#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
284f4730
JB
9953 /* For systems with SysV TERMIO, C-g is set up for both SIGINT and
9954 SIGQUIT and we can't tell which one it will give us. */
9955 signal (SIGQUIT, interrupt_signal);
9956#endif /* HAVE_TERMIO */
7a80a6f6 9957 }
284f4730
JB
9958/* Note SIGIO has been undef'd if FIONREAD is missing. */
9959#ifdef SIGIO
7a80a6f6
RS
9960 if (!noninteractive)
9961 signal (SIGIO, input_available_signal);
8ea0a720 9962#endif /* SIGIO */
284f4730
JB
9963
9964/* Use interrupt input by default, if it works and noninterrupt input
9965 has deficiencies. */
9966
9967#ifdef INTERRUPT_INPUT
9968 interrupt_input = 1;
9969#else
9970 interrupt_input = 0;
9971#endif
9972
9973/* Our VMS input only works by interrupts, as of now. */
9974#ifdef VMS
9975 interrupt_input = 1;
9976#endif
9977
9978 sigfree ();
9979 dribble = 0;
9980
9981 if (keyboard_init_hook)
9982 (*keyboard_init_hook) ();
9983
9984#ifdef POLL_FOR_INPUT
9985 poll_suppress_count = 1;
9986 start_polling ();
9987#endif
9988}
9989
df0f2ba1 9990/* This type's only use is in syms_of_keyboard, to initialize the
284f4730
JB
9991 event header symbols and put properties on them. */
9992struct event_head {
9993 Lisp_Object *var;
9994 char *name;
9995 Lisp_Object *kind;
9996};
9997
9998struct event_head head_table[] = {
7b4aedb9 9999 &Qmouse_movement, "mouse-movement", &Qmouse_movement,
3c370943 10000 &Qscroll_bar_movement, "scroll-bar-movement", &Qmouse_movement,
7b4aedb9 10001 &Qswitch_frame, "switch-frame", &Qswitch_frame,
bbdc2092 10002 &Qdelete_frame, "delete-frame", &Qdelete_frame,
af17bd2b
KH
10003 &Qiconify_frame, "iconify-frame", &Qiconify_frame,
10004 &Qmake_frame_visible, "make-frame-visible", &Qmake_frame_visible,
284f4730
JB
10005};
10006
dfcf069d 10007void
284f4730
JB
10008syms_of_keyboard ()
10009{
8e1e4240
GM
10010 Vlispy_mouse_stem = build_string ("mouse");
10011 staticpro (&Vlispy_mouse_stem);
10012
9ea173e8 10013 /* Tool-bars. */
7ee32cda
GM
10014 QCimage = intern (":image");
10015 staticpro (&QCimage);
10016
10017 staticpro (&Qhelp_echo);
10018 Qhelp_echo = intern ("help-echo");
10019
e8886a1d
RS
10020 staticpro (&item_properties);
10021 item_properties = Qnil;
10022
9ea173e8
GM
10023 staticpro (&tool_bar_item_properties);
10024 tool_bar_item_properties = Qnil;
10025 staticpro (&tool_bar_items_vector);
10026 tool_bar_items_vector = Qnil;
7ee32cda 10027
d5eecefb
RS
10028 staticpro (&real_this_command);
10029 real_this_command = Qnil;
10030
d925fb39
RS
10031 Qtimer_event_handler = intern ("timer-event-handler");
10032 staticpro (&Qtimer_event_handler);
10033
2e894dab
RS
10034 Qdisabled_command_hook = intern ("disabled-command-hook");
10035 staticpro (&Qdisabled_command_hook);
10036
284f4730
JB
10037 Qself_insert_command = intern ("self-insert-command");
10038 staticpro (&Qself_insert_command);
10039
10040 Qforward_char = intern ("forward-char");
10041 staticpro (&Qforward_char);
10042
10043 Qbackward_char = intern ("backward-char");
10044 staticpro (&Qbackward_char);
10045
10046 Qdisabled = intern ("disabled");
10047 staticpro (&Qdisabled);
10048
e58aa385
RS
10049 Qundefined = intern ("undefined");
10050 staticpro (&Qundefined);
10051
86e5706b
RS
10052 Qpre_command_hook = intern ("pre-command-hook");
10053 staticpro (&Qpre_command_hook);
10054
10055 Qpost_command_hook = intern ("post-command-hook");
10056 staticpro (&Qpost_command_hook);
10057
59aadc81
RS
10058 Qpost_command_idle_hook = intern ("post-command-idle-hook");
10059 staticpro (&Qpost_command_idle_hook);
10060
3ef14e46
RS
10061 Qdeferred_action_function = intern ("deferred-action-function");
10062 staticpro (&Qdeferred_action_function);
10063
40932d1a
RS
10064 Qcommand_hook_internal = intern ("command-hook-internal");
10065 staticpro (&Qcommand_hook_internal);
10066
284f4730
JB
10067 Qfunction_key = intern ("function-key");
10068 staticpro (&Qfunction_key);
13b5e56c 10069 Qmouse_click = intern ("mouse-click");
284f4730 10070 staticpro (&Qmouse_click);
07de30b9
GV
10071#ifdef WINDOWSNT
10072 Qmouse_wheel = intern ("mouse-wheel");
10073 staticpro (&Qmouse_wheel);
1161d367
GV
10074 Qlanguage_change = intern ("language-change");
10075 staticpro (&Qlanguage_change);
07de30b9 10076#endif
a24dc617
RS
10077 Qdrag_n_drop = intern ("drag-n-drop");
10078 staticpro (&Qdrag_n_drop);
284f4730 10079
5bf68f6e
AS
10080 Qusr1_signal = intern ("usr1-signal");
10081 staticpro (&Qusr1_signal);
10082 Qusr2_signal = intern ("usr2-signal");
10083 staticpro (&Qusr2_signal);
10084
598a9fa7
JB
10085 Qmenu_enable = intern ("menu-enable");
10086 staticpro (&Qmenu_enable);
e8886a1d
RS
10087 Qmenu_alias = intern ("menu-alias");
10088 staticpro (&Qmenu_alias);
10089 QCenable = intern (":enable");
10090 staticpro (&QCenable);
10091 QCvisible = intern (":visible");
10092 staticpro (&QCvisible);
7ee32cda
GM
10093 QChelp = intern (":help");
10094 staticpro (&QChelp);
e8886a1d
RS
10095 QCfilter = intern (":filter");
10096 staticpro (&QCfilter);
10097 QCbutton = intern (":button");
10098 staticpro (&QCbutton);
74c1de23
RS
10099 QCkeys = intern (":keys");
10100 staticpro (&QCkeys);
10101 QCkey_sequence = intern (":key-sequence");
10102 staticpro (&QCkey_sequence);
e8886a1d
RS
10103 QCtoggle = intern (":toggle");
10104 staticpro (&QCtoggle);
10105 QCradio = intern (":radio");
10106 staticpro (&QCradio);
598a9fa7 10107
284f4730
JB
10108 Qmode_line = intern ("mode-line");
10109 staticpro (&Qmode_line);
e5d77022
JB
10110 Qvertical_line = intern ("vertical-line");
10111 staticpro (&Qvertical_line);
3c370943
JB
10112 Qvertical_scroll_bar = intern ("vertical-scroll-bar");
10113 staticpro (&Qvertical_scroll_bar);
5ec75a55
RS
10114 Qmenu_bar = intern ("menu-bar");
10115 staticpro (&Qmenu_bar);
4bb994d1
JB
10116
10117 Qabove_handle = intern ("above-handle");
10118 staticpro (&Qabove_handle);
10119 Qhandle = intern ("handle");
10120 staticpro (&Qhandle);
10121 Qbelow_handle = intern ("below-handle");
10122 staticpro (&Qbelow_handle);
db08707d
RS
10123 Qup = intern ("up");
10124 staticpro (&Qup);
10125 Qdown = intern ("down");
10126 staticpro (&Qdown);
7ee32cda
GM
10127 Qtop = intern ("top");
10128 staticpro (&Qtop);
10129 Qbottom = intern ("bottom");
10130 staticpro (&Qbottom);
10131 Qend_scroll = intern ("end-scroll");
10132 staticpro (&Qend_scroll);
eef28553
SM
10133 Qratio = intern ("ratio");
10134 staticpro (&Qratio);
284f4730 10135
cd21b839 10136 Qevent_kind = intern ("event-kind");
284f4730 10137 staticpro (&Qevent_kind);
88cb0656
JB
10138 Qevent_symbol_elements = intern ("event-symbol-elements");
10139 staticpro (&Qevent_symbol_elements);
0a7f1fc0
JB
10140 Qevent_symbol_element_mask = intern ("event-symbol-element-mask");
10141 staticpro (&Qevent_symbol_element_mask);
10142 Qmodifier_cache = intern ("modifier-cache");
10143 staticpro (&Qmodifier_cache);
284f4730 10144
48e416d4
RS
10145 Qrecompute_lucid_menubar = intern ("recompute-lucid-menubar");
10146 staticpro (&Qrecompute_lucid_menubar);
10147 Qactivate_menubar_hook = intern ("activate-menubar-hook");
10148 staticpro (&Qactivate_menubar_hook);
10149
f4eef8b4
RS
10150 Qpolling_period = intern ("polling-period");
10151 staticpro (&Qpolling_period);
10152
7d18f9ae
RS
10153 Qinput_method_function = intern ("input-method-function");
10154 staticpro (&Qinput_method_function);
10155
d5eecefb
RS
10156 Qinput_method_exit_on_first_char = intern ("input-method-exit-on-first-char");
10157 staticpro (&Qinput_method_exit_on_first_char);
10158 Qinput_method_use_echo_area = intern ("input-method-use-echo-area");
10159 staticpro (&Qinput_method_use_echo_area);
10160
10161 Fset (Qinput_method_exit_on_first_char, Qnil);
10162 Fset (Qinput_method_use_echo_area, Qnil);
10163
e18dfbf4
KR
10164 last_point_position_buffer = Qnil;
10165
284f4730
JB
10166 {
10167 struct event_head *p;
10168
10169 for (p = head_table;
10170 p < head_table + (sizeof (head_table) / sizeof (head_table[0]));
10171 p++)
10172 {
10173 *p->var = intern (p->name);
10174 staticpro (p->var);
10175 Fput (*p->var, Qevent_kind, *p->kind);
88cb0656 10176 Fput (*p->var, Qevent_symbol_elements, Fcons (*p->var, Qnil));
284f4730
JB
10177 }
10178 }
10179
8e1e4240 10180 button_down_location = Fmake_vector (make_number (1), Qnil);
7b4aedb9 10181 staticpro (&button_down_location);
8e1e4240
GM
10182 mouse_syms = Fmake_vector (make_number (1), Qnil);
10183 staticpro (&mouse_syms);
88cb0656
JB
10184
10185 {
10186 int i;
10187 int len = sizeof (modifier_names) / sizeof (modifier_names[0]);
10188
10189 modifier_symbols = Fmake_vector (make_number (len), Qnil);
10190 for (i = 0; i < len; i++)
86e5706b
RS
10191 if (modifier_names[i])
10192 XVECTOR (modifier_symbols)->contents[i] = intern (modifier_names[i]);
88cb0656
JB
10193 staticpro (&modifier_symbols);
10194 }
10195
9deb415a
JB
10196 recent_keys = Fmake_vector (make_number (NUM_RECENT_KEYS), Qnil);
10197 staticpro (&recent_keys);
10198
6569cc8d 10199 this_command_keys = Fmake_vector (make_number (40), Qnil);
715d9345 10200 staticpro (&this_command_keys);
6569cc8d 10201
7d18f9ae
RS
10202 raw_keybuf = Fmake_vector (make_number (30), Qnil);
10203 staticpro (&raw_keybuf);
10204
03b4122a
BF
10205 Qextended_command_history = intern ("extended-command-history");
10206 Fset (Qextended_command_history, Qnil);
10207 staticpro (&Qextended_command_history);
10208
da8f7368
GM
10209 kbd_buffer_gcpro = Fmake_vector (make_number (2 * KBD_BUFFER_SIZE), Qnil);
10210 staticpro (&kbd_buffer_gcpro);
beecf6a1 10211
24597608
RS
10212 accent_key_syms = Qnil;
10213 staticpro (&accent_key_syms);
10214
284f4730
JB
10215 func_key_syms = Qnil;
10216 staticpro (&func_key_syms);
10217
07de30b9
GV
10218#ifdef WINDOWSNT
10219 mouse_wheel_syms = Qnil;
10220 staticpro (&mouse_wheel_syms);
a24dc617
RS
10221
10222 drag_n_drop_syms = Qnil;
10223 staticpro (&drag_n_drop_syms);
07de30b9
GV
10224#endif
10225
cd21b839
JB
10226 unread_switch_frame = Qnil;
10227 staticpro (&unread_switch_frame);
10228
fe412364
EN
10229 internal_last_event_frame = Qnil;
10230 staticpro (&internal_last_event_frame);
10231
10232 read_key_sequence_cmd = Qnil;
10233 staticpro (&read_key_sequence_cmd);
10234
759860a6
RS
10235 menu_bar_one_keymap_changed_items = Qnil;
10236 staticpro (&menu_bar_one_keymap_changed_items);
10237
a1706c30 10238 defsubr (&Sevent_convert_list);
284f4730 10239 defsubr (&Sread_key_sequence);
e39da3d7 10240 defsubr (&Sread_key_sequence_vector);
284f4730 10241 defsubr (&Srecursive_edit);
2eb6bfbe 10242#ifdef HAVE_MOUSE
284f4730 10243 defsubr (&Strack_mouse);
2eb6bfbe 10244#endif
284f4730
JB
10245 defsubr (&Sinput_pending_p);
10246 defsubr (&Scommand_execute);
10247 defsubr (&Srecent_keys);
10248 defsubr (&Sthis_command_keys);
e39da3d7 10249 defsubr (&Sthis_command_keys_vector);
6321824f 10250 defsubr (&Sthis_single_command_keys);
7d18f9ae 10251 defsubr (&Sthis_single_command_raw_keys);
71918b75 10252 defsubr (&Sreset_this_command_lengths);
82e6e5af 10253 defsubr (&Sclear_this_command_keys);
284f4730
JB
10254 defsubr (&Ssuspend_emacs);
10255 defsubr (&Sabort_recursive_edit);
10256 defsubr (&Sexit_recursive_edit);
10257 defsubr (&Srecursion_depth);
10258 defsubr (&Stop_level);
10259 defsubr (&Sdiscard_input);
10260 defsubr (&Sopen_dribble_file);
10261 defsubr (&Sset_input_mode);
80645119 10262 defsubr (&Scurrent_input_mode);
284f4730
JB
10263 defsubr (&Sexecute_extended_command);
10264
284f4730 10265 DEFVAR_LISP ("last-command-char", &last_command_char,
86e5706b
RS
10266 "Last input event that was part of a command.");
10267
186cf719 10268 DEFVAR_LISP_NOPRO ("last-command-event", &last_command_char,
86e5706b 10269 "Last input event that was part of a command.");
284f4730 10270
7d6de002 10271 DEFVAR_LISP ("last-nonmenu-event", &last_nonmenu_event,
86e5706b 10272 "Last input event in a command, except for mouse menu events.\n\
7d6de002
RS
10273Mouse menus give back keys that don't look like mouse events;\n\
10274this variable holds the actual mouse event that led to the menu,\n\
10275so that you can determine whether the command was run by mouse or not.");
10276
284f4730 10277 DEFVAR_LISP ("last-input-char", &last_input_char,
86e5706b
RS
10278 "Last input event.");
10279
186cf719 10280 DEFVAR_LISP_NOPRO ("last-input-event", &last_input_char,
86e5706b 10281 "Last input event.");
284f4730 10282
24597608 10283 DEFVAR_LISP ("unread-command-events", &Vunread_command_events,
7d18f9ae
RS
10284 "List of events to be read as the command input.\n\
10285These events are processed first, before actual keyboard input.");
10286 Vunread_command_events = Qnil;
284f4730 10287
86e5706b
RS
10288 DEFVAR_INT ("unread-command-char", &unread_command_char,
10289 "If not -1, an object to be read as next command input event.");
10290
7d18f9ae
RS
10291 DEFVAR_LISP ("unread-post-input-method-events", &Vunread_post_input_method_events,
10292 "List of events to be processed as input by input methods.\n\
10293These events are processed after `unread-command-events', but\n\
10294before actual keyboard input.");
10295 Vunread_post_input_method_events = Qnil;
10296
10297 DEFVAR_LISP ("unread-input-method-events", &Vunread_input_method_events,
10298 "List of events to be processed as input by input methods.\n\
10299These events are processed after `unread-command-events', but\n\
10300before actual keyboard input.");
10301 Vunread_input_method_events = Qnil;
10302
284f4730 10303 DEFVAR_LISP ("meta-prefix-char", &meta_prefix_char,
b283f79e
KH
10304 "Meta-prefix character code.\n\
10305Meta-foo as command input turns into this character followed by foo.");
18cd2eeb 10306 XSETINT (meta_prefix_char, 033);
284f4730 10307
6c7178b9 10308 DEFVAR_KBOARD ("last-command", Vlast_command,
b283f79e
KH
10309 "The last command executed.\n\
10310Normally a symbol with a function definition, but can be whatever was found\n\
10311in the keymap, or whatever the variable `this-command' was set to by that\n\
10312command.\n\
18f29056
RS
10313\n\
10314The value `mode-exit' is special; it means that the previous command\n\
10315read an event that told it to exit, and it did so and unread that event.\n\
10316In other words, the present command is the event that made the previous\n\
10317command exit.\n\
10318\n\
10319The value `kill-region' is special; it means that the previous command\n\
10320was a kill command.");
284f4730 10321
75045dcb
RS
10322 DEFVAR_KBOARD ("real-last-command", Vreal_last_command,
10323 "Same as `last-command', but never altered by Lisp code.");
10324
d5eecefb 10325 DEFVAR_LISP ("this-command", &Vthis_command,
284f4730
JB
10326 "The command now being executed.\n\
10327The command can set this variable; whatever is put here\n\
10328will be in `last-command' during the following command.");
d5eecefb 10329 Vthis_command = Qnil;
284f4730
JB
10330
10331 DEFVAR_INT ("auto-save-interval", &auto_save_interval,
dace7f4e 10332 "*Number of input events between auto-saves.\n\
284f4730
JB
10333Zero means disable autosaving due to number of characters typed.");
10334 auto_save_interval = 300;
10335
10336 DEFVAR_LISP ("auto-save-timeout", &Vauto_save_timeout,
10337 "*Number of seconds idle time before auto-save.\n\
06ef7355
RS
10338Zero or nil means disable auto-saving due to idleness.\n\
10339After auto-saving due to this many seconds of idle time,\n\
84447c71 10340Emacs also does a garbage collection if that seems to be warranted.");
bb9e9bed 10341 XSETFASTINT (Vauto_save_timeout, 30);
284f4730 10342
39aab679 10343 DEFVAR_LISP ("echo-keystrokes", &Vecho_keystrokes,
f2647d04
DL
10344 "*Nonzero means echo unfinished commands after this many seconds of pause.\n\
10345The value may be integer or floating point.");
39aab679 10346 Vecho_keystrokes = make_number (1);
284f4730
JB
10347
10348 DEFVAR_INT ("polling-period", &polling_period,
10349 "*Interval between polling for input during Lisp execution.\n\
10350The reason for polling is to make C-g work to stop a running program.\n\
10351Polling is needed only when using X windows and SIGIO does not work.\n\
10352Polling is automatically disabled in all other cases.");
10353 polling_period = 2;
df0f2ba1 10354
564dc952 10355 DEFVAR_LISP ("double-click-time", &Vdouble_click_time,
fbcd35bd 10356 "*Maximum time between mouse clicks to make a double-click.\n\
564dc952
JB
10357Measured in milliseconds. nil means disable double-click recognition;\n\
10358t means double-clicks have no time limit and are detected\n\
fbcd35bd 10359by position only.");
aab06933 10360 Vdouble_click_time = make_number (500);
fbcd35bd 10361
03361bcc
RS
10362 DEFVAR_BOOL ("inhibit-local-menu-bar-menus", &inhibit_local_menu_bar_menus,
10363 "*Non-nil means inhibit local map menu bar menus.");
10364 inhibit_local_menu_bar_menus = 0;
10365
284f4730 10366 DEFVAR_INT ("num-input-keys", &num_input_keys,
c43b1734 10367 "Number of complete key sequences read as input so far.\n\
58ce35fb
KH
10368This includes key sequences read from keyboard macros.\n\
10369The number is effectively the number of interactive command invocations.");
284f4730
JB
10370 num_input_keys = 0;
10371
c43b1734
RS
10372 DEFVAR_INT ("num-nonmacro-input-events", &num_nonmacro_input_events,
10373 "Number of input events read from the keyboard so far.\n\
10374This does not include events generated by keyboard macros.");
10375 num_nonmacro_input_events = 0;
fa90970d 10376
4c52b668
KH
10377 DEFVAR_LISP ("last-event-frame", &Vlast_event_frame,
10378 "The frame in which the most recently read event occurred.\n\
10379If the last event came from a keyboard macro, this is set to `macro'.");
10380 Vlast_event_frame = Qnil;
10381
fa90970d
RS
10382 /* This variable is set up in sysdep.c. */
10383 DEFVAR_LISP ("tty-erase-char", &Vtty_erase_char,
10384 "The ERASE character as set by the user with stty.");
10385
7e85b935 10386 DEFVAR_LISP ("help-char", &Vhelp_char,
284f4730
JB
10387 "Character to recognize as meaning Help.\n\
10388When it is read, do `(eval help-form)', and display result if it's a string.\n\
10389If the value of `help-form' is nil, this char can be read normally.");
18cd2eeb 10390 XSETINT (Vhelp_char, Ctl ('H'));
284f4730 10391
ecb7cb34
KH
10392 DEFVAR_LISP ("help-event-list", &Vhelp_event_list,
10393 "List of input events to recognize as meaning Help.\n\
10394These work just like the value of `help-char' (see that).");
10395 Vhelp_event_list = Qnil;
10396
284f4730 10397 DEFVAR_LISP ("help-form", &Vhelp_form,
7e85b935 10398 "Form to execute when character `help-char' is read.\n\
284f4730
JB
10399If the form returns a string, that string is displayed.\n\
10400If `help-form' is nil, the help char is not recognized.");
10401 Vhelp_form = Qnil;
10402
7e85b935
RS
10403 DEFVAR_LISP ("prefix-help-command", &Vprefix_help_command,
10404 "Command to run when `help-char' character follows a prefix key.\n\
10405This command is used only when there is no actual binding\n\
10406for that character after that prefix key.");
10407 Vprefix_help_command = Qnil;
10408
284f4730
JB
10409 DEFVAR_LISP ("top-level", &Vtop_level,
10410 "Form to evaluate when Emacs starts up.\n\
10411Useful to set before you dump a modified Emacs.");
10412 Vtop_level = Qnil;
10413
10414 DEFVAR_LISP ("keyboard-translate-table", &Vkeyboard_translate_table,
f9414d62 10415 "Translate table for keyboard input, or nil.\n\
284f4730 10416Each character is looked up in this string and the contents used instead.\n\
f9414d62
RS
10417The value may be a string, a vector, or a char-table.\n\
10418If it is a string or vector of length N,\n\
10419character codes N and up are untranslated.\n\
10420In a vector or a char-table, an element which is nil means \"no translation\".");
284f4730
JB
10421 Vkeyboard_translate_table = Qnil;
10422
8026024c 10423 DEFVAR_BOOL ("cannot-suspend", &cannot_suspend,
b283f79e
KH
10424 "Non-nil means to always spawn a subshell instead of suspending.\n\
10425\(Even if the operating system has support for stopping a process.\)");
8026024c
KH
10426 cannot_suspend = 0;
10427
284f4730 10428 DEFVAR_BOOL ("menu-prompting", &menu_prompting,
7d6de002 10429 "Non-nil means prompt with menus when appropriate.\n\
284f4730 10430This is done when reading from a keymap that has a prompt string,\n\
7d6de002
RS
10431for elements that have prompt strings.\n\
10432The menu is displayed on the screen\n\
10433if X menus were enabled at configuration\n\
10434time and the previous event was a mouse click prefix key.\n\
10435Otherwise, menu prompting uses the echo area.");
284f4730
JB
10436 menu_prompting = 1;
10437
10438 DEFVAR_LISP ("menu-prompt-more-char", &menu_prompt_more_char,
10439 "Character to see next line of menu prompt.\n\
10440Type this character while in a menu prompt to rotate around the lines of it.");
18cd2eeb 10441 XSETINT (menu_prompt_more_char, ' ');
9fa4395d
RS
10442
10443 DEFVAR_INT ("extra-keyboard-modifiers", &extra_keyboard_modifiers,
10444 "A mask of additional modifier keys to use with every keyboard character.\n\
ad163903
JB
10445Emacs applies the modifiers of the character stored here to each keyboard\n\
10446character it reads. For example, after evaluating the expression\n\
9d9f56dd 10447 (setq extra-keyboard-modifiers ?\\C-x)\n\
80645119
JB
10448all input characters will have the control modifier applied to them.\n\
10449\n\
9d9f56dd 10450Note that the character ?\\C-@, equivalent to the integer zero, does\n\
80645119 10451not count as a control character; rather, it counts as a character\n\
27203ead 10452with no modifiers; thus, setting `extra-keyboard-modifiers' to zero\n\
80645119 10453cancels any modification.");
9fa4395d 10454 extra_keyboard_modifiers = 0;
86e5706b
RS
10455
10456 DEFVAR_LISP ("deactivate-mark", &Vdeactivate_mark,
10457 "If an editing command sets this to t, deactivate the mark afterward.\n\
10458The command loop sets this to nil before each command,\n\
10459and tests the value when the command returns.\n\
10460Buffer modification stores t in this variable.");
10461 Vdeactivate_mark = Qnil;
10462
b0f2a7bf
KH
10463 DEFVAR_LISP ("command-hook-internal", &Vcommand_hook_internal,
10464 "Temporary storage of pre-command-hook or post-command-hook.");
10465 Vcommand_hook_internal = Qnil;
10466
86e5706b 10467 DEFVAR_LISP ("pre-command-hook", &Vpre_command_hook,
a1fd42c0 10468 "Normal hook run before each command is executed.\n\
307958d6
RS
10469If an unhandled error happens in running this hook,\n\
10470the hook value is set to nil, since otherwise the error\n\
10471might happen repeatedly and make Emacs nonfunctional.");
86e5706b
RS
10472 Vpre_command_hook = Qnil;
10473
10474 DEFVAR_LISP ("post-command-hook", &Vpost_command_hook,
a1fd42c0 10475 "Normal hook run after each command is executed.\n\
307958d6
RS
10476If an unhandled error happens in running this hook,\n\
10477the hook value is set to nil, since otherwise the error\n\
10478might happen repeatedly and make Emacs nonfunctional.");
86e5706b 10479 Vpost_command_hook = Qnil;
48e416d4 10480
59aadc81
RS
10481 DEFVAR_LISP ("post-command-idle-hook", &Vpost_command_idle_hook,
10482 "Normal hook run after each command is executed, if idle.\n\
d4d62e8d
RS
10483Errors running the hook are caught and ignored.\n\
10484This feature is obsolete; use idle timers instead. See `etc/NEWS'.");
59aadc81
RS
10485 Vpost_command_idle_hook = Qnil;
10486
10487 DEFVAR_INT ("post-command-idle-delay", &post_command_idle_delay,
7051b69b 10488 "Delay time before running `post-command-idle-hook'.\n\
59aadc81
RS
10489This is measured in microseconds.");
10490 post_command_idle_delay = 100000;
10491
cdb9d665
RS
10492#if 0
10493 DEFVAR_LISP ("echo-area-clear-hook", ...,
10494 "Normal hook run when clearing the echo area.");
10495#endif
10496 Qecho_area_clear_hook = intern ("echo-area-clear-hook");
10497 XSYMBOL (Qecho_area_clear_hook)->value = Qnil;
10498
48e416d4
RS
10499 DEFVAR_LISP ("lucid-menu-bar-dirty-flag", &Vlucid_menu_bar_dirty_flag,
10500 "t means menu bar, specified Lucid style, needs to be recomputed.");
10501 Vlucid_menu_bar_dirty_flag = Qnil;
a73c5e29 10502
9f9c0e27
RS
10503 DEFVAR_LISP ("menu-bar-final-items", &Vmenu_bar_final_items,
10504 "List of menu bar items to move to the end of the menu bar.\n\
a612e298 10505The elements of the list are event types that may have menu bar bindings.");
9f9c0e27 10506 Vmenu_bar_final_items = Qnil;
e9bf89a0 10507
217258d5
KH
10508 DEFVAR_KBOARD ("overriding-terminal-local-map",
10509 Voverriding_terminal_local_map,
779b34df 10510 "Per-terminal keymap that overrides all other local keymaps.\n\
217258d5 10511If this variable is non-nil, it is used as a keymap instead of the\n\
779b34df
RS
10512buffer's local map, and the minor mode keymaps and text property keymaps.\n\
10513This variable is intended to let commands such as `universal-argumemnt'\n\
10514set up a different keymap for reading the next command.");
217258d5 10515
9dd3131c
RS
10516 DEFVAR_LISP ("overriding-local-map", &Voverriding_local_map,
10517 "Keymap that overrides all other local keymaps.\n\
10518If this variable is non-nil, it is used as a keymap instead of the\n\
10519buffer's local map, and the minor mode keymaps and text property keymaps.");
10520 Voverriding_local_map = Qnil;
10521
d0a49716
RS
10522 DEFVAR_LISP ("overriding-local-map-menu-flag", &Voverriding_local_map_menu_flag,
10523 "Non-nil means `overriding-local-map' applies to the menu bar.\n\
10524Otherwise, the menu bar continues to reflect the buffer's local map\n\
10525and the minor mode maps regardless of `overriding-local-map'.");
10526 Voverriding_local_map_menu_flag = Qnil;
10527
7f07d5ca
RS
10528 DEFVAR_LISP ("special-event-map", &Vspecial_event_map,
10529 "Keymap defining bindings for special events to execute at low level.");
10530 Vspecial_event_map = Fcons (intern ("keymap"), Qnil);
10531
71edead1 10532 DEFVAR_LISP ("track-mouse", &do_mouse_tracking,
a53c7666 10533 "*Non-nil means generate motion events for mouse motion.");
80e4aa30 10534
7c97ffdc 10535 DEFVAR_KBOARD ("system-key-alist", Vsystem_key_alist,
270a208f 10536 "Alist of system-specific X windows key symbols.\n\
80e4aa30 10537Each element should have the form (N . SYMBOL) where N is the\n\
270a208f 10538numeric keysym code (sans the \"system-specific\" bit 1<<28)\n\
80e4aa30 10539and SYMBOL is its name.");
8a792f3a
RS
10540
10541 DEFVAR_LISP ("deferred-action-list", &Vdeferred_action_list,
10542 "List of deferred actions to be performed at a later time.\n\
10543The precise format isn't relevant here; we just check whether it is nil.");
10544 Vdeferred_action_list = Qnil;
10545
10546 DEFVAR_LISP ("deferred-action-function", &Vdeferred_action_function,
10547 "Function to call to handle deferred actions, after each command.\n\
10548This function is called with no arguments after each command\n\
10549whenever `deferred-action-list' is non-nil.");
10550 Vdeferred_action_function = Qnil;
6526ab49
RS
10551
10552 DEFVAR_LISP ("suggest-key-bindings", &Vsuggest_key_bindings,
ac52ebd5 10553 "*Non-nil means show the equivalent key-binding when M-x command has one.\n\
6526ab49
RS
10554The value can be a length of time to show the message for.\n\
10555If the value is non-nil and not a number, we wait 2 seconds.");
10556 Vsuggest_key_bindings = Qt;
8bb1c042 10557
c04cbc3b 10558 DEFVAR_LISP ("timer-list", &Vtimer_list,
d9d4c147 10559 "List of active absolute time timers in order of increasing time");
c04cbc3b 10560 Vtimer_list = Qnil;
d9d4c147
KH
10561
10562 DEFVAR_LISP ("timer-idle-list", &Vtimer_idle_list,
10563 "List of active idle-time timers in order of increasing time");
10564 Vtimer_idle_list = Qnil;
7d18f9ae
RS
10565
10566 DEFVAR_LISP ("input-method-function", &Vinput_method_function,
10567 "If non-nil, the function that implements the current input method.\n\
10568It's called with one argument, a printing character that was just read.\n\
10569\(That means a character with code 040...0176.)\n\
10570Typically this function uses `read-event' to read additional events.\n\
10571When it does so, it should first bind `input-method-function' to nil\n\
10572so it will not be called recursively.\n\
10573\n\
10574The function should return a list of zero or more events\n\
10575to be used as input. If it wants to put back some events\n\
10576to be reconsidered, separately, by the input method,\n\
d5eecefb
RS
10577it can add them to the beginning of `unread-command-events'.\n\
10578\n\
10579The input method function can find in `input-method-previous-method'\n\
10580the previous echo area message.\n\
10581\n\
10582The input method function should refer to the variables\n\
10583`input-method-use-echo-area' and `input-method-exit-on-first-char'\n\
10584for guidance on what to do.");
7d18f9ae 10585 Vinput_method_function = Qnil;
d5eecefb
RS
10586
10587 DEFVAR_LISP ("input-method-previous-message",
10588 &Vinput_method_previous_message,
a8b13665 10589 "When `input-method-function' is called, hold the previous echo area message.\n\
d5eecefb
RS
10590This variable exists because `read-event' clears the echo area\n\
10591before running the input method. It is nil if there was no message.");
10592 Vinput_method_previous_message = Qnil;
7ee32cda
GM
10593
10594 DEFVAR_LISP ("show-help-function", &Vshow_help_function,
10595 "If non-nil, the function that implements the display of help.\n\
10596It's called with one argument, the help string to display.");
10597 Vshow_help_function = Qnil;
adf5cb9c
KH
10598
10599 DEFVAR_LISP ("disable-point-adjustment", &Vdisable_point_adjustment,
10600 "If non-nil, suppress point adjustment after executing a command.\n\
10601\n\
10602After a command is executed, if point is moved into a region that has\n\
10603special properties (e.g. composition, display), we adjust point to\n\
10604the boundary of the region. But, several special commands sets this\n\
10605variable to non-nil, then we suppress the point adjustment.\n\
10606\n\
10607This variable is set to nil before reading a command, and is checked\n\
10608just after executing the command");
10609 Vdisable_point_adjustment = Qnil;
10610
10611 DEFVAR_LISP ("global-disable-point-adjustment",
10612 &Vglobal_disable_point_adjustment,
10613 "*If non-nil, always suppress point adjustment.\n\
10614\n\
10615The default value is nil, in which case, point adjustment are\n\
10616suppressed only after special commands that set\n\
10617`disable-point-adjustment' (which see) to non-nil.");
10618 Vglobal_disable_point_adjustment = Qnil;
284f4730
JB
10619}
10620
dfcf069d 10621void
284f4730
JB
10622keys_of_keyboard ()
10623{
10624 initial_define_key (global_map, Ctl ('Z'), "suspend-emacs");
10625 initial_define_key (control_x_map, Ctl ('Z'), "suspend-emacs");
10626 initial_define_key (meta_map, Ctl ('C'), "exit-recursive-edit");
10627 initial_define_key (global_map, Ctl (']'), "abort-recursive-edit");
10628 initial_define_key (meta_map, 'x', "execute-extended-command");
7f07d5ca
RS
10629
10630 initial_define_lispy_key (Vspecial_event_map, "delete-frame",
10631 "handle-delete-frame");
10632 initial_define_lispy_key (Vspecial_event_map, "iconify-frame",
10633 "ignore-event");
10634 initial_define_lispy_key (Vspecial_event_map, "make-frame-visible",
10635 "ignore-event");
284f4730 10636}