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