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