This source file includes following definitions.
- next_kbd_event
- xevent_start
- kset_echo_string
- kset_echo_prompt
- kset_kbd_queue
- kset_keyboard_translate_table
- kset_last_prefix_arg
- kset_last_repeatable_command
- kset_local_function_key_map
- kset_overriding_terminal_local_map
- kset_real_last_command
- kset_system_key_syms
- echo_keystrokes_p
- echo_add_key
- echo_dash
- echo_update
- echo_now
- cancel_echoing
- echo_length
- echo_truncate
- add_command_key
- recursive_edit_1
- record_auto_save
- force_auto_save_soon
- DEFUN
- recursive_edit_unwind
- not_single_kboard_state
- push_kboard
- pop_kboard
- temporarily_switch_to_single_kboard
- restore_kboard_configuration
- cmd_error
- cmd_error_internal
- command_loop
- command_loop_2
- top_level_2
- top_level_1
- DEFUN
- user_error
- DEFUN
- DEFUN
- tracking_off
- DEFUN
- some_mouse_moved
- command_loop_1
- read_menu_command
- adjust_point_for_property
- safe_run_hooks_1
- safe_run_hooks_error
- safe_run_hook_funcall
- safe_run_hooks
- safe_run_hooks_maybe_narrowed
- safe_run_hooks_2
- poll_for_input_1
- poll_for_input
- start_polling
- input_polling_used
- stop_polling
- set_poll_suppress_count
- bind_polling_period
- make_ctrl_char
- help_echo_substitute_command_keys
- show_help_echo
- read_char_help_form_unwind
- read_event_from_main_queue
- read_decoded_event_from_main_queue
- read_char
- record_menu_key
- help_char_p
- record_char
- save_getcjmp
- restore_getcjmp
- readable_events
- event_to_kboard
- kbd_buffer_nr_stored
- kbd_buffer_store_event
- kbd_buffer_store_buffered_event
- position_to_Time
- Time_to_position
- gen_help_event
- kbd_buffer_store_help_event
- discard_mouse_events
- kbd_buffer_events_waiting
- clear_event
- kbd_buffer_get_event_1
- kbd_buffer_get_event_2
- kbd_buffer_get_event
- process_special_events
- swallow_events
- timer_start_idle
- timer_stop_idle
- timer_resume_idle
- decode_timer
- timer_check_2
- timer_check
- DEFUN
- make_lispy_position
- toolkit_menubar_in_use
- make_scroll_bar_position
- coords_in_menu_bar_window
- coords_in_tab_bar_window
- make_lispy_event
- make_lispy_movement
- make_lispy_switch_frame
- make_lispy_focus_in
- make_lispy_focus_out
- parse_modifiers_uncached
- apply_modifiers_uncached
- lispy_modifier_list
- parse_modifiers
- DEFUN
- apply_modifiers
- reorder_modifiers
- modify_event_symbol
- DEFUN
- DEFUN
- parse_solitary_modifier
- lucid_event_type_list_p
- get_input_pending
- gobble_input
- tty_read_avail_input
- handle_async_input
- process_pending_signals
- unblock_input_to
- unblock_input
- totally_unblock_input
- handle_input_available_signal
- deliver_input_available_signal
- add_user_signal
- handle_user_signal
- deliver_user_signal
- find_user_signal_name
- store_user_signal_events
- menu_separator_name_p
- menu_bar_items
- menu_bar_item
- menu_item_eval_property_1
- eval_dyn
- menu_item_eval_property
- parse_menu_item
- tab_bar_items
- process_tab_bar_item
- set_prop_tab_bar
- parse_tab_bar_item
- init_tab_bar_items
- append_tab_bar_item
- tool_bar_items
- process_tool_bar_item
- set_prop
- parse_tool_bar_item
- init_tool_bar_items
- append_tool_bar_item
- read_char_x_menu_prompt
- read_char_minibuf_menu_prompt
- follow_key
- active_maps
- access_keymap_keyremap
- keyremap_step
- test_undefined
- init_raw_keybuf_count
- restore_reading_key_sequence
- read_key_sequence
- read_key_sequence_vs
- detect_input_pending
- detect_input_pending_ignore_squeezables
- detect_input_pending_run_timers
- clear_input_pending
- requeued_events_pending_p
- DEFUN
- update_recent_keys
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- stuff_buffered_input
- set_waiting_for_input
- clear_waiting_for_input
- handle_interrupt_signal
- deliver_interrupt_signal
- write_stdout
- read_stdin
- handle_interrupt
- quit_throw_to_read_char
- DEFUN
- DEFUN
- DEFUN
- init_kboard
- allocate_kboard
- wipe_kboard
- delete_kboard
- init_keyboard
- init_while_no_input_ignore_events
- is_ignored_event
- syms_of_keyboard
- syms_of_keyboard_for_pdumper
- keys_of_keyboard
- mark_kboards
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <config.h>
22
23 #include <sys/stat.h>
24
25 #include "lisp.h"
26 #include "coding.h"
27 #include "termchar.h"
28 #include "termopts.h"
29 #include "frame.h"
30 #include "termhooks.h"
31 #include "macros.h"
32 #include "keyboard.h"
33 #include "window.h"
34 #include "commands.h"
35 #include "character.h"
36 #include "buffer.h"
37 #include "dispextern.h"
38 #include "syntax.h"
39 #include "intervals.h"
40 #include "keymap.h"
41 #include "blockinput.h"
42 #include "sysstdio.h"
43 #include "systime.h"
44 #include "atimer.h"
45 #include "process.h"
46 #include "menu.h"
47
48 #ifdef HAVE_TEXT_CONVERSION
49 #include "textconv.h"
50 #endif
51
52 #ifdef HAVE_ANDROID
53 #include "android.h"
54 #endif
55
56 #include <errno.h>
57
58 #ifdef HAVE_PTHREAD
59 #include <pthread.h>
60 #endif
61 #ifdef MSDOS
62 #include "msdos.h"
63 #include <time.h>
64 #else
65 #include <sys/ioctl.h>
66 #endif
67
68 #if defined USABLE_FIONREAD && defined USG5_4
69 # include <sys/filio.h>
70 #endif
71
72 #include "syssignal.h"
73
74 #if defined HAVE_STACK_OVERFLOW_HANDLING && !defined WINDOWSNT
75 #include <setjmp.h>
76 #endif
77
78 #include <sys/types.h>
79 #include <unistd.h>
80 #include <fcntl.h>
81 #include <math.h>
82
83 #include <ignore-value.h>
84
85 #include "pdumper.h"
86
87 #ifdef HAVE_WINDOW_SYSTEM
88 #include TERM_HEADER
89 #endif
90
91
92 #if GNUC_PREREQ (4, 3, 0)
93 # pragma GCC diagnostic ignored "-Wclobbered"
94 #endif
95
96 #ifdef WINDOWSNT
97 char const DEV_TTY[] = "CONOUT$";
98 #else
99 char const DEV_TTY[] = "/dev/tty";
100 #endif
101
102
103
104
105 volatile int interrupt_input_blocked;
106
107
108
109 volatile bool pending_signals;
110
111 KBOARD *initial_kboard;
112 KBOARD *current_kboard;
113 static KBOARD *all_kboards;
114
115
116 static bool single_kboard;
117
118 #ifdef HAVE_TEXT_CONVERSION
119
120
121 bool reading_key_sequence;
122
123 #endif
124
125
126 #define MIN_NUM_RECENT_KEYS (100)
127
128
129 #if INTPTR_MAX <= INT_MAX
130 # define MAX_NUM_RECENT_KEYS (INT_MAX / EMACS_INT_WIDTH / 10)
131 #else
132 # define MAX_NUM_RECENT_KEYS (INT_MAX / EMACS_INT_WIDTH)
133 #endif
134
135
136 static int recent_keys_index;
137
138
139 static int total_keys;
140
141
142 static int lossage_limit = 3 * MIN_NUM_RECENT_KEYS;
143
144
145 static Lisp_Object recent_keys;
146
147
148
149
150
151
152 Lisp_Object this_command_keys;
153 ptrdiff_t this_command_key_count;
154
155
156
157 static Lisp_Object raw_keybuf;
158 static int raw_keybuf_count;
159
160 #define GROW_RAW_KEYBUF \
161 if (raw_keybuf_count == ASIZE (raw_keybuf)) \
162 raw_keybuf = larger_vector (raw_keybuf, 1, -1)
163
164
165
166 static ptrdiff_t this_single_command_key_start;
167
168 #ifdef HAVE_STACK_OVERFLOW_HANDLING
169
170
171 sigjmp_buf return_to_command_loop;
172
173
174 static Lisp_Object recover_top_level_message;
175
176 #endif
177
178
179 static Lisp_Object regular_top_level_message;
180
181
182
183 static bool echoing;
184
185
186
187
188 static struct kboard *ok_to_echo_at_next_pause;
189
190
191
192
193
194
195 struct kboard *echo_kboard;
196
197
198
199
200 Lisp_Object echo_message_buffer;
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218 int quit_char;
219
220
221 EMACS_INT command_loop_level;
222
223
224
225
226
227
228
229
230 Lisp_Object unread_switch_frame;
231
232
233 static ptrdiff_t last_non_minibuf_size;
234
235 uintmax_t num_input_events;
236 ptrdiff_t point_before_last_command_or_undo;
237 struct buffer *buffer_before_last_command_or_undo;
238
239
240
241 static intmax_t last_auto_save;
242
243
244 static ptrdiff_t last_point_position;
245
246
247
248
249
250
251
252
253
254
255 Lisp_Object internal_last_event_frame;
256
257
258
259 static Lisp_Object read_key_sequence_cmd;
260 static Lisp_Object read_key_sequence_remapped;
261
262
263 static FILE *dribble;
264
265
266 bool input_pending;
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314 bool input_was_pending;
315
316
317
318 union buffered_input_event kbd_buffer[KBD_BUFFER_SIZE];
319
320
321
322 union buffered_input_event *kbd_fetch_ptr;
323
324
325 union buffered_input_event *kbd_store_ptr;
326
327
328
329
330
331
332
333
334
335 static void recursive_edit_unwind (Lisp_Object buffer);
336 static Lisp_Object command_loop (void);
337
338 static void echo_now (void);
339 static ptrdiff_t echo_length (void);
340
341 static void safe_run_hooks_maybe_narrowed (Lisp_Object, struct window *);
342
343
344 unsigned timers_run;
345
346
347
348 struct timespec *input_available_clear_time;
349
350
351
352 bool interrupt_input;
353
354
355 bool interrupts_deferred;
356
357
358
359 static struct timespec timer_idleness_start_time;
360
361
362
363
364 static struct timespec timer_last_idleness_start_time;
365
366
367
368 static Lisp_Object virtual_core_pointer_name;
369 static Lisp_Object virtual_core_keyboard_name;
370
371
372
373 static Lisp_Object menu_bar_touch_id;
374
375
376
377
378
379 #define READABLE_EVENTS_DO_TIMERS_NOW (1 << 0)
380 #define READABLE_EVENTS_FILTER_EVENTS (1 << 1)
381 #define READABLE_EVENTS_IGNORE_SQUEEZABLES (1 << 2)
382
383
384 static void (*keyboard_init_hook) (void);
385
386 static bool get_input_pending (int);
387 static bool readable_events (int);
388 static Lisp_Object read_char_x_menu_prompt (Lisp_Object,
389 Lisp_Object, bool *);
390 static Lisp_Object read_char_minibuf_menu_prompt (int, Lisp_Object);
391 static Lisp_Object make_lispy_event (struct input_event *);
392 static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object,
393 enum scroll_bar_part,
394 Lisp_Object, Lisp_Object,
395 Time);
396 static Lisp_Object modify_event_symbol (ptrdiff_t, int, Lisp_Object,
397 Lisp_Object, const char *const *,
398 Lisp_Object *, ptrdiff_t);
399 static Lisp_Object make_lispy_switch_frame (Lisp_Object);
400 static Lisp_Object make_lispy_focus_in (Lisp_Object);
401 static Lisp_Object make_lispy_focus_out (Lisp_Object);
402 static bool help_char_p (Lisp_Object);
403 static void save_getcjmp (sys_jmp_buf);
404 static void restore_getcjmp (void *);
405 static Lisp_Object apply_modifiers (int, Lisp_Object);
406 static void restore_kboard_configuration (int);
407 static void handle_interrupt (bool);
408 static AVOID quit_throw_to_read_char (bool);
409 static void timer_start_idle (void);
410 static void timer_stop_idle (void);
411 static void timer_resume_idle (void);
412 static void deliver_user_signal (int);
413 static char *find_user_signal_name (int);
414 static void store_user_signal_events (void);
415 static bool is_ignored_event (union buffered_input_event *);
416
417
418
419 static union buffered_input_event *
420 next_kbd_event (union buffered_input_event *ptr)
421 {
422 return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
423 }
424
425
426
427
428 static Lisp_Object
429 xevent_start (Lisp_Object event)
430 {
431 return XCAR (XCDR (event));
432 }
433
434
435 static void
436 kset_echo_string (struct kboard *kb, Lisp_Object val)
437 {
438 kb->echo_string_ = val;
439 }
440 static void
441 kset_echo_prompt (struct kboard *kb, Lisp_Object val)
442 {
443 kb->echo_prompt_ = val;
444 }
445 static void
446 kset_kbd_queue (struct kboard *kb, Lisp_Object val)
447 {
448 kb->kbd_queue_ = val;
449 }
450 static void
451 kset_keyboard_translate_table (struct kboard *kb, Lisp_Object val)
452 {
453 kb->Vkeyboard_translate_table_ = val;
454 }
455 static void
456 kset_last_prefix_arg (struct kboard *kb, Lisp_Object val)
457 {
458 kb->Vlast_prefix_arg_ = val;
459 }
460 static void
461 kset_last_repeatable_command (struct kboard *kb, Lisp_Object val)
462 {
463 kb->Vlast_repeatable_command_ = val;
464 }
465 static void
466 kset_local_function_key_map (struct kboard *kb, Lisp_Object val)
467 {
468 kb->Vlocal_function_key_map_ = val;
469 }
470 static void
471 kset_overriding_terminal_local_map (struct kboard *kb, Lisp_Object val)
472 {
473 kb->Voverriding_terminal_local_map_ = val;
474 }
475 static void
476 kset_real_last_command (struct kboard *kb, Lisp_Object val)
477 {
478 kb->Vreal_last_command_ = val;
479 }
480 static void
481 kset_system_key_syms (struct kboard *kb, Lisp_Object val)
482 {
483 kb->system_key_syms_ = val;
484 }
485
486
487 static bool
488 echo_keystrokes_p (void)
489 {
490 return (FLOATP (Vecho_keystrokes) ? XFLOAT_DATA (Vecho_keystrokes) > 0.0
491 : FIXNUMP (Vecho_keystrokes) ? XFIXNUM (Vecho_keystrokes) > 0
492 : false);
493 }
494
495
496
497
498
499 static void
500 echo_add_key (Lisp_Object c)
501 {
502 char initbuf[KEY_DESCRIPTION_SIZE + 100];
503 ptrdiff_t size = sizeof initbuf;
504 char *buffer = initbuf;
505 char *ptr = buffer;
506 Lisp_Object echo_string = KVAR (current_kboard, echo_string);
507 USE_SAFE_ALLOCA;
508
509 if (STRINGP (echo_string) && SCHARS (echo_string) > 0)
510
511 ptr++[0] = ' ';
512
513
514 c = EVENT_HEAD (c);
515
516 if (FIXNUMP (c))
517 ptr = push_key_description (XFIXNUM (c), ptr);
518 else if (SYMBOLP (c))
519 {
520 Lisp_Object name = SYMBOL_NAME (c);
521 ptrdiff_t nbytes = SBYTES (name);
522
523 if (size - (ptr - buffer) < nbytes)
524 {
525 ptrdiff_t offset = ptr - buffer;
526 size = max (2 * size, size + nbytes);
527 buffer = SAFE_ALLOCA (size);
528 ptr = buffer + offset;
529 }
530
531 ptr += copy_text (SDATA (name), (unsigned char *) ptr, nbytes,
532 STRING_MULTIBYTE (name), 1);
533 }
534
535 Lisp_Object new_string = make_string (buffer, ptr - buffer);
536 if ((NILP (echo_string) || SCHARS (echo_string) == 0)
537 && help_char_p (c))
538 {
539 AUTO_STRING (str, " (Type ? for further options, C-q for quick help)");
540 AUTO_LIST2 (props, Qface, Qhelp_key_binding);
541 Fadd_text_properties (make_fixnum (7), make_fixnum (8), props, str);
542 Fadd_text_properties (make_fixnum (30), make_fixnum (33), props, str);
543 new_string = concat2 (new_string, str);
544 }
545
546 kset_echo_string (current_kboard,
547 concat2 (echo_string, new_string));
548 SAFE_FREE ();
549 }
550
551
552
553
554
555 static void
556 echo_dash (void)
557 {
558
559 if (NILP (KVAR (current_kboard, echo_string)))
560 return;
561
562 if (!current_kboard->immediate_echo
563 && SCHARS (KVAR (current_kboard, echo_string)) == 0)
564 return;
565
566
567 if (STRINGP (KVAR (current_kboard, echo_prompt))
568 && (SCHARS (KVAR (current_kboard, echo_prompt))
569 == SCHARS (KVAR (current_kboard, echo_string))))
570 return;
571
572
573 if (SCHARS (KVAR (current_kboard, echo_string)) > 1)
574 {
575 Lisp_Object last_char, prev_char, idx;
576
577 idx = make_fixnum (SCHARS (KVAR (current_kboard, echo_string)) - 2);
578 prev_char = Faref (KVAR (current_kboard, echo_string), idx);
579
580 idx = make_fixnum (SCHARS (KVAR (current_kboard, echo_string)) - 1);
581 last_char = Faref (KVAR (current_kboard, echo_string), idx);
582
583 if (XFIXNUM (last_char) == '-' && XFIXNUM (prev_char) != ' ')
584 return;
585 }
586
587
588
589 AUTO_STRING (dash, "-");
590 kset_echo_string (current_kboard,
591 concat2 (KVAR (current_kboard, echo_string), dash));
592 echo_now ();
593 }
594
595 static void
596 echo_update (void)
597 {
598 if (current_kboard->immediate_echo)
599 {
600 ptrdiff_t i;
601 Lisp_Object prompt = KVAR (current_kboard, echo_prompt);
602 Lisp_Object prefix = call0 (Qinternal_echo_keystrokes_prefix);
603 kset_echo_string (current_kboard,
604 NILP (prompt) ? prefix
605 : NILP (prefix) ? prompt
606 : concat2 (prompt, prefix));
607
608 for (i = 0; i < this_command_key_count; i++)
609 {
610 Lisp_Object c;
611
612 c = AREF (this_command_keys, i);
613 if (! (EVENT_HAS_PARAMETERS (c)
614 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
615 echo_add_key (c);
616 }
617
618 echo_now ();
619 }
620 }
621
622
623
624
625 static void
626 echo_now (void)
627 {
628 if (!current_kboard->immediate_echo
629
630 )
631 {
632 current_kboard->immediate_echo = true;
633 echo_update ();
634
635 echo_dash ();
636 }
637
638 echoing = true;
639
640 message3_nolog (KVAR (current_kboard, echo_string));
641 echoing = false;
642
643
644 echo_message_buffer = echo_area_buffer[0];
645 echo_kboard = current_kboard;
646
647 if (waiting_for_input && !NILP (Vquit_flag))
648 quit_throw_to_read_char (0);
649 }
650
651
652
653 void
654 cancel_echoing (void)
655 {
656 current_kboard->immediate_echo = false;
657 kset_echo_prompt (current_kboard, Qnil);
658 kset_echo_string (current_kboard, Qnil);
659 ok_to_echo_at_next_pause = NULL;
660 echo_kboard = NULL;
661 echo_message_buffer = Qnil;
662 }
663
664
665
666 static ptrdiff_t
667 echo_length (void)
668 {
669 return (STRINGP (KVAR (current_kboard, echo_string))
670 ? SCHARS (KVAR (current_kboard, echo_string))
671 : 0);
672 }
673
674
675
676
677
678 static void
679 echo_truncate (ptrdiff_t nchars)
680 {
681 Lisp_Object es = KVAR (current_kboard, echo_string);
682 if (STRINGP (es) && SCHARS (es) > nchars)
683 kset_echo_string (current_kboard,
684 Fsubstring (KVAR (current_kboard, echo_string),
685 make_fixnum (0), make_fixnum (nchars)));
686 truncate_echo_area (nchars);
687 }
688
689
690
691 static void
692 add_command_key (Lisp_Object key)
693 {
694 if (this_command_key_count >= ASIZE (this_command_keys))
695 this_command_keys = larger_vector (this_command_keys, 1, -1);
696
697 ASET (this_command_keys, this_command_key_count, key);
698 ++this_command_key_count;
699 }
700
701
702 Lisp_Object
703 recursive_edit_1 (void)
704 {
705 specpdl_ref count = SPECPDL_INDEX ();
706 Lisp_Object val;
707
708 if (command_loop_level > 0)
709 {
710 specbind (Qstandard_output, Qt);
711 specbind (Qstandard_input, Qt);
712 specbind (Qsymbols_with_pos_enabled, Qnil);
713 specbind (Qprint_symbols_bare, Qnil);
714 }
715
716 #ifdef HAVE_WINDOW_SYSTEM
717
718
719
720
721 cancel_hourglass ();
722 #endif
723
724
725
726
727
728
729
730
731
732
733 specbind (Qinhibit_redisplay, Qnil);
734 redisplaying_p = 0;
735
736
737
738
739
740
741
742 specbind (Qundo_auto__undoably_changed_buffers, Qnil);
743
744 val = command_loop ();
745 if (EQ (val, Qt))
746 quit ();
747
748
749 if (STRINGP (val))
750 xsignal1 (Qerror, val);
751
752 if (FUNCTIONP (val))
753 call0 (val);
754
755 return unbind_to (count, Qnil);
756 }
757
758
759
760 void
761 record_auto_save (void)
762 {
763 last_auto_save = num_nonmacro_input_events;
764 }
765
766
767
768 #ifdef SIGDANGER
769 void
770 force_auto_save_soon (void)
771 {
772 last_auto_save = - auto_save_interval - 1;
773 }
774 #endif
775
776 DEFUN ("recursive-edit", Frecursive_edit, Srecursive_edit, 0, 0, "",
777 doc:
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796 )
797 (void)
798 {
799 specpdl_ref count = SPECPDL_INDEX ();
800 Lisp_Object buffer;
801
802
803
804 if (input_blocked_p ())
805 return Qnil;
806
807 if (command_loop_level >= 0
808 && current_buffer != XBUFFER (XWINDOW (selected_window)->contents))
809 buffer = Fcurrent_buffer ();
810 else
811 buffer = Qnil;
812
813
814
815
816 command_loop_level++;
817 update_mode_lines = 17;
818 record_unwind_protect (recursive_edit_unwind, buffer);
819
820
821
822
823
824 if (command_loop_level > 0)
825 temporarily_switch_to_single_kboard (SELECTED_FRAME ());
826
827 recursive_edit_1 ();
828 return unbind_to (count, Qnil);
829 }
830
831 void
832 recursive_edit_unwind (Lisp_Object buffer)
833 {
834 if (BUFFERP (buffer))
835 Fset_buffer (buffer);
836
837 command_loop_level--;
838 update_mode_lines = 18;
839 }
840
841
842
843
844
845
846 void
847 not_single_kboard_state (KBOARD *kboard)
848 {
849 if (kboard == current_kboard)
850 single_kboard = false;
851 }
852
853
854
855
856
857 struct kboard_stack
858 {
859 KBOARD *kboard;
860 struct kboard_stack *next;
861 };
862
863 static struct kboard_stack *kboard_stack;
864
865 void
866 push_kboard (struct kboard *k)
867 {
868 struct kboard_stack *p = xmalloc (sizeof *p);
869
870 p->next = kboard_stack;
871 p->kboard = current_kboard;
872 kboard_stack = p;
873
874 current_kboard = k;
875 }
876
877 void
878 pop_kboard (void)
879 {
880 struct terminal *t;
881 struct kboard_stack *p = kboard_stack;
882 bool found = false;
883 for (t = terminal_list; t; t = t->next_terminal)
884 {
885 if (t->kboard == p->kboard)
886 {
887 current_kboard = p->kboard;
888 found = true;
889 break;
890 }
891 }
892 if (!found)
893 {
894
895 current_kboard = FRAME_KBOARD (SELECTED_FRAME ());
896 single_kboard = false;
897 }
898 kboard_stack = p->next;
899 xfree (p);
900 }
901
902
903
904
905
906
907
908
909
910
911
912 void
913 temporarily_switch_to_single_kboard (struct frame *f)
914 {
915 bool was_locked = single_kboard;
916 if (was_locked)
917 {
918 if (f != NULL && FRAME_KBOARD (f) != current_kboard)
919
920
921
922
923
924
925
926 error ("Terminal %d is locked, cannot read from it",
927 FRAME_TERMINAL (f)->id);
928 else
929
930
931
932 push_kboard (current_kboard);
933 }
934 else if (f != NULL)
935 current_kboard = FRAME_KBOARD (f);
936 single_kboard = true;
937 record_unwind_protect_int (restore_kboard_configuration, was_locked);
938 }
939
940 static void
941 restore_kboard_configuration (int was_locked)
942 {
943 single_kboard = was_locked;
944 if (was_locked)
945 {
946 struct kboard *prev = current_kboard;
947 pop_kboard ();
948
949 if (single_kboard && current_kboard != prev)
950 emacs_abort ();
951 }
952 }
953
954
955
956
957
958 static Lisp_Object
959 cmd_error (Lisp_Object data)
960 {
961 Lisp_Object old_level, old_length;
962 specpdl_ref count = SPECPDL_INDEX ();
963 Lisp_Object conditions;
964 char macroerror[sizeof "After..kbd macro iterations: "
965 + INT_STRLEN_BOUND (EMACS_INT)];
966
967 #ifdef HAVE_WINDOW_SYSTEM
968 if (display_hourglass_p)
969 cancel_hourglass ();
970 #endif
971
972 if (!NILP (executing_kbd_macro))
973 {
974 if (executing_kbd_macro_iterations == 1)
975 sprintf (macroerror, "After 1 kbd macro iteration: ");
976 else
977 sprintf (macroerror, "After %"pI"d kbd macro iterations: ",
978 executing_kbd_macro_iterations);
979 }
980 else
981 *macroerror = 0;
982
983 conditions = Fget (XCAR (data), Qerror_conditions);
984 if (NILP (Fmemq (Qminibuffer_quit, conditions)))
985 {
986 Vexecuting_kbd_macro = Qnil;
987 executing_kbd_macro = Qnil;
988 }
989 else if (!NILP (KVAR (current_kboard, defining_kbd_macro)))
990
991
992 finalize_kbd_macro_chars ();
993
994 specbind (Qstandard_output, Qt);
995 specbind (Qstandard_input, Qt);
996 kset_prefix_arg (current_kboard, Qnil);
997 kset_last_prefix_arg (current_kboard, Qnil);
998 cancel_echoing ();
999
1000
1001 old_level = Vprint_level;
1002 old_length = Vprint_length;
1003 XSETFASTINT (Vprint_level, 10);
1004 XSETFASTINT (Vprint_length, 10);
1005 cmd_error_internal (data, macroerror);
1006 Vprint_level = old_level;
1007 Vprint_length = old_length;
1008
1009 Vquit_flag = Qnil;
1010 Vinhibit_quit = Qnil;
1011
1012 unbind_to (count, Qnil);
1013 return make_fixnum (0);
1014 }
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024 void
1025 cmd_error_internal (Lisp_Object data, const char *context)
1026 {
1027
1028
1029 if (signal_quit_p (XCAR (data)))
1030 Vsignaling_function = Qnil;
1031
1032 Vquit_flag = Qnil;
1033 Vinhibit_quit = Qt;
1034
1035
1036 if (!NILP (Vcommand_error_function))
1037 call3 (Vcommand_error_function, data,
1038 context ? build_string (context) : empty_unibyte_string,
1039 Vsignaling_function);
1040
1041 Vsignaling_function = Qnil;
1042 }
1043
1044 DEFUN ("command-error-default-function", Fcommand_error_default_function,
1045 Scommand_error_default_function, 3, 3, 0,
1046 doc:
1047 )
1048 (Lisp_Object data, Lisp_Object context, Lisp_Object signal)
1049 {
1050 struct frame *sf = SELECTED_FRAME ();
1051 Lisp_Object conditions = Fget (XCAR (data), Qerror_conditions);
1052 int is_minibuffer_quit = !NILP (Fmemq (Qminibuffer_quit, conditions));
1053
1054 CHECK_STRING (context);
1055
1056
1057
1058
1059 if (!is_minibuffer_quit
1060 && (!sf->glyphs_initialized_p
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071 || (!IS_DAEMON && FRAME_INITIAL_P (sf))
1072 || noninteractive))
1073 {
1074 print_error_message (data, Qexternal_debugging_output,
1075 SSDATA (context), signal);
1076 Fterpri (Qexternal_debugging_output, Qnil);
1077 Fkill_emacs (make_fixnum (-1), Qnil);
1078 }
1079 else
1080 {
1081 clear_message (1, 0);
1082 message_log_maybe_newline ();
1083
1084 if (is_minibuffer_quit)
1085 {
1086 Fding (Qt);
1087 }
1088 else
1089 {
1090 Fdiscard_input ();
1091 bitch_at_user ();
1092 }
1093
1094 print_error_message (data, Qt, SSDATA (context), signal);
1095 }
1096 return Qnil;
1097 }
1098
1099 static Lisp_Object command_loop_1 (void);
1100 static Lisp_Object top_level_1 (Lisp_Object);
1101
1102
1103
1104
1105
1106 Lisp_Object
1107 command_loop (void)
1108 {
1109 #ifdef HAVE_STACK_OVERFLOW_HANDLING
1110
1111 if (sigsetjmp (return_to_command_loop, 1) != 0)
1112 {
1113
1114
1115 #ifdef WINDOWSNT
1116 w32_reset_stack_overflow_guard ();
1117 #endif
1118 init_eval ();
1119 Vinternal__top_level_message = recover_top_level_message;
1120 }
1121 else
1122 Vinternal__top_level_message = regular_top_level_message;
1123 #endif
1124 if (command_loop_level > 0 || minibuf_level > 0)
1125 {
1126 Lisp_Object val;
1127 val = internal_catch (Qexit, command_loop_2, Qerror);
1128 executing_kbd_macro = Qnil;
1129 return val;
1130 }
1131 else
1132 while (1)
1133 {
1134 internal_catch (Qtop_level, top_level_1, Qnil);
1135 internal_catch (Qtop_level, command_loop_2, Qerror);
1136 executing_kbd_macro = Qnil;
1137
1138
1139 if (noninteractive)
1140 Fkill_emacs (Qt, Qnil);
1141 }
1142 }
1143
1144
1145
1146
1147
1148
1149
1150
1151 Lisp_Object
1152 command_loop_2 (Lisp_Object handlers)
1153 {
1154 register Lisp_Object val;
1155
1156 do
1157 val = internal_condition_case (command_loop_1, handlers, cmd_error);
1158 while (!NILP (val));
1159
1160 return Qnil;
1161 }
1162
1163 static Lisp_Object
1164 top_level_2 (void)
1165 {
1166 return Feval (Vtop_level, Qnil);
1167 }
1168
1169 static Lisp_Object
1170 top_level_1 (Lisp_Object ignore)
1171 {
1172
1173 if (!NILP (Vtop_level))
1174 internal_condition_case (top_level_2, Qerror, cmd_error);
1175 else if (!NILP (Vpurify_flag))
1176 message1 ("Bare impure Emacs (standard Lisp code not loaded)");
1177 else
1178 message1 ("Bare Emacs (standard Lisp code not loaded)");
1179 return Qnil;
1180 }
1181
1182 DEFUN ("top-level", Ftop_level, Stop_level, 0, 0, "",
1183 doc:
1184
1185 attributes: noreturn)
1186 (void)
1187 {
1188 #ifdef HAVE_WINDOW_SYSTEM
1189 if (display_hourglass_p)
1190 cancel_hourglass ();
1191 #endif
1192
1193
1194
1195 totally_unblock_input ();
1196
1197 Fthrow (Qtop_level, Qnil);
1198 }
1199
1200 static AVOID
1201 user_error (const char *msg)
1202 {
1203 xsignal1 (Quser_error, build_string (msg));
1204 }
1205
1206 DEFUN ("exit-recursive-edit", Fexit_recursive_edit, Sexit_recursive_edit, 0, 0, "",
1207 doc:
1208 attributes: noreturn)
1209 (void)
1210 {
1211 if (command_loop_level > 0 || minibuf_level > 0)
1212 Fthrow (Qexit, Qnil);
1213
1214 user_error ("No recursive edit is in progress");
1215 }
1216
1217 DEFUN ("abort-recursive-edit", Fabort_recursive_edit, Sabort_recursive_edit, 0, 0, "",
1218 doc:
1219 attributes: noreturn)
1220 (void)
1221 {
1222 if (command_loop_level > 0 || minibuf_level > 0)
1223 Fthrow (Qexit, Qt);
1224
1225 user_error ("No recursive edit is in progress");
1226 }
1227
1228
1229
1230
1231 static void
1232 tracking_off (Lisp_Object old_track_mouse)
1233 {
1234 track_mouse = old_track_mouse;
1235 if (NILP (old_track_mouse))
1236 {
1237
1238
1239
1240
1241
1242 if (!readable_events (READABLE_EVENTS_DO_TIMERS_NOW))
1243 {
1244 redisplay_preserve_echo_area (6);
1245 get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW);
1246 }
1247 }
1248 }
1249
1250 DEFUN ("internal--track-mouse", Finternal_track_mouse, Sinternal_track_mouse,
1251 1, 1, 0,
1252 doc: )
1253 (Lisp_Object bodyfun)
1254 {
1255 specpdl_ref count = SPECPDL_INDEX ();
1256 Lisp_Object val;
1257
1258 record_unwind_protect (tracking_off, track_mouse);
1259
1260 track_mouse = Qt;
1261
1262 val = call0 (bodyfun);
1263 return unbind_to (count, val);
1264 }
1265
1266
1267
1268
1269
1270
1271
1272 bool ignore_mouse_drag_p;
1273
1274 static struct frame *
1275 some_mouse_moved (void)
1276 {
1277 Lisp_Object tail, frame;
1278
1279 if (NILP (track_mouse) || ignore_mouse_drag_p)
1280 return NULL;
1281
1282 FOR_EACH_FRAME (tail, frame)
1283 {
1284 if (XFRAME (frame)->mouse_moved)
1285 return XFRAME (frame);
1286 }
1287
1288 return NULL;
1289 }
1290
1291
1292
1293
1294
1295 enum { READ_KEY_ELTS = 30 };
1296 static int read_key_sequence (Lisp_Object *, Lisp_Object,
1297 bool, bool, bool, bool, bool);
1298 static void adjust_point_for_property (ptrdiff_t, bool);
1299
1300 static Lisp_Object
1301 command_loop_1 (void)
1302 {
1303 modiff_count prev_modiff = 0;
1304 struct buffer *prev_buffer = NULL;
1305
1306 kset_prefix_arg (current_kboard, Qnil);
1307 kset_last_prefix_arg (current_kboard, Qnil);
1308 Vdeactivate_mark = Qnil;
1309 waiting_for_input = false;
1310 cancel_echoing ();
1311
1312 this_command_key_count = 0;
1313 this_single_command_key_start = 0;
1314
1315 if (NILP (Vmemory_full))
1316 {
1317
1318
1319
1320
1321 if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
1322 safe_run_hooks_maybe_narrowed (Qpost_command_hook,
1323 XWINDOW (selected_window));
1324
1325
1326
1327 if (!NILP (echo_area_buffer[0]))
1328 resize_echo_area_exactly ();
1329
1330
1331 if (!NILP (Vdelayed_warnings_list))
1332 safe_run_hooks (Qdelayed_warnings_hook);
1333 }
1334
1335
1336 kset_last_command (current_kboard, Vthis_command);
1337 kset_real_last_command (current_kboard, Vreal_this_command);
1338 if (!CONSP (last_command_event))
1339 kset_last_repeatable_command (current_kboard, Vreal_this_command);
1340
1341 while (true)
1342 {
1343 Lisp_Object cmd;
1344
1345 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
1346 Fkill_emacs (Qnil, Qnil);
1347
1348
1349 set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));
1350
1351
1352
1353
1354 while (pending_malloc_warning)
1355 display_malloc_warning ();
1356
1357 Vdeactivate_mark = Qnil;
1358 backtrace_yet = false;
1359
1360
1361
1362
1363
1364 ignore_mouse_drag_p = false;
1365
1366
1367
1368
1369 if (minibuf_level
1370 && !NILP (echo_area_buffer[0])
1371 && BASE_EQ (minibuf_window, echo_area_window)
1372 && NUMBERP (Vminibuffer_message_timeout))
1373 {
1374
1375
1376 specpdl_ref count = SPECPDL_INDEX ();
1377 specbind (Qinhibit_quit, Qt);
1378
1379 sit_for (Vminibuffer_message_timeout, 0, 2);
1380
1381
1382 message1 (0);
1383 safe_run_hooks (Qecho_area_clear_hook);
1384
1385
1386
1387
1388 resize_mini_window (XWINDOW (minibuf_window), false);
1389
1390 unbind_to (count, Qnil);
1391
1392
1393 if (!NILP (Vquit_flag))
1394 {
1395 Vquit_flag = Qnil;
1396 Vunread_command_events = list1i (quit_char);
1397 }
1398 }
1399
1400 Vthis_command = Qnil;
1401 Vreal_this_command = Qnil;
1402 Vthis_original_command = Qnil;
1403 Vthis_command_keys_shift_translated = Qnil;
1404
1405
1406 raw_keybuf_count = 0;
1407 Lisp_Object keybuf[READ_KEY_ELTS];
1408 int i = read_key_sequence (keybuf, Qnil, false, true, true, false,
1409 false);
1410
1411
1412 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
1413 Fkill_emacs (Qnil, Qnil);
1414 set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));
1415
1416 ++num_input_keys;
1417
1418
1419
1420
1421 if (i == 0)
1422 return Qnil;
1423
1424
1425 if (i == -1)
1426 {
1427 cancel_echoing ();
1428 this_command_key_count = 0;
1429 this_single_command_key_start = 0;
1430 goto finalize;
1431 }
1432
1433 last_command_event = keybuf[i - 1];
1434
1435
1436
1437
1438
1439
1440 if (XWINDOW (selected_window)->force_start)
1441 {
1442 struct buffer *b;
1443 XWINDOW (selected_window)->force_start = 0;
1444 b = XBUFFER (XWINDOW (selected_window)->contents);
1445 BUF_BEG_UNCHANGED (b) = BUF_END_UNCHANGED (b) = 0;
1446 }
1447
1448 cmd = read_key_sequence_cmd;
1449 if (!NILP (Vexecuting_kbd_macro))
1450 {
1451 if (!NILP (Vquit_flag))
1452 {
1453 Vexecuting_kbd_macro = Qt;
1454 maybe_quit ();
1455
1456 }
1457 }
1458
1459
1460
1461 prev_buffer = current_buffer;
1462 prev_modiff = MODIFF;
1463 last_point_position = PT;
1464 ptrdiff_t last_pt = PT;
1465
1466
1467
1468
1469
1470 Vdisable_point_adjustment = Qnil;
1471
1472
1473
1474 Vdeactivate_mark = Qnil;
1475
1476
1477 Vthis_original_command = cmd;
1478 if (!NILP (read_key_sequence_remapped))
1479 cmd = read_key_sequence_remapped;
1480
1481
1482
1483 {
1484 total_keys += total_keys < lossage_limit;
1485 ASET (recent_keys, recent_keys_index,
1486 Fcons (Qnil, cmd));
1487 if (++recent_keys_index >= lossage_limit)
1488 recent_keys_index = 0;
1489 }
1490 Vthis_command = cmd;
1491 Vreal_this_command = cmd;
1492
1493 safe_run_hooks_maybe_narrowed (Qpre_command_hook,
1494 XWINDOW (selected_window));
1495
1496 if (NILP (Vthis_command))
1497
1498 call0 (Qundefined);
1499 else
1500 {
1501
1502
1503 #ifdef HAVE_WINDOW_SYSTEM
1504 specpdl_ref scount = SPECPDL_INDEX ();
1505
1506 if (display_hourglass_p
1507 && NILP (Vexecuting_kbd_macro))
1508 {
1509 record_unwind_protect_void (cancel_hourglass);
1510 start_hourglass ();
1511 }
1512 #endif
1513
1514
1515
1516 call0 (Qundo_auto__add_boundary);
1517
1518
1519
1520 point_before_last_command_or_undo = PT;
1521 buffer_before_last_command_or_undo = current_buffer;
1522
1523
1524
1525
1526 update_redisplay_ticks (0, NULL);
1527 display_working_on_window_p = false;
1528
1529 call1 (Qcommand_execute, Vthis_command);
1530 display_working_on_window_p = false;
1531
1532 #ifdef HAVE_WINDOW_SYSTEM
1533
1534
1535
1536
1537
1538 if (NILP (Vexecuting_kbd_macro))
1539 unbind_to (scount, Qnil);
1540 #endif
1541 }
1542
1543
1544 last_point_position = last_pt;
1545 kset_last_prefix_arg (current_kboard, Vcurrent_prefix_arg);
1546
1547 safe_run_hooks_maybe_narrowed (Qpost_command_hook,
1548 XWINDOW (selected_window));
1549
1550
1551
1552
1553
1554 if (!NILP (echo_area_buffer[0])
1555 && (EQ (echo_area_window,
1556 FRAME_MINIBUF_WINDOW (XFRAME (selected_frame)))))
1557 resize_echo_area_exactly ();
1558
1559
1560 if (!NILP (Vdelayed_warnings_list))
1561 safe_run_hooks (Qdelayed_warnings_hook);
1562
1563 kset_last_command (current_kboard, Vthis_command);
1564 kset_real_last_command (current_kboard, Vreal_this_command);
1565 if (!CONSP (last_command_event))
1566 kset_last_repeatable_command (current_kboard, Vreal_this_command);
1567
1568 this_command_key_count = 0;
1569 this_single_command_key_start = 0;
1570
1571 if (current_kboard->immediate_echo
1572 && !NILP (call0 (Qinternal_echo_keystrokes_prefix)))
1573 {
1574 current_kboard->immediate_echo = false;
1575
1576 echo_now ();
1577 }
1578 else
1579 cancel_echoing ();
1580
1581 if (!NILP (BVAR (current_buffer, mark_active))
1582 && !NILP (Vrun_hooks))
1583 {
1584
1585
1586
1587 if (EQ (Vtransient_mark_mode, Qidentity))
1588 Vtransient_mark_mode = Qnil;
1589 else if (EQ (Vtransient_mark_mode, Qonly))
1590 Vtransient_mark_mode = Qidentity;
1591
1592 if (!NILP (Vdeactivate_mark))
1593
1594
1595 call0 (Qdeactivate_mark);
1596 else
1597 {
1598 Lisp_Object symval;
1599
1600
1601 if ((!NILP (Fwindow_system (Qnil))
1602 || ((symval =
1603 find_symbol_value (Qtty_select_active_regions),
1604 (!EQ (symval, Qunbound) && !NILP (symval)))
1605 && !NILP (Fterminal_parameter (Qnil,
1606 Qxterm__set_selection))))
1607
1608
1609 && XMARKER (BVAR (current_buffer, mark))->buffer
1610 && (EQ (Vselect_active_regions, Qonly)
1611 ? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
1612 : (!NILP (Vselect_active_regions)
1613 && !NILP (Vtransient_mark_mode)))
1614 && NILP (Fmemq (Vthis_command,
1615 Vselection_inhibit_update_commands)))
1616 {
1617 Lisp_Object txt
1618 = call1 (Vregion_extract_function, Qnil);
1619
1620 if (XFIXNUM (Flength (txt)) > 0)
1621
1622 call2 (Qgui_set_selection, QPRIMARY, txt);
1623
1624 CALLN (Frun_hook_with_args, Qpost_select_region_hook, txt);
1625 }
1626
1627 if (current_buffer != prev_buffer || MODIFF != prev_modiff)
1628 run_hook (intern ("activate-mark-hook"));
1629 }
1630
1631 Vsaved_region_selection = Qnil;
1632 }
1633
1634 finalize:
1635
1636 if (current_buffer == prev_buffer
1637 && XBUFFER (XWINDOW (selected_window)->contents) == current_buffer
1638 && last_point_position != PT)
1639 {
1640 if (NILP (Vdisable_point_adjustment)
1641 && NILP (Vglobal_disable_point_adjustment)
1642 && !composition_break_at_point)
1643 {
1644 if (last_point_position > BEGV
1645 && last_point_position < ZV
1646 && (composition_adjust_point (last_point_position,
1647 last_point_position)
1648 != last_point_position))
1649
1650
1651
1652
1653 windows_or_buffers_changed = 21;
1654 adjust_point_for_property (last_point_position,
1655 MODIFF != prev_modiff);
1656 }
1657 else if (PT > BEGV && PT < ZV
1658 && (composition_adjust_point (last_point_position, PT)
1659 != PT))
1660
1661
1662
1663 windows_or_buffers_changed = 39;
1664 }
1665
1666
1667
1668 if (!NILP (KVAR (current_kboard, defining_kbd_macro))
1669 && NILP (KVAR (current_kboard, Vprefix_arg)))
1670 finalize_kbd_macro_chars ();
1671 }
1672 }
1673
1674 Lisp_Object
1675 read_menu_command (void)
1676 {
1677 specpdl_ref count = SPECPDL_INDEX ();
1678
1679
1680
1681 specbind (Qecho_keystrokes, make_fixnum (0));
1682
1683 Lisp_Object keybuf[READ_KEY_ELTS];
1684 int i = read_key_sequence (keybuf, Qnil, false, true, true, true,
1685 false);
1686
1687 unbind_to (count, Qnil);
1688
1689 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
1690 Fkill_emacs (Qnil, Qnil);
1691 if (i == 0 || i == -1)
1692 return Qt;
1693
1694 return read_key_sequence_cmd;
1695 }
1696
1697
1698
1699
1700
1701
1702 static void
1703 adjust_point_for_property (ptrdiff_t last_pt, bool modified)
1704 {
1705 ptrdiff_t beg, end;
1706 Lisp_Object val, overlay, tmp;
1707
1708
1709
1710
1711 bool check_composition = ! modified;
1712 bool check_display = true, check_invisible = true;
1713 ptrdiff_t orig_pt = PT;
1714
1715 eassert (XBUFFER (XWINDOW (selected_window)->contents) == current_buffer);
1716
1717
1718
1719 while (check_composition || check_display || check_invisible)
1720 {
1721
1722 if (check_composition
1723 && PT > BEGV && PT < ZV
1724 && (beg = composition_adjust_point (last_pt, PT)) != PT)
1725 {
1726 SET_PT (beg);
1727 check_display = check_invisible = true;
1728 }
1729 check_composition = false;
1730 if (check_display
1731 && PT > BEGV && PT < ZV
1732 && !NILP (val = get_char_property_and_overlay
1733 (make_fixnum (PT), Qdisplay, selected_window,
1734 &overlay))
1735 && display_prop_intangible_p (val, overlay, PT, PT_BYTE)
1736 && (!OVERLAYP (overlay)
1737 ? get_property_and_range (PT, Qdisplay, &val, &beg, &end, Qnil)
1738 : (beg = OVERLAY_START (overlay),
1739 end = OVERLAY_END (overlay)))
1740 && (beg < PT
1741 || (beg <= PT && STRINGP (val) && SCHARS (val) == 0)))
1742 {
1743 eassert (end > PT);
1744 SET_PT (PT < last_pt
1745 ? (STRINGP (val) && SCHARS (val) == 0
1746 ? max (beg - 1, BEGV)
1747 : beg)
1748 : end);
1749 check_composition = check_invisible = true;
1750 }
1751 check_display = false;
1752 if (check_invisible && PT > BEGV && PT < ZV)
1753 {
1754 int inv;
1755 bool ellipsis = false;
1756 beg = end = PT;
1757
1758
1759 while (end < ZV
1760 #if 0
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770 && (val = Fget_pos_property (make_fixnum (end),
1771 Qinvisible, Qnil),
1772 TEXT_PROP_MEANS_INVISIBLE (val))
1773 #endif
1774 && !NILP (val = get_char_property_and_overlay
1775 (make_fixnum (end), Qinvisible, Qnil, &overlay))
1776 && (inv = TEXT_PROP_MEANS_INVISIBLE (val)))
1777 {
1778 ellipsis = ellipsis || inv > 1
1779 || (OVERLAYP (overlay)
1780 && (!NILP (Foverlay_get (overlay, Qafter_string))
1781 || !NILP (Foverlay_get (overlay, Qbefore_string))));
1782 tmp = Fnext_single_char_property_change
1783 (make_fixnum (end), Qinvisible, Qnil, Qnil);
1784 end = FIXNATP (tmp) ? XFIXNAT (tmp) : ZV;
1785 }
1786 while (beg > BEGV
1787 #if 0
1788 && (val = Fget_pos_property (make_fixnum (beg),
1789 Qinvisible, Qnil),
1790 TEXT_PROP_MEANS_INVISIBLE (val))
1791 #endif
1792 && !NILP (val = get_char_property_and_overlay
1793 (make_fixnum (beg - 1), Qinvisible, Qnil, &overlay))
1794 && (inv = TEXT_PROP_MEANS_INVISIBLE (val)))
1795 {
1796 ellipsis = ellipsis || inv > 1
1797 || (OVERLAYP (overlay)
1798 && (!NILP (Foverlay_get (overlay, Qafter_string))
1799 || !NILP (Foverlay_get (overlay, Qbefore_string))));
1800 tmp = Fprevious_single_char_property_change
1801 (make_fixnum (beg), Qinvisible, Qnil, Qnil);
1802 beg = FIXNATP (tmp) ? XFIXNAT (tmp) : BEGV;
1803 }
1804
1805
1806 if (beg < PT && end > PT)
1807 {
1808 SET_PT ((orig_pt == PT && (last_pt < beg || last_pt > end))
1809
1810
1811
1812
1813
1814
1815
1816 ? (orig_pt = -1, PT < last_pt ? end : beg)
1817
1818
1819
1820 : (PT < last_pt ? beg : end));
1821 check_composition = check_display = true;
1822 }
1823 #if 0
1824
1825
1826 eassert (PT == beg || PT == end);
1827 #endif
1828
1829
1830
1831 if (!modified && !ellipsis && beg < end)
1832 {
1833 if (last_pt == beg && PT == end && end < ZV)
1834 (check_composition = check_display = true, SET_PT (end + 1));
1835 else if (last_pt == end && PT == beg && beg > BEGV)
1836 (check_composition = check_display = true, SET_PT (beg - 1));
1837 else if (PT == ((PT < last_pt) ? beg : end))
1838
1839
1840
1841 ;
1842 else if (val = Fget_pos_property (make_fixnum (PT),
1843 Qinvisible, Qnil),
1844 TEXT_PROP_MEANS_INVISIBLE (val)
1845 && (val = (Fget_pos_property
1846 (make_fixnum (PT == beg ? end : beg),
1847 Qinvisible, Qnil)),
1848 !TEXT_PROP_MEANS_INVISIBLE (val)))
1849 (check_composition = check_display = true,
1850 SET_PT (PT == beg ? end : beg));
1851 }
1852 }
1853 check_invisible = false;
1854 }
1855 }
1856
1857
1858
1859
1860
1861 static Lisp_Object
1862 safe_run_hooks_1 (ptrdiff_t nargs, Lisp_Object *args)
1863 {
1864 eassert (nargs >= 2);
1865 return Ffuncall (nargs - 1, args + 1);
1866 }
1867
1868
1869
1870
1871 static Lisp_Object
1872 safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args)
1873 {
1874 eassert (nargs >= 2);
1875 AUTO_STRING (format, "Error in %s (%S): %S");
1876 Lisp_Object hook = args[0];
1877 Lisp_Object fun = args[1];
1878 CALLN (Fmessage, format, hook, fun, error);
1879
1880 if (SYMBOLP (hook))
1881 {
1882 bool found = false;
1883 Lisp_Object newval = Qnil;
1884 Lisp_Object val = find_symbol_value (hook);
1885 FOR_EACH_TAIL (val)
1886 if (EQ (fun, XCAR (val)))
1887 found = true;
1888 else
1889 newval = Fcons (XCAR (val), newval);
1890 if (found)
1891 return Fset (hook, Fnreverse (newval));
1892
1893
1894 newval = Qnil;
1895 val = NILP (Fdefault_boundp (hook)) ? Qnil : Fdefault_value (hook);
1896 FOR_EACH_TAIL (val)
1897 if (EQ (fun, XCAR (val)))
1898 found = true;
1899 else
1900 newval = Fcons (XCAR (val), newval);
1901 if (found)
1902 return Fset_default (hook, Fnreverse (newval));
1903 }
1904 return Qnil;
1905 }
1906
1907 static Lisp_Object
1908 safe_run_hook_funcall (ptrdiff_t nargs, Lisp_Object *args)
1909 {
1910
1911
1912 eassert (nargs >= 2);
1913 Lisp_Object fun = args[0], hook = args[1];
1914
1915
1916
1917
1918 USE_SAFE_ALLOCA;
1919 Lisp_Object *newargs;
1920 SAFE_ALLOCA_LISP (newargs, nargs);
1921 newargs[0] = hook, newargs[1] = fun;
1922 memcpy (newargs + 2, args + 2, (nargs - 2) * word_size);
1923 internal_condition_case_n (safe_run_hooks_1, nargs, newargs,
1924 Qt, safe_run_hooks_error);
1925 SAFE_FREE ();
1926 return Qnil;
1927 }
1928
1929
1930
1931
1932
1933 void
1934 safe_run_hooks (Lisp_Object hook)
1935 {
1936 specpdl_ref count = SPECPDL_INDEX ();
1937
1938 specbind (Qinhibit_quit, Qt);
1939 run_hook_with_args (2, ((Lisp_Object []) {hook, hook}),
1940 safe_run_hook_funcall);
1941 unbind_to (count, Qnil);
1942 }
1943
1944 static void
1945 safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w)
1946 {
1947 specpdl_ref count = SPECPDL_INDEX ();
1948
1949 specbind (Qinhibit_quit, Qt);
1950
1951 if (current_buffer->long_line_optimizations_p
1952 && long_line_optimizations_region_size > 0)
1953 {
1954 ptrdiff_t begv = get_large_narrowing_begv (PT);
1955 ptrdiff_t zv = get_large_narrowing_zv (PT);
1956 if (begv != BEG || zv != Z)
1957 labeled_narrow_to_region (make_fixnum (begv), make_fixnum (zv),
1958 Qlong_line_optimizations_in_command_hooks);
1959 }
1960
1961 run_hook_with_args (2, ((Lisp_Object []) {hook, hook}),
1962 safe_run_hook_funcall);
1963 unbind_to (count, Qnil);
1964 }
1965
1966 void
1967 safe_run_hooks_2 (Lisp_Object hook, Lisp_Object arg1, Lisp_Object arg2)
1968 {
1969 specpdl_ref count = SPECPDL_INDEX ();
1970
1971 specbind (Qinhibit_quit, Qt);
1972 run_hook_with_args (4, ((Lisp_Object []) {hook, hook, arg1, arg2}),
1973 safe_run_hook_funcall);
1974 unbind_to (count, Qnil);
1975 }
1976
1977
1978
1979
1980 int poll_suppress_count;
1981
1982
1983 #ifdef POLL_FOR_INPUT
1984
1985
1986
1987 static struct atimer *poll_timer;
1988
1989
1990 static Lisp_Object poll_timer_time;
1991
1992 #if defined CYGWIN || defined DOS_NT
1993
1994 void
1995 poll_for_input_1 (void)
1996 {
1997 if (! input_blocked_p ()
1998 && !waiting_for_input)
1999 gobble_input ();
2000 }
2001 #endif
2002
2003
2004
2005
2006 static void
2007 poll_for_input (struct atimer *timer)
2008 {
2009 if (poll_suppress_count == 0)
2010 pending_signals = true;
2011 }
2012
2013 #endif
2014
2015
2016
2017
2018 void
2019 start_polling (void)
2020 {
2021 #ifdef POLL_FOR_INPUT
2022
2023
2024
2025 if (!interrupt_input)
2026 {
2027
2028
2029 turn_on_atimers (1);
2030
2031
2032
2033 if (NUMBERP (Vpolling_period)
2034 && (poll_timer == NULL
2035 || NILP (Fequal (Vpolling_period, poll_timer_time))))
2036 {
2037 struct timespec interval = dtotimespec (XFLOATINT (Vpolling_period));
2038
2039 if (poll_timer)
2040 cancel_atimer (poll_timer);
2041
2042 poll_timer = start_atimer (ATIMER_CONTINUOUS, interval,
2043 poll_for_input, NULL);
2044 poll_timer_time = Vpolling_period;
2045 }
2046
2047
2048
2049 --poll_suppress_count;
2050 }
2051 #endif
2052 }
2053
2054 #if defined CYGWIN || defined DOS_NT
2055
2056
2057 bool
2058 input_polling_used (void)
2059 {
2060 # ifdef POLL_FOR_INPUT
2061
2062
2063
2064 return !interrupt_input;
2065 # else
2066 return false;
2067 # endif
2068 }
2069 #endif
2070
2071
2072
2073 void
2074 stop_polling (void)
2075 {
2076 #ifdef POLL_FOR_INPUT
2077
2078
2079
2080 if (!interrupt_input)
2081 ++poll_suppress_count;
2082 #endif
2083 }
2084
2085
2086
2087
2088 void
2089 set_poll_suppress_count (int count)
2090 {
2091 #ifdef POLL_FOR_INPUT
2092 if (count == 0 && poll_suppress_count != 0)
2093 {
2094 poll_suppress_count = 1;
2095 start_polling ();
2096 }
2097 else if (count != 0 && poll_suppress_count == 0)
2098 {
2099 stop_polling ();
2100 }
2101 poll_suppress_count = count;
2102 #endif
2103 }
2104
2105
2106
2107
2108 void
2109 bind_polling_period (int n)
2110 {
2111 #ifdef POLL_FOR_INPUT
2112 if (FIXNUMP (Vpolling_period))
2113 {
2114 intmax_t new = XFIXNUM (Vpolling_period);
2115
2116 if (n > new)
2117 new = n;
2118
2119 stop_other_atimers (poll_timer);
2120 stop_polling ();
2121 specbind (Qpolling_period, make_int (new));
2122 }
2123 else if (FLOATP (Vpolling_period))
2124 {
2125 double new = XFLOAT_DATA (Vpolling_period);
2126
2127 stop_other_atimers (poll_timer);
2128 stop_polling ();
2129 specbind (Qpolling_period, (n > new
2130 ? make_int (n)
2131 : Vpolling_period));
2132 }
2133
2134
2135 start_polling ();
2136 #endif
2137 }
2138
2139
2140
2141 int
2142 make_ctrl_char (int c)
2143 {
2144
2145 int upper = c & ~0177;
2146
2147 if (! ASCII_CHAR_P (c))
2148 return c |= ctrl_modifier;
2149
2150 c &= 0177;
2151
2152
2153
2154 if (c >= 0100 && c < 0140)
2155 {
2156 int oc = c;
2157 c &= ~0140;
2158
2159
2160 if (oc >= 'A' && oc <= 'Z')
2161 c |= shift_modifier;
2162 }
2163
2164
2165 else if (c >= 'a' && c <= 'z')
2166 c &= ~0140;
2167
2168
2169
2170 else if (c >= ' ')
2171 c |= ctrl_modifier;
2172
2173
2174 c |= (upper & ~ctrl_modifier);
2175
2176 return c;
2177 }
2178
2179
2180
2181
2182 static Lisp_Object
2183 help_echo_substitute_command_keys (Lisp_Object help)
2184 {
2185 if (STRINGP (help)
2186 && SCHARS (help) > 0
2187 && !NILP (Fget_text_property (make_fixnum (0),
2188 Qhelp_echo_inhibit_substitution,
2189 help)))
2190 return help;
2191
2192 return call1 (Qsubstitute_command_keys, help);
2193 }
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222 void
2223 show_help_echo (Lisp_Object help, Lisp_Object window, Lisp_Object object,
2224 Lisp_Object pos)
2225 {
2226 if (!NILP (help) && !STRINGP (help))
2227 {
2228 if (FUNCTIONP (help))
2229 help = safe_call (4, help, window, object, pos);
2230 else
2231 help = safe_eval (help);
2232
2233 if (!STRINGP (help))
2234 return;
2235 }
2236
2237 if (!noninteractive && STRINGP (help))
2238 {
2239
2240
2241
2242
2243
2244 struct frame *f = some_mouse_moved ();
2245
2246 help = call1 (Qmouse_fixup_help_message, help);
2247 if (f)
2248 f->mouse_moved = true;
2249 }
2250
2251 if (STRINGP (help) || NILP (help))
2252 {
2253 if (!NILP (Vshow_help_function))
2254 call1 (Vshow_help_function, help_echo_substitute_command_keys (help));
2255 help_echo_showing_p = STRINGP (help);
2256 }
2257 }
2258
2259
2260
2261
2262
2263 static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu,
2264 struct timespec *end_time);
2265 static void record_char (Lisp_Object c);
2266
2267 static Lisp_Object help_form_saved_window_configs;
2268 static void
2269 read_char_help_form_unwind (void)
2270 {
2271 Lisp_Object window_config = XCAR (help_form_saved_window_configs);
2272 help_form_saved_window_configs = XCDR (help_form_saved_window_configs);
2273 if (!NILP (window_config))
2274 Fset_window_configuration (window_config, Qnil, Qnil);
2275 }
2276
2277 #define STOP_POLLING \
2278 do { if (! polling_stopped_here) stop_polling (); \
2279 polling_stopped_here = true; } while (0)
2280
2281 #define RESUME_POLLING \
2282 do { if (polling_stopped_here) start_polling (); \
2283 polling_stopped_here = false; } while (0)
2284
2285 static Lisp_Object
2286 read_event_from_main_queue (struct timespec *end_time,
2287 sys_jmp_buf local_getcjmp,
2288 bool *used_mouse_menu)
2289 {
2290 Lisp_Object c = Qnil;
2291 sys_jmp_buf save_jump;
2292 KBOARD *kb;
2293
2294 start:
2295
2296
2297
2298
2299 if (end_time && timespec_cmp (*end_time, current_timespec ()) <= 0)
2300 return c;
2301
2302
2303 specpdl_ref count = SPECPDL_INDEX ();
2304 save_getcjmp (save_jump);
2305 record_unwind_protect_ptr (restore_getcjmp, save_jump);
2306 restore_getcjmp (local_getcjmp);
2307 if (!end_time)
2308 timer_start_idle ();
2309 c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
2310 unbind_to (count, Qnil);
2311
2312 if (! NILP (c) && (kb != current_kboard))
2313 {
2314 Lisp_Object last = KVAR (kb, kbd_queue);
2315 if (CONSP (last))
2316 {
2317 while (CONSP (XCDR (last)))
2318 last = XCDR (last);
2319 if (!NILP (XCDR (last)))
2320 emacs_abort ();
2321 }
2322 if (!CONSP (last))
2323 kset_kbd_queue (kb, list1 (c));
2324 else
2325 XSETCDR (last, list1 (c));
2326 kb->kbd_queue_has_data = true;
2327 c = Qnil;
2328 if (single_kboard)
2329 goto start;
2330 current_kboard = kb;
2331 return make_fixnum (-2);
2332 }
2333
2334
2335 if (noninteractive && FIXNUMP (c) && XFIXNUM (c) < 0)
2336 Fkill_emacs (make_fixnum (1), Qnil);
2337
2338 if (FIXNUMP (c))
2339 {
2340
2341 if ((extra_keyboard_modifiers & CHAR_CTL)
2342 || ((extra_keyboard_modifiers & 0177) < ' '
2343 && (extra_keyboard_modifiers & 0177) != 0))
2344 XSETINT (c, make_ctrl_char (XFIXNUM (c)));
2345
2346
2347
2348
2349 XSETINT (c, XFIXNUM (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
2350 }
2351
2352 return c;
2353 }
2354
2355
2356
2357
2358
2359 static Lisp_Object
2360 read_decoded_event_from_main_queue (struct timespec *end_time,
2361 sys_jmp_buf local_getcjmp,
2362 Lisp_Object prev_event,
2363 bool *used_mouse_menu)
2364 {
2365 #ifndef WINDOWSNT
2366 #define MAX_ENCODED_BYTES 16
2367 Lisp_Object events[MAX_ENCODED_BYTES];
2368 int n = 0;
2369 #endif
2370 while (true)
2371 {
2372 Lisp_Object nextevt
2373 = read_event_from_main_queue (end_time, local_getcjmp,
2374 used_mouse_menu);
2375 #ifdef WINDOWSNT
2376
2377
2378
2379
2380 return nextevt;
2381 #else
2382 struct frame *frame = XFRAME (selected_frame);
2383 struct terminal *terminal = frame->terminal;
2384 if (!((FRAME_TERMCAP_P (frame) || FRAME_MSDOS_P (frame))
2385
2386
2387
2388 && (!EQ (prev_event, Qt))
2389 && (TERMINAL_KEYBOARD_CODING (terminal)->common_flags
2390 & CODING_REQUIRE_DECODING_MASK)))
2391 return nextevt;
2392 else
2393 {
2394 int meta_key = terminal->display_info.tty->meta_key;
2395 eassert (n < MAX_ENCODED_BYTES);
2396 events[n++] = nextevt;
2397 if (FIXNATP (nextevt)
2398 && XFIXNUM (nextevt) < (meta_key == 1 ? 0x80 : 0x100))
2399 {
2400 struct coding_system *coding
2401 = TERMINAL_KEYBOARD_CODING (terminal);
2402
2403 if (raw_text_coding_system_p (coding))
2404 {
2405 int i;
2406 if (meta_key != 2)
2407 {
2408 for (i = 0; i < n; i++)
2409 {
2410 int c = XFIXNUM (events[i]);
2411 int modifier =
2412 (meta_key == 3 && c < 0x100 && (c & 0x80))
2413 ? meta_modifier
2414 : 0;
2415 events[i] = make_fixnum ((c & ~0x80) | modifier);
2416 }
2417 }
2418 }
2419 else
2420 {
2421 unsigned char src[MAX_ENCODED_BYTES];
2422 unsigned char dest[MAX_ENCODED_BYTES * MAX_MULTIBYTE_LENGTH];
2423 int i;
2424 for (i = 0; i < n; i++)
2425 src[i] = XFIXNUM (events[i]);
2426 if (meta_key < 2)
2427 for (i = 0; i < n; i++)
2428 src[i] &= ~0x80;
2429 coding->destination = dest;
2430 coding->dst_bytes = sizeof dest;
2431 decode_coding_c_string (coding, src, n, Qnil);
2432 eassert (coding->produced_char <= n);
2433 if (coding->produced_char == 0)
2434 {
2435 if (n < MAX_ENCODED_BYTES)
2436 continue;
2437 }
2438 else
2439 {
2440 const unsigned char *p = coding->destination;
2441 eassert (coding->carryover_bytes == 0);
2442 n = 0;
2443 while (n < coding->produced_char)
2444 {
2445 int c = string_char_advance (&p);
2446 if (meta_key == 3)
2447 {
2448 int modifier
2449 = (c < 0x100 && (c & 0x80)
2450 ? meta_modifier
2451 : 0);
2452 c = (c & ~0x80) | modifier;
2453 }
2454 events[n++] = make_fixnum (c);
2455 }
2456 }
2457 }
2458 }
2459
2460
2461
2462
2463 while (n > 1)
2464 Vunread_command_events
2465 = Fcons (events[--n], Vunread_command_events);
2466 return events[0];
2467 }
2468 #endif
2469 }
2470 }
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499 Lisp_Object
2500 read_char (int commandflag, Lisp_Object map,
2501 Lisp_Object prev_event,
2502 bool *used_mouse_menu, struct timespec *end_time)
2503 {
2504 Lisp_Object c;
2505 sys_jmp_buf local_getcjmp;
2506 sys_jmp_buf save_jump;
2507 Lisp_Object tem, save;
2508 volatile Lisp_Object previous_echo_area_message;
2509 volatile Lisp_Object also_record;
2510 volatile bool reread, recorded;
2511 bool volatile polling_stopped_here = false;
2512 struct kboard *orig_kboard = current_kboard;
2513
2514 also_record = Qnil;
2515
2516 c = Qnil;
2517 previous_echo_area_message = Qnil;
2518
2519 retry:
2520
2521 recorded = false;
2522
2523 if (CONSP (Vunread_post_input_method_events))
2524 {
2525 c = XCAR (Vunread_post_input_method_events);
2526 Vunread_post_input_method_events
2527 = XCDR (Vunread_post_input_method_events);
2528
2529
2530
2531 if (CONSP (c)
2532 && (SYMBOLP (XCAR (c)) || FIXNUMP (XCAR (c)))
2533 && NILP (XCDR (c)))
2534 c = XCAR (c);
2535
2536 reread = true;
2537 goto reread_first;
2538 }
2539 else
2540 reread = false;
2541
2542 Vlast_event_device = Qnil;
2543
2544 if (CONSP (Vunread_command_events))
2545 {
2546 bool was_disabled = false;
2547
2548 c = XCAR (Vunread_command_events);
2549 Vunread_command_events = XCDR (Vunread_command_events);
2550
2551
2552
2553
2554 if (CONSP (c) && EQ (XCAR (c), Qt))
2555 c = XCDR (c);
2556 else
2557 {
2558 if (CONSP (c) && EQ (XCAR (c), Qno_record))
2559 {
2560 c = XCDR (c);
2561 recorded = true;
2562 }
2563 reread = true;
2564 }
2565
2566
2567
2568 if (CONSP (c)
2569 && EQ (XCDR (c), Qdisabled)
2570 && (SYMBOLP (XCAR (c)) || FIXNUMP (XCAR (c))))
2571 {
2572 was_disabled = true;
2573 c = XCAR (c);
2574 }
2575
2576
2577
2578 if (used_mouse_menu
2579
2580
2581 && (EQ (c, Qtool_bar) || EQ (c, Qtab_bar) || EQ (c, Qmenu_bar)
2582 || was_disabled))
2583 *used_mouse_menu = true;
2584
2585 goto reread_for_input_method;
2586 }
2587
2588 if (CONSP (Vunread_input_method_events))
2589 {
2590 c = XCAR (Vunread_input_method_events);
2591 Vunread_input_method_events = XCDR (Vunread_input_method_events);
2592
2593
2594
2595 if (CONSP (c)
2596 && (SYMBOLP (XCAR (c)) || FIXNUMP (XCAR (c)))
2597 && NILP (XCDR (c)))
2598 c = XCAR (c);
2599 reread = true;
2600 goto reread_for_input_method;
2601 }
2602
2603 if (!NILP (Vexecuting_kbd_macro))
2604 {
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615 Vlast_event_frame = internal_last_event_frame = Qmacro;
2616
2617
2618
2619
2620 if (EQ (Vexecuting_kbd_macro, Qt)
2621 || executing_kbd_macro_index >= XFIXNAT (Flength (Vexecuting_kbd_macro)))
2622 {
2623 XSETINT (c, -1);
2624 goto exit;
2625 }
2626
2627 c = Faref (Vexecuting_kbd_macro, make_int (executing_kbd_macro_index));
2628 if (STRINGP (Vexecuting_kbd_macro)
2629 && (XFIXNAT (c) & 0x80) && (XFIXNAT (c) <= 0xff))
2630 XSETFASTINT (c, CHAR_META | (XFIXNAT (c) & ~0x80));
2631
2632 executing_kbd_macro_index++;
2633
2634 goto from_macro;
2635 }
2636
2637 if (!NILP (unread_switch_frame))
2638 {
2639 c = unread_switch_frame;
2640 unread_switch_frame = Qnil;
2641
2642
2643
2644 goto reread_first;
2645 }
2646
2647
2648 if (commandflag >= 0)
2649 {
2650 bool echo_current = EQ (echo_message_buffer, echo_area_buffer[0]);
2651
2652
2653
2654 if (input_pending
2655 || detect_input_pending_run_timers (0))
2656 swallow_events (false);
2657
2658
2659 while (!(input_pending
2660 && (input_was_pending || !redisplay_dont_pause)))
2661 {
2662 input_was_pending = input_pending;
2663 if (help_echo_showing_p && !BASE_EQ (selected_window, minibuf_window))
2664 redisplay_preserve_echo_area (5);
2665 else
2666 redisplay ();
2667
2668 if (!input_pending)
2669
2670 break;
2671
2672
2673
2674 swallow_events (false);
2675
2676 }
2677
2678
2679
2680 if (commandflag == 0 && echo_current)
2681 echo_message_buffer = echo_area_buffer[0];
2682
2683 }
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710 if (
2711 !NILP (echo_area_buffer[0])
2712 && (
2713 echo_kboard != current_kboard
2714
2715 || ok_to_echo_at_next_pause == NULL))
2716 cancel_echoing ();
2717 else
2718 echo_dash ();
2719
2720
2721
2722
2723
2724
2725 c = Qnil;
2726 if (KEYMAPP (map) && INTERACTIVE
2727 && !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event)
2728
2729 && !CONSP (Vunread_command_events)
2730 && !detect_input_pending_run_timers (0))
2731 {
2732 c = read_char_minibuf_menu_prompt (commandflag, map);
2733
2734 if (FIXNUMP (c) && XFIXNUM (c) == -2)
2735 return c;
2736
2737 if (! NILP (c))
2738 goto exit;
2739 }
2740
2741
2742
2743
2744
2745
2746
2747 specpdl_ref jmpcount = SPECPDL_INDEX ();
2748 if (sys_setjmp (local_getcjmp))
2749 {
2750
2751
2752
2753 restore_getcjmp (save_jump);
2754 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
2755 unbind_to (jmpcount, Qnil);
2756
2757
2758 if (!EQ (Vquit_flag, Vthrow_on_input))
2759 XSETINT (c, quit_char);
2760 internal_last_event_frame = selected_frame;
2761 Vlast_event_frame = internal_last_event_frame;
2762
2763
2764 if (!NILP (Vinhibit_quit))
2765 Vquit_flag = Qnil;
2766
2767 {
2768 KBOARD *kb = FRAME_KBOARD (XFRAME (selected_frame));
2769 if (kb != current_kboard)
2770 {
2771 Lisp_Object last = KVAR (kb, kbd_queue);
2772
2773 if (single_kboard)
2774 emacs_abort ();
2775 if (CONSP (last))
2776 {
2777 while (CONSP (XCDR (last)))
2778 last = XCDR (last);
2779 if (!NILP (XCDR (last)))
2780 emacs_abort ();
2781 }
2782 if (!CONSP (last))
2783 kset_kbd_queue (kb, list1 (c));
2784 else
2785 XSETCDR (last, list1 (c));
2786 kb->kbd_queue_has_data = true;
2787 current_kboard = kb;
2788 return make_fixnum (-2);
2789 }
2790 }
2791 goto non_reread;
2792 }
2793
2794
2795
2796
2797
2798 if (!end_time)
2799 timer_start_idle ();
2800
2801
2802
2803
2804 if (minibuf_level == 0
2805 && !end_time
2806 && !current_kboard->immediate_echo
2807 && (this_command_key_count > 0
2808 || !NILP (call0 (Qinternal_echo_keystrokes_prefix)))
2809 && ! noninteractive
2810 && echo_keystrokes_p ()
2811 && (
2812 NILP (echo_area_buffer[0])
2813
2814 || (BUF_BEG (XBUFFER (echo_area_buffer[0]))
2815 == BUF_Z (XBUFFER (echo_area_buffer[0])))
2816
2817 || (echo_kboard && ok_to_echo_at_next_pause == echo_kboard)
2818
2819 || (!echo_kboard && ok_to_echo_at_next_pause)))
2820 {
2821
2822
2823
2824 if (EVENT_HAS_PARAMETERS (prev_event))
2825 echo_now ();
2826 else
2827 {
2828 Lisp_Object tem0;
2829
2830 specpdl_ref count = SPECPDL_INDEX ();
2831 save_getcjmp (save_jump);
2832 record_unwind_protect_ptr (restore_getcjmp, save_jump);
2833 restore_getcjmp (local_getcjmp);
2834 tem0 = sit_for (Vecho_keystrokes, 1, 1);
2835 unbind_to (count, Qnil);
2836 if (EQ (tem0, Qt)
2837 && ! CONSP (Vunread_command_events))
2838 echo_now ();
2839 }
2840 }
2841
2842
2843
2844 if (commandflag != 0 && commandflag != -2
2845 && auto_save_interval > 0
2846 && num_nonmacro_input_events - last_auto_save > max (auto_save_interval, 20)
2847 && !detect_input_pending_run_timers (0))
2848 {
2849 Fdo_auto_save (auto_save_no_message ? Qt : Qnil, Qnil);
2850
2851 redisplay ();
2852 }
2853
2854
2855
2856
2857
2858
2859 if (KEYMAPP (map) && INTERACTIVE
2860 && !NILP (prev_event)
2861 && EVENT_HAS_PARAMETERS (prev_event)
2862 && !EQ (XCAR (prev_event), Qmenu_bar)
2863 && !EQ (XCAR (prev_event), Qtab_bar)
2864 && !EQ (XCAR (prev_event), Qtool_bar)
2865
2866 && !CONSP (Vunread_command_events))
2867 {
2868 c = read_char_x_menu_prompt (map, prev_event, used_mouse_menu);
2869
2870
2871 if (!end_time)
2872 timer_stop_idle ();
2873
2874 goto exit;
2875 }
2876
2877
2878
2879 if (INTERACTIVE && NILP (c))
2880 {
2881 int delay_level;
2882 ptrdiff_t buffer_size;
2883
2884
2885
2886 if (! MINI_WINDOW_P (XWINDOW (selected_window)))
2887 last_non_minibuf_size = Z - BEG;
2888 buffer_size = (last_non_minibuf_size >> 8) + 1;
2889 delay_level = 0;
2890 while (buffer_size > 64)
2891 delay_level++, buffer_size -= buffer_size >> 2;
2892 if (delay_level < 4) delay_level = 4;
2893
2894
2895
2896
2897 if (commandflag != 0 && commandflag != -2
2898 && num_nonmacro_input_events > last_auto_save
2899 && FIXNUMP (Vauto_save_timeout)
2900 && XFIXNUM (Vauto_save_timeout) > 0)
2901 {
2902 Lisp_Object tem0;
2903 EMACS_INT timeout = XFIXNAT (Vauto_save_timeout);
2904
2905 timeout = min (timeout, MOST_POSITIVE_FIXNUM / delay_level * 4);
2906 timeout = delay_level * timeout / 4;
2907 specpdl_ref count1 = SPECPDL_INDEX ();
2908 save_getcjmp (save_jump);
2909 record_unwind_protect_ptr (restore_getcjmp, save_jump);
2910 restore_getcjmp (local_getcjmp);
2911 tem0 = sit_for (make_fixnum (timeout), 1, 1);
2912 unbind_to (count1, Qnil);
2913
2914 if (EQ (tem0, Qt)
2915 && ! CONSP (Vunread_command_events))
2916 {
2917 Fdo_auto_save (auto_save_no_message ? Qt : Qnil, Qnil);
2918 redisplay ();
2919 }
2920 }
2921
2922
2923 if (!detect_input_pending_run_timers (0))
2924 maybe_gc ();
2925 }
2926
2927
2928
2929
2930
2931
2932
2933
2934 if (NILP (c) && current_kboard != orig_kboard)
2935 return make_fixnum (-2);
2936
2937
2938
2939 if (CONSP (Vunread_command_events))
2940 {
2941 c = XCAR (Vunread_command_events);
2942 Vunread_command_events = XCDR (Vunread_command_events);
2943
2944 if (CONSP (c) && EQ (XCAR (c), Qt))
2945 c = XCDR (c);
2946 else
2947 {
2948 if (CONSP (c) && EQ (XCAR (c), Qno_record))
2949 {
2950 c = XCDR (c);
2951 recorded = true;
2952 }
2953 reread = true;
2954 }
2955 }
2956
2957
2958
2959 if (NILP (c))
2960 {
2961 if (current_kboard->kbd_queue_has_data)
2962 {
2963 if (!CONSP (KVAR (current_kboard, kbd_queue)))
2964 emacs_abort ();
2965 c = XCAR (KVAR (current_kboard, kbd_queue));
2966 kset_kbd_queue (current_kboard,
2967 XCDR (KVAR (current_kboard, kbd_queue)));
2968 if (NILP (KVAR (current_kboard, kbd_queue)))
2969 current_kboard->kbd_queue_has_data = false;
2970 input_pending = readable_events (0);
2971 if (EVENT_HAS_PARAMETERS (c)
2972 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qswitch_frame))
2973 internal_last_event_frame = XCAR (XCDR (c));
2974 Vlast_event_frame = internal_last_event_frame;
2975 }
2976 }
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986 if (NILP (c) && !single_kboard)
2987 {
2988 KBOARD *kb;
2989 for (kb = all_kboards; kb; kb = kb->next_kboard)
2990 if (kb->kbd_queue_has_data)
2991 {
2992 current_kboard = kb;
2993 return make_fixnum (-2);
2994 }
2995 }
2996
2997 wrong_kboard:
2998
2999 STOP_POLLING;
3000
3001 if (NILP (c))
3002 {
3003 c = read_decoded_event_from_main_queue (end_time, local_getcjmp,
3004 prev_event, used_mouse_menu);
3005 if (NILP (c) && end_time
3006 && timespec_cmp (*end_time, current_timespec ()) <= 0)
3007 {
3008 goto exit;
3009 }
3010
3011 if (BASE_EQ (c, make_fixnum (-2)))
3012 return c;
3013
3014 if (CONSP (c) && EQ (XCAR (c), Qt))
3015 c = XCDR (c);
3016 else if (CONSP (c) && EQ (XCAR (c), Qno_record))
3017 {
3018 c = XCDR (c);
3019 recorded = true;
3020 }
3021 }
3022
3023 non_reread:
3024
3025 if (!end_time)
3026 timer_stop_idle ();
3027 RESUME_POLLING;
3028
3029 if (NILP (c))
3030 {
3031 if (commandflag >= 0
3032 && !input_pending && !detect_input_pending_run_timers (0))
3033 redisplay ();
3034
3035 goto wrong_kboard;
3036 }
3037
3038
3039
3040
3041 if (BUFFERP (c))
3042 goto exit;
3043
3044
3045
3046 save = Vquit_flag;
3047 Vquit_flag = Qnil;
3048 tem = access_keymap (get_keymap (Vspecial_event_map, 0, 1), c, 0, 0, 1);
3049 Vquit_flag = save;
3050
3051 if (!NILP (tem))
3052 {
3053 struct buffer *prev_buffer = current_buffer;
3054 last_input_event = c;
3055
3056 call4 (Qcommand_execute, tem, Qnil, Fvector (1, &last_input_event), Qt);
3057
3058 if (CONSP (c) && !NILP (Fmemq (XCAR (c), Vwhile_no_input_ignore_events))
3059 && !end_time)
3060
3061
3062
3063
3064 timer_resume_idle ();
3065
3066 #ifdef HAVE_NS
3067 if (CONSP (c)
3068 && (EQ (XCAR (c), intern ("ns-unput-working-text"))))
3069 input_was_pending = input_pending;
3070 #endif
3071
3072 if (current_buffer != prev_buffer)
3073 {
3074
3075
3076
3077 c = make_fixnum (-2);
3078 goto exit;
3079 }
3080 else
3081 goto retry;
3082 }
3083
3084
3085 if (FIXNUMP (c))
3086 {
3087
3088 if (XFIXNUM (c) == -1)
3089 goto exit;
3090
3091 if ((STRINGP (KVAR (current_kboard, Vkeyboard_translate_table))
3092 && XFIXNAT (c) < SCHARS (KVAR (current_kboard,
3093 Vkeyboard_translate_table)))
3094 || (VECTORP (KVAR (current_kboard, Vkeyboard_translate_table))
3095 && XFIXNAT (c) < ASIZE (KVAR (current_kboard,
3096 Vkeyboard_translate_table)))
3097 || (CHAR_TABLE_P (KVAR (current_kboard, Vkeyboard_translate_table))
3098 && CHARACTERP (c)))
3099 {
3100 Lisp_Object d;
3101 d = Faref (KVAR (current_kboard, Vkeyboard_translate_table), c);
3102
3103 if (!NILP (d))
3104 c = d;
3105 }
3106 }
3107
3108
3109
3110
3111 if (EVENT_HAS_PARAMETERS (c)
3112 && CONSP (XCDR (c))
3113 && CONSP (xevent_start (c))
3114 && CONSP (XCDR (xevent_start (c))))
3115 {
3116 Lisp_Object posn;
3117
3118 posn = POSN_POSN (xevent_start (c));
3119
3120
3121 if (EQ (posn, Qmenu_bar) || EQ (posn, Qtab_bar) || EQ (posn, Qtool_bar))
3122 {
3123
3124 POSN_SET_POSN (xevent_start (c), list1 (posn));
3125
3126 also_record = c;
3127 Vunread_command_events = Fcons (c, Vunread_command_events);
3128 c = posn;
3129 }
3130 }
3131
3132
3133
3134 record_char (c);
3135 recorded = true;
3136 if (! NILP (also_record))
3137 record_char (also_record);
3138
3139
3140
3141
3142 if (FIXNUMP (c)
3143 && ! NILP (Vinput_method_function)
3144 && ' ' <= XFIXNUM (c) && XFIXNUM (c) < 256 && XFIXNUM (c) != 127)
3145 {
3146 previous_echo_area_message = Fcurrent_message ();
3147 Vinput_method_previous_message = previous_echo_area_message;
3148 }
3149
3150
3151
3152 if (!CONSP (c)
3153 || (!(EQ (Qhelp_echo, XCAR (c)))
3154 && !(EQ (Qswitch_frame, XCAR (c)))
3155
3156
3157 && !(EQ (Qselect_window, XCAR (c)))))
3158 {
3159 if (!NILP (echo_area_buffer[0]))
3160 {
3161 safe_run_hooks (Qecho_area_clear_hook);
3162 clear_message (1, 0);
3163
3164
3165
3166
3167 if (minibuf_level
3168 && EQ (minibuf_window, echo_area_window)
3169
3170
3171 && !NUMBERP (Vminibuffer_message_timeout))
3172 resize_mini_window (XWINDOW (minibuf_window), false);
3173 }
3174 else if (FUNCTIONP (Vclear_message_function))
3175 clear_message (1, 0);
3176 }
3177
3178 reread_for_input_method:
3179 from_macro:
3180
3181 if (FIXNUMP (c)
3182 && ! NILP (Vinput_method_function)
3183
3184
3185 && NILP (prev_event)
3186 && ' ' <= XFIXNUM (c) && XFIXNUM (c) < 256 && XFIXNUM (c) != 127)
3187 {
3188 Lisp_Object keys;
3189 ptrdiff_t key_count;
3190 ptrdiff_t command_key_start;
3191 specpdl_ref count = SPECPDL_INDEX ();
3192
3193
3194 bool saved_immediate_echo = current_kboard->immediate_echo;
3195 struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause;
3196 Lisp_Object saved_echo_string = KVAR (current_kboard, echo_string);
3197 Lisp_Object saved_echo_prompt = KVAR (current_kboard, echo_prompt);
3198
3199
3200 key_count = this_command_key_count;
3201 command_key_start = this_single_command_key_start;
3202
3203 if (key_count > 0)
3204 keys = Fcopy_sequence (this_command_keys);
3205 else
3206 keys = Qnil;
3207
3208
3209 this_command_key_count = 0;
3210 this_single_command_key_start = 0;
3211
3212
3213 if (!NILP (echo_area_buffer[0]))
3214 safe_run_hooks (Qecho_area_clear_hook);
3215 clear_message (1, 0);
3216 echo_truncate (0);
3217
3218
3219
3220 if (!KEYMAPP (map))
3221 {
3222 specbind (Qinput_method_use_echo_area, Qt);
3223 }
3224
3225
3226 tem = call1 (Vinput_method_function, c);
3227
3228 tem = unbind_to (count, tem);
3229
3230
3231
3232 this_command_key_count = key_count;
3233 this_single_command_key_start = command_key_start;
3234 if (key_count > 0)
3235 this_command_keys = keys;
3236
3237 cancel_echoing ();
3238 ok_to_echo_at_next_pause = saved_ok_to_echo;
3239 kset_echo_string (current_kboard, saved_echo_string);
3240 kset_echo_prompt (current_kboard, saved_echo_prompt);
3241 if (saved_immediate_echo)
3242 echo_now ();
3243
3244
3245 if (! CONSP (tem))
3246 {
3247
3248 if (! NILP (previous_echo_area_message))
3249 message_with_string ("%s", previous_echo_area_message, 0);
3250 goto retry;
3251 }
3252
3253 c = XCAR (tem);
3254 Vunread_post_input_method_events
3255 = nconc2 (XCDR (tem), Vunread_post_input_method_events);
3256 }
3257
3258
3259
3260 if (!recorded)
3261 {
3262 record_char (c);
3263 recorded = true;
3264 }
3265
3266 reread_first:
3267
3268
3269 if (CONSP (c) && EQ (XCAR (c), Qhelp_echo))
3270 {
3271
3272 Lisp_Object help, object, position, window, htem;
3273
3274 htem = Fcdr (XCDR (c));
3275 help = Fcar (htem);
3276 htem = Fcdr (htem);
3277 window = Fcar (htem);
3278 htem = Fcdr (htem);
3279 object = Fcar (htem);
3280 htem = Fcdr (htem);
3281 position = Fcar (htem);
3282
3283 show_help_echo (help, window, object, position);
3284
3285
3286 if (!end_time)
3287 timer_resume_idle ();
3288 goto retry;
3289 }
3290
3291 if ((! reread || this_command_key_count == 0)
3292 && !end_time)
3293 {
3294
3295
3296 if (! (EVENT_HAS_PARAMETERS (c)
3297 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
3298
3299
3300 ok_to_echo_at_next_pause = current_kboard;
3301
3302
3303 add_command_key (c);
3304 if (! NILP (also_record))
3305 add_command_key (also_record);
3306
3307 echo_update ();
3308 }
3309
3310 last_input_event = c;
3311 num_input_events++;
3312
3313
3314 if (!NILP (Vhelp_form) && help_char_p (c))
3315 {
3316 specpdl_ref count = SPECPDL_INDEX ();
3317
3318 help_form_saved_window_configs
3319 = Fcons (Fcurrent_window_configuration (Qnil),
3320 help_form_saved_window_configs);
3321 record_unwind_protect_void (read_char_help_form_unwind);
3322 call0 (Qhelp_form_show);
3323
3324 cancel_echoing ();
3325 do
3326 {
3327 c = read_char (0, Qnil, Qnil, 0, NULL);
3328 if (EVENT_HAS_PARAMETERS (c)
3329 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_click))
3330 XSETCAR (help_form_saved_window_configs, Qnil);
3331 }
3332 while (BUFFERP (c));
3333
3334 unbind_to (count, Qnil);
3335
3336 redisplay ();
3337 if (BASE_EQ (c, make_fixnum (040)))
3338 {
3339 cancel_echoing ();
3340 do
3341 c = read_char (0, Qnil, Qnil, 0, NULL);
3342 while (BUFFERP (c));
3343 }
3344 }
3345
3346 exit:
3347 RESUME_POLLING;
3348 input_was_pending = input_pending;
3349 return c;
3350 }
3351
3352
3353
3354
3355 static void
3356 record_menu_key (Lisp_Object c)
3357 {
3358
3359 clear_message (1, 0);
3360
3361 record_char (c);
3362
3363
3364
3365 ok_to_echo_at_next_pause = NULL;
3366
3367
3368 add_command_key (c);
3369 echo_update ();
3370
3371
3372 last_input_event = c;
3373 num_input_events++;
3374 }
3375
3376
3377
3378 static bool
3379 help_char_p (Lisp_Object c)
3380 {
3381 if (EQ (c, Vhelp_char))
3382 return true;
3383 Lisp_Object tail = Vhelp_event_list;
3384 FOR_EACH_TAIL_SAFE (tail)
3385 if (EQ (c, XCAR (tail)))
3386 return true;
3387 return false;
3388 }
3389
3390
3391
3392 static void
3393 record_char (Lisp_Object c)
3394 {
3395
3396
3397 if (!record_all_keys && inhibit_record_char)
3398 return;
3399
3400 int recorded = 0;
3401
3402 if (CONSP (c) && (EQ (XCAR (c), Qhelp_echo) || EQ (XCAR (c), Qmouse_movement)))
3403 {
3404
3405
3406
3407
3408
3409
3410 Lisp_Object ev1, ev2, ev3;
3411 int ix1, ix2, ix3;
3412
3413 if ((ix1 = recent_keys_index - 1) < 0)
3414 ix1 = lossage_limit - 1;
3415 ev1 = AREF (recent_keys, ix1);
3416
3417 if ((ix2 = ix1 - 1) < 0)
3418 ix2 = lossage_limit - 1;
3419 ev2 = AREF (recent_keys, ix2);
3420
3421 if ((ix3 = ix2 - 1) < 0)
3422 ix3 = lossage_limit - 1;
3423 ev3 = AREF (recent_keys, ix3);
3424
3425 if (EQ (XCAR (c), Qhelp_echo))
3426 {
3427
3428
3429
3430 Lisp_Object help, last_help;
3431
3432 help = Fcar_safe (Fcdr_safe (XCDR (c)));
3433 if (!STRINGP (help))
3434 recorded = 1;
3435 else if (CONSP (ev1) && EQ (XCAR (ev1), Qhelp_echo)
3436 && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev1))), EQ (last_help, help)))
3437 recorded = 1;
3438 else if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3439 && CONSP (ev2) && EQ (XCAR (ev2), Qhelp_echo)
3440 && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev2))), EQ (last_help, help)))
3441 recorded = -1;
3442 else if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3443 && CONSP (ev2) && EQ (XCAR (ev2), Qmouse_movement)
3444 && CONSP (ev3) && EQ (XCAR (ev3), Qhelp_echo)
3445 && (last_help = Fcar_safe (Fcdr_safe (XCDR (ev3))), EQ (last_help, help)))
3446 recorded = -2;
3447 }
3448 else if (EQ (XCAR (c), Qmouse_movement))
3449 {
3450
3451
3452 Lisp_Object last_window, window;
3453
3454 window = Fcar_safe (Fcar_safe (XCDR (c)));
3455 if (CONSP (ev1) && EQ (XCAR (ev1), Qmouse_movement)
3456 && (last_window = Fcar_safe (Fcar_safe (XCDR (ev1))), EQ (last_window, window))
3457 && CONSP (ev2) && EQ (XCAR (ev2), Qmouse_movement)
3458 && (last_window = Fcar_safe (Fcar_safe (XCDR (ev2))), EQ (last_window, window)))
3459 {
3460 ASET (recent_keys, ix1, c);
3461 recorded = 1;
3462 }
3463 }
3464 }
3465 else if (NILP (Vexecuting_kbd_macro))
3466 store_kbd_macro_char (c);
3467
3468
3469 if (NILP (Vexecuting_kbd_macro))
3470 {
3471 if (!recorded)
3472 {
3473 total_keys += total_keys < lossage_limit;
3474 ASET (recent_keys, recent_keys_index,
3475
3476
3477 CONSP (c) ? Fcopy_sequence (c) : c);
3478 if (++recent_keys_index >= lossage_limit)
3479 recent_keys_index = 0;
3480 }
3481 else if (recorded < 0)
3482 {
3483
3484
3485
3486
3487
3488
3489
3490 while (recorded++ < 0 && total_keys > 0)
3491 {
3492 if (total_keys < lossage_limit)
3493 total_keys--;
3494 if (--recent_keys_index < 0)
3495 recent_keys_index = lossage_limit - 1;
3496 ASET (recent_keys, recent_keys_index, Qnil);
3497 }
3498 }
3499
3500 num_nonmacro_input_events++;
3501 }
3502
3503
3504
3505
3506 if (dribble && NILP (Vexecuting_kbd_macro))
3507 {
3508 block_input ();
3509 if (FIXNUMP (c))
3510 {
3511 if (XUFIXNUM (c) < 0x100)
3512 putc (XUFIXNUM (c), dribble);
3513 else
3514 fprintf (dribble, " 0x%"pI"x", XUFIXNUM (c));
3515 }
3516 else
3517 {
3518 Lisp_Object dribblee;
3519
3520
3521 dribblee = EVENT_HEAD (c);
3522
3523 if (SYMBOLP (dribblee))
3524 {
3525 putc ('<', dribble);
3526 fwrite (SDATA (SYMBOL_NAME (dribblee)), sizeof (char),
3527 SBYTES (SYMBOL_NAME (dribblee)), dribble);
3528 putc ('>', dribble);
3529 }
3530 }
3531
3532 fflush (dribble);
3533 unblock_input ();
3534 }
3535 }
3536
3537
3538
3539
3540
3541
3542 static void
3543 save_getcjmp (sys_jmp_buf temp)
3544 {
3545 memcpy (temp, getcjmp, sizeof getcjmp);
3546 }
3547
3548 static void
3549 restore_getcjmp (void *temp)
3550 {
3551 memcpy (getcjmp, temp, sizeof getcjmp);
3552 }
3553
3554
3555
3556
3557
3558
3559
3560 static bool
3561 readable_events (int flags)
3562 {
3563 if (flags & READABLE_EVENTS_DO_TIMERS_NOW)
3564 timer_check ();
3565
3566
3567
3568
3569
3570
3571
3572
3573 if (kbd_fetch_ptr != kbd_store_ptr)
3574 {
3575
3576
3577 if (flags & (READABLE_EVENTS_FILTER_EVENTS
3578 #ifdef USE_TOOLKIT_SCROLL_BARS
3579 | READABLE_EVENTS_IGNORE_SQUEEZABLES
3580 #endif
3581 ))
3582 {
3583 union buffered_input_event *event = kbd_fetch_ptr;
3584
3585 do
3586 {
3587 if (!(
3588 #ifdef USE_TOOLKIT_SCROLL_BARS
3589 (flags & READABLE_EVENTS_FILTER_EVENTS) &&
3590 #endif
3591 ((!input_pending_p_filter_events
3592 && (event->kind == FOCUS_IN_EVENT
3593 || event->kind == FOCUS_OUT_EVENT))
3594 || (input_pending_p_filter_events
3595 && is_ignored_event (event))))
3596 #ifdef USE_TOOLKIT_SCROLL_BARS
3597 && !((flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
3598 && (event->kind == SCROLL_BAR_CLICK_EVENT
3599 || event->kind == HORIZONTAL_SCROLL_BAR_CLICK_EVENT)
3600 && event->ie.part == scroll_bar_handle
3601 && event->ie.modifiers == 0)
3602 #endif
3603 )
3604 return 1;
3605 event = next_kbd_event (event);
3606 }
3607 while (event != kbd_store_ptr);
3608 }
3609 else
3610 return 1;
3611 }
3612
3613 #ifdef HAVE_X_WINDOWS
3614 if (x_detect_pending_selection_requests ())
3615 return 1;
3616 #endif
3617
3618 #ifdef HAVE_TEXT_CONVERSION
3619 if (detect_conversion_events ())
3620 return 1;
3621 #endif
3622
3623 if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES) && some_mouse_moved ())
3624 return 1;
3625 if (single_kboard)
3626 {
3627 if (current_kboard->kbd_queue_has_data)
3628 return 1;
3629 }
3630 else
3631 {
3632 KBOARD *kb;
3633 for (kb = all_kboards; kb; kb = kb->next_kboard)
3634 if (kb->kbd_queue_has_data)
3635 return 1;
3636 }
3637 return 0;
3638 }
3639
3640
3641 int stop_character EXTERNALLY_VISIBLE;
3642
3643 static KBOARD *
3644 event_to_kboard (struct input_event *event)
3645 {
3646
3647 if (event->kind == SELECTION_REQUEST_EVENT
3648 || event->kind == SELECTION_CLEAR_EVENT)
3649 return NULL;
3650 else
3651 {
3652 Lisp_Object obj = event->frame_or_window;
3653
3654 if (WINDOWP (obj))
3655 obj = WINDOW_FRAME (XWINDOW (obj));
3656
3657 return ((FRAMEP (obj) && FRAME_LIVE_P (XFRAME (obj)))
3658 ? FRAME_KBOARD (XFRAME (obj)) : NULL);
3659 }
3660 }
3661
3662 #ifdef subprocesses
3663
3664
3665 static int
3666 kbd_buffer_nr_stored (void)
3667 {
3668 int n = kbd_store_ptr - kbd_fetch_ptr;
3669 return n + (n < 0 ? KBD_BUFFER_SIZE : 0);
3670 }
3671 #endif
3672
3673 void
3674 kbd_buffer_store_event (register struct input_event *event)
3675 {
3676 kbd_buffer_store_event_hold (event, 0);
3677 }
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689 void
3690 kbd_buffer_store_buffered_event (union buffered_input_event *event,
3691 struct input_event *hold_quit)
3692 {
3693 if (event->kind == NO_EVENT)
3694 emacs_abort ();
3695
3696 if (hold_quit && hold_quit->kind != NO_EVENT)
3697 return;
3698
3699 if (event->kind == ASCII_KEYSTROKE_EVENT)
3700 {
3701 int c = event->ie.code & 0377;
3702
3703 if (event->ie.modifiers & ctrl_modifier)
3704 c = make_ctrl_char (c);
3705
3706 c |= (event->ie.modifiers
3707 & (meta_modifier | alt_modifier
3708 | hyper_modifier | super_modifier));
3709
3710 if (c == quit_char)
3711 {
3712 KBOARD *kb = FRAME_KBOARD (XFRAME (event->ie.frame_or_window));
3713
3714 if (single_kboard && kb != current_kboard)
3715 {
3716 kset_kbd_queue
3717 (kb, list2 (make_lispy_switch_frame (event->ie.frame_or_window),
3718 make_fixnum (c)));
3719 kb->kbd_queue_has_data = true;
3720
3721 for (union buffered_input_event *sp = kbd_fetch_ptr;
3722 sp != kbd_store_ptr; sp = next_kbd_event (sp))
3723 {
3724 if (event_to_kboard (&sp->ie) == kb)
3725 {
3726 sp->ie.kind = NO_EVENT;
3727 sp->ie.frame_or_window = Qnil;
3728 sp->ie.arg = Qnil;
3729 }
3730 }
3731 return;
3732 }
3733
3734 if (hold_quit)
3735 {
3736 *hold_quit = event->ie;
3737 return;
3738 }
3739
3740
3741
3742
3743
3744 {
3745 Lisp_Object focus;
3746
3747 focus = FRAME_FOCUS_FRAME (XFRAME (event->ie.frame_or_window));
3748 if (NILP (focus))
3749 focus = event->ie.frame_or_window;
3750 internal_last_event_frame = focus;
3751 Vlast_event_frame = focus;
3752 }
3753
3754 handle_interrupt (0);
3755 return;
3756 }
3757
3758 if (c && c == stop_character)
3759 {
3760 sys_suspend ();
3761 return;
3762 }
3763 }
3764
3765
3766
3767
3768
3769 union buffered_input_event *next_slot = next_kbd_event (kbd_store_ptr);
3770 if (kbd_fetch_ptr != next_slot)
3771 {
3772 *kbd_store_ptr = *event;
3773 kbd_store_ptr = next_slot;
3774 #ifdef subprocesses
3775 if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE / 2
3776 && ! kbd_on_hold_p ())
3777 {
3778
3779
3780 hold_keyboard_input ();
3781 unrequest_sigio ();
3782 stop_polling ();
3783 }
3784 #endif
3785 }
3786
3787
3788
3789 if (!NILP (Vthrow_on_input)
3790 && !is_ignored_event (event))
3791 Vquit_flag = Vthrow_on_input;
3792 }
3793
3794
3795 #define INPUT_EVENT_POS_MAX \
3796 ((ptrdiff_t) min (PTRDIFF_MAX, min (TYPE_MAXIMUM (Time) / 2, \
3797 MOST_POSITIVE_FIXNUM)))
3798 #define INPUT_EVENT_POS_MIN (PTRDIFF_MIN < -INPUT_EVENT_POS_MAX \
3799 ? -1 - INPUT_EVENT_POS_MAX : PTRDIFF_MIN)
3800
3801
3802
3803 static Time
3804 position_to_Time (ptrdiff_t pos)
3805 {
3806 eassert (INPUT_EVENT_POS_MIN <= pos && pos <= INPUT_EVENT_POS_MAX);
3807 return pos;
3808 }
3809
3810
3811
3812
3813 static ptrdiff_t
3814 Time_to_position (Time encoded_pos)
3815 {
3816 if (encoded_pos <= INPUT_EVENT_POS_MAX)
3817 return encoded_pos;
3818 Time encoded_pos_min = position_to_Time (INPUT_EVENT_POS_MIN);
3819 eassert (encoded_pos_min <= encoded_pos);
3820 ptrdiff_t notpos = -1 - encoded_pos;
3821 return -1 - notpos;
3822 }
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835 void
3836 gen_help_event (Lisp_Object help, Lisp_Object frame, Lisp_Object window,
3837 Lisp_Object object, ptrdiff_t pos)
3838 {
3839 struct input_event event;
3840 EVENT_INIT (event);
3841
3842 event.kind = HELP_EVENT;
3843 event.frame_or_window = frame;
3844 event.arg = object;
3845 event.x = WINDOWP (window) ? window : frame;
3846 event.y = help;
3847 event.timestamp = position_to_Time (pos);
3848 kbd_buffer_store_event (&event);
3849 }
3850
3851
3852
3853
3854 void
3855 kbd_buffer_store_help_event (Lisp_Object frame, Lisp_Object help)
3856 {
3857 struct input_event event;
3858 EVENT_INIT (event);
3859
3860 event.kind = HELP_EVENT;
3861 event.frame_or_window = frame;
3862 event.arg = Qnil;
3863 event.x = Qnil;
3864 event.y = help;
3865 event.timestamp = 0;
3866 kbd_buffer_store_event (&event);
3867 }
3868
3869
3870
3871
3872 void
3873 discard_mouse_events (void)
3874 {
3875 for (union buffered_input_event *sp = kbd_fetch_ptr;
3876 sp != kbd_store_ptr; sp = next_kbd_event (sp))
3877 {
3878 if (sp->kind == MOUSE_CLICK_EVENT
3879 || sp->kind == WHEEL_EVENT
3880 || sp->kind == HORIZ_WHEEL_EVENT
3881 || sp->kind == SCROLL_BAR_CLICK_EVENT
3882 || sp->kind == HORIZONTAL_SCROLL_BAR_CLICK_EVENT)
3883 {
3884 sp->kind = NO_EVENT;
3885 }
3886 }
3887 }
3888
3889
3890
3891
3892
3893
3894
3895
3896 bool
3897 kbd_buffer_events_waiting (void)
3898 {
3899 for (union buffered_input_event *sp = kbd_fetch_ptr;
3900 ; sp = next_kbd_event (sp))
3901 if (sp == kbd_store_ptr || sp->kind != NO_EVENT)
3902 {
3903 kbd_fetch_ptr = sp;
3904 return sp != kbd_store_ptr && sp->kind != NO_EVENT;
3905 }
3906 }
3907
3908
3909
3910
3911 static void
3912 clear_event (struct input_event *event)
3913 {
3914 event->kind = NO_EVENT;
3915 }
3916
3917 static Lisp_Object
3918 kbd_buffer_get_event_1 (Lisp_Object arg)
3919 {
3920 Lisp_Object coding_system = Fget_text_property (make_fixnum (0),
3921 Qcoding, arg);
3922
3923 if (EQ (coding_system, Qt))
3924 return arg;
3925
3926 return code_convert_string (arg, (!NILP (coding_system)
3927 ? coding_system
3928 : Vlocale_coding_system),
3929 Qnil, 0, false, 0);
3930 }
3931
3932 static Lisp_Object
3933 kbd_buffer_get_event_2 (Lisp_Object val)
3934 {
3935 return Qnil;
3936 }
3937
3938
3939
3940
3941
3942
3943
3944 static Lisp_Object
3945 kbd_buffer_get_event (KBOARD **kbp,
3946 bool *used_mouse_menu,
3947 struct timespec *end_time)
3948 {
3949 Lisp_Object obj, str;
3950 #ifdef HAVE_X_WINDOWS
3951 bool had_pending_selection_requests;
3952
3953 had_pending_selection_requests = false;
3954 #endif
3955 #ifdef HAVE_TEXT_CONVERSION
3956 bool had_pending_conversion_events;
3957
3958 had_pending_conversion_events = false;
3959 #endif
3960
3961 #ifdef subprocesses
3962 if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE / 4)
3963 {
3964
3965
3966 unhold_keyboard_input ();
3967 request_sigio ();
3968 start_polling ();
3969 }
3970 #endif
3971
3972 #if !defined HAVE_DBUS && !defined USE_FILE_NOTIFY && !defined THREADS_ENABLED
3973 if (noninteractive
3974
3975
3976 || (IS_DAEMON && DAEMON_RUNNING))
3977 {
3978 int c = getchar ();
3979 XSETINT (obj, c);
3980 *kbp = current_kboard;
3981 return obj;
3982 }
3983 #endif
3984
3985 *kbp = current_kboard;
3986
3987
3988 for (;;)
3989 {
3990
3991
3992
3993 if (CONSP (Vunread_command_events))
3994 break;
3995
3996 if (kbd_fetch_ptr != kbd_store_ptr)
3997 break;
3998 if (some_mouse_moved ())
3999 break;
4000
4001
4002
4003 if (!NILP (Vquit_flag))
4004 quit_throw_to_read_char (0);
4005
4006
4007
4008
4009 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
4010 gobble_input ();
4011 #endif
4012
4013 if (kbd_fetch_ptr != kbd_store_ptr)
4014 break;
4015 if (some_mouse_moved ())
4016 break;
4017 #ifdef HAVE_X_WINDOWS
4018 if (x_detect_pending_selection_requests ())
4019 {
4020 had_pending_selection_requests = true;
4021 break;
4022 }
4023 #endif
4024 #ifdef HAVE_TEXT_CONVERSION
4025 if (detect_conversion_events ())
4026 {
4027 had_pending_conversion_events = true;
4028 break;
4029 }
4030 #endif
4031 if (end_time)
4032 {
4033 struct timespec now = current_timespec ();
4034 if (timespec_cmp (*end_time, now) <= 0)
4035 return Qnil;
4036 else
4037 {
4038 struct timespec duration = timespec_sub (*end_time, now);
4039 wait_reading_process_output (min (duration.tv_sec,
4040 WAIT_READING_MAX),
4041 duration.tv_nsec,
4042 -1, 1, Qnil, NULL, 0);
4043 }
4044 }
4045 else
4046 {
4047 bool do_display = true;
4048
4049 if (FRAME_TERMCAP_P (SELECTED_FRAME ()))
4050 {
4051 struct tty_display_info *tty = CURTTY ();
4052
4053
4054
4055
4056 if (tty->showing_menu)
4057 do_display = false;
4058 }
4059
4060 wait_reading_process_output (0, 0, -1, do_display, Qnil, NULL, 0);
4061 }
4062
4063 if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr)
4064 gobble_input ();
4065 }
4066
4067 #ifdef HAVE_X_WINDOWS
4068
4069
4070
4071
4072
4073 if (had_pending_selection_requests)
4074 x_handle_pending_selection_requests ();
4075 #endif
4076
4077 if (CONSP (Vunread_command_events))
4078 {
4079 Lisp_Object first;
4080 first = XCAR (Vunread_command_events);
4081 Vunread_command_events = XCDR (Vunread_command_events);
4082 *kbp = current_kboard;
4083 return first;
4084 }
4085
4086 #ifdef HAVE_TEXT_CONVERSION
4087
4088
4089
4090 if (had_pending_conversion_events)
4091 {
4092 handle_pending_conversion_events ();
4093 obj = Qtext_conversion;
4094
4095
4096
4097
4098 if (conversion_disabled_p ()
4099 || NILP (Vtext_conversion_edits))
4100 obj = Qnil;
4101 }
4102 else
4103 #endif
4104
4105
4106
4107 if (kbd_fetch_ptr != kbd_store_ptr)
4108 {
4109 union buffered_input_event *event = kbd_fetch_ptr;
4110
4111 *kbp = event_to_kboard (&event->ie);
4112 if (*kbp == 0)
4113 *kbp = current_kboard;
4114
4115 obj = Qnil;
4116
4117
4118
4119
4120 switch (event->kind)
4121 {
4122 #ifndef HAVE_HAIKU
4123 case SELECTION_REQUEST_EVENT:
4124 case SELECTION_CLEAR_EVENT:
4125 {
4126 #if defined HAVE_X11 || HAVE_PGTK
4127
4128
4129
4130 struct selection_input_event copy = event->sie;
4131 kbd_fetch_ptr = next_kbd_event (event);
4132 input_pending = readable_events (0);
4133
4134 #ifdef HAVE_X11
4135 x_handle_selection_event (©);
4136 #else
4137 pgtk_handle_selection_event (©);
4138 #endif
4139 #else
4140
4141
4142 emacs_abort ();
4143 #endif
4144 }
4145 break;
4146 #else
4147 case SELECTION_REQUEST_EVENT:
4148 emacs_abort ();
4149
4150 case SELECTION_CLEAR_EVENT:
4151 {
4152 struct input_event copy = event->ie;
4153
4154 kbd_fetch_ptr = next_kbd_event (event);
4155 input_pending = readable_events (0);
4156 haiku_handle_selection_clear (©);
4157 }
4158 break;
4159 #endif
4160
4161 case MONITORS_CHANGED_EVENT:
4162 {
4163 kbd_fetch_ptr = next_kbd_event (event);
4164 input_pending = readable_events (0);
4165
4166 CALLN (Frun_hook_with_args,
4167 Qdisplay_monitors_changed_functions,
4168 event->ie.arg);
4169
4170 break;
4171 }
4172
4173 #ifdef HAVE_EXT_MENU_BAR
4174 case MENU_BAR_ACTIVATE_EVENT:
4175 {
4176 struct frame *f;
4177 kbd_fetch_ptr = next_kbd_event (event);
4178 input_pending = readable_events (0);
4179 f = (XFRAME (event->ie.frame_or_window));
4180 if (FRAME_LIVE_P (f) && FRAME_TERMINAL (f)->activate_menubar_hook)
4181 FRAME_TERMINAL (f)->activate_menubar_hook (f);
4182 }
4183 break;
4184 #endif
4185 #if defined (HAVE_NS)
4186 case NS_TEXT_EVENT:
4187 if (used_mouse_menu)
4188 *used_mouse_menu = true;
4189 FALLTHROUGH;
4190 #endif
4191 case PREEDIT_TEXT_EVENT:
4192 #ifdef HAVE_NTGUI
4193 case END_SESSION_EVENT:
4194 case LANGUAGE_CHANGE_EVENT:
4195 #endif
4196 #ifdef HAVE_WINDOW_SYSTEM
4197 case DELETE_WINDOW_EVENT:
4198 case ICONIFY_EVENT:
4199 case DEICONIFY_EVENT:
4200 case MOVE_FRAME_EVENT:
4201 #endif
4202 #ifdef USE_FILE_NOTIFY
4203 case FILE_NOTIFY_EVENT:
4204 #endif
4205 #ifdef HAVE_DBUS
4206 case DBUS_EVENT:
4207 #endif
4208 #ifdef THREADS_ENABLED
4209 case THREAD_EVENT:
4210 #endif
4211 #ifdef HAVE_XWIDGETS
4212 case XWIDGET_EVENT:
4213 case XWIDGET_DISPLAY_EVENT:
4214 #endif
4215 case SAVE_SESSION_EVENT:
4216 case NO_EVENT:
4217 case HELP_EVENT:
4218 case FOCUS_IN_EVENT:
4219 case CONFIG_CHANGED_EVENT:
4220 case FOCUS_OUT_EVENT:
4221 case SELECT_WINDOW_EVENT:
4222 {
4223 obj = make_lispy_event (&event->ie);
4224 kbd_fetch_ptr = next_kbd_event (event);
4225 }
4226 break;
4227 default:
4228 {
4229
4230
4231
4232 Lisp_Object frame;
4233 Lisp_Object focus;
4234
4235 frame = event->ie.frame_or_window;
4236 if (CONSP (frame))
4237 frame = XCAR (frame);
4238 else if (WINDOWP (frame))
4239 frame = WINDOW_FRAME (XWINDOW (frame));
4240
4241 focus = FRAME_FOCUS_FRAME (XFRAME (frame));
4242 if (! NILP (focus))
4243 frame = focus;
4244
4245 if (!EQ (frame, internal_last_event_frame)
4246 && !EQ (frame, selected_frame))
4247 obj = make_lispy_switch_frame (frame);
4248 internal_last_event_frame = frame;
4249
4250 if (EQ (event->ie.device, Qt))
4251 Vlast_event_device = ((event->ie.kind == ASCII_KEYSTROKE_EVENT
4252 || event->ie.kind == MULTIBYTE_CHAR_KEYSTROKE_EVENT
4253 || event->ie.kind == NON_ASCII_KEYSTROKE_EVENT)
4254 ? virtual_core_keyboard_name
4255 : virtual_core_pointer_name);
4256 else
4257 Vlast_event_device = event->ie.device;
4258
4259
4260
4261 if (NILP (obj))
4262 {
4263 double pinch_dx, pinch_dy, pinch_angle;
4264
4265
4266
4267
4268
4269
4270
4271 if (event->ie.kind == PINCH_EVENT
4272
4273
4274
4275
4276 && ((pinch_dx
4277 = XFLOAT_DATA (XCAR (event->ie.arg))) != 0.0
4278 || XFLOAT_DATA (XCAR (XCDR (event->ie.arg))) != 0.0
4279 || XFLOAT_DATA (Fnth (make_fixnum (3), event->ie.arg)) != 0.0))
4280 {
4281 union buffered_input_event *maybe_event = next_kbd_event (event);
4282
4283 pinch_dy = XFLOAT_DATA (XCAR (XCDR (event->ie.arg)));
4284 pinch_angle = XFLOAT_DATA (Fnth (make_fixnum (3), event->ie.arg));
4285
4286 while (maybe_event != kbd_store_ptr
4287 && maybe_event->ie.kind == PINCH_EVENT
4288
4289
4290 && maybe_event->ie.modifiers == event->ie.modifiers
4291
4292
4293 && EQ (maybe_event->ie.frame_or_window,
4294 event->ie.frame_or_window)
4295
4296
4297 && (XFLOAT_DATA (XCAR (maybe_event->ie.arg)) != 0.0
4298 || XFLOAT_DATA (XCAR (XCDR (maybe_event->ie.arg))) != 0.0
4299 || XFLOAT_DATA (Fnth (make_fixnum (3),
4300 maybe_event->ie.arg)) != 0.0))
4301 {
4302 event = maybe_event;
4303
4304 pinch_dx += XFLOAT_DATA (XCAR (maybe_event->ie.arg));
4305 pinch_dy += XFLOAT_DATA (XCAR (XCDR (maybe_event->ie.arg)));
4306 pinch_angle += XFLOAT_DATA (Fnth (make_fixnum (3),
4307 maybe_event->ie.arg));
4308
4309 XSETCAR (maybe_event->ie.arg, make_float (pinch_dx));
4310 XSETCAR (XCDR (maybe_event->ie.arg), make_float (pinch_dy));
4311 XSETCAR (Fnthcdr (make_fixnum (3),
4312 maybe_event->ie.arg),
4313 make_float (fmod (pinch_angle, 360.0)));
4314
4315 if (!EQ (maybe_event->ie.device, Qt))
4316 Vlast_event_device = maybe_event->ie.device;
4317
4318 maybe_event = next_kbd_event (event);
4319 }
4320 }
4321
4322 if (event->kind == MULTIBYTE_CHAR_KEYSTROKE_EVENT
4323
4324 && STRINGP (event->ie.arg))
4325 {
4326 str = internal_condition_case_1 (kbd_buffer_get_event_1,
4327 event->ie.arg, Qt,
4328 kbd_buffer_get_event_2);
4329
4330
4331
4332 if (NILP (str))
4333 str = event->ie.arg;
4334
4335 if (!SCHARS (str))
4336 {
4337 kbd_fetch_ptr = next_kbd_event (event);
4338 obj = Qnil;
4339 break;
4340 }
4341
4342
4343
4344
4345 event->ie.arg = Fcons (make_fixnum (0), str);
4346 }
4347
4348 if (event->kind == MULTIBYTE_CHAR_KEYSTROKE_EVENT
4349 && CONSP (event->ie.arg))
4350 {
4351 eassert (FIXNUMP (XCAR (event->ie.arg)));
4352 eassert (STRINGP (XCDR (event->ie.arg)));
4353 eassert (XFIXNUM (XCAR (event->ie.arg))
4354 < SCHARS (XCDR (event->ie.arg)));
4355
4356 event->ie.code = XFIXNUM (Faref (XCDR (event->ie.arg),
4357 XCAR (event->ie.arg)));
4358
4359 XSETCAR (event->ie.arg,
4360 make_fixnum (XFIXNUM (XCAR (event->ie.arg)) + 1));
4361 }
4362
4363 obj = make_lispy_event (&event->ie);
4364
4365 #ifdef HAVE_EXT_MENU_BAR
4366
4367
4368
4369
4370
4371 if (used_mouse_menu
4372 && !EQ (event->ie.frame_or_window, event->ie.arg)
4373 && (event->kind == MENU_BAR_EVENT
4374 || event->kind == TAB_BAR_EVENT
4375 || event->kind == TOOL_BAR_EVENT))
4376 *used_mouse_menu = true;
4377 #endif
4378 #ifdef HAVE_NS
4379
4380 if (used_mouse_menu
4381 && event->kind == NS_NONKEY_EVENT)
4382 *used_mouse_menu = true;
4383 #endif
4384
4385 if (event->kind != MULTIBYTE_CHAR_KEYSTROKE_EVENT
4386 || !CONSP (event->ie.arg)
4387 || (XFIXNUM (XCAR (event->ie.arg))
4388 >= SCHARS (XCDR (event->ie.arg))))
4389 {
4390
4391 clear_event (&event->ie);
4392 kbd_fetch_ptr = next_kbd_event (event);
4393 }
4394 }
4395 }
4396 }
4397 }
4398
4399 else if (some_mouse_moved ())
4400 {
4401 struct frame *f, *movement_frame = some_mouse_moved ();
4402 Lisp_Object bar_window;
4403 enum scroll_bar_part part;
4404 Lisp_Object x, y;
4405 Time t;
4406
4407 f = movement_frame;
4408 *kbp = current_kboard;
4409
4410
4411
4412 x = Qnil;
4413
4414
4415 if (f && FRAME_TERMINAL (f)->mouse_position_hook)
4416 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, 0, &bar_window,
4417 &part, &x, &y, &t);
4418
4419 obj = Qnil;
4420
4421
4422
4423
4424 if (!NILP (x) && f)
4425 {
4426 Lisp_Object frame;
4427
4428 frame = FRAME_FOCUS_FRAME (f);
4429 if (NILP (frame))
4430 XSETFRAME (frame, f);
4431
4432 if (!EQ (frame, internal_last_event_frame)
4433 && !EQ (frame, selected_frame))
4434 obj = make_lispy_switch_frame (frame);
4435 internal_last_event_frame = frame;
4436 }
4437
4438
4439
4440 if (!NILP (x) && NILP (obj))
4441 obj = make_lispy_movement (f, bar_window, part, x, y, t);
4442
4443 if (!NILP (obj))
4444 Vlast_event_device = (STRINGP (movement_frame->last_mouse_device)
4445 ? movement_frame->last_mouse_device
4446 : virtual_core_pointer_name);
4447 }
4448 #ifdef HAVE_X_WINDOWS
4449 else if (had_pending_selection_requests)
4450 obj = Qnil;
4451 #endif
4452 else
4453
4454
4455 emacs_abort ();
4456
4457 input_pending = readable_events (0);
4458
4459 Vlast_event_frame = internal_last_event_frame;
4460
4461 return (obj);
4462 }
4463
4464
4465
4466
4467 static void
4468 process_special_events (void)
4469 {
4470 union buffered_input_event *event;
4471 #if defined HAVE_X11 || defined HAVE_PGTK || defined HAVE_HAIKU
4472 #ifndef HAVE_HAIKU
4473 struct selection_input_event copy;
4474 #else
4475 struct input_event copy;
4476 #endif
4477 int moved_events;
4478 #endif
4479
4480 for (event = kbd_fetch_ptr; event != kbd_store_ptr;
4481 event = next_kbd_event (event))
4482 {
4483
4484 if (event->kind == SELECTION_REQUEST_EVENT
4485 || event->kind == SELECTION_CLEAR_EVENT)
4486 {
4487 #if defined HAVE_X11 || defined HAVE_PGTK
4488
4489
4490
4491
4492
4493
4494
4495 copy = event->sie;
4496
4497 if (event < kbd_fetch_ptr)
4498 {
4499 memmove (kbd_buffer + 1, kbd_buffer,
4500 (event - kbd_buffer) * sizeof *kbd_buffer);
4501 kbd_buffer[0] = kbd_buffer[KBD_BUFFER_SIZE - 1];
4502 moved_events = kbd_buffer + KBD_BUFFER_SIZE - 1 - kbd_fetch_ptr;
4503 }
4504 else
4505 moved_events = event - kbd_fetch_ptr;
4506
4507 memmove (kbd_fetch_ptr + 1, kbd_fetch_ptr,
4508 moved_events * sizeof *kbd_fetch_ptr);
4509 kbd_fetch_ptr = next_kbd_event (kbd_fetch_ptr);
4510 input_pending = readable_events (0);
4511
4512 #ifdef HAVE_X11
4513 x_handle_selection_event (©);
4514 #else
4515 pgtk_handle_selection_event (©);
4516 #endif
4517 #elif defined HAVE_HAIKU
4518 if (event->ie.kind != SELECTION_CLEAR_EVENT)
4519 emacs_abort ();
4520
4521 copy = event->ie;
4522
4523 if (event < kbd_fetch_ptr)
4524 {
4525 memmove (kbd_buffer + 1, kbd_buffer,
4526 (event - kbd_buffer) * sizeof *kbd_buffer);
4527 kbd_buffer[0] = kbd_buffer[KBD_BUFFER_SIZE - 1];
4528 moved_events = kbd_buffer + KBD_BUFFER_SIZE - 1 - kbd_fetch_ptr;
4529 }
4530 else
4531 moved_events = event - kbd_fetch_ptr;
4532
4533 memmove (kbd_fetch_ptr + 1, kbd_fetch_ptr,
4534 moved_events * sizeof *kbd_fetch_ptr);
4535 kbd_fetch_ptr = next_kbd_event (kbd_fetch_ptr);
4536 input_pending = readable_events (0);
4537 haiku_handle_selection_clear (©);
4538 #else
4539
4540
4541 emacs_abort ();
4542 #endif
4543 }
4544 }
4545 }
4546
4547
4548
4549
4550 void
4551 swallow_events (bool do_display)
4552 {
4553 unsigned old_timers_run;
4554
4555 process_special_events ();
4556
4557 old_timers_run = timers_run;
4558 get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW);
4559
4560 if (!input_pending && timers_run != old_timers_run && do_display)
4561 redisplay_preserve_echo_area (7);
4562 }
4563
4564
4565
4566
4567 static void
4568 timer_start_idle (void)
4569 {
4570
4571 if (timespec_valid_p (timer_idleness_start_time))
4572 return;
4573
4574 timer_idleness_start_time = current_timespec ();
4575 timer_last_idleness_start_time = timer_idleness_start_time;
4576
4577
4578 call0 (intern ("internal-timer-start-idle"));
4579 }
4580
4581
4582
4583 static void
4584 timer_stop_idle (void)
4585 {
4586 timer_idleness_start_time = invalid_timespec ();
4587 }
4588
4589
4590
4591 static void
4592 timer_resume_idle (void)
4593 {
4594 if (timespec_valid_p (timer_idleness_start_time))
4595 return;
4596
4597 timer_idleness_start_time = timer_last_idleness_start_time;
4598 }
4599
4600
4601
4602
4603 Lisp_Object pending_funcalls;
4604
4605
4606 static bool
4607 decode_timer (Lisp_Object timer, struct timespec *result)
4608 {
4609 Lisp_Object *vec;
4610
4611 if (! (VECTORP (timer) && ASIZE (timer) == 10))
4612 return false;
4613 vec = XVECTOR (timer)->contents;
4614 if (! NILP (vec[0]))
4615 return false;
4616 if (! FIXNUMP (vec[2]))
4617 return false;
4618 return list4_to_timespec (vec[1], vec[2], vec[3], vec[8], result);
4619 }
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634 static struct timespec
4635 timer_check_2 (Lisp_Object timers, Lisp_Object idle_timers)
4636 {
4637 struct timespec nexttime;
4638 struct timespec now;
4639 struct timespec idleness_now;
4640 Lisp_Object chosen_timer;
4641
4642 nexttime = invalid_timespec ();
4643
4644 chosen_timer = Qnil;
4645
4646
4647 while (CONSP (pending_funcalls))
4648 {
4649 Lisp_Object funcall = XCAR (pending_funcalls);
4650 pending_funcalls = XCDR (pending_funcalls);
4651 safe_call2 (Qapply, XCAR (funcall), XCDR (funcall));
4652 }
4653
4654 if (CONSP (timers) || CONSP (idle_timers))
4655 {
4656 now = current_timespec ();
4657 idleness_now = (timespec_valid_p (timer_idleness_start_time)
4658 ? timespec_sub (now, timer_idleness_start_time)
4659 : make_timespec (0, 0));
4660 }
4661
4662 while (CONSP (timers) || CONSP (idle_timers))
4663 {
4664 Lisp_Object timer = Qnil, idle_timer = Qnil;
4665 struct timespec timer_time, idle_timer_time;
4666 struct timespec difference;
4667 struct timespec timer_difference = invalid_timespec ();
4668 struct timespec idle_timer_difference = invalid_timespec ();
4669 bool ripe, timer_ripe = 0, idle_timer_ripe = 0;
4670
4671
4672
4673
4674
4675
4676 if (CONSP (timers))
4677 {
4678 timer = XCAR (timers);
4679 if (! decode_timer (timer, &timer_time))
4680 {
4681 timers = XCDR (timers);
4682 continue;
4683 }
4684
4685 timer_ripe = timespec_cmp (timer_time, now) <= 0;
4686 timer_difference = (timer_ripe
4687 ? timespec_sub (now, timer_time)
4688 : timespec_sub (timer_time, now));
4689 }
4690
4691
4692
4693 if (CONSP (idle_timers))
4694 {
4695 idle_timer = XCAR (idle_timers);
4696 if (! decode_timer (idle_timer, &idle_timer_time))
4697 {
4698 idle_timers = XCDR (idle_timers);
4699 continue;
4700 }
4701
4702 idle_timer_ripe = timespec_cmp (idle_timer_time, idleness_now) <= 0;
4703 idle_timer_difference
4704 = (idle_timer_ripe
4705 ? timespec_sub (idleness_now, idle_timer_time)
4706 : timespec_sub (idle_timer_time, idleness_now));
4707 }
4708
4709
4710
4711
4712
4713 if (timespec_valid_p (timer_difference)
4714 && (! timespec_valid_p (idle_timer_difference)
4715 || idle_timer_ripe < timer_ripe
4716 || (idle_timer_ripe == timer_ripe
4717 && ((timer_ripe
4718 ? timespec_cmp (idle_timer_difference,
4719 timer_difference)
4720 : timespec_cmp (timer_difference,
4721 idle_timer_difference))
4722 < 0))))
4723 {
4724 chosen_timer = timer;
4725 timers = XCDR (timers);
4726 difference = timer_difference;
4727 ripe = timer_ripe;
4728 }
4729 else
4730 {
4731 chosen_timer = idle_timer;
4732 idle_timers = XCDR (idle_timers);
4733 difference = idle_timer_difference;
4734 ripe = idle_timer_ripe;
4735 }
4736
4737
4738 if (ripe)
4739 {
4740
4741
4742 eassert (NILP (AREF (chosen_timer, 0)));
4743
4744
4745 if (NILP (AREF (chosen_timer, 0)))
4746 {
4747 specpdl_ref count = SPECPDL_INDEX ();
4748 Lisp_Object old_deactivate_mark = Vdeactivate_mark;
4749
4750
4751
4752 ASET (chosen_timer, 0, Qt);
4753
4754 specbind (Qinhibit_quit, Qt);
4755
4756 call1 (Qtimer_event_handler, chosen_timer);
4757 Vdeactivate_mark = old_deactivate_mark;
4758 timers_run++;
4759 unbind_to (count, Qnil);
4760
4761
4762
4763
4764
4765 }
4766
4767 nexttime = make_timespec (0, 0);
4768 break;
4769 }
4770 else
4771
4772
4773 {
4774 return difference;
4775 }
4776 }
4777
4778
4779
4780 return nexttime;
4781 }
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793 struct timespec
4794 timer_check (void)
4795 {
4796 struct timespec nexttime;
4797 Lisp_Object timers, idle_timers;
4798
4799 Lisp_Object tem = Vinhibit_quit;
4800 Vinhibit_quit = Qt;
4801 block_input ();
4802 turn_on_atimers (false);
4803
4804
4805
4806
4807
4808
4809 timers = Fcopy_sequence (Vtimer_list);
4810
4811 if (timespec_valid_p (timer_idleness_start_time))
4812 idle_timers = Fcopy_sequence (Vtimer_idle_list);
4813 else
4814 idle_timers = Qnil;
4815
4816 turn_on_atimers (true);
4817 unblock_input ();
4818 Vinhibit_quit = tem;
4819
4820 do
4821 {
4822 nexttime = timer_check_2 (timers, idle_timers);
4823 }
4824 while (nexttime.tv_sec == 0 && nexttime.tv_nsec == 0);
4825
4826 return nexttime;
4827 }
4828
4829 DEFUN ("current-idle-time", Fcurrent_idle_time, Scurrent_idle_time, 0, 0, 0,
4830 doc:
4831
4832
4833
4834
4835
4836 )
4837 (void)
4838 {
4839 if (timespec_valid_p (timer_idleness_start_time))
4840 return make_lisp_time (timespec_sub (current_timespec (),
4841 timer_idleness_start_time));
4842
4843 return Qnil;
4844 }
4845
4846
4847 static Lisp_Object accent_key_syms;
4848 static Lisp_Object func_key_syms;
4849 static Lisp_Object mouse_syms;
4850 static Lisp_Object wheel_syms;
4851 static Lisp_Object drag_n_drop_syms;
4852 static Lisp_Object pinch_syms;
4853
4854
4855
4856
4857 static const int lispy_accent_codes[] =
4858 {
4859 #ifdef XK_dead_circumflex
4860 XK_dead_circumflex,
4861 #else
4862 0,
4863 #endif
4864 #ifdef XK_dead_grave
4865 XK_dead_grave,
4866 #else
4867 0,
4868 #endif
4869 #ifdef XK_dead_tilde
4870 XK_dead_tilde,
4871 #else
4872 0,
4873 #endif
4874 #ifdef XK_dead_diaeresis
4875 XK_dead_diaeresis,
4876 #else
4877 0,
4878 #endif
4879 #ifdef XK_dead_macron
4880 XK_dead_macron,
4881 #else
4882 0,
4883 #endif
4884 #ifdef XK_dead_degree
4885 XK_dead_degree,
4886 #else
4887 0,
4888 #endif
4889 #ifdef XK_dead_acute
4890 XK_dead_acute,
4891 #else
4892 0,
4893 #endif
4894 #ifdef XK_dead_cedilla
4895 XK_dead_cedilla,
4896 #else
4897 0,
4898 #endif
4899 #ifdef XK_dead_breve
4900 XK_dead_breve,
4901 #else
4902 0,
4903 #endif
4904 #ifdef XK_dead_ogonek
4905 XK_dead_ogonek,
4906 #else
4907 0,
4908 #endif
4909 #ifdef XK_dead_caron
4910 XK_dead_caron,
4911 #else
4912 0,
4913 #endif
4914 #ifdef XK_dead_doubleacute
4915 XK_dead_doubleacute,
4916 #else
4917 0,
4918 #endif
4919 #ifdef XK_dead_abovedot
4920 XK_dead_abovedot,
4921 #else
4922 0,
4923 #endif
4924 #ifdef XK_dead_abovering
4925 XK_dead_abovering,
4926 #else
4927 0,
4928 #endif
4929 #ifdef XK_dead_iota
4930 XK_dead_iota,
4931 #else
4932 0,
4933 #endif
4934 #ifdef XK_dead_belowdot
4935 XK_dead_belowdot,
4936 #else
4937 0,
4938 #endif
4939 #ifdef XK_dead_voiced_sound
4940 XK_dead_voiced_sound,
4941 #else
4942 0,
4943 #endif
4944 #ifdef XK_dead_semivoiced_sound
4945 XK_dead_semivoiced_sound,
4946 #else
4947 0,
4948 #endif
4949 #ifdef XK_dead_hook
4950 XK_dead_hook,
4951 #else
4952 0,
4953 #endif
4954 #ifdef XK_dead_horn
4955 XK_dead_horn,
4956 #else
4957 0,
4958 #endif
4959 };
4960
4961
4962
4963
4964 static const char *const lispy_accent_keys[] =
4965 {
4966 "dead-circumflex",
4967 "dead-grave",
4968 "dead-tilde",
4969 "dead-diaeresis",
4970 "dead-macron",
4971 "dead-degree",
4972 "dead-acute",
4973 "dead-cedilla",
4974 "dead-breve",
4975 "dead-ogonek",
4976 "dead-caron",
4977 "dead-doubleacute",
4978 "dead-abovedot",
4979 "dead-abovering",
4980 "dead-iota",
4981 "dead-belowdot",
4982 "dead-voiced-sound",
4983 "dead-semivoiced-sound",
4984 "dead-hook",
4985 "dead-horn",
4986 };
4987
4988 #ifdef HAVE_ANDROID
4989 #define FUNCTION_KEY_OFFSET 0
4990
4991 const char *const lispy_function_keys[] =
4992 {
4993
4994
4995 [111] = "escape",
4996 [112] = "delete",
4997 [120] = "sysrq",
4998 [121] = "break",
4999 [122] = "home",
5000 [123] = "end",
5001 [124] = "insert",
5002 [126] = "media-play",
5003 [127] = "media-pause",
5004 [130] = "media-record",
5005 [131] = "f1",
5006 [132] = "f2",
5007 [133] = "f3",
5008 [134] = "f4",
5009 [135] = "f5",
5010 [136] = "f6",
5011 [137] = "f7",
5012 [138] = "f8",
5013 [139] = "f9",
5014 [140] = "f10",
5015 [141] = "f11",
5016 [142] = "f12",
5017 [160] = "kp-ret",
5018 [164] = "volume-mute",
5019 [19] = "up",
5020 [20] = "down",
5021 [213] = "muhenkan",
5022 [214] = "henkan",
5023 [215] = "hiragana-katakana",
5024 [218] = "kana",
5025 [21] = "left",
5026 [22] = "right",
5027 [24] = "volume-up",
5028 [259] = "help",
5029 [25] = "volume-down",
5030 [268] = "kp-up-left",
5031 [269] = "kp-down-left",
5032 [270] = "kp-up-right",
5033 [271] = "kp-down-right",
5034 [272] = "media-skip-forward",
5035 [273] = "media-skip-backward",
5036 [277] = "cut",
5037 [278] = "copy",
5038 [279] = "paste",
5039 [28] = "clear",
5040 [4] = "XF86Back",
5041 [61] = "tab",
5042 [66] = "return",
5043 [67] = "backspace",
5044 [82] = "menu",
5045 [84] = "find",
5046 [85] = "media-play-pause",
5047 [86] = "media-stop",
5048 [87] = "media-next",
5049 [88] = "media-previous",
5050 [89] = "media-rewind",
5051 [92] = "prior",
5052 [93] = "next",
5053 };
5054
5055 #elif defined HAVE_NTGUI
5056 #define FUNCTION_KEY_OFFSET 0x0
5057
5058 const char *const lispy_function_keys[] =
5059 {
5060 0,
5061
5062 0,
5063 0,
5064 "cancel",
5065 0,
5066
5067 0, 0, 0,
5068
5069 "backspace",
5070 "tab",
5071
5072 0, 0,
5073
5074 "clear",
5075 "return",
5076
5077 0, 0,
5078
5079 0,
5080 0,
5081 0,
5082 "pause",
5083 "capslock",
5084 "kana",
5085 0,
5086 "junja",
5087 "final",
5088 "kanji",
5089 0,
5090 "escape",
5091 "convert",
5092 "non-convert",
5093 "accept",
5094 "mode-change",
5095 0,
5096 "prior",
5097 "next",
5098 "end",
5099 "home",
5100 "left",
5101 "up",
5102 "right",
5103 "down",
5104 "select",
5105 "print",
5106 "execute",
5107 "snapshot",
5108 "insert",
5109 "delete",
5110 "help",
5111
5112
5113
5114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5115
5116 0, 0, 0, 0, 0, 0, 0,
5117
5118
5119
5120 0, 0, 0, 0, 0, 0, 0, 0, 0,
5121 0, 0, 0, 0, 0, 0, 0, 0, 0,
5122 0, 0, 0, 0, 0, 0, 0, 0,
5123
5124 "lwindow",
5125 "rwindow",
5126 "apps",
5127 0,
5128 "sleep",
5129 "kp-0",
5130 "kp-1",
5131 "kp-2",
5132 "kp-3",
5133 "kp-4",
5134 "kp-5",
5135 "kp-6",
5136 "kp-7",
5137 "kp-8",
5138 "kp-9",
5139 "kp-multiply",
5140 "kp-add",
5141 "kp-separator",
5142 "kp-subtract",
5143 "kp-decimal",
5144 "kp-divide",
5145 "f1",
5146 "f2",
5147 "f3",
5148 "f4",
5149 "f5",
5150 "f6",
5151 "f7",
5152 "f8",
5153 "f9",
5154 "f10",
5155 "f11",
5156 "f12",
5157 "f13",
5158 "f14",
5159 "f15",
5160 "f16",
5161 "f17",
5162 "f18",
5163 "f19",
5164 "f20",
5165 "f21",
5166 "f22",
5167 "f23",
5168 "f24",
5169
5170 0, 0, 0, 0,
5171 0, 0, 0, 0,
5172
5173 "kp-numlock",
5174 "scroll",
5175
5176
5177
5178 "kp-space",
5179 "kp-enter",
5180 "kp-prior",
5181 "kp-next",
5182 "kp-end",
5183 "kp-home",
5184 "kp-left",
5185 "kp-up",
5186 "kp-right",
5187 "kp-down",
5188 "kp-insert",
5189 "kp-delete",
5190
5191 0, 0,
5192
5193
5194
5195
5196
5197
5198
5199 0, 0, 0, 0, 0, 0,
5200
5201
5202
5203
5204 0, 0, 0, 0, 0, 0, 0,
5205 0, 0, 0,
5206 0, 0, 0, 0,
5207 0, 0, 0, 0,
5208
5209
5210 0, 0, 0, 0, 0, 0, 0, 0, 0,
5211
5212
5213 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5214 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5215
5216 0,
5217 "ax",
5218 0,
5219 "ico-help",
5220 "ico-00",
5221 0,
5222 "ico-clear",
5223 0,
5224 0,
5225 "reset",
5226 "jump",
5227 "oem-pa1",
5228 "oem-pa2",
5229 "oem-pa3",
5230 "wsctrl",
5231 "cusel",
5232 "oem-attn",
5233 "finish",
5234 "copy",
5235 "auto",
5236 "enlw",
5237 "backtab",
5238 "attn",
5239 "crsel",
5240 "exsel",
5241 "ereof",
5242 "play",
5243 "zoom",
5244 "noname",
5245 "pa1",
5246 "oem_clear",
5247 0
5248 };
5249
5250
5251
5252 static const char *const lispy_multimedia_keys[] =
5253 {
5254 0,
5255 "browser-back",
5256 "browser-forward",
5257 "browser-refresh",
5258 "browser-stop",
5259 "browser-search",
5260 "browser-favorites",
5261 "browser-home",
5262 "volume-mute",
5263 "volume-down",
5264 "volume-up",
5265 "media-next",
5266 "media-previous",
5267 "media-stop",
5268 "media-play-pause",
5269 "mail",
5270 "media-select",
5271 "app-1",
5272 "app-2",
5273 "bass-down",
5274 "bass-boost",
5275 "bass-up",
5276 "treble-down",
5277 "treble-up",
5278 "mic-volume-mute",
5279 "mic-volume-down",
5280 "mic-volume-up",
5281 "help",
5282 "find",
5283 "new",
5284 "open",
5285 "close",
5286 "save",
5287 "print",
5288 "undo",
5289 "redo",
5290 "copy",
5291 "cut",
5292 "paste",
5293 "mail-reply",
5294 "mail-forward",
5295 "mail-send",
5296 "spell-check",
5297 "toggle-dictate-command",
5298 "mic-toggle",
5299 "correction-list",
5300 "media-play",
5301 "media-pause",
5302 "media-record",
5303 "media-fast-forward",
5304 "media-rewind",
5305 "media-channel-up",
5306 "media-channel-down"
5307 };
5308
5309 #else
5310
5311
5312
5313
5314 #if 0
5315 #ifdef XK_kana_A
5316 static const char *const lispy_kana_keys[] =
5317 {
5318
5319 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5320 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5321 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5322 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5323 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5324 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5325 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5326 0,0,0,0,0,0,0,0,0,0,0,0,0,0,"overline",0,
5327 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5328 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5329 0, "kana-fullstop", "kana-openingbracket", "kana-closingbracket",
5330 "kana-comma", "kana-conjunctive", "kana-WO", "kana-a",
5331 "kana-i", "kana-u", "kana-e", "kana-o",
5332 "kana-ya", "kana-yu", "kana-yo", "kana-tsu",
5333 "prolongedsound", "kana-A", "kana-I", "kana-U",
5334 "kana-E", "kana-O", "kana-KA", "kana-KI",
5335 "kana-KU", "kana-KE", "kana-KO", "kana-SA",
5336 "kana-SHI", "kana-SU", "kana-SE", "kana-SO",
5337 "kana-TA", "kana-CHI", "kana-TSU", "kana-TE",
5338 "kana-TO", "kana-NA", "kana-NI", "kana-NU",
5339 "kana-NE", "kana-NO", "kana-HA", "kana-HI",
5340 "kana-FU", "kana-HE", "kana-HO", "kana-MA",
5341 "kana-MI", "kana-MU", "kana-ME", "kana-MO",
5342 "kana-YA", "kana-YU", "kana-YO", "kana-RA",
5343 "kana-RI", "kana-RU", "kana-RE", "kana-RO",
5344 "kana-WA", "kana-N", "voicedsound", "semivoicedsound",
5345 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5346 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5347 };
5348 #endif
5349 #endif
5350
5351 #define FUNCTION_KEY_OFFSET 0xff00
5352
5353
5354
5355 const char *const lispy_function_keys[] =
5356 {
5357
5358
5359 0, 0, 0, 0, 0, 0, 0, 0,
5360 "backspace", "tab", "linefeed", "clear",
5361 0, "return", 0, 0,
5362 0, 0, 0, "pause",
5363 0, 0, 0, 0, 0, 0, 0, "escape",
5364 0, 0, 0, 0,
5365 0, "kanji", "muhenkan", "henkan",
5366 "romaji", "hiragana", "katakana", "hiragana-katakana",
5367 "zenkaku", "hankaku", "zenkaku-hankaku", "touroku",
5368 "massyo", "kana-lock", "kana-shift", "eisu-shift",
5369 "eisu-toggle",
5370 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5371 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5372
5373 "home", "left", "up", "right",
5374 "down", "prior", "next", "end",
5375 "begin", 0, 0, 0, 0, 0, 0, 0,
5376 "select",
5377 "print",
5378 "execute",
5379 "insert",
5380 0,
5381 "undo",
5382 "redo",
5383 "menu",
5384 "find",
5385 "cancel",
5386 "help",
5387 "break",
5388
5389 0, 0, 0, 0,
5390 0, 0, 0, 0, "backtab", 0, 0, 0,
5391 0, 0, 0, 0, 0, 0, 0, "kp-numlock",
5392 "kp-space",
5393 0, 0, 0, 0, 0, 0, 0, 0,
5394 "kp-tab",
5395 0, 0, 0,
5396 "kp-enter",
5397 0, 0, 0,
5398 "kp-f1",
5399 "kp-f2",
5400 "kp-f3",
5401 "kp-f4",
5402 "kp-home",
5403 "kp-left",
5404 "kp-up",
5405 "kp-right",
5406 "kp-down",
5407 "kp-prior",
5408 "kp-next",
5409 "kp-end",
5410 "kp-begin",
5411 "kp-insert",
5412 "kp-delete",
5413 0,
5414 0, 0, 0, 0, 0, 0, 0, 0, 0,
5415 "kp-multiply",
5416 "kp-add",
5417 "kp-separator",
5418 "kp-subtract",
5419 "kp-decimal",
5420 "kp-divide",
5421 "kp-0",
5422 "kp-1", "kp-2", "kp-3", "kp-4", "kp-5", "kp-6", "kp-7", "kp-8", "kp-9",
5423 0,
5424 0, 0,
5425 "kp-equal",
5426 "f1",
5427 "f2",
5428 "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10",
5429 "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18",
5430 "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26",
5431 "f27", "f28", "f29", "f30", "f31", "f32", "f33", "f34",
5432 "f35", 0, 0, 0, 0, 0, 0, 0,
5433 0, 0, 0, 0, 0, 0, 0, 0,
5434 0, 0, 0, 0, 0, 0, 0, 0,
5435 0, 0, 0, 0, 0, 0, 0, "delete"
5436 };
5437
5438
5439 #define ISO_FUNCTION_KEY_OFFSET 0xfe00
5440
5441 static const char *const iso_lispy_function_keys[] =
5442 {
5443 0, 0, 0, 0, 0, 0, 0, 0,
5444 0, 0, 0, 0, 0, 0, 0, 0,
5445 0, 0, 0, 0, 0, 0, 0, 0,
5446 0, 0, 0, 0, 0, 0, 0, 0,
5447 "iso-lefttab",
5448 "iso-move-line-up", "iso-move-line-down",
5449 "iso-partial-line-up", "iso-partial-line-down",
5450 "iso-partial-space-left", "iso-partial-space-right",
5451 "iso-set-margin-left", "iso-set-margin-right",
5452 "iso-release-margin-left", "iso-release-margin-right",
5453 "iso-release-both-margins",
5454 "iso-fast-cursor-left", "iso-fast-cursor-right",
5455 "iso-fast-cursor-up", "iso-fast-cursor-down",
5456 "iso-continuous-underline", "iso-discontinuous-underline",
5457 "iso-emphasize", "iso-center-object", "iso-enter",
5458 };
5459
5460 #endif
5461
5462 static Lisp_Object Vlispy_mouse_stem;
5463
5464 static const char *const lispy_wheel_names[] =
5465 {
5466 "wheel-up", "wheel-down", "wheel-left", "wheel-right"
5467 };
5468
5469
5470
5471 static const char *const lispy_drag_n_drop_names[] =
5472 {
5473 "drag-n-drop"
5474 };
5475
5476
5477
5478
5479 static short const scroll_bar_parts[] = {
5480 SYMBOL_INDEX (Qnil), SYMBOL_INDEX (Qabove_handle), SYMBOL_INDEX (Qhandle),
5481 SYMBOL_INDEX (Qbelow_handle), SYMBOL_INDEX (Qup), SYMBOL_INDEX (Qdown),
5482 SYMBOL_INDEX (Qtop), SYMBOL_INDEX (Qbottom), SYMBOL_INDEX (Qend_scroll),
5483 SYMBOL_INDEX (Qratio), SYMBOL_INDEX (Qbefore_handle),
5484 SYMBOL_INDEX (Qhorizontal_handle), SYMBOL_INDEX (Qafter_handle),
5485 SYMBOL_INDEX (Qleft), SYMBOL_INDEX (Qright), SYMBOL_INDEX (Qleftmost),
5486 SYMBOL_INDEX (Qrightmost), SYMBOL_INDEX (Qend_scroll), SYMBOL_INDEX (Qratio)
5487 };
5488
5489 #ifdef HAVE_WINDOW_SYSTEM
5490
5491
5492
5493 static short const internal_border_parts[] = {
5494 SYMBOL_INDEX (Qnil), SYMBOL_INDEX (Qleft_edge),
5495 SYMBOL_INDEX (Qtop_left_corner), SYMBOL_INDEX (Qtop_edge),
5496 SYMBOL_INDEX (Qtop_right_corner), SYMBOL_INDEX (Qright_edge),
5497 SYMBOL_INDEX (Qbottom_right_corner), SYMBOL_INDEX (Qbottom_edge),
5498 SYMBOL_INDEX (Qbottom_left_corner)
5499 };
5500 #endif
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513 static Lisp_Object button_down_location;
5514
5515
5516
5517 static Lisp_Object frame_relative_event_pos;
5518
5519
5520
5521
5522 static int last_mouse_button;
5523 static int last_mouse_x;
5524 static int last_mouse_y;
5525 static Time button_down_time;
5526
5527
5528
5529 static int double_click_count;
5530
5531
5532
5533
5534 static Lisp_Object
5535 make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
5536 Time t)
5537 {
5538 enum window_part part;
5539 Lisp_Object posn = Qnil;
5540 Lisp_Object extra_info = Qnil;
5541 int mx = XFIXNUM (x), my = XFIXNUM (y);
5542
5543 int xret = 0, yret = 0;
5544
5545 Lisp_Object window_or_frame = f
5546 ? window_from_coordinates (f, mx, my, &part, true, true)
5547 : Qnil;
5548 #ifdef HAVE_WINDOW_SYSTEM
5549 bool tool_bar_p = false;
5550 bool menu_bar_p = false;
5551
5552
5553
5554 if (f && ((WINDOWP (f->tab_bar_window)
5555 && EQ (window_or_frame, f->tab_bar_window))
5556 #ifndef HAVE_EXT_TOOL_BAR
5557 || (WINDOWP (f->tool_bar_window)
5558 && EQ (window_or_frame, f->tool_bar_window))
5559 #endif
5560 ))
5561 {
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575 if (NILP (track_mouse) || EQ (track_mouse, Qt))
5576 posn = EQ (window_or_frame, f->tab_bar_window) ? Qtab_bar : Qtool_bar;
5577
5578
5579
5580
5581 window_or_frame = Qnil;
5582 }
5583
5584 if (f && FRAME_TERMINAL (f)->toolkit_position_hook)
5585 {
5586 FRAME_TERMINAL (f)->toolkit_position_hook (f, mx, my, &menu_bar_p,
5587 &tool_bar_p);
5588
5589 if (NILP (track_mouse) || EQ (track_mouse, Qt))
5590 {
5591 if (menu_bar_p)
5592 posn = Qmenu_bar;
5593 else if (tool_bar_p)
5594 posn = Qtool_bar;
5595 }
5596 }
5597 #endif
5598 if (f
5599 && !FRAME_WINDOW_P (f)
5600 && FRAME_TAB_BAR_LINES (f) > 0
5601 && my >= FRAME_MENU_BAR_LINES (f)
5602 && my < FRAME_MENU_BAR_LINES (f) + FRAME_TAB_BAR_LINES (f))
5603 {
5604 posn = Qtab_bar;
5605 window_or_frame = Qnil;
5606 }
5607
5608 if (WINDOWP (window_or_frame))
5609 {
5610
5611 struct window *w = XWINDOW (window_or_frame);
5612 Lisp_Object string_info = Qnil;
5613 ptrdiff_t textpos = 0;
5614 int col = -1, row = -1;
5615 int dx = -1, dy = -1;
5616 int width = -1, height = -1;
5617 Lisp_Object object = Qnil;
5618
5619
5620 int wx = mx - WINDOW_LEFT_EDGE_X (w);
5621 int wy = my - WINDOW_TOP_EDGE_Y (w);
5622
5623
5624
5625
5626 if (part == ON_TEXT)
5627 {
5628 xret = mx - window_box_left (w, TEXT_AREA);
5629 yret = wy - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
5630 }
5631
5632
5633
5634 else if (part == ON_MODE_LINE || part == ON_TAB_LINE
5635 || part == ON_HEADER_LINE)
5636 {
5637 Lisp_Object string;
5638 ptrdiff_t charpos;
5639
5640 posn = (part == ON_MODE_LINE ? Qmode_line
5641 : (part == ON_TAB_LINE ? Qtab_line
5642 : Qheader_line));
5643
5644
5645
5646 col = wx;
5647 row = wy;
5648 string = mode_line_string (w, part, &col, &row, &charpos,
5649 &object, &dx, &dy, &width, &height);
5650 if (STRINGP (string))
5651 string_info = Fcons (string, make_fixnum (charpos));
5652 textpos = -1;
5653
5654 xret = wx;
5655 yret = wy;
5656 }
5657
5658
5659 else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
5660 {
5661 Lisp_Object string;
5662 ptrdiff_t charpos;
5663
5664 posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin;
5665 col = wx;
5666 row = wy;
5667 string = marginal_area_string (w, part, &col, &row, &charpos,
5668 &object, &dx, &dy, &width, &height);
5669 if (STRINGP (string))
5670 string_info = Fcons (string, make_fixnum (charpos));
5671 xret = wx;
5672 yret = wy - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
5673 }
5674 else if (part == ON_LEFT_FRINGE)
5675 {
5676 posn = Qleft_fringe;
5677 col = 0;
5678 xret = wx;
5679 dx = wx
5680 - (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5681 ? 0 : window_box_width (w, LEFT_MARGIN_AREA));
5682 dy = yret = wy - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
5683 }
5684 else if (part == ON_RIGHT_FRINGE)
5685 {
5686 posn = Qright_fringe;
5687 col = 0;
5688 xret = wx;
5689 dx = wx
5690 - window_box_width (w, LEFT_MARGIN_AREA)
5691 - window_box_width (w, TEXT_AREA)
5692 - (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5693 ? window_box_width (w, RIGHT_MARGIN_AREA)
5694 : 0);
5695 dy = yret = wy - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
5696 }
5697 else if (part == ON_VERTICAL_BORDER)
5698 {
5699 posn = Qvertical_line;
5700 width = 1;
5701 dx = 0;
5702 xret = wx;
5703 dy = yret = wy;
5704 }
5705 else if (part == ON_VERTICAL_SCROLL_BAR)
5706 {
5707 posn = Qvertical_scroll_bar;
5708 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
5709 dx = xret = wx;
5710 dy = yret = wy;
5711 }
5712 else if (part == ON_HORIZONTAL_SCROLL_BAR)
5713 {
5714 posn = Qhorizontal_scroll_bar;
5715 width = WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
5716 dx = xret = wx;
5717 dy = yret = wy;
5718 }
5719 else if (part == ON_RIGHT_DIVIDER)
5720 {
5721 posn = Qright_divider;
5722 width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
5723 dx = xret = wx;
5724 dy = yret = wy;
5725 }
5726 else if (part == ON_BOTTOM_DIVIDER)
5727 {
5728 posn = Qbottom_divider;
5729 width = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
5730 dx = xret = wx;
5731 dy = yret = wy;
5732 }
5733
5734
5735
5736
5737 if (!textpos)
5738 {
5739 Lisp_Object string2, object2 = Qnil;
5740 struct display_pos p;
5741 int dx2, dy2;
5742 int width2, height2;
5743
5744
5745
5746
5747 int x2
5748 = (part == ON_TEXT) ? xret
5749 : (part == ON_RIGHT_FRINGE || part == ON_RIGHT_MARGIN
5750 || (part == ON_VERTICAL_SCROLL_BAR
5751 && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
5752 ? (mx - window_box_left (w, TEXT_AREA))
5753 : 0;
5754 int y2 = wy;
5755
5756 string2 = buffer_posn_from_coords (w, &x2, &y2, &p,
5757 &object2, &dx2, &dy2,
5758 &width2, &height2);
5759 textpos = CHARPOS (p.pos);
5760 if (col < 0) col = x2;
5761 if (row < 0) row = y2;
5762 if (dx < 0) dx = dx2;
5763 if (dy < 0) dy = dy2;
5764 if (width < 0) width = width2;
5765 if (height < 0) height = height2;
5766
5767 if (NILP (posn))
5768 {
5769 posn = make_fixnum (textpos);
5770 if (STRINGP (string2))
5771 string_info = Fcons (string2,
5772 make_fixnum (CHARPOS (p.string_pos)));
5773 }
5774 if (NILP (object))
5775 object = object2;
5776 }
5777
5778 #ifdef HAVE_WINDOW_SYSTEM
5779 if (IMAGEP (object))
5780 {
5781 Lisp_Object image_map, hotspot;
5782 if ((image_map = plist_get (XCDR (object), QCmap),
5783 !NILP (image_map))
5784 && (hotspot = find_hot_spot (image_map, dx, dy),
5785 CONSP (hotspot))
5786 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
5787 posn = XCAR (hotspot);
5788 }
5789 #endif
5790
5791
5792 extra_info
5793 = list3 (object,
5794 Fcons (make_fixnum (dx), make_fixnum (dy)),
5795 Fcons (make_fixnum (width), make_fixnum (height)));
5796
5797
5798 extra_info = Fcons (string_info,
5799 Fcons (textpos < 0 ? Qnil : make_fixnum (textpos),
5800 Fcons (Fcons (make_fixnum (col),
5801 make_fixnum (row)),
5802 extra_info)));
5803 }
5804 else if (f)
5805 {
5806
5807 XSETFRAME (window_or_frame, f);
5808 xret = mx;
5809 yret = my;
5810
5811 #ifdef HAVE_WINDOW_SYSTEM
5812 if (FRAME_WINDOW_P (f)
5813 && FRAME_LIVE_P (f)
5814 && NILP (posn)
5815 && FRAME_INTERNAL_BORDER_WIDTH (f) > 0
5816 && !NILP (get_frame_param (f, Qdrag_internal_border)))
5817 {
5818 enum internal_border_part part
5819 = frame_internal_border_part (f, xret, yret);
5820
5821 posn = builtin_lisp_symbol (internal_border_parts[part]);
5822 }
5823 #endif
5824 }
5825 else
5826 {
5827 if (EQ (track_mouse, Qdrag_source))
5828 {
5829 xret = mx;
5830 yret = my;
5831 }
5832
5833 window_or_frame = Qnil;
5834 }
5835
5836 return Fcons (window_or_frame,
5837 Fcons (posn,
5838 Fcons (Fcons (make_fixnum (xret),
5839 make_fixnum (yret)),
5840 Fcons (INT_TO_INTEGER (t),
5841 extra_info))));
5842 }
5843
5844
5845
5846
5847
5848 static bool
5849 toolkit_menubar_in_use (struct frame *f)
5850 {
5851 #ifdef HAVE_EXT_MENU_BAR
5852 return !(!FRAME_WINDOW_P (f));
5853 #else
5854 return false;
5855 #endif
5856 }
5857
5858
5859
5860
5861 static Lisp_Object
5862 make_scroll_bar_position (struct input_event *ev, Lisp_Object type)
5863 {
5864 return list5 (ev->frame_or_window, type, Fcons (ev->x, ev->y),
5865 INT_TO_INTEGER (ev->timestamp),
5866 builtin_lisp_symbol (scroll_bar_parts[ev->part]));
5867 }
5868
5869 #if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
5870
5871
5872
5873
5874 static bool
5875 coords_in_menu_bar_window (struct frame *f, int x, int y)
5876 {
5877 struct window *window;
5878
5879 if (!WINDOWP (f->menu_bar_window))
5880 return false;
5881
5882 window = XWINDOW (f->menu_bar_window);
5883
5884 return (y >= WINDOW_TOP_EDGE_Y (window)
5885 && x >= WINDOW_LEFT_EDGE_X (window)
5886 && y <= WINDOW_BOTTOM_EDGE_Y (window)
5887 && x <= WINDOW_RIGHT_EDGE_X (window));
5888 }
5889
5890 #endif
5891
5892 #ifdef HAVE_WINDOW_SYSTEM
5893
5894
5895
5896
5897 static bool
5898 coords_in_tab_bar_window (struct frame *f, int x, int y)
5899 {
5900 struct window *window;
5901
5902 if (!WINDOWP (f->tab_bar_window))
5903 return false;
5904
5905 window = XWINDOW (f->tab_bar_window);
5906
5907 return (y >= WINDOW_TOP_EDGE_Y (window)
5908 && x >= WINDOW_LEFT_EDGE_X (window)
5909 && y <= WINDOW_BOTTOM_EDGE_Y (window)
5910 && x <= WINDOW_RIGHT_EDGE_X (window));
5911 }
5912
5913 #endif
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923 static Lisp_Object
5924 make_lispy_event (struct input_event *event)
5925 {
5926 int i;
5927
5928 switch (event->kind)
5929 {
5930 #ifdef HAVE_WINDOW_SYSTEM
5931 case DELETE_WINDOW_EVENT:
5932
5933 return list2 (Qdelete_frame, list1 (event->frame_or_window));
5934
5935 case ICONIFY_EVENT:
5936
5937 return list2 (Qiconify_frame, list1 (event->frame_or_window));
5938
5939 case DEICONIFY_EVENT:
5940
5941 return list2 (Qmake_frame_visible, list1 (event->frame_or_window));
5942
5943 case MOVE_FRAME_EVENT:
5944
5945 return list2 (Qmove_frame, list1 (event->frame_or_window));
5946 #endif
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956 case NO_EVENT:
5957 return Qnil;
5958
5959 case HELP_EVENT:
5960 {
5961 Lisp_Object frame = event->frame_or_window;
5962 Lisp_Object object = event->arg;
5963 Lisp_Object position
5964 = make_fixnum (Time_to_position (event->timestamp));
5965 Lisp_Object window = event->x;
5966 Lisp_Object help = event->y;
5967 clear_event (event);
5968
5969 if (!WINDOWP (window))
5970 window = Qnil;
5971 return Fcons (Qhelp_echo,
5972 list5 (frame, help, window, object, position));
5973 }
5974
5975 case FOCUS_IN_EVENT:
5976 return make_lispy_focus_in (event->frame_or_window);
5977
5978 case FOCUS_OUT_EVENT:
5979 return make_lispy_focus_out (event->frame_or_window);
5980
5981
5982 case ASCII_KEYSTROKE_EVENT:
5983 case MULTIBYTE_CHAR_KEYSTROKE_EVENT:
5984 {
5985 Lisp_Object lispy_c;
5986 EMACS_INT c = event->code;
5987 if (event->kind == ASCII_KEYSTROKE_EVENT)
5988 {
5989 c &= 0377;
5990 eassert (c == event->code);
5991 }
5992
5993
5994
5995
5996
5997 if (event->modifiers & ~shift_modifier)
5998 {
5999
6000
6001
6002 if (uppercasep (c) &&
6003 !(event->modifiers & shift_modifier))
6004 {
6005
6006
6007 c = downcase (c);
6008 }
6009 else if (lowercasep (c) &&
6010 (event->modifiers & shift_modifier))
6011 {
6012
6013
6014
6015 c = upcase (c);
6016 }
6017 }
6018
6019 if (event->kind == ASCII_KEYSTROKE_EVENT)
6020 {
6021
6022
6023 if (event->modifiers & ctrl_modifier)
6024 {
6025 c = make_ctrl_char (c);
6026 event->modifiers &= ~ctrl_modifier;
6027 }
6028 }
6029
6030
6031
6032 c |= (event->modifiers
6033 & (meta_modifier | alt_modifier
6034 | hyper_modifier | super_modifier | ctrl_modifier));
6035
6036 if ((event->code) == 040
6037 && event->modifiers & shift_modifier)
6038 c |= shift_modifier;
6039 button_down_time = 0;
6040 XSETFASTINT (lispy_c, c);
6041 return lispy_c;
6042 }
6043
6044 #ifdef HAVE_NS
6045 case NS_TEXT_EVENT:
6046 return list1 (intern (event->code == KEY_NS_PUT_WORKING_TEXT
6047 ? "ns-put-working-text"
6048 : "ns-unput-working-text"));
6049
6050
6051
6052 case NS_NONKEY_EVENT:
6053 #endif
6054
6055
6056
6057 case NON_ASCII_KEYSTROKE_EVENT:
6058 button_down_time = 0;
6059
6060 for (i = 0; i < ARRAYELTS (lispy_accent_codes); i++)
6061 if (event->code == lispy_accent_codes[i])
6062 return modify_event_symbol (i,
6063 event->modifiers,
6064 Qfunction_key, Qnil,
6065 lispy_accent_keys, &accent_key_syms,
6066 ARRAYELTS (lispy_accent_keys));
6067
6068 #if 0
6069 #ifdef XK_kana_A
6070 if (event->code >= 0x400 && event->code < 0x500)
6071 return modify_event_symbol (event->code - 0x400,
6072 event->modifiers & ~shift_modifier,
6073 Qfunction_key, Qnil,
6074 lispy_kana_keys, &func_key_syms,
6075 ARRAYELTS (lispy_kana_keys));
6076 #endif
6077 #endif
6078
6079 #ifdef ISO_FUNCTION_KEY_OFFSET
6080 if (event->code < FUNCTION_KEY_OFFSET
6081 && event->code >= ISO_FUNCTION_KEY_OFFSET)
6082 return modify_event_symbol (event->code - ISO_FUNCTION_KEY_OFFSET,
6083 event->modifiers,
6084 Qfunction_key, Qnil,
6085 iso_lispy_function_keys, &func_key_syms,
6086 ARRAYELTS (iso_lispy_function_keys));
6087 #endif
6088
6089 if ((FUNCTION_KEY_OFFSET <= event->code
6090 && (event->code
6091 < FUNCTION_KEY_OFFSET + ARRAYELTS (lispy_function_keys)))
6092 && lispy_function_keys[event->code - FUNCTION_KEY_OFFSET])
6093 return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET,
6094 event->modifiers,
6095 Qfunction_key, Qnil,
6096 lispy_function_keys, &func_key_syms,
6097 ARRAYELTS (lispy_function_keys));
6098
6099
6100
6101
6102 if (NILP (KVAR (current_kboard, system_key_syms)))
6103 kset_system_key_syms (current_kboard, Fcons (Qnil, Qnil));
6104 return modify_event_symbol (event->code,
6105 event->modifiers,
6106 Qfunction_key,
6107 KVAR (current_kboard, Vsystem_key_alist),
6108 0, &KVAR (current_kboard, system_key_syms),
6109 PTRDIFF_MAX);
6110
6111 #ifdef HAVE_NTGUI
6112 case END_SESSION_EVENT:
6113
6114 return list1 (Qend_session);
6115
6116 case LANGUAGE_CHANGE_EVENT:
6117
6118 return list4 (Qlanguage_change,
6119 event->frame_or_window,
6120 make_fixnum (event->code),
6121 make_fixnum (event->modifiers));
6122
6123 case MULTIMEDIA_KEY_EVENT:
6124 if (event->code < ARRAYELTS (lispy_multimedia_keys)
6125 && event->code > 0 && lispy_multimedia_keys[event->code])
6126 {
6127 return modify_event_symbol (event->code, event->modifiers,
6128 Qfunction_key, Qnil,
6129 lispy_multimedia_keys, &func_key_syms,
6130 ARRAYELTS (lispy_multimedia_keys));
6131 }
6132 return Qnil;
6133 #endif
6134
6135
6136
6137 case MOUSE_CLICK_EVENT:
6138 #ifndef USE_TOOLKIT_SCROLL_BARS
6139 case SCROLL_BAR_CLICK_EVENT:
6140 case HORIZONTAL_SCROLL_BAR_CLICK_EVENT:
6141 #endif
6142 {
6143 int button = event->code;
6144 bool is_double;
6145 Lisp_Object position;
6146 Lisp_Object *start_pos_ptr;
6147 Lisp_Object start_pos;
6148
6149 position = Qnil;
6150
6151
6152 if (event->kind == MOUSE_CLICK_EVENT)
6153 {
6154 struct frame *f = XFRAME (event->frame_or_window);
6155 int row, column;
6156
6157
6158
6159 if (! FRAME_LIVE_P (f))
6160 return Qnil;
6161
6162
6163
6164
6165
6166
6167 if (!toolkit_menubar_in_use (f)
6168 #if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
6169
6170
6171 && (!FRAME_WINDOW_P (f)
6172 || coords_in_menu_bar_window (f, XFIXNUM (event->x),
6173 XFIXNUM (event->y)))
6174 #endif
6175 )
6176 {
6177 #if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
6178 if (FRAME_WINDOW_P (f))
6179 {
6180 struct window *menu_w = XWINDOW (f->menu_bar_window);
6181 int x, y, dummy;
6182
6183 x = FRAME_TO_WINDOW_PIXEL_X (menu_w, XFIXNUM (event->x));
6184 y = FRAME_TO_WINDOW_PIXEL_Y (menu_w, XFIXNUM (event->y));
6185
6186 x_y_to_hpos_vpos (XWINDOW (f->menu_bar_window), x, y, &column, &row,
6187 NULL, NULL, &dummy);
6188 }
6189 else
6190 #endif
6191 pixel_to_glyph_coords (f, XFIXNUM (event->x), XFIXNUM (event->y),
6192 &column, &row, NULL, 1);
6193
6194
6195
6196
6197
6198
6199
6200
6201 if (row >= 0 && row < FRAME_MENU_BAR_LINES (f)
6202 && (event->modifiers & down_modifier))
6203 {
6204 Lisp_Object items, item;
6205
6206
6207 item = Qnil;
6208 items = FRAME_MENU_BAR_ITEMS (f);
6209 for (i = 0; i < ASIZE (items); i += 4)
6210 {
6211 Lisp_Object pos, string;
6212 string = AREF (items, i + 1);
6213 pos = AREF (items, i + 3);
6214 if (NILP (string))
6215 break;
6216 if (column >= XFIXNUM (pos)
6217 && column < XFIXNUM (pos) + SCHARS (string))
6218 {
6219 item = AREF (items, i);
6220 break;
6221 }
6222 }
6223
6224
6225
6226 if (NILP (item))
6227 return Qnil;
6228
6229
6230
6231
6232 position = list4 (event->frame_or_window,
6233 Qmenu_bar,
6234 Fcons (event->x, event->y),
6235 INT_TO_INTEGER (event->timestamp));
6236
6237 return list2 (item, position);
6238 }
6239 }
6240
6241 position = make_lispy_position (f, event->x, event->y,
6242 event->timestamp);
6243
6244
6245
6246 if (CONSP (event->arg) && EQ (XCAR (event->arg), Qtab_bar))
6247 position = nconc2 (position, Fcons (XCDR (event->arg), Qnil));
6248 }
6249 #ifndef USE_TOOLKIT_SCROLL_BARS
6250 else
6251
6252 position = make_scroll_bar_position (event, Qvertical_scroll_bar);
6253 #endif
6254
6255 if (button >= ASIZE (button_down_location))
6256 {
6257 ptrdiff_t incr = button - ASIZE (button_down_location) + 1;
6258 button_down_location = larger_vector (button_down_location,
6259 incr, -1);
6260 mouse_syms = larger_vector (mouse_syms, incr, -1);
6261 }
6262
6263 start_pos_ptr = aref_addr (button_down_location, button);
6264 start_pos = *start_pos_ptr;
6265 *start_pos_ptr = Qnil;
6266
6267 {
6268
6269
6270
6271 struct frame *f;
6272 intmax_t fuzz;
6273
6274 if (WINDOWP (event->frame_or_window))
6275 f = XFRAME (XWINDOW (event->frame_or_window)->frame);
6276 else if (FRAMEP (event->frame_or_window))
6277 f = XFRAME (event->frame_or_window);
6278 else
6279 emacs_abort ();
6280
6281 if (FRAME_WINDOW_P (f))
6282 fuzz = double_click_fuzz;
6283 else
6284 fuzz = double_click_fuzz / 8;
6285
6286 is_double = (button == last_mouse_button
6287 && (eabs (XFIXNUM (event->x) - last_mouse_x) <= fuzz)
6288 && (eabs (XFIXNUM (event->y) - last_mouse_y) <= fuzz)
6289 && button_down_time != 0
6290 && (EQ (Vdouble_click_time, Qt)
6291 || (FIXNATP (Vdouble_click_time)
6292 && (event->timestamp - button_down_time
6293 < XFIXNAT (Vdouble_click_time)))));
6294 }
6295
6296 last_mouse_button = button;
6297 last_mouse_x = XFIXNUM (event->x);
6298 last_mouse_y = XFIXNUM (event->y);
6299
6300
6301
6302 if (event->modifiers & down_modifier)
6303 {
6304 if (is_double)
6305 {
6306 double_click_count++;
6307 event->modifiers |= ((double_click_count > 2)
6308 ? triple_modifier
6309 : double_modifier);
6310 }
6311 else
6312 double_click_count = 1;
6313 button_down_time = event->timestamp;
6314 *start_pos_ptr = Fcopy_alist (position);
6315 frame_relative_event_pos = Fcons (event->x, event->y);
6316 ignore_mouse_drag_p = false;
6317 }
6318
6319
6320
6321 else if (event->modifiers & up_modifier)
6322 {
6323
6324
6325
6326
6327
6328
6329 if (!CONSP (start_pos))
6330 return Qnil;
6331
6332 unsigned click_or_drag_modifier = click_modifier;
6333
6334 if (ignore_mouse_drag_p)
6335 ignore_mouse_drag_p = false;
6336 else
6337 {
6338 intmax_t xdiff = double_click_fuzz, ydiff = double_click_fuzz;
6339
6340 xdiff = XFIXNUM (event->x)
6341 - XFIXNUM (XCAR (frame_relative_event_pos));
6342 ydiff = XFIXNUM (event->y)
6343 - XFIXNUM (XCDR (frame_relative_event_pos));
6344
6345 if (! (0 < double_click_fuzz
6346 && - double_click_fuzz < xdiff
6347 && xdiff < double_click_fuzz
6348 && - double_click_fuzz < ydiff
6349 && ydiff < double_click_fuzz
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360 && (EQ (Fcar (Fcdr (start_pos)),
6361 Fcar (Fcdr (position)))
6362 || !EQ (Fcar (start_pos),
6363 Fcar (position)))))
6364 {
6365
6366 button_down_time = 0;
6367 click_or_drag_modifier = drag_modifier;
6368 }
6369 else if (((!EQ (Fcar (start_pos), Fcar (position)))
6370 || (!EQ (Fcar (Fcdr (start_pos)),
6371 Fcar (Fcdr (position)))))
6372
6373 && FIXNUMP (Fcar (Fcdr (start_pos)))
6374 && WINDOW_LIVE_P (Fcar (start_pos))
6375 && !NILP (Ffboundp (Qwindow_edges)))
6376
6377
6378
6379
6380
6381
6382 {
6383 Lisp_Object edges
6384 = call4 (Qwindow_edges, Fcar (start_pos), Qt, Qnil, Qt);
6385 int new_x = XFIXNUM (Fcar (frame_relative_event_pos));
6386 int new_y = XFIXNUM (Fcdr (frame_relative_event_pos));
6387
6388
6389
6390 if (new_x < XFIXNUM (Fcar (edges)))
6391 new_x = XFIXNUM (Fcar (edges));
6392 else if (new_x >= XFIXNUM (Fcar (Fcdr (Fcdr (edges)))))
6393 new_x = XFIXNUM (Fcar (Fcdr (Fcdr (edges)))) - 1;
6394 if (new_y < XFIXNUM (Fcar (Fcdr (edges))))
6395 new_y = XFIXNUM (Fcar (Fcdr (edges)));
6396 else if (new_y
6397 >= XFIXNUM (Fcar (Fcdr (Fcdr (Fcdr (edges))))))
6398 new_y = XFIXNUM (Fcar (Fcdr (Fcdr (Fcdr (edges))))) - 1;
6399
6400 position = make_lispy_position
6401 (XFRAME (event->frame_or_window),
6402 make_fixnum (new_x), make_fixnum (new_y),
6403 event->timestamp);
6404 }
6405 }
6406
6407
6408
6409 event->modifiers
6410 = ((event->modifiers & ~up_modifier)
6411 | click_or_drag_modifier
6412 | (double_click_count < 2 ? 0
6413 : double_click_count == 2 ? double_modifier
6414 : triple_modifier));
6415 }
6416 else
6417
6418
6419 emacs_abort ();
6420
6421 {
6422
6423 Lisp_Object head;
6424
6425 head = modify_event_symbol (button,
6426 event->modifiers,
6427 Qmouse_click, Vlispy_mouse_stem,
6428 NULL,
6429 &mouse_syms,
6430 ASIZE (mouse_syms));
6431 if (event->modifiers & drag_modifier)
6432 return list3 (head, start_pos, position);
6433 else if (event->modifiers & (double_modifier | triple_modifier))
6434 return list3 (head, position, make_fixnum (double_click_count));
6435 else
6436 return list2 (head, position);
6437 }
6438 }
6439
6440 case WHEEL_EVENT:
6441 case HORIZ_WHEEL_EVENT:
6442 {
6443 Lisp_Object position;
6444 Lisp_Object head;
6445
6446
6447 struct frame *f = XFRAME (event->frame_or_window);
6448
6449
6450
6451 if (! FRAME_LIVE_P (f))
6452 return Qnil;
6453
6454 position = make_lispy_position (f, event->x, event->y,
6455 event->timestamp);
6456
6457
6458 {
6459
6460
6461
6462 struct frame *fr;
6463 intmax_t fuzz;
6464 int symbol_num;
6465 bool is_double;
6466
6467 if (WINDOWP (event->frame_or_window))
6468 fr = XFRAME (XWINDOW (event->frame_or_window)->frame);
6469 else if (FRAMEP (event->frame_or_window))
6470 fr = XFRAME (event->frame_or_window);
6471 else
6472 emacs_abort ();
6473
6474 fuzz = FRAME_WINDOW_P (fr)
6475 ? double_click_fuzz : double_click_fuzz / 8;
6476
6477 if (event->modifiers & up_modifier)
6478 {
6479
6480 event->modifiers &= ~up_modifier;
6481 symbol_num = 0;
6482 }
6483 else if (event->modifiers & down_modifier)
6484 {
6485
6486 event->modifiers &= ~down_modifier;
6487 symbol_num = 1;
6488 }
6489 else
6490
6491
6492 emacs_abort ();
6493
6494 if (event->kind == HORIZ_WHEEL_EVENT)
6495 symbol_num += 2;
6496
6497 is_double = (last_mouse_button == - (1 + symbol_num)
6498 && (eabs (XFIXNUM (event->x) - last_mouse_x) <= fuzz)
6499 && (eabs (XFIXNUM (event->y) - last_mouse_y) <= fuzz)
6500 && button_down_time != 0
6501 && (EQ (Vdouble_click_time, Qt)
6502 || (FIXNATP (Vdouble_click_time)
6503 && (event->timestamp - button_down_time
6504 < XFIXNAT (Vdouble_click_time)))));
6505 if (is_double)
6506 {
6507 double_click_count++;
6508 event->modifiers |= ((double_click_count > 2)
6509 ? triple_modifier
6510 : double_modifier);
6511 }
6512 else
6513 {
6514 double_click_count = 1;
6515 event->modifiers |= click_modifier;
6516 }
6517
6518 button_down_time = event->timestamp;
6519
6520 last_mouse_button = - (1 + symbol_num);
6521 last_mouse_x = XFIXNUM (event->x);
6522 last_mouse_y = XFIXNUM (event->y);
6523
6524
6525 head = modify_event_symbol (symbol_num,
6526 event->modifiers,
6527 Qmouse_click,
6528 Qnil,
6529 lispy_wheel_names,
6530 &wheel_syms,
6531 ASIZE (wheel_syms));
6532 }
6533
6534 if (CONSP (event->arg))
6535 return list5 (head, position, make_fixnum (double_click_count),
6536 XCAR (event->arg), Fcons (XCAR (XCDR (event->arg)),
6537 XCAR (XCDR (XCDR (event->arg)))));
6538 else if (NUMBERP (event->arg))
6539 return list4 (head, position, make_fixnum (double_click_count),
6540 event->arg);
6541 else if (event->modifiers & (double_modifier | triple_modifier))
6542 return list3 (head, position, make_fixnum (double_click_count));
6543 else
6544 return list2 (head, position);
6545 }
6546
6547 case TOUCH_END_EVENT:
6548 {
6549 Lisp_Object position;
6550
6551
6552 struct frame *f = XFRAME (event->frame_or_window);
6553
6554 if (! FRAME_LIVE_P (f))
6555 return Qnil;
6556
6557 position = make_lispy_position (f, event->x, event->y,
6558 event->timestamp);
6559
6560 return list2 (Qtouch_end, position);
6561 }
6562
6563 case TOUCHSCREEN_BEGIN_EVENT:
6564 {
6565 Lisp_Object x, y, id, position;
6566 struct frame *f;
6567 #ifdef HAVE_WINDOW_SYSTEM
6568 int tab_bar_item;
6569 bool close;
6570 #endif
6571
6572 f = XFRAME (event->frame_or_window);
6573
6574 if (!FRAME_LIVE_P (f))
6575 return Qnil;
6576
6577 id = event->arg;
6578 x = event->x;
6579 y = event->y;
6580
6581 #if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
6582 if (coords_in_menu_bar_window (f, XFIXNUM (x), XFIXNUM (y)))
6583 {
6584
6585
6586 menu_bar_touch_id = id;
6587 return Qnil;
6588 }
6589 #endif
6590
6591 position = make_lispy_position (f, x, y, event->timestamp);
6592
6593 #ifdef HAVE_WINDOW_SYSTEM
6594
6595
6596
6597
6598
6599 if (coords_in_tab_bar_window (f, XFIXNUM (event->x),
6600 XFIXNUM (event->y))
6601
6602
6603
6604 && get_tab_bar_item_kbd (f, XFIXNUM (event->x),
6605 XFIXNUM (event->y), &tab_bar_item,
6606 &close) >= 0)
6607 {
6608
6609 x = Fcopy_sequence (AREF (f->tab_bar_items,
6610 (tab_bar_item
6611 + TAB_BAR_ITEM_CAPTION)));
6612
6613
6614 AUTO_LIST2 (y, Qmenu_item, list3 (AREF (f->tab_bar_items,
6615 (tab_bar_item
6616 + TAB_BAR_ITEM_KEY)),
6617 AREF (f->tab_bar_items,
6618 (tab_bar_item
6619 + TAB_BAR_ITEM_BINDING)),
6620 close ? Qt : Qnil));
6621
6622
6623 Fadd_text_properties (make_fixnum (0),
6624 make_fixnum (SCHARS (x)),
6625 y, x);
6626
6627
6628 x = Fcons (x, make_fixnum (0));
6629
6630
6631 position = nconc2 (position, Fcons (x, Qnil));
6632 }
6633
6634 #endif
6635
6636 return list2 (Qtouchscreen_begin,
6637 Fcons (id, position));
6638 }
6639
6640 case TOUCHSCREEN_END_EVENT:
6641 {
6642 Lisp_Object x, y, id, position;
6643 struct frame *f = XFRAME (event->frame_or_window);
6644 #if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
6645 int column, row, dummy;
6646 #endif
6647 #ifdef HAVE_WINDOW_SYSTEM
6648 int tab_bar_item;
6649 bool close;
6650 #endif
6651
6652 if (!FRAME_LIVE_P (f))
6653 return Qnil;
6654
6655 id = event->arg;
6656 x = event->x;
6657 y = event->y;
6658
6659 #if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
6660 if (EQ (menu_bar_touch_id, id))
6661 {
6662
6663
6664 menu_bar_touch_id = Qnil;
6665
6666 if (!NILP (f->menu_bar_window))
6667 {
6668 x_y_to_hpos_vpos (XWINDOW (f->menu_bar_window), XFIXNUM (x),
6669 XFIXNUM (y), &column, &row, NULL, NULL,
6670 &dummy);
6671
6672 if (row >= 0 && row < FRAME_MENU_BAR_LINES (f))
6673 {
6674 Lisp_Object items, item;
6675
6676
6677 item = Qnil;
6678 items = FRAME_MENU_BAR_ITEMS (f);
6679 for (i = 0; i < ASIZE (items); i += 4)
6680 {
6681 Lisp_Object pos, string;
6682 string = AREF (items, i + 1);
6683 pos = AREF (items, i + 3);
6684 if (NILP (string))
6685 break;
6686 if (column >= XFIXNUM (pos)
6687 && column < XFIXNUM (pos) + SCHARS (string))
6688 {
6689 item = AREF (items, i);
6690 break;
6691 }
6692 }
6693
6694
6695
6696 if (NILP (item))
6697 return Qnil;
6698
6699
6700
6701
6702 position = list4 (event->frame_or_window,
6703 Qmenu_bar,
6704 Fcons (event->x, event->y),
6705 INT_TO_INTEGER (event->timestamp));
6706
6707 return list2 (item, position);
6708 }
6709 }
6710
6711 return Qnil;
6712 }
6713 #endif
6714
6715 position = make_lispy_position (f, x, y, event->timestamp);
6716
6717 #ifdef HAVE_WINDOW_SYSTEM
6718
6719
6720
6721
6722
6723 if (coords_in_tab_bar_window (f, XFIXNUM (event->x),
6724 XFIXNUM (event->y))
6725
6726
6727
6728 && get_tab_bar_item_kbd (f, XFIXNUM (event->x),
6729 XFIXNUM (event->y), &tab_bar_item,
6730 &close) >= 0)
6731 {
6732
6733 x = Fcopy_sequence (AREF (f->tab_bar_items,
6734 (tab_bar_item
6735 + TAB_BAR_ITEM_CAPTION)));
6736
6737
6738 AUTO_LIST2 (y, Qmenu_item, list3 (AREF (f->tab_bar_items,
6739 (tab_bar_item
6740 + TAB_BAR_ITEM_KEY)),
6741 AREF (f->tab_bar_items,
6742 (tab_bar_item
6743 + TAB_BAR_ITEM_BINDING)),
6744 close ? Qt : Qnil));
6745
6746
6747 Fadd_text_properties (make_fixnum (0),
6748 make_fixnum (SCHARS (x)),
6749 y, x);
6750
6751
6752 x = Fcons (x, make_fixnum (0));
6753
6754
6755 position = nconc2 (position, Fcons (x, Qnil));
6756 }
6757
6758 #endif
6759
6760 position = make_lispy_position (f, x, y, event->timestamp);
6761
6762 return list3 (Qtouchscreen_end, Fcons (id, position),
6763 event->modifiers ? Qt : Qnil);
6764 }
6765
6766 case PINCH_EVENT:
6767 {
6768 Lisp_Object x, y, position;
6769 struct frame *f = XFRAME (event->frame_or_window);
6770
6771 x = event->x;
6772 y = event->y;
6773
6774 position = make_lispy_position (f, x, y, event->timestamp);
6775
6776 return Fcons (modify_event_symbol (0, event->modifiers, Qpinch,
6777 Qnil, (const char *[]) {"pinch"},
6778 &pinch_syms, 1),
6779 Fcons (position, event->arg));
6780 }
6781
6782 case TOUCHSCREEN_UPDATE_EVENT:
6783 {
6784 Lisp_Object x, y, id, position, tem, it, evt;
6785 struct frame *f = XFRAME (event->frame_or_window);
6786 evt = Qnil;
6787
6788 if (!FRAME_LIVE_P (f))
6789 return Qnil;
6790
6791 for (tem = event->arg; CONSP (tem); tem = XCDR (tem))
6792 {
6793 it = XCAR (tem);
6794
6795 x = XCAR (it);
6796 y = XCAR (XCDR (it));
6797 id = XCAR (XCDR (XCDR (it)));
6798
6799
6800 if (EQ (id, menu_bar_touch_id))
6801 continue;
6802
6803 position = make_lispy_position (f, x, y, event->timestamp);
6804 evt = Fcons (Fcons (id, position), evt);
6805 }
6806
6807 if (NILP (evt))
6808
6809
6810 return Qnil;
6811
6812 return list2 (Qtouchscreen_update, evt);
6813 }
6814
6815 #ifdef USE_TOOLKIT_SCROLL_BARS
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834 case SCROLL_BAR_CLICK_EVENT:
6835 {
6836 Lisp_Object position, head;
6837
6838 position = make_scroll_bar_position (event, Qvertical_scroll_bar);
6839
6840
6841 event->modifiers |= click_modifier;
6842 event->modifiers &= ~up_modifier;
6843
6844 if (event->code >= ASIZE (mouse_syms))
6845 mouse_syms = larger_vector (mouse_syms,
6846 event->code - ASIZE (mouse_syms) + 1,
6847 -1);
6848
6849
6850 head = modify_event_symbol (event->code,
6851 event->modifiers,
6852 Qmouse_click,
6853 Vlispy_mouse_stem,
6854 NULL, &mouse_syms,
6855 ASIZE (mouse_syms));
6856 return list2 (head, position);
6857 }
6858
6859 case HORIZONTAL_SCROLL_BAR_CLICK_EVENT:
6860 {
6861 Lisp_Object position, head;
6862
6863 position = make_scroll_bar_position (event, Qhorizontal_scroll_bar);
6864
6865
6866 event->modifiers |= click_modifier;
6867 event->modifiers &= ~up_modifier;
6868
6869 if (event->code >= ASIZE (mouse_syms))
6870 mouse_syms = larger_vector (mouse_syms,
6871 event->code - ASIZE (mouse_syms) + 1,
6872 -1);
6873
6874
6875 head = modify_event_symbol (event->code,
6876 event->modifiers,
6877 Qmouse_click,
6878 Vlispy_mouse_stem,
6879 NULL, &mouse_syms,
6880 ASIZE (mouse_syms));
6881 return list2 (head, position);
6882 }
6883
6884 #endif
6885
6886 case DRAG_N_DROP_EVENT:
6887 {
6888 struct frame *f;
6889 Lisp_Object head, position;
6890 Lisp_Object files;
6891
6892 f = XFRAME (event->frame_or_window);
6893 files = event->arg;
6894
6895
6896
6897 if (! FRAME_LIVE_P (f))
6898 return Qnil;
6899
6900 position = make_lispy_position (f, event->x, event->y,
6901 event->timestamp);
6902
6903 head = modify_event_symbol (0, event->modifiers,
6904 Qdrag_n_drop, Qnil,
6905 lispy_drag_n_drop_names,
6906 &drag_n_drop_syms, 1);
6907 return list3 (head, position, files);
6908 }
6909
6910 #ifdef HAVE_EXT_MENU_BAR
6911 case MENU_BAR_EVENT:
6912 if (EQ (event->arg, event->frame_or_window))
6913
6914
6915
6916 return list1 (Qmenu_bar);
6917 return event->arg;
6918 #endif
6919
6920 case SELECT_WINDOW_EVENT:
6921
6922 return list2 (Qselect_window, list1 (event->frame_or_window));
6923
6924 case TAB_BAR_EVENT:
6925 case TOOL_BAR_EVENT:
6926 {
6927 Lisp_Object res = event->arg;
6928 Lisp_Object location
6929 = event->kind == TAB_BAR_EVENT ? Qtab_bar : Qtool_bar;
6930 if (SYMBOLP (res)) res = apply_modifiers (event->modifiers, res);
6931 return list2 (res, list2 (event->frame_or_window, location));
6932 }
6933
6934 case USER_SIGNAL_EVENT:
6935
6936 {
6937 char *name = find_user_signal_name (event->code);
6938 if (!name)
6939 emacs_abort ();
6940 return intern (name);
6941 }
6942
6943 case SAVE_SESSION_EVENT:
6944 return list2 (Qsave_session, event->arg);
6945
6946 #ifdef HAVE_DBUS
6947 case DBUS_EVENT:
6948 return Fcons (Qdbus_event, event->arg);
6949 #endif
6950
6951 #ifdef THREADS_ENABLED
6952 case THREAD_EVENT:
6953 return Fcons (Qthread_event, event->arg);
6954 #endif
6955
6956 #ifdef HAVE_XWIDGETS
6957 case XWIDGET_EVENT:
6958 return Fcons (Qxwidget_event, event->arg);
6959
6960 case XWIDGET_DISPLAY_EVENT:
6961 return Fcons (Qxwidget_display_event, event->arg);
6962 #endif
6963
6964 #ifdef USE_FILE_NOTIFY
6965 case FILE_NOTIFY_EVENT:
6966 #ifdef HAVE_W32NOTIFY
6967
6968 return list3 (Qfile_notify, event->arg, event->frame_or_window);
6969 #else
6970 return Fcons (Qfile_notify, event->arg);
6971 #endif
6972 #endif
6973
6974 case CONFIG_CHANGED_EVENT:
6975 return list3 (Qconfig_changed_event,
6976 event->arg, event->frame_or_window);
6977
6978 case PREEDIT_TEXT_EVENT:
6979 return list2 (Qpreedit_text, event->arg);
6980
6981
6982 default:
6983 emacs_abort ();
6984 }
6985 }
6986
6987 static Lisp_Object
6988 make_lispy_movement (struct frame *frame, Lisp_Object bar_window, enum scroll_bar_part part,
6989 Lisp_Object x, Lisp_Object y, Time t)
6990 {
6991
6992 if (frame && ! NILP (bar_window))
6993 {
6994 Lisp_Object part_sym;
6995
6996 part_sym = builtin_lisp_symbol (scroll_bar_parts[part]);
6997 return list2 (Qscroll_bar_movement,
6998 list5 (bar_window,
6999 Qvertical_scroll_bar,
7000 Fcons (x, y),
7001 make_fixnum (t),
7002 part_sym));
7003 }
7004
7005 else
7006 {
7007 Lisp_Object position;
7008 position = make_lispy_position (frame, x, y, t);
7009 return list2 (Qmouse_movement, position);
7010 }
7011 }
7012
7013
7014 static Lisp_Object
7015 make_lispy_switch_frame (Lisp_Object frame)
7016 {
7017 return list2 (Qswitch_frame, frame);
7018 }
7019
7020 static Lisp_Object
7021 make_lispy_focus_in (Lisp_Object frame)
7022 {
7023 return list2 (Qfocus_in, frame);
7024 }
7025
7026 static Lisp_Object
7027 make_lispy_focus_out (Lisp_Object frame)
7028 {
7029 return list2 (Qfocus_out, frame);
7030 }
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042 static int
7043 parse_modifiers_uncached (Lisp_Object symbol, ptrdiff_t *modifier_end)
7044 {
7045 Lisp_Object name;
7046 ptrdiff_t i;
7047 int modifiers;
7048
7049 CHECK_SYMBOL (symbol);
7050
7051 modifiers = 0;
7052 name = SYMBOL_NAME (symbol);
7053
7054 for (i = 0; i < SBYTES (name) - 1; )
7055 {
7056 ptrdiff_t this_mod_end = 0;
7057 int this_mod = 0;
7058
7059
7060
7061
7062
7063 switch (SREF (name, i))
7064 {
7065 #define SINGLE_LETTER_MOD(BIT) \
7066 (this_mod_end = i + 1, this_mod = BIT)
7067
7068 case 'A':
7069 SINGLE_LETTER_MOD (alt_modifier);
7070 break;
7071
7072 case 'C':
7073 SINGLE_LETTER_MOD (ctrl_modifier);
7074 break;
7075
7076 case 'H':
7077 SINGLE_LETTER_MOD (hyper_modifier);
7078 break;
7079
7080 case 'M':
7081 SINGLE_LETTER_MOD (meta_modifier);
7082 break;
7083
7084 case 'S':
7085 SINGLE_LETTER_MOD (shift_modifier);
7086 break;
7087
7088 case 's':
7089 SINGLE_LETTER_MOD (super_modifier);
7090 break;
7091
7092 #undef SINGLE_LETTER_MOD
7093
7094 #define MULTI_LETTER_MOD(BIT, NAME, LEN) \
7095 if (i + LEN + 1 <= SBYTES (name) \
7096 && ! memcmp (SDATA (name) + i, NAME, LEN)) \
7097 { \
7098 this_mod_end = i + LEN; \
7099 this_mod = BIT; \
7100 }
7101
7102 case 'd':
7103 MULTI_LETTER_MOD (drag_modifier, "drag", 4);
7104 MULTI_LETTER_MOD (down_modifier, "down", 4);
7105 MULTI_LETTER_MOD (double_modifier, "double", 6);
7106 break;
7107
7108 case 't':
7109 MULTI_LETTER_MOD (triple_modifier, "triple", 6);
7110 break;
7111
7112 case 'u':
7113 MULTI_LETTER_MOD (up_modifier, "up", 2);
7114 break;
7115 #undef MULTI_LETTER_MOD
7116
7117 }
7118
7119
7120 if (this_mod_end == 0)
7121 break;
7122
7123
7124
7125 if (this_mod_end >= SBYTES (name)
7126 || SREF (name, this_mod_end) != '-')
7127 break;
7128
7129
7130 modifiers |= this_mod;
7131 i = this_mod_end + 1;
7132 }
7133
7134
7135 if (! (modifiers & (down_modifier | drag_modifier
7136 | double_modifier | triple_modifier))
7137 && i + 7 == SBYTES (name)
7138 && memcmp (SDATA (name) + i, "mouse-", 6) == 0
7139 && ('0' <= SREF (name, i + 6) && SREF (name, i + 6) <= '9'))
7140 modifiers |= click_modifier;
7141
7142 if (! (modifiers & (double_modifier | triple_modifier))
7143 && i + 6 < SBYTES (name)
7144 && memcmp (SDATA (name) + i, "wheel-", 6) == 0)
7145 modifiers |= click_modifier;
7146
7147 if (modifier_end)
7148 *modifier_end = i;
7149
7150 return modifiers;
7151 }
7152
7153
7154
7155
7156 static Lisp_Object
7157 apply_modifiers_uncached (int modifiers, char *base, int base_len, int base_len_byte)
7158 {
7159
7160
7161
7162 char new_mods[sizeof "A-C-H-M-S-s-up-down-drag-double-triple-"];
7163 int mod_len;
7164
7165 {
7166 char *p = new_mods;
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176 if (modifiers & alt_modifier) { *p++ = 'A'; *p++ = '-'; }
7177 if (modifiers & ctrl_modifier) { *p++ = 'C'; *p++ = '-'; }
7178 if (modifiers & hyper_modifier) { *p++ = 'H'; *p++ = '-'; }
7179 if (modifiers & meta_modifier) { *p++ = 'M'; *p++ = '-'; }
7180 if (modifiers & shift_modifier) { *p++ = 'S'; *p++ = '-'; }
7181 if (modifiers & super_modifier) { *p++ = 's'; *p++ = '-'; }
7182 if (modifiers & double_modifier) p = stpcpy (p, "double-");
7183 if (modifiers & triple_modifier) p = stpcpy (p, "triple-");
7184 if (modifiers & up_modifier) p = stpcpy (p, "up-");
7185 if (modifiers & down_modifier) p = stpcpy (p, "down-");
7186 if (modifiers & drag_modifier) p = stpcpy (p, "drag-");
7187
7188
7189 *p = '\0';
7190
7191 mod_len = p - new_mods;
7192 }
7193
7194 {
7195 Lisp_Object new_name;
7196
7197 new_name = make_uninit_multibyte_string (mod_len + base_len,
7198 mod_len + base_len_byte);
7199 memcpy (SDATA (new_name), new_mods, mod_len);
7200 memcpy (SDATA (new_name) + mod_len, base, base_len_byte);
7201
7202 return Fintern (new_name, Qnil);
7203 }
7204 }
7205
7206
7207 static const char *const modifier_names[] =
7208 {
7209 "up", "down", "drag", "click", "double", "triple", 0, 0,
7210 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7211 0, 0, "alt", "super", "hyper", "shift", "control", "meta"
7212 };
7213 #define NUM_MOD_NAMES ARRAYELTS (modifier_names)
7214
7215 static Lisp_Object modifier_symbols;
7216
7217
7218 static Lisp_Object
7219 lispy_modifier_list (int modifiers)
7220 {
7221 Lisp_Object modifier_list;
7222 int i;
7223
7224 modifier_list = Qnil;
7225 for (i = 0; (1<<i) <= modifiers && i < NUM_MOD_NAMES; i++)
7226 if (modifiers & (1<<i))
7227 modifier_list = Fcons (AREF (modifier_symbols, i),
7228 modifier_list);
7229
7230 return modifier_list;
7231 }
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241 #define KEY_TO_CHAR(k) (XFIXNUM (k) & ((1 << CHARACTERBITS) - 1))
7242
7243 Lisp_Object
7244 parse_modifiers (Lisp_Object symbol)
7245 {
7246 Lisp_Object elements;
7247
7248 if (FIXNUMP (symbol))
7249 return list2i (KEY_TO_CHAR (symbol), XFIXNUM (symbol) & CHAR_MODIFIER_MASK);
7250 else if (!SYMBOLP (symbol))
7251 return Qnil;
7252
7253 elements = Fget (symbol, Qevent_symbol_element_mask);
7254 if (CONSP (elements))
7255 return elements;
7256 else
7257 {
7258 ptrdiff_t end;
7259 int modifiers = parse_modifiers_uncached (symbol, &end);
7260 Lisp_Object unmodified;
7261 Lisp_Object mask;
7262
7263 unmodified = Fintern (make_string (SSDATA (SYMBOL_NAME (symbol)) + end,
7264 SBYTES (SYMBOL_NAME (symbol)) - end),
7265 Qnil);
7266
7267 if (modifiers & ~INTMASK)
7268 emacs_abort ();
7269 XSETFASTINT (mask, modifiers);
7270 elements = list2 (unmodified, mask);
7271
7272
7273 Fput (symbol, Qevent_symbol_element_mask,
7274 elements);
7275 Fput (symbol, Qevent_symbol_elements,
7276 Fcons (unmodified, lispy_modifier_list (modifiers)));
7277
7278
7279
7280
7281
7282
7283 return elements;
7284 }
7285 }
7286
7287 DEFUN ("internal-event-symbol-parse-modifiers", Fevent_symbol_parse_modifiers,
7288 Sevent_symbol_parse_modifiers, 1, 1, 0,
7289 doc: )
7290 (Lisp_Object symbol)
7291 {
7292
7293 parse_modifiers (symbol);
7294
7295
7296
7297 return Fget (symbol, Qevent_symbol_elements);
7298 }
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308 static Lisp_Object
7309 apply_modifiers (int modifiers, Lisp_Object base)
7310 {
7311 Lisp_Object cache, idx, entry, new_symbol;
7312
7313
7314 modifiers &= INTMASK;
7315
7316 if (FIXNUMP (base))
7317 return make_fixnum (XFIXNUM (base) | modifiers);
7318
7319
7320 cache = Fget (base, Qmodifier_cache);
7321 XSETFASTINT (idx, (modifiers & ~click_modifier));
7322 entry = assq_no_quit (idx, cache);
7323
7324 if (CONSP (entry))
7325 new_symbol = XCDR (entry);
7326 else
7327 {
7328
7329 new_symbol = apply_modifiers_uncached (modifiers,
7330 SSDATA (SYMBOL_NAME (base)),
7331 SCHARS (SYMBOL_NAME (base)),
7332 SBYTES (SYMBOL_NAME (base)));
7333
7334
7335 entry = Fcons (idx, new_symbol);
7336 Fput (base, Qmodifier_cache, Fcons (entry, cache));
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347 }
7348
7349
7350
7351
7352
7353
7354
7355
7356 if (NILP (Fget (new_symbol, Qevent_kind)))
7357 {
7358 Lisp_Object kind;
7359
7360 kind = Fget (base, Qevent_kind);
7361 if (! NILP (kind))
7362 Fput (new_symbol, Qevent_kind, kind);
7363 }
7364
7365 return new_symbol;
7366 }
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377 Lisp_Object
7378 reorder_modifiers (Lisp_Object symbol)
7379 {
7380
7381
7382 Lisp_Object parsed;
7383
7384 parsed = parse_modifiers (symbol);
7385 return apply_modifiers (XFIXNAT (XCAR (XCDR (parsed))),
7386 XCAR (parsed));
7387 }
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422 static Lisp_Object
7423 modify_event_symbol (ptrdiff_t symbol_num, int modifiers, Lisp_Object symbol_kind,
7424 Lisp_Object name_alist_or_stem, const char *const *name_table,
7425 Lisp_Object *symbol_table, ptrdiff_t table_size)
7426 {
7427 Lisp_Object value;
7428 Lisp_Object symbol_int;
7429
7430
7431 XSETINT (symbol_int, symbol_num & 0xffffff);
7432
7433
7434 if (symbol_num < 0 || symbol_num >= table_size)
7435 return Qnil;
7436
7437 if (CONSP (*symbol_table))
7438 value = Fcdr (assq_no_quit (symbol_int, *symbol_table));
7439
7440
7441
7442
7443
7444 else
7445 {
7446 if (! VECTORP (*symbol_table)
7447 || ASIZE (*symbol_table) != table_size)
7448 *symbol_table = make_nil_vector (table_size);
7449
7450 value = AREF (*symbol_table, symbol_num);
7451 }
7452
7453
7454 if (NILP (value))
7455 {
7456
7457 if (CONSP (name_alist_or_stem))
7458 value = Fcdr_safe (Fassq (symbol_int, name_alist_or_stem));
7459 else if (STRINGP (name_alist_or_stem))
7460 {
7461 char *buf;
7462 ptrdiff_t len = (SBYTES (name_alist_or_stem)
7463 + sizeof "-" + INT_STRLEN_BOUND (EMACS_INT));
7464 USE_SAFE_ALLOCA;
7465 buf = SAFE_ALLOCA (len);
7466 esprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem),
7467 XFIXNUM (symbol_int) + 1);
7468 value = intern (buf);
7469 SAFE_FREE ();
7470 }
7471 else if (name_table != 0 && name_table[symbol_num])
7472 value = intern (name_table[symbol_num]);
7473
7474 #ifdef HAVE_WINDOW_SYSTEM
7475 if (NILP (value))
7476 {
7477 char *name = get_keysym_name (symbol_num);
7478 if (name)
7479 value = intern (name);
7480 }
7481 #endif
7482
7483 if (NILP (value))
7484 {
7485 char buf[sizeof "key-" + INT_STRLEN_BOUND (EMACS_INT)];
7486 sprintf (buf, "key-%"pD"d", symbol_num);
7487 value = intern (buf);
7488 }
7489
7490 if (CONSP (*symbol_table))
7491 *symbol_table = Fcons (Fcons (symbol_int, value), *symbol_table);
7492 else
7493 ASET (*symbol_table, symbol_num, value);
7494
7495
7496
7497
7498 apply_modifiers (modifiers & click_modifier, value);
7499 Fput (value, Qevent_kind, symbol_kind);
7500 }
7501
7502
7503 return apply_modifiers (modifiers, value);
7504 }
7505
7506
7507
7508
7509
7510 DEFUN ("event-convert-list", Fevent_convert_list, Sevent_convert_list, 1, 1, 0,
7511 doc:
7512
7513
7514
7515
7516
7517
7518
7519 )
7520 (Lisp_Object event_desc)
7521 {
7522 Lisp_Object base = Qnil;
7523 int modifiers = 0;
7524
7525 FOR_EACH_TAIL_SAFE (event_desc)
7526 {
7527 Lisp_Object elt = XCAR (event_desc);
7528 int this = 0;
7529
7530
7531 if (SYMBOLP (elt) && CONSP (XCDR (event_desc)))
7532 this = parse_solitary_modifier (elt);
7533
7534 if (this != 0)
7535 modifiers |= this;
7536 else if (!NILP (base))
7537 error ("Two bases given in one event");
7538 else
7539 base = elt;
7540 }
7541
7542
7543 if (SYMBOLP (base) && SCHARS (SYMBOL_NAME (base)) == 1)
7544 XSETINT (base, SREF (SYMBOL_NAME (base), 0));
7545
7546 if (FIXNUMP (base))
7547 {
7548
7549 if ((modifiers & shift_modifier) != 0
7550 && (XFIXNUM (base) >= 'a' && XFIXNUM (base) <= 'z'))
7551 {
7552 XSETINT (base, XFIXNUM (base) - ('a' - 'A'));
7553 modifiers &= ~shift_modifier;
7554 }
7555
7556
7557 if (modifiers & ctrl_modifier)
7558 return make_fixnum ((modifiers & ~ctrl_modifier)
7559 | make_ctrl_char (XFIXNUM (base)));
7560 else
7561 return make_fixnum (modifiers | XFIXNUM (base));
7562 }
7563 else if (SYMBOLP (base))
7564 return apply_modifiers (modifiers, base);
7565 else
7566 error ("Invalid base event");
7567 }
7568
7569 DEFUN ("internal-handle-focus-in", Finternal_handle_focus_in,
7570 Sinternal_handle_focus_in, 1, 1, 0,
7571 doc:
7572 )
7573 (Lisp_Object event)
7574 {
7575 Lisp_Object frame;
7576 if (!EQ (CAR_SAFE (event), Qfocus_in) ||
7577 !CONSP (XCDR (event)) ||
7578 !FRAMEP ((frame = XCAR (XCDR (event)))))
7579 error ("invalid focus-in event");
7580
7581
7582
7583
7584
7585 bool switching = (!EQ (frame, internal_last_event_frame)
7586 && !EQ (frame, selected_frame));
7587 internal_last_event_frame = frame;
7588 if (switching || !NILP (unread_switch_frame))
7589 unread_switch_frame = make_lispy_switch_frame (frame);
7590
7591 return Qnil;
7592 }
7593
7594
7595
7596
7597 int
7598 parse_solitary_modifier (Lisp_Object symbol)
7599 {
7600 Lisp_Object name;
7601
7602 if (!SYMBOLP (symbol))
7603 return 0;
7604
7605 name = SYMBOL_NAME (symbol);
7606
7607 switch (SREF (name, 0))
7608 {
7609 #define SINGLE_LETTER_MOD(BIT) \
7610 if (SBYTES (name) == 1) \
7611 return BIT;
7612
7613 #define MULTI_LETTER_MOD(BIT, NAME, LEN) \
7614 if (LEN == SBYTES (name) \
7615 && ! memcmp (SDATA (name), NAME, LEN)) \
7616 return BIT;
7617
7618 case 'A':
7619 SINGLE_LETTER_MOD (alt_modifier);
7620 break;
7621
7622 case 'a':
7623 MULTI_LETTER_MOD (alt_modifier, "alt", 3);
7624 break;
7625
7626 case 'C':
7627 SINGLE_LETTER_MOD (ctrl_modifier);
7628 break;
7629
7630 case 'c':
7631 MULTI_LETTER_MOD (ctrl_modifier, "ctrl", 4);
7632 MULTI_LETTER_MOD (ctrl_modifier, "control", 7);
7633 MULTI_LETTER_MOD (click_modifier, "click", 5);
7634 break;
7635
7636 case 'H':
7637 SINGLE_LETTER_MOD (hyper_modifier);
7638 break;
7639
7640 case 'h':
7641 MULTI_LETTER_MOD (hyper_modifier, "hyper", 5);
7642 break;
7643
7644 case 'M':
7645 SINGLE_LETTER_MOD (meta_modifier);
7646 break;
7647
7648 case 'm':
7649 MULTI_LETTER_MOD (meta_modifier, "meta", 4);
7650 break;
7651
7652 case 'S':
7653 SINGLE_LETTER_MOD (shift_modifier);
7654 break;
7655
7656 case 's':
7657 MULTI_LETTER_MOD (shift_modifier, "shift", 5);
7658 MULTI_LETTER_MOD (super_modifier, "super", 5);
7659 SINGLE_LETTER_MOD (super_modifier);
7660 break;
7661
7662 case 'd':
7663 MULTI_LETTER_MOD (drag_modifier, "drag", 4);
7664 MULTI_LETTER_MOD (down_modifier, "down", 4);
7665 MULTI_LETTER_MOD (double_modifier, "double", 6);
7666 break;
7667
7668 case 't':
7669 MULTI_LETTER_MOD (triple_modifier, "triple", 6);
7670 break;
7671
7672 case 'u':
7673 MULTI_LETTER_MOD (up_modifier, "up", 2);
7674 break;
7675
7676 #undef SINGLE_LETTER_MOD
7677 #undef MULTI_LETTER_MOD
7678 }
7679
7680 return 0;
7681 }
7682
7683
7684
7685
7686
7687 bool
7688 lucid_event_type_list_p (Lisp_Object object)
7689 {
7690 if (! CONSP (object))
7691 return false;
7692
7693 if (EQ (XCAR (object), Qhelp_echo)
7694 || EQ (XCAR (object), Qvertical_line)
7695 || EQ (XCAR (object), Qmode_line)
7696 || EQ (XCAR (object), Qtab_line)
7697 || EQ (XCAR (object), Qheader_line))
7698 return false;
7699
7700 Lisp_Object tail = object;
7701 FOR_EACH_TAIL_SAFE (object)
7702 {
7703 Lisp_Object elt = XCAR (object);
7704 if (! (FIXNUMP (elt) || SYMBOLP (elt)))
7705 return false;
7706 tail = XCDR (object);
7707 }
7708
7709 return NILP (tail);
7710 }
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729 static bool
7730 get_input_pending (int flags)
7731 {
7732
7733 input_pending = (!NILP (Vquit_flag) || readable_events (flags));
7734
7735
7736 if (!input_pending && (!interrupt_input || interrupts_deferred))
7737 {
7738
7739 gobble_input ();
7740 input_pending = (!NILP (Vquit_flag) || readable_events (flags));
7741 }
7742
7743 return input_pending;
7744 }
7745
7746
7747
7748
7749
7750
7751
7752 int
7753 gobble_input (void)
7754 {
7755 int nread = 0;
7756 bool err = false;
7757 struct terminal *t;
7758
7759
7760 store_user_signal_events ();
7761
7762
7763 t = terminal_list;
7764 while (t)
7765 {
7766 struct terminal *next = t->next_terminal;
7767
7768 if (t->read_socket_hook)
7769 {
7770 int nr;
7771 struct input_event hold_quit;
7772
7773 if (input_blocked_p ())
7774 {
7775 pending_signals = true;
7776 break;
7777 }
7778
7779 EVENT_INIT (hold_quit);
7780 hold_quit.kind = NO_EVENT;
7781
7782
7783 while ((nr = (*t->read_socket_hook) (t, &hold_quit)) > 0)
7784 nread += nr;
7785
7786 if (nr == -1)
7787 {
7788 err = true;
7789 }
7790 else if (nr == -2)
7791 {
7792
7793
7794
7795 if (!terminal_list->next_terminal)
7796
7797
7798
7799
7800
7801
7802
7803
7804 terminate_due_to_signal (SIGHUP, 10);
7805
7806
7807 {
7808 Lisp_Object tmp;
7809 XSETTERMINAL (tmp, t);
7810 Fdelete_terminal (tmp, Qnoelisp);
7811 }
7812 }
7813
7814
7815
7816 if (nr >= 0)
7817 {
7818 Lisp_Object tail, frame;
7819
7820 FOR_EACH_FRAME (tail, frame)
7821 {
7822 struct frame *f = XFRAME (frame);
7823 if (FRAME_TERMINAL (f) == t)
7824 frame_make_pointer_visible (f);
7825 }
7826 }
7827
7828 if (hold_quit.kind != NO_EVENT)
7829 kbd_buffer_store_event (&hold_quit);
7830 }
7831
7832 t = next;
7833 }
7834
7835 if (err && !nread)
7836 nread = -1;
7837
7838 return nread;
7839 }
7840
7841
7842
7843
7844
7845
7846
7847 int
7848 tty_read_avail_input (struct terminal *terminal,
7849 struct input_event *hold_quit)
7850 {
7851
7852
7853
7854 unsigned char cbuf[KBD_BUFFER_SIZE - 1];
7855 #ifndef WINDOWSNT
7856 int n_to_read;
7857 #endif
7858 int i;
7859 struct tty_display_info *tty = terminal->display_info.tty;
7860 int nread = 0;
7861 #ifdef subprocesses
7862 int buffer_free = KBD_BUFFER_SIZE - kbd_buffer_nr_stored () - 1;
7863
7864 if (kbd_on_hold_p () || buffer_free <= 0)
7865 return 0;
7866 #endif
7867
7868 if (!terminal->name)
7869 return 0;
7870
7871 if (terminal->type != output_termcap
7872 && terminal->type != output_msdos_raw)
7873 emacs_abort ();
7874
7875
7876
7877 #ifdef WINDOWSNT
7878
7879
7880 return 0;
7881 #else
7882 if (! tty->term_initted)
7883 return 0;
7884
7885 if (! tty->input)
7886 return 0;
7887
7888 #ifdef MSDOS
7889 n_to_read = dos_keysns ();
7890 if (n_to_read == 0)
7891 return 0;
7892
7893 cbuf[0] = dos_keyread ();
7894 nread = 1;
7895
7896 #else
7897 #ifdef HAVE_GPM
7898 if (gpm_tty == tty)
7899 {
7900 Gpm_Event event;
7901 int gpm, fd = gpm_fd;
7902
7903
7904
7905
7906
7907
7908
7909 while (gpm = Gpm_GetEvent (&event), gpm == 1) {
7910 nread += handle_one_term_event (tty, &event);
7911 }
7912 if (gpm == 0)
7913
7914 close_gpm (fd);
7915 if (nread)
7916 return nread;
7917 }
7918 #endif
7919
7920
7921 #ifdef USABLE_FIONREAD
7922
7923 if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0)
7924 {
7925 if (! noninteractive)
7926 return -2;
7927 else
7928 n_to_read = 0;
7929 }
7930 if (n_to_read == 0)
7931 return 0;
7932 if (n_to_read > sizeof cbuf)
7933 n_to_read = sizeof cbuf;
7934 #elif defined USG || defined CYGWIN
7935
7936 n_to_read = sizeof cbuf;
7937 fcntl (fileno (tty->input), F_SETFL, O_NONBLOCK);
7938 #else
7939 # error "Cannot read without possibly delaying"
7940 #endif
7941
7942 #ifdef subprocesses
7943
7944 if (n_to_read > buffer_free)
7945 n_to_read = buffer_free;
7946 #endif
7947
7948
7949
7950 nread = emacs_read (fileno (tty->input), (char *) cbuf, n_to_read);
7951
7952
7953
7954
7955
7956 if (nread == -1 && errno == EIO)
7957 return -2;
7958 #if defined AIX && defined _BSD
7959
7960
7961
7962
7963 if (nread == 0)
7964 return -2;
7965 #endif
7966
7967 #ifndef USABLE_FIONREAD
7968 #if defined (USG) || defined (CYGWIN)
7969 fcntl (fileno (tty->input), F_SETFL, 0);
7970 #endif
7971 #endif
7972
7973 if (nread <= 0)
7974 return nread;
7975
7976 #endif
7977 #endif
7978
7979 for (i = 0; i < nread; i++)
7980 {
7981 struct input_event buf;
7982 EVENT_INIT (buf);
7983 buf.kind = ASCII_KEYSTROKE_EVENT;
7984 buf.modifiers = 0;
7985 if (tty->meta_key == 1 && (cbuf[i] & 0x80))
7986 buf.modifiers = meta_modifier;
7987 if (tty->meta_key < 2)
7988 cbuf[i] &= ~0x80;
7989
7990 buf.code = cbuf[i];
7991
7992
7993
7994 buf.frame_or_window = tty->top_frame;
7995 buf.arg = Qnil;
7996
7997 kbd_buffer_store_event (&buf);
7998
7999
8000 if (buf.kind == ASCII_KEYSTROKE_EVENT
8001 && buf.code == quit_char)
8002 break;
8003 }
8004
8005 return nread;
8006 }
8007
8008 static void
8009 handle_async_input (void)
8010 {
8011 #if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
8012
8013
8014
8015
8016 android_check_query_urgent ();
8017 #endif
8018
8019 #ifndef DOS_NT
8020 while (1)
8021 {
8022 int nread = gobble_input ();
8023
8024
8025
8026 if (nread <= 0)
8027 break;
8028 }
8029 #endif
8030 }
8031
8032 void
8033 process_pending_signals (void)
8034 {
8035 pending_signals = false;
8036 handle_async_input ();
8037 do_pending_atimers ();
8038 }
8039
8040
8041
8042
8043
8044 void
8045 unblock_input_to (int level)
8046 {
8047 interrupt_input_blocked = level;
8048 if (level == 0)
8049 {
8050 if (pending_signals && !fatal_error_in_progress)
8051 process_pending_signals ();
8052 }
8053 else if (level < 0)
8054 emacs_abort ();
8055 }
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067 void
8068 unblock_input (void)
8069 {
8070 unblock_input_to (interrupt_input_blocked - 1);
8071 }
8072
8073
8074
8075
8076 void
8077 totally_unblock_input (void)
8078 {
8079 unblock_input_to (0);
8080 }
8081
8082 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
8083
8084 void
8085 handle_input_available_signal (int sig)
8086 {
8087 #if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
8088
8089
8090
8091 #if defined __aarch64__
8092 asm ("dmb ishst");
8093 #else
8094 __atomic_thread_fence (__ATOMIC_SEQ_CST);
8095 #endif
8096 #endif
8097 pending_signals = true;
8098
8099 if (input_available_clear_time)
8100 *input_available_clear_time = make_timespec (0, 0);
8101 }
8102
8103 static void
8104 deliver_input_available_signal (int sig)
8105 {
8106 deliver_process_signal (sig, handle_input_available_signal);
8107 }
8108 #endif
8109
8110
8111
8112
8113 struct user_signal_info
8114 {
8115
8116 int sig;
8117
8118
8119 char *name;
8120
8121
8122 int npending;
8123
8124 struct user_signal_info *next;
8125 };
8126
8127
8128 static struct user_signal_info *user_signals = NULL;
8129
8130 void
8131 add_user_signal (int sig, const char *name)
8132 {
8133 struct sigaction action;
8134 struct user_signal_info *p;
8135
8136 for (p = user_signals; p; p = p->next)
8137 if (p->sig == sig)
8138
8139 return;
8140
8141 p = xmalloc (sizeof *p);
8142 p->sig = sig;
8143 p->name = xstrdup (name);
8144 p->npending = 0;
8145 p->next = user_signals;
8146 user_signals = p;
8147
8148 emacs_sigaction_init (&action, deliver_user_signal);
8149 sigaction (sig, &action, 0);
8150 }
8151
8152 static void
8153 handle_user_signal (int sig)
8154 {
8155 struct user_signal_info *p;
8156 const char *special_event_name = NULL;
8157
8158 if (SYMBOLP (Vdebug_on_event))
8159 special_event_name = SSDATA (SYMBOL_NAME (Vdebug_on_event));
8160
8161 for (p = user_signals; p; p = p->next)
8162 if (p->sig == sig)
8163 {
8164 if (special_event_name
8165 && strcmp (special_event_name, p->name) == 0)
8166 {
8167
8168 debug_on_next_call = true;
8169 debug_on_quit = true;
8170 Vquit_flag = Qt;
8171 Vinhibit_quit = Qnil;
8172
8173
8174 break;
8175 }
8176
8177 p->npending++;
8178 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
8179 if (interrupt_input)
8180 handle_input_available_signal (sig);
8181 else
8182 #endif
8183 {
8184
8185
8186 if (input_available_clear_time)
8187 *input_available_clear_time = make_timespec (0, 0);
8188 }
8189 break;
8190 }
8191 }
8192
8193 static void
8194 deliver_user_signal (int sig)
8195 {
8196 deliver_process_signal (sig, handle_user_signal);
8197 }
8198
8199 static char *
8200 find_user_signal_name (int sig)
8201 {
8202 struct user_signal_info *p;
8203
8204 for (p = user_signals; p; p = p->next)
8205 if (p->sig == sig)
8206 return p->name;
8207
8208 return NULL;
8209 }
8210
8211 static void
8212 store_user_signal_events (void)
8213 {
8214 struct user_signal_info *p;
8215 struct input_event buf;
8216 bool buf_initialized = false;
8217
8218 for (p = user_signals; p; p = p->next)
8219 if (p->npending > 0)
8220 {
8221 if (! buf_initialized)
8222 {
8223 memset (&buf, 0, sizeof buf);
8224 buf.kind = USER_SIGNAL_EVENT;
8225 buf.frame_or_window = selected_frame;
8226 buf_initialized = true;
8227 }
8228
8229 do
8230 {
8231 buf.code = p->sig;
8232 kbd_buffer_store_event (&buf);
8233 p->npending--;
8234 }
8235 while (p->npending > 0);
8236 }
8237 }
8238
8239
8240 static void menu_bar_item (Lisp_Object, Lisp_Object, Lisp_Object, void *);
8241 static Lisp_Object menu_bar_one_keymap_changed_items;
8242
8243
8244
8245
8246 static Lisp_Object menu_bar_items_vector;
8247 static int menu_bar_items_index;
8248
8249
8250 static const char *separator_names[] = {
8251 "space",
8252 "no-line",
8253 "single-line",
8254 "double-line",
8255 "single-dashed-line",
8256 "double-dashed-line",
8257 "shadow-etched-in",
8258 "shadow-etched-out",
8259 "shadow-etched-in-dash",
8260 "shadow-etched-out-dash",
8261 "shadow-double-etched-in",
8262 "shadow-double-etched-out",
8263 "shadow-double-etched-in-dash",
8264 "shadow-double-etched-out-dash",
8265 0,
8266 };
8267
8268
8269
8270 bool
8271 menu_separator_name_p (const char *label)
8272 {
8273 if (!label)
8274 return 0;
8275 else if (strnlen (label, 4) == 4
8276 && memcmp (label, "--", 2) == 0
8277 && label[2] != '-')
8278 {
8279 int i;
8280 label += 2;
8281 for (i = 0; separator_names[i]; ++i)
8282 if (strcmp (label, separator_names[i]) == 0)
8283 return 1;
8284 }
8285 else
8286 {
8287
8288 while (*label == '-')
8289 ++label;
8290 return (*label == 0);
8291 }
8292
8293 return 0;
8294 }
8295
8296
8297
8298
8299
8300
8301
8302
8303 Lisp_Object
8304 menu_bar_items (Lisp_Object old)
8305 {
8306
8307
8308 ptrdiff_t nmaps;
8309
8310
8311
8312 Lisp_Object *maps;
8313
8314 Lisp_Object mapsbuf[3];
8315 Lisp_Object def;
8316
8317 ptrdiff_t mapno;
8318 Lisp_Object oquit;
8319
8320 USE_SAFE_ALLOCA;
8321
8322
8323
8324
8325
8326
8327
8328 oquit = Vinhibit_quit;
8329 Vinhibit_quit = Qt;
8330
8331 if (!NILP (old))
8332 menu_bar_items_vector = old;
8333 else
8334 menu_bar_items_vector = make_nil_vector (24);
8335 menu_bar_items_index = 0;
8336
8337
8338
8339
8340
8341
8342 {
8343 Lisp_Object *tmaps;
8344
8345
8346 if (!NILP (Voverriding_local_map_menu_flag)
8347 && !NILP (Voverriding_local_map))
8348 {
8349
8350 maps = mapsbuf;
8351 nmaps = 0;
8352 if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
8353 maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
8354 if (!NILP (Voverriding_local_map))
8355 maps[nmaps++] = Voverriding_local_map;
8356 }
8357 else
8358 {
8359
8360
8361
8362
8363
8364 ptrdiff_t nminor = current_minor_maps (NULL, &tmaps);
8365 SAFE_NALLOCA (maps, 1, nminor + 4);
8366 nmaps = 0;
8367 Lisp_Object tem = KVAR (current_kboard, Voverriding_terminal_local_map);
8368 if (!NILP (tem) && !NILP (Voverriding_local_map_menu_flag))
8369 maps[nmaps++] = tem;
8370 if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem))
8371 maps[nmaps++] = tem;
8372 if (nminor != 0)
8373 {
8374 memcpy (maps + nmaps, tmaps, nminor * sizeof (maps[0]));
8375 nmaps += nminor;
8376 }
8377 maps[nmaps++] = get_local_map (PT, current_buffer, Qlocal_map);
8378 }
8379 maps[nmaps++] = current_global_map;
8380 }
8381
8382
8383
8384 for (mapno = nmaps - 1; mapno >= 0; mapno--)
8385 if (!NILP (maps[mapno]))
8386 {
8387 def = get_keymap (access_keymap (maps[mapno], Qmenu_bar, 1, 0, 1),
8388 0, 1);
8389 if (CONSP (def))
8390 {
8391 menu_bar_one_keymap_changed_items = Qnil;
8392 map_keymap_canonical (def, menu_bar_item, Qnil, NULL);
8393 }
8394 }
8395
8396
8397
8398 Lisp_Object tail = Vmenu_bar_final_items;
8399 FOR_EACH_TAIL (tail)
8400 {
8401 int end = menu_bar_items_index;
8402
8403 for (int i = 0; i < end; i += 4)
8404 if (EQ (XCAR (tail), AREF (menu_bar_items_vector, i)))
8405 {
8406 Lisp_Object tem0, tem1, tem2, tem3;
8407
8408
8409 tem0 = AREF (menu_bar_items_vector, i + 0);
8410 tem1 = AREF (menu_bar_items_vector, i + 1);
8411 tem2 = AREF (menu_bar_items_vector, i + 2);
8412 tem3 = AREF (menu_bar_items_vector, i + 3);
8413 if (end > i + 4)
8414 memmove (aref_addr (menu_bar_items_vector, i),
8415 aref_addr (menu_bar_items_vector, i + 4),
8416 (end - i - 4) * word_size);
8417 ASET (menu_bar_items_vector, end - 4, tem0);
8418 ASET (menu_bar_items_vector, end - 3, tem1);
8419 ASET (menu_bar_items_vector, end - 2, tem2);
8420 ASET (menu_bar_items_vector, end - 1, tem3);
8421 break;
8422 }
8423 }
8424
8425
8426 {
8427 int i = menu_bar_items_index;
8428 if (i + 4 > ASIZE (menu_bar_items_vector))
8429 menu_bar_items_vector
8430 = larger_vector (menu_bar_items_vector, 4, -1);
8431
8432 ASET (menu_bar_items_vector, i, Qnil); i++;
8433 ASET (menu_bar_items_vector, i, Qnil); i++;
8434 ASET (menu_bar_items_vector, i, Qnil); i++;
8435 ASET (menu_bar_items_vector, i, Qnil); i++;
8436 menu_bar_items_index = i;
8437 }
8438
8439 Vinhibit_quit = oquit;
8440 SAFE_FREE ();
8441 return menu_bar_items_vector;
8442 }
8443
8444
8445
8446
8447 Lisp_Object item_properties;
8448
8449 static void
8450 menu_bar_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy1, void *dummy2)
8451 {
8452 int i;
8453 bool parsed;
8454 Lisp_Object tem;
8455
8456 if (EQ (item, Qundefined))
8457 {
8458
8459
8460
8461 for (i = 0; i < menu_bar_items_index; i += 4)
8462 if (EQ (key, AREF (menu_bar_items_vector, i)))
8463 {
8464 if (menu_bar_items_index > i + 4)
8465 memmove (aref_addr (menu_bar_items_vector, i),
8466 aref_addr (menu_bar_items_vector, i + 4),
8467 (menu_bar_items_index - i - 4) * word_size);
8468 menu_bar_items_index -= 4;
8469 }
8470 }
8471
8472
8473
8474 tem = Fmemq (key, menu_bar_one_keymap_changed_items);
8475 if (!NILP (tem) || NILP (item))
8476 return;
8477
8478 menu_bar_one_keymap_changed_items
8479 = Fcons (key, menu_bar_one_keymap_changed_items);
8480
8481
8482
8483
8484 parsed = parse_menu_item (item, 1);
8485 if (!parsed)
8486 return;
8487
8488 item = AREF (item_properties, ITEM_PROPERTY_DEF);
8489
8490
8491 for (i = 0; i < menu_bar_items_index; i += 4)
8492 if (EQ (key, AREF (menu_bar_items_vector, i)))
8493 break;
8494
8495
8496 if (i == menu_bar_items_index)
8497 {
8498
8499 if (i + 4 > ASIZE (menu_bar_items_vector))
8500 menu_bar_items_vector = larger_vector (menu_bar_items_vector, 4, -1);
8501
8502 ASET (menu_bar_items_vector, i, key); i++;
8503 ASET (menu_bar_items_vector, i,
8504 AREF (item_properties, ITEM_PROPERTY_NAME)); i++;
8505 ASET (menu_bar_items_vector, i, list1 (item)); i++;
8506 ASET (menu_bar_items_vector, i, make_fixnum (0)); i++;
8507 menu_bar_items_index = i;
8508 }
8509
8510 else
8511 {
8512 Lisp_Object old;
8513 old = AREF (menu_bar_items_vector, i + 2);
8514
8515
8516 item = Fcons (item, KEYMAPP (item) && KEYMAPP (XCAR (old)) ? old : Qnil);
8517 ASET (menu_bar_items_vector, i + 2, item);
8518 }
8519 }
8520
8521
8522 static Lisp_Object
8523 menu_item_eval_property_1 (Lisp_Object arg)
8524 {
8525
8526
8527 if (CONSP (arg) && signal_quit_p (XCAR (arg)))
8528 quit ();
8529
8530 return Qnil;
8531 }
8532
8533 static Lisp_Object
8534 eval_dyn (Lisp_Object form)
8535 {
8536 return Feval (form, Qnil);
8537 }
8538
8539
8540
8541 Lisp_Object
8542 menu_item_eval_property (Lisp_Object sexpr)
8543 {
8544 specpdl_ref count = SPECPDL_INDEX ();
8545 Lisp_Object val;
8546 specbind (Qinhibit_redisplay, Qt);
8547 val = internal_condition_case_1 (eval_dyn, sexpr, Qerror,
8548 menu_item_eval_property_1);
8549 return unbind_to (count, val);
8550 }
8551
8552
8553
8554
8555
8556
8557
8558
8559
8560
8561 bool
8562 parse_menu_item (Lisp_Object item, int inmenubar)
8563 {
8564 Lisp_Object def, tem, item_string, start;
8565 Lisp_Object filter;
8566 Lisp_Object keyhint;
8567 int i;
8568
8569 filter = Qnil;
8570 keyhint = Qnil;
8571
8572 if (!CONSP (item))
8573 return 0;
8574
8575
8576 if (NILP (item_properties))
8577 item_properties = make_nil_vector (ITEM_PROPERTY_ENABLE + 1);
8578
8579
8580 for (i = ITEM_PROPERTY_DEF; i < ITEM_PROPERTY_ENABLE; i++)
8581 ASET (item_properties, i, Qnil);
8582 ASET (item_properties, ITEM_PROPERTY_ENABLE, Qt);
8583
8584
8585 ASET (item_properties, ITEM_PROPERTY_ITEM, item);
8586
8587 item_string = XCAR (item);
8588
8589 start = item;
8590 item = XCDR (item);
8591 if (STRINGP (item_string))
8592 {
8593
8594 ASET (item_properties, ITEM_PROPERTY_NAME, item_string);
8595
8596
8597 if (CONSP (item) && STRINGP (XCAR (item)))
8598 {
8599 ASET (item_properties, ITEM_PROPERTY_HELP,
8600 help_echo_substitute_command_keys (XCAR (item)));
8601 start = item;
8602 item = XCDR (item);
8603 }
8604
8605
8606 if (CONSP (item) && CONSP (XCAR (item))
8607 && (NILP (XCAR (XCAR (item)))
8608 || VECTORP (XCAR (XCAR (item)))))
8609 item = XCDR (item);
8610
8611
8612 ASET (item_properties, ITEM_PROPERTY_DEF, item);
8613
8614
8615 if (SYMBOLP (item))
8616 {
8617 tem = Fget (item, Qmenu_enable);
8618 if (!NILP (Venable_disabled_menus_and_buttons))
8619 ASET (item_properties, ITEM_PROPERTY_ENABLE, Qt);
8620 else if (!NILP (tem))
8621 ASET (item_properties, ITEM_PROPERTY_ENABLE, tem);
8622 }
8623 }
8624 else if (EQ (item_string, Qmenu_item) && CONSP (item))
8625 {
8626
8627 ASET (item_properties, ITEM_PROPERTY_NAME, XCAR (item));
8628 start = XCDR (item);
8629 if (CONSP (start))
8630 {
8631
8632 ASET (item_properties, ITEM_PROPERTY_DEF, XCAR (start));
8633
8634 item = XCDR (start);
8635
8636 if (CONSP (item) && CONSP (XCAR (item)))
8637 item = XCDR (item);
8638
8639
8640 FOR_EACH_TAIL (item)
8641 {
8642 tem = XCAR (item);
8643 item = XCDR (item);
8644 if (!CONSP (item))
8645 break;
8646
8647 if (EQ (tem, QCenable))
8648 {
8649 if (!NILP (Venable_disabled_menus_and_buttons))
8650 ASET (item_properties, ITEM_PROPERTY_ENABLE, Qt);
8651 else
8652 ASET (item_properties, ITEM_PROPERTY_ENABLE, XCAR (item));
8653 }
8654 else if (EQ (tem, QCvisible))
8655 {
8656
8657
8658 tem = menu_item_eval_property (XCAR (item));
8659 if (NILP (tem))
8660 return 0;
8661 }
8662 else if (EQ (tem, QChelp))
8663 {
8664 Lisp_Object help = XCAR (item);
8665 if (STRINGP (help))
8666 help = help_echo_substitute_command_keys (help);
8667 ASET (item_properties, ITEM_PROPERTY_HELP, help);
8668 }
8669 else if (EQ (tem, QCfilter))
8670 filter = item;
8671 else if (EQ (tem, QCkey_sequence))
8672 {
8673 tem = XCAR (item);
8674 if (SYMBOLP (tem) || STRINGP (tem) || VECTORP (tem))
8675
8676 keyhint = item;
8677 }
8678 else if (EQ (tem, QCkeys))
8679 {
8680 tem = XCAR (item);
8681 if (FUNCTIONP (tem))
8682 ASET (item_properties, ITEM_PROPERTY_KEYEQ, call0 (tem));
8683 else if (CONSP (tem) || STRINGP (tem))
8684 ASET (item_properties, ITEM_PROPERTY_KEYEQ, tem);
8685 }
8686 else if (EQ (tem, QCbutton) && CONSP (XCAR (item)))
8687 {
8688 Lisp_Object type;
8689 tem = XCAR (item);
8690 type = XCAR (tem);
8691 if (EQ (type, QCtoggle) || EQ (type, QCradio))
8692 {
8693 ASET (item_properties, ITEM_PROPERTY_SELECTED,
8694 XCDR (tem));
8695 ASET (item_properties, ITEM_PROPERTY_TYPE, type);
8696 }
8697 }
8698 }
8699 }
8700 else if (inmenubar || !NILP (start))
8701 return 0;
8702 }
8703 else
8704 return 0;
8705
8706
8707
8708 item_string = AREF (item_properties, ITEM_PROPERTY_NAME);
8709 if (!(STRINGP (item_string)))
8710 {
8711 item_string = menu_item_eval_property (item_string);
8712 if (!STRINGP (item_string))
8713 return 0;
8714 ASET (item_properties, ITEM_PROPERTY_NAME, item_string);
8715 }
8716
8717
8718 def = AREF (item_properties, ITEM_PROPERTY_DEF);
8719 if (!NILP (filter))
8720 {
8721 def = menu_item_eval_property (list2 (XCAR (filter),
8722 list2 (Qquote, def)));
8723
8724 ASET (item_properties, ITEM_PROPERTY_DEF, def);
8725 }
8726
8727
8728 tem = AREF (item_properties, ITEM_PROPERTY_ENABLE);
8729 if (!EQ (tem, Qt))
8730 {
8731 tem = menu_item_eval_property (tem);
8732 if (inmenubar && NILP (tem))
8733 return 0;
8734 ASET (item_properties, ITEM_PROPERTY_ENABLE, tem);
8735 }
8736
8737
8738
8739 if (NILP (def))
8740 return (!inmenubar);
8741
8742
8743 def = AREF (item_properties, ITEM_PROPERTY_DEF);
8744 tem = get_keymap (def, 0, 1);
8745
8746 if (CONSP (tem))
8747 {
8748 ASET (item_properties, ITEM_PROPERTY_MAP, tem);
8749 ASET (item_properties, ITEM_PROPERTY_DEF, tem);
8750 return 1;
8751 }
8752
8753
8754
8755
8756 if (inmenubar > 0)
8757 return 1;
8758
8759 {
8760 Lisp_Object keyeq = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
8761 AUTO_STRING (space_space, " ");
8762
8763
8764
8765 if (STRINGP (keyeq) && !CONSP (keyhint))
8766 keyeq = concat2 (space_space, call1 (Qsubstitute_command_keys, keyeq));
8767 else
8768 {
8769 Lisp_Object prefix = keyeq;
8770 Lisp_Object keys = Qnil;
8771
8772 if (CONSP (prefix))
8773 {
8774 def = XCAR (prefix);
8775 prefix = XCDR (prefix);
8776 }
8777 else
8778 def = AREF (item_properties, ITEM_PROPERTY_DEF);
8779
8780 if (CONSP (keyhint) && !NILP (XCAR (keyhint)))
8781 {
8782 keys = XCAR (keyhint);
8783 tem = Fkey_binding (keys, Qnil, Qnil, Qnil);
8784
8785
8786 if (NILP (tem)
8787 || (!EQ (tem, def)
8788
8789
8790
8791 && !(SYMBOLP (def)
8792 && EQ (tem, XSYMBOL (def)->u.s.function))))
8793 keys = Qnil;
8794 }
8795
8796 if (NILP (keys))
8797 keys = Fwhere_is_internal (def, Qnil, Qt, Qnil, Qnil);
8798
8799 if (!NILP (keys))
8800 {
8801 tem = Fkey_description (keys, Qnil);
8802 if (CONSP (prefix))
8803 {
8804 if (STRINGP (XCAR (prefix)))
8805 tem = concat2 (XCAR (prefix), tem);
8806 if (STRINGP (XCDR (prefix)))
8807 tem = concat2 (tem, XCDR (prefix));
8808 }
8809 keyeq = concat2 (space_space, tem);
8810 }
8811 else
8812 keyeq = Qnil;
8813 }
8814
8815
8816 ASET (item_properties, ITEM_PROPERTY_KEYEQ, keyeq);
8817 }
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831 tem = AREF (item_properties, ITEM_PROPERTY_SELECTED);
8832 if (!NILP (tem))
8833 ASET (item_properties, ITEM_PROPERTY_SELECTED,
8834 menu_item_eval_property (tem));
8835
8836 return 1;
8837 }
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849 static Lisp_Object tab_bar_items_vector;
8850
8851
8852
8853
8854 static Lisp_Object tab_bar_item_properties;
8855
8856
8857
8858 static int ntab_bar_items;
8859
8860
8861
8862 static void init_tab_bar_items (Lisp_Object);
8863 static void process_tab_bar_item (Lisp_Object, Lisp_Object, Lisp_Object,
8864 void *);
8865 static bool parse_tab_bar_item (Lisp_Object, Lisp_Object);
8866 static void append_tab_bar_item (void);
8867
8868
8869
8870
8871
8872
8873 Lisp_Object
8874 tab_bar_items (Lisp_Object reuse, int *nitems)
8875 {
8876 Lisp_Object *maps;
8877 Lisp_Object mapsbuf[3];
8878 ptrdiff_t nmaps, i;
8879 Lisp_Object oquit;
8880 Lisp_Object *tmaps;
8881 USE_SAFE_ALLOCA;
8882
8883 *nitems = 0;
8884
8885
8886
8887
8888
8889
8890
8891 oquit = Vinhibit_quit;
8892 Vinhibit_quit = Qt;
8893
8894
8895 init_tab_bar_items (reuse);
8896
8897
8898
8899
8900
8901 if (!NILP (Voverriding_local_map_menu_flag)
8902 && !NILP (Voverriding_local_map))
8903 {
8904
8905 maps = mapsbuf;
8906 nmaps = 0;
8907 if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
8908 maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
8909 if (!NILP (Voverriding_local_map))
8910 maps[nmaps++] = Voverriding_local_map;
8911 }
8912 else
8913 {
8914
8915
8916
8917
8918
8919 ptrdiff_t nminor = current_minor_maps (NULL, &tmaps);
8920 SAFE_NALLOCA (maps, 1, nminor + 4);
8921 nmaps = 0;
8922 Lisp_Object tem = KVAR (current_kboard, Voverriding_terminal_local_map);
8923 if (!NILP (tem) && !NILP (Voverriding_local_map_menu_flag))
8924 maps[nmaps++] = tem;
8925 if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem))
8926 maps[nmaps++] = tem;
8927 if (nminor != 0)
8928 {
8929 memcpy (maps + nmaps, tmaps, nminor * sizeof (maps[0]));
8930 nmaps += nminor;
8931 }
8932 maps[nmaps++] = get_local_map (PT, current_buffer, Qlocal_map);
8933 }
8934
8935
8936 maps[nmaps++] = current_global_map;
8937
8938
8939
8940 for (i = nmaps - 1; i >= 0; --i)
8941 if (!NILP (maps[i]))
8942 {
8943 Lisp_Object keymap;
8944
8945 keymap = get_keymap (access_keymap (maps[i], Qtab_bar, 1, 0, 1), 0, 1);
8946 if (CONSP (keymap))
8947 map_keymap (keymap, process_tab_bar_item, Qnil, NULL, 1);
8948 }
8949
8950 Vinhibit_quit = oquit;
8951 *nitems = ntab_bar_items / TAB_BAR_ITEM_NSLOTS;
8952 SAFE_FREE ();
8953 return tab_bar_items_vector;
8954 }
8955
8956
8957
8958
8959 static void
8960 process_tab_bar_item (Lisp_Object key, Lisp_Object def, Lisp_Object data, void *args)
8961 {
8962 int i;
8963
8964 if (EQ (def, Qundefined))
8965 {
8966
8967
8968 for (i = 0; i < ntab_bar_items; i += TAB_BAR_ITEM_NSLOTS)
8969 {
8970 Lisp_Object *v = XVECTOR (tab_bar_items_vector)->contents + i;
8971
8972 if (EQ (key, v[TAB_BAR_ITEM_KEY]))
8973 {
8974 if (ntab_bar_items > i + TAB_BAR_ITEM_NSLOTS)
8975 memmove (v, v + TAB_BAR_ITEM_NSLOTS,
8976 ((ntab_bar_items - i - TAB_BAR_ITEM_NSLOTS)
8977 * word_size));
8978 ntab_bar_items -= TAB_BAR_ITEM_NSLOTS;
8979 break;
8980 }
8981 }
8982 }
8983 else if (parse_tab_bar_item (key, def))
8984
8985
8986 append_tab_bar_item ();
8987 }
8988
8989
8990 #define PROP(IDX) AREF (tab_bar_item_properties, (IDX))
8991 static void
8992 set_prop_tab_bar (ptrdiff_t idx, Lisp_Object val)
8993 {
8994 ASET (tab_bar_item_properties, idx, val);
8995 }
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044 static bool
9045 parse_tab_bar_item (Lisp_Object key, Lisp_Object item)
9046 {
9047 Lisp_Object filter = Qnil;
9048 Lisp_Object caption;
9049 int i;
9050
9051
9052
9053
9054
9055 if (!CONSP (item))
9056 return 0;
9057
9058
9059 if (STRINGP (XCAR (item)))
9060 item = list1 (XCAR (item));
9061 else if (!EQ (XCAR (item), Qmenu_item)
9062 || (item = XCDR (item), !CONSP (item)))
9063 return 0;
9064
9065
9066
9067 if (VECTORP (tab_bar_item_properties))
9068 {
9069 for (i = 0; i < TAB_BAR_ITEM_NSLOTS; ++i)
9070 set_prop_tab_bar (i, Qnil);
9071 }
9072 else
9073 tab_bar_item_properties = make_nil_vector (TAB_BAR_ITEM_NSLOTS);
9074
9075
9076 set_prop_tab_bar (TAB_BAR_ITEM_KEY, key);
9077 set_prop_tab_bar (TAB_BAR_ITEM_ENABLED_P, Qt);
9078
9079
9080
9081
9082 caption = XCAR (item);
9083 if (!STRINGP (caption))
9084 {
9085 caption = menu_item_eval_property (caption);
9086 if (!STRINGP (caption))
9087 return 0;
9088 }
9089 set_prop_tab_bar (TAB_BAR_ITEM_CAPTION, caption);
9090
9091
9092
9093 item = XCDR (item);
9094 if (!CONSP (item))
9095 {
9096 if (menu_separator_name_p (SSDATA (caption)))
9097 {
9098 set_prop_tab_bar (TAB_BAR_ITEM_ENABLED_P, Qnil);
9099 set_prop_tab_bar (TAB_BAR_ITEM_SELECTED_P, Qnil);
9100 set_prop_tab_bar (TAB_BAR_ITEM_CAPTION, Qnil);
9101 return 1;
9102 }
9103 return 0;
9104 }
9105
9106
9107 set_prop_tab_bar (TAB_BAR_ITEM_BINDING, XCAR (item));
9108 item = XCDR (item);
9109
9110
9111 if (CONSP (item) && CONSP (XCAR (item)))
9112 item = XCDR (item);
9113
9114
9115 FOR_EACH_TAIL (item)
9116 {
9117 Lisp_Object ikey = XCAR (item);
9118 item = XCDR (item);
9119 if (!CONSP (item))
9120 break;
9121 Lisp_Object value = XCAR (item);
9122
9123 if (EQ (ikey, QCenable))
9124 {
9125
9126 if (!NILP (Venable_disabled_menus_and_buttons))
9127 set_prop_tab_bar (TAB_BAR_ITEM_ENABLED_P, Qt);
9128 else
9129 set_prop_tab_bar (TAB_BAR_ITEM_ENABLED_P, value);
9130 }
9131 else if (EQ (ikey, QCvisible))
9132 {
9133
9134
9135 if (NILP (menu_item_eval_property (value)))
9136 return 0;
9137 }
9138 else if (EQ (ikey, QChelp))
9139
9140 set_prop_tab_bar (TAB_BAR_ITEM_HELP, value);
9141 else if (EQ (ikey, QCfilter))
9142
9143 filter = value;
9144 else if (EQ (ikey, QCbutton) && CONSP (value))
9145 {
9146
9147 Lisp_Object type, selected;
9148
9149 type = XCAR (value);
9150 selected = XCDR (value);
9151 if (EQ (type, QCtoggle) || EQ (type, QCradio))
9152 {
9153 set_prop_tab_bar (TAB_BAR_ITEM_SELECTED_P, selected);
9154 }
9155 }
9156 }
9157
9158
9159 if (!NILP (filter))
9160 set_prop_tab_bar (TAB_BAR_ITEM_BINDING,
9161 (menu_item_eval_property
9162 (list2 (filter,
9163 list2 (Qquote,
9164 PROP (TAB_BAR_ITEM_BINDING))))));
9165
9166
9167 if (CONSP (get_keymap (PROP (TAB_BAR_ITEM_BINDING), 0, 1)))
9168 return 0;
9169
9170
9171 if (!EQ (PROP (TAB_BAR_ITEM_ENABLED_P), Qt))
9172 set_prop_tab_bar (TAB_BAR_ITEM_ENABLED_P,
9173 menu_item_eval_property (PROP (TAB_BAR_ITEM_ENABLED_P)));
9174
9175
9176 if (!NILP (PROP (TAB_BAR_ITEM_SELECTED_P)))
9177 set_prop_tab_bar (TAB_BAR_ITEM_SELECTED_P,
9178 menu_item_eval_property (PROP (TAB_BAR_ITEM_SELECTED_P)));
9179
9180 return 1;
9181
9182 #undef PROP
9183 }
9184
9185
9186
9187
9188
9189 static void
9190 init_tab_bar_items (Lisp_Object reuse)
9191 {
9192 if (VECTORP (reuse))
9193 tab_bar_items_vector = reuse;
9194 else
9195 tab_bar_items_vector = make_nil_vector (64);
9196 ntab_bar_items = 0;
9197 }
9198
9199
9200
9201
9202
9203 static void
9204 append_tab_bar_item (void)
9205 {
9206 ptrdiff_t incr
9207 = (ntab_bar_items
9208 - (ASIZE (tab_bar_items_vector) - TAB_BAR_ITEM_NSLOTS));
9209
9210
9211 if (incr > 0)
9212 tab_bar_items_vector = larger_vector (tab_bar_items_vector, incr, -1);
9213
9214
9215
9216 vcopy (tab_bar_items_vector, ntab_bar_items,
9217 xvector_contents (tab_bar_item_properties), TAB_BAR_ITEM_NSLOTS);
9218 ntab_bar_items += TAB_BAR_ITEM_NSLOTS;
9219 }
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233 static Lisp_Object tool_bar_items_vector;
9234
9235
9236
9237
9238 static Lisp_Object tool_bar_item_properties;
9239
9240
9241
9242 static int ntool_bar_items;
9243
9244
9245
9246 static void init_tool_bar_items (Lisp_Object);
9247 static void process_tool_bar_item (Lisp_Object, Lisp_Object, Lisp_Object,
9248 void *);
9249 static bool parse_tool_bar_item (Lisp_Object, Lisp_Object);
9250 static void append_tool_bar_item (void);
9251
9252
9253
9254
9255
9256
9257 Lisp_Object
9258 tool_bar_items (Lisp_Object reuse, int *nitems)
9259 {
9260 Lisp_Object *maps;
9261 Lisp_Object mapsbuf[3];
9262 ptrdiff_t nmaps, i;
9263 Lisp_Object oquit;
9264 Lisp_Object *tmaps;
9265 USE_SAFE_ALLOCA;
9266
9267 *nitems = 0;
9268
9269
9270
9271
9272
9273
9274
9275 oquit = Vinhibit_quit;
9276 Vinhibit_quit = Qt;
9277
9278
9279 init_tool_bar_items (reuse);
9280
9281
9282
9283
9284
9285 if (!NILP (Voverriding_local_map_menu_flag)
9286 && !NILP (Voverriding_local_map))
9287 {
9288
9289 maps = mapsbuf;
9290 nmaps = 0;
9291 if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
9292 maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
9293 if (!NILP (Voverriding_local_map))
9294 maps[nmaps++] = Voverriding_local_map;
9295 }
9296 else
9297 {
9298
9299
9300
9301
9302
9303 ptrdiff_t nminor = current_minor_maps (NULL, &tmaps);
9304 SAFE_NALLOCA (maps, 1, nminor + 4);
9305 nmaps = 0;
9306 Lisp_Object tem = KVAR (current_kboard, Voverriding_terminal_local_map);
9307 if (!NILP (tem) && !NILP (Voverriding_local_map_menu_flag))
9308 maps[nmaps++] = tem;
9309 if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem))
9310 maps[nmaps++] = tem;
9311 if (nminor != 0)
9312 {
9313 memcpy (maps + nmaps, tmaps, nminor * sizeof (maps[0]));
9314 nmaps += nminor;
9315 }
9316 maps[nmaps++] = get_local_map (PT, current_buffer, Qlocal_map);
9317 }
9318
9319
9320 maps[nmaps++] = current_global_map;
9321
9322
9323
9324 for (i = nmaps - 1; i >= 0; --i)
9325 if (!NILP (maps[i]))
9326 {
9327 Lisp_Object keymap;
9328
9329 keymap = get_keymap (access_keymap (maps[i], Qtool_bar, 1, 0, 1), 0, 1);
9330 if (CONSP (keymap))
9331 map_keymap (keymap, process_tool_bar_item, Qnil, NULL, 1);
9332 }
9333
9334 Vinhibit_quit = oquit;
9335 *nitems = ntool_bar_items / TOOL_BAR_ITEM_NSLOTS;
9336 SAFE_FREE ();
9337 return tool_bar_items_vector;
9338 }
9339
9340
9341
9342
9343 static void
9344 process_tool_bar_item (Lisp_Object key, Lisp_Object def, Lisp_Object data, void *args)
9345 {
9346 int i;
9347
9348 if (EQ (def, Qundefined))
9349 {
9350
9351
9352 for (i = 0; i < ntool_bar_items; i += TOOL_BAR_ITEM_NSLOTS)
9353 {
9354 Lisp_Object *v = XVECTOR (tool_bar_items_vector)->contents + i;
9355
9356 if (EQ (key, v[TOOL_BAR_ITEM_KEY]))
9357 {
9358 if (ntool_bar_items > i + TOOL_BAR_ITEM_NSLOTS)
9359 memmove (v, v + TOOL_BAR_ITEM_NSLOTS,
9360 ((ntool_bar_items - i - TOOL_BAR_ITEM_NSLOTS)
9361 * word_size));
9362 ntool_bar_items -= TOOL_BAR_ITEM_NSLOTS;
9363 break;
9364 }
9365 }
9366 }
9367 else if (parse_tool_bar_item (key, def))
9368
9369
9370 append_tool_bar_item ();
9371 }
9372
9373
9374 #define PROP(IDX) AREF (tool_bar_item_properties, (IDX))
9375 static void
9376 set_prop (ptrdiff_t idx, Lisp_Object val)
9377 {
9378 ASET (tool_bar_item_properties, idx, val);
9379 }
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434 static bool
9435 parse_tool_bar_item (Lisp_Object key, Lisp_Object item)
9436 {
9437 Lisp_Object filter = Qnil;
9438 Lisp_Object caption;
9439 int i;
9440 bool have_label;
9441 #ifndef HAVE_EXT_TOOL_BAR
9442 bool is_wrap;
9443 #endif
9444
9445 have_label = false;
9446 #ifndef HAVE_EXT_TOOL_BAR
9447 is_wrap = false;
9448 #endif
9449
9450
9451
9452
9453
9454 if (!CONSP (item))
9455 return 0;
9456
9457
9458 if (STRINGP (XCAR (item)))
9459 item = list1 (XCAR (item));
9460 else if (!EQ (XCAR (item), Qmenu_item)
9461 || (item = XCDR (item), !CONSP (item)))
9462 return 0;
9463
9464
9465
9466 if (VECTORP (tool_bar_item_properties))
9467 {
9468 for (i = 0; i < TOOL_BAR_ITEM_NSLOTS; ++i)
9469 set_prop (i, Qnil);
9470 }
9471 else
9472 tool_bar_item_properties = make_nil_vector (TOOL_BAR_ITEM_NSLOTS);
9473
9474
9475 set_prop (TOOL_BAR_ITEM_KEY, key);
9476 set_prop (TOOL_BAR_ITEM_ENABLED_P, Qt);
9477
9478
9479
9480
9481 caption = XCAR (item);
9482 if (!STRINGP (caption))
9483 {
9484 caption = menu_item_eval_property (caption);
9485 if (!STRINGP (caption))
9486 return 0;
9487 }
9488 set_prop (TOOL_BAR_ITEM_CAPTION, caption);
9489
9490
9491
9492 item = XCDR (item);
9493 if (!CONSP (item))
9494 {
9495 if (menu_separator_name_p (SSDATA (caption)))
9496 {
9497 set_prop (TOOL_BAR_ITEM_TYPE, Qt);
9498 #ifndef HAVE_EXT_TOOL_BAR
9499
9500
9501 set_prop (TOOL_BAR_ITEM_IMAGES,
9502 (menu_item_eval_property
9503 (Vtool_bar_separator_image_expression)));
9504 set_prop (TOOL_BAR_ITEM_ENABLED_P, Qnil);
9505 set_prop (TOOL_BAR_ITEM_SELECTED_P, Qnil);
9506 set_prop (TOOL_BAR_ITEM_CAPTION, Qnil);
9507 #endif
9508 return 1;
9509 }
9510 return 0;
9511 }
9512
9513
9514 set_prop (TOOL_BAR_ITEM_BINDING, XCAR (item));
9515 item = XCDR (item);
9516
9517
9518 if (CONSP (item) && CONSP (XCAR (item)))
9519 item = XCDR (item);
9520
9521
9522 FOR_EACH_TAIL (item)
9523 {
9524 Lisp_Object ikey = XCAR (item);
9525 item = XCDR (item);
9526 if (!CONSP (item))
9527 break;
9528 Lisp_Object value = XCAR (item);
9529
9530 if (EQ (ikey, QCenable))
9531 {
9532
9533 if (!NILP (Venable_disabled_menus_and_buttons))
9534 set_prop (TOOL_BAR_ITEM_ENABLED_P, Qt);
9535 else
9536 set_prop (TOOL_BAR_ITEM_ENABLED_P, value);
9537 }
9538 else if (EQ (ikey, QCvisible))
9539 {
9540
9541
9542 if (NILP (menu_item_eval_property (value)))
9543 return 0;
9544 }
9545 else if (EQ (ikey, QChelp))
9546
9547 set_prop (TOOL_BAR_ITEM_HELP, value);
9548 else if (EQ (ikey, QCvert_only))
9549
9550 set_prop (TOOL_BAR_ITEM_VERT_ONLY, value);
9551 else if (EQ (ikey, QClabel))
9552 {
9553 const char *bad_label = "!!?GARBLED ITEM?!!";
9554
9555 set_prop (TOOL_BAR_ITEM_LABEL,
9556 STRINGP (value) ? value : build_string (bad_label));
9557 have_label = true;
9558 }
9559 else if (EQ (ikey, QCfilter))
9560
9561 filter = value;
9562 else if (EQ (ikey, QCbutton) && CONSP (value))
9563 {
9564
9565 Lisp_Object type, selected;
9566
9567 type = XCAR (value);
9568 selected = XCDR (value);
9569 if (EQ (type, QCtoggle) || EQ (type, QCradio))
9570 {
9571 set_prop (TOOL_BAR_ITEM_SELECTED_P, selected);
9572 set_prop (TOOL_BAR_ITEM_TYPE, type);
9573 }
9574 }
9575 else if (EQ (ikey, QCimage)
9576 && (CONSP (value)
9577 || (VECTORP (value) && ASIZE (value) == 4)))
9578
9579
9580 set_prop (TOOL_BAR_ITEM_IMAGES, value);
9581 else if (EQ (ikey, QCrtl))
9582
9583 set_prop (TOOL_BAR_ITEM_RTL_IMAGE, value);
9584 else if (EQ (ikey, QCwrap))
9585 {
9586 #ifndef HAVE_EXT_TOOL_BAR
9587
9588
9589
9590 set_prop (TOOL_BAR_ITEM_WRAP, value);
9591 is_wrap = !NILP (value);
9592 #else
9593
9594
9595 return false;
9596 #endif
9597 }
9598 }
9599
9600
9601 if (!have_label)
9602 {
9603
9604 Lisp_Object tkey = PROP (TOOL_BAR_ITEM_KEY);
9605 Lisp_Object tcapt = PROP (TOOL_BAR_ITEM_CAPTION);
9606 const char *label = SYMBOLP (tkey) ? SSDATA (SYMBOL_NAME (tkey)) : "";
9607 const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : "";
9608 ptrdiff_t max_lbl_size =
9609 2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2)) + 1;
9610 char *buf = xmalloc (max_lbl_size);
9611 Lisp_Object new_lbl;
9612 ptrdiff_t caption_len = strnlen (capt, max_lbl_size);
9613
9614 if (0 < caption_len && caption_len < max_lbl_size)
9615 {
9616 strcpy (buf, capt);
9617 while (caption_len > 0 && buf[caption_len - 1] == '.')
9618 caption_len--;
9619 buf[caption_len] = '\0';
9620 label = capt = buf;
9621 }
9622
9623 ptrdiff_t label_len = strnlen (label, max_lbl_size);
9624 if (0 < label_len && label_len < max_lbl_size)
9625 {
9626 ptrdiff_t j;
9627 if (label != buf)
9628 strcpy (buf, label);
9629
9630 for (j = 0; buf[j] != '\0'; ++j)
9631 if (buf[j] == '-')
9632 buf[j] = ' ';
9633 label = buf;
9634 }
9635 else
9636 label = "";
9637
9638 new_lbl = Fupcase_initials (build_string (label));
9639 if (SCHARS (new_lbl) <= tool_bar_max_label_size)
9640 set_prop (TOOL_BAR_ITEM_LABEL, new_lbl);
9641 else
9642 set_prop (TOOL_BAR_ITEM_LABEL, empty_unibyte_string);
9643 xfree (buf);
9644 }
9645
9646
9647 if (!NILP (filter))
9648 set_prop (TOOL_BAR_ITEM_BINDING,
9649 (menu_item_eval_property
9650 (list2 (filter,
9651 list2 (Qquote,
9652 PROP (TOOL_BAR_ITEM_BINDING))))));
9653
9654
9655 if (CONSP (get_keymap (PROP (TOOL_BAR_ITEM_BINDING), 0, 1)))
9656 return 0;
9657
9658
9659 #ifndef HAVE_EXT_TOOL_BAR
9660
9661
9662
9663 if (is_wrap)
9664 set_prop (TOOL_BAR_ITEM_ENABLED_P, Qnil);
9665 #endif
9666
9667
9668
9669 Lisp_Object binding = PROP (TOOL_BAR_ITEM_BINDING);
9670 Lisp_Object keys = Fwhere_is_internal (binding, Qnil, Qt, Qnil, Qnil);
9671 if (!NILP (keys))
9672 {
9673 AUTO_STRING (beg, " (");
9674 AUTO_STRING (end, ")");
9675 Lisp_Object orig = PROP (TOOL_BAR_ITEM_HELP);
9676 Lisp_Object desc = Fkey_description (keys, Qnil);
9677
9678 if (NILP (orig))
9679 orig = PROP (TOOL_BAR_ITEM_CAPTION);
9680
9681 set_prop (TOOL_BAR_ITEM_HELP, CALLN (Fconcat, orig, beg, desc, end));
9682 }
9683
9684
9685 if (!EQ (PROP (TOOL_BAR_ITEM_ENABLED_P), Qt))
9686 set_prop (TOOL_BAR_ITEM_ENABLED_P,
9687 menu_item_eval_property (PROP (TOOL_BAR_ITEM_ENABLED_P)));
9688
9689
9690 if (!NILP (PROP (TOOL_BAR_ITEM_SELECTED_P)))
9691 set_prop (TOOL_BAR_ITEM_SELECTED_P,
9692 menu_item_eval_property (PROP (TOOL_BAR_ITEM_SELECTED_P)));
9693
9694 return 1;
9695
9696 #undef PROP
9697 }
9698
9699
9700
9701
9702
9703 static void
9704 init_tool_bar_items (Lisp_Object reuse)
9705 {
9706 if (VECTORP (reuse))
9707 tool_bar_items_vector = reuse;
9708 else
9709 tool_bar_items_vector = make_nil_vector (64);
9710 ntool_bar_items = 0;
9711 }
9712
9713
9714
9715
9716
9717 static void
9718 append_tool_bar_item (void)
9719 {
9720 ptrdiff_t incr
9721 = (ntool_bar_items
9722 - (ASIZE (tool_bar_items_vector) - TOOL_BAR_ITEM_NSLOTS));
9723
9724
9725 if (incr > 0)
9726 tool_bar_items_vector = larger_vector (tool_bar_items_vector, incr, -1);
9727
9728
9729
9730 vcopy (tool_bar_items_vector, ntool_bar_items,
9731 xvector_contents (tool_bar_item_properties), TOOL_BAR_ITEM_NSLOTS);
9732 ntool_bar_items += TOOL_BAR_ITEM_NSLOTS;
9733 }
9734
9735
9736
9737
9738
9739
9740
9741
9742
9743
9744
9745
9746
9747
9748
9749
9750
9751
9752
9753
9754
9755
9756
9757
9758
9759 static Lisp_Object
9760 read_char_x_menu_prompt (Lisp_Object map,
9761 Lisp_Object prev_event, bool *used_mouse_menu)
9762 {
9763 if (used_mouse_menu)
9764 *used_mouse_menu = false;
9765
9766
9767
9768 if (! menu_prompting)
9769 return Qnil;
9770
9771
9772
9773 if (EVENT_HAS_PARAMETERS (prev_event)
9774 && !EQ (XCAR (prev_event), Qmenu_bar)
9775 && !EQ (XCAR (prev_event), Qtab_bar)
9776 && !EQ (XCAR (prev_event), Qtool_bar))
9777 {
9778
9779 Lisp_Object value;
9780
9781 value = x_popup_menu_1 (prev_event, get_keymap (map, 0, 1));
9782 if (CONSP (value))
9783 {
9784 Lisp_Object tem;
9785
9786 record_menu_key (XCAR (value));
9787
9788
9789
9790
9791
9792
9793
9794
9795
9796 for (tem = XCDR (value); CONSP (tem); tem = XCDR (tem))
9797 {
9798 record_menu_key (XCAR (tem));
9799 if (SYMBOLP (XCAR (tem))
9800 || FIXNUMP (XCAR (tem)))
9801 XSETCAR (tem, Fcons (XCAR (tem), Qdisabled));
9802 }
9803
9804
9805
9806
9807 Vunread_command_events
9808 = nconc2 (XCDR (value), Vunread_command_events);
9809 value = XCAR (value);
9810 }
9811 else if (NILP (value))
9812 value = Qt;
9813 if (used_mouse_menu)
9814 *used_mouse_menu = true;
9815 return value;
9816 }
9817 return Qnil ;
9818 }
9819
9820 static Lisp_Object
9821 read_char_minibuf_menu_prompt (int commandflag,
9822 Lisp_Object map)
9823 {
9824 Lisp_Object name;
9825 ptrdiff_t nlength;
9826
9827 ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4;
9828 ptrdiff_t idx = -1;
9829 bool nobindings = true;
9830 Lisp_Object rest, vector;
9831 Lisp_Object prompt_strings = Qnil;
9832
9833 vector = Qnil;
9834
9835 if (! menu_prompting)
9836 return Qnil;
9837
9838 map = get_keymap (map, 0, 1);
9839 name = Fkeymap_prompt (map);
9840
9841
9842 if (!STRINGP (name))
9843 return Qnil;
9844
9845 #define PUSH_C_STR(str, listvar) \
9846 listvar = Fcons (build_unibyte_string (str), listvar)
9847
9848
9849 prompt_strings = Fcons (name, prompt_strings);
9850 PUSH_C_STR (": ", prompt_strings);
9851 nlength = SCHARS (name) + 2;
9852
9853 rest = map;
9854
9855
9856 while (1)
9857 {
9858 bool notfirst = false;
9859 Lisp_Object menu_strings = prompt_strings;
9860 ptrdiff_t i = nlength;
9861 Lisp_Object obj;
9862 Lisp_Object orig_defn_macro;
9863
9864
9865 while (i < width)
9866 {
9867 Lisp_Object elt;
9868
9869
9870
9871
9872
9873 if (NILP (rest))
9874 {
9875 if (notfirst || nobindings)
9876 break;
9877 else
9878 rest = map;
9879 }
9880
9881
9882 if (idx >= 0)
9883 elt = AREF (vector, idx);
9884 else
9885 elt = Fcar_safe (rest);
9886
9887 if (idx < 0 && VECTORP (elt))
9888 {
9889
9890
9891 rest = Fcdr_safe (rest);
9892 vector = elt;
9893 idx = 0;
9894 }
9895 else
9896 {
9897
9898 Lisp_Object event, tem;
9899
9900 if (idx < 0)
9901 {
9902 event = Fcar_safe (elt);
9903 elt = Fcdr_safe (elt);
9904 }
9905 else
9906 {
9907 XSETINT (event, idx);
9908 }
9909
9910
9911 if (FIXNUMP (event) && parse_menu_item (elt, -1))
9912 {
9913
9914 bool char_matches;
9915 Lisp_Object upcased_event, downcased_event;
9916 Lisp_Object desc = Qnil;
9917 Lisp_Object s
9918 = AREF (item_properties, ITEM_PROPERTY_NAME);
9919
9920 upcased_event = Fupcase (event);
9921 downcased_event = Fdowncase (event);
9922 char_matches = (XFIXNUM (upcased_event) == SREF (s, 0)
9923 || XFIXNUM (downcased_event) == SREF (s, 0));
9924 if (! char_matches)
9925 desc = Fsingle_key_description (event, Qnil);
9926
9927 #if 0
9928
9929 tem
9930 = XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ];
9931 if (!NILP (tem))
9932
9933 s = concat2 (s, tem);
9934 #endif
9935 tem
9936 = AREF (item_properties, ITEM_PROPERTY_TYPE);
9937 if (EQ (tem, QCradio) || EQ (tem, QCtoggle))
9938 {
9939
9940 Lisp_Object selected
9941 = AREF (item_properties, ITEM_PROPERTY_SELECTED);
9942 AUTO_STRING (radio_yes, "(*) ");
9943 AUTO_STRING (radio_no , "( ) ");
9944 AUTO_STRING (check_yes, "[X] ");
9945 AUTO_STRING (check_no , "[ ] ");
9946 if (EQ (tem, QCradio))
9947 tem = NILP (selected) ? radio_yes : radio_no;
9948 else
9949 tem = NILP (selected) ? check_yes : check_no;
9950 s = concat2 (tem, s);
9951 }
9952
9953
9954
9955
9956 if ((SCHARS (s) + i + 2
9957 + (char_matches ? 0 : SCHARS (desc) + 3))
9958 < width
9959 || !notfirst)
9960 {
9961 ptrdiff_t thiswidth;
9962
9963
9964 if (notfirst)
9965 {
9966 PUSH_C_STR (", ", menu_strings);
9967 i += 2;
9968 }
9969 notfirst = true;
9970 nobindings = false;
9971
9972
9973
9974 if (! char_matches)
9975 {
9976
9977 thiswidth = min (SCHARS (desc), width - i);
9978 menu_strings
9979 = Fcons (Fsubstring (desc, make_fixnum (0),
9980 make_fixnum (thiswidth)),
9981 menu_strings);
9982 i += thiswidth;
9983 PUSH_C_STR (" = ", menu_strings);
9984 i += 3;
9985 }
9986
9987
9988 thiswidth = min (SCHARS (s), width - i);
9989 menu_strings
9990 = Fcons (Fsubstring (s, make_fixnum (0),
9991 make_fixnum (thiswidth)),
9992 menu_strings);
9993 i += thiswidth;
9994 }
9995 else
9996 {
9997
9998
9999 PUSH_C_STR ("...", menu_strings);
10000 break;
10001 }
10002 }
10003
10004
10005 if (idx >= 0 && idx + 1 >= ASIZE (vector))
10006
10007 idx = -1;
10008 if (idx >= 0)
10009 idx++;
10010 else
10011 rest = Fcdr_safe (rest);
10012 }
10013 }
10014
10015
10016 message3_nolog (apply1 (intern ("concat"), Fnreverse (menu_strings)));
10017
10018
10019
10020
10021 orig_defn_macro = KVAR (current_kboard, defining_kbd_macro);
10022 kset_defining_kbd_macro (current_kboard, Qnil);
10023 do
10024 obj = read_char (commandflag, Qnil, Qt, 0, NULL);
10025 while (BUFFERP (obj));
10026 kset_defining_kbd_macro (current_kboard, orig_defn_macro);
10027
10028 if (!FIXNUMP (obj) || XFIXNUM (obj) == -2
10029 || (! EQ (obj, menu_prompt_more_char)
10030 && (!FIXNUMP (menu_prompt_more_char)
10031 || ! BASE_EQ (obj, make_fixnum (Ctl (XFIXNUM (menu_prompt_more_char)))))))
10032 {
10033 if (!NILP (KVAR (current_kboard, defining_kbd_macro)))
10034 store_kbd_macro_char (obj);
10035 return obj;
10036 }
10037
10038 }
10039 }
10040
10041
10042
10043 static Lisp_Object
10044 follow_key (Lisp_Object keymap, Lisp_Object key)
10045 {
10046 return access_keymap (get_keymap (keymap, 0, 1),
10047 key, 1, 0, 1);
10048 }
10049
10050 static Lisp_Object
10051 active_maps (Lisp_Object first_event, Lisp_Object second_event)
10052 {
10053 Lisp_Object position
10054 = EVENT_HAS_PARAMETERS (first_event) ? EVENT_START (first_event) : Qnil;
10055
10056
10057 if (SYMBOLP (first_event)
10058 && EVENT_HAS_PARAMETERS (second_event)
10059 && EQ (first_event, POSN_POSN (EVENT_START (second_event))))
10060 {
10061 eassert (NILP (position));
10062 position = EVENT_START (second_event);
10063 }
10064 return Fcons (Qkeymap, Fcurrent_active_maps (Qt, position));
10065 }
10066
10067
10068
10069 typedef struct keyremap
10070 {
10071
10072 Lisp_Object parent;
10073
10074
10075 Lisp_Object map;
10076
10077
10078
10079
10080 int start, end;
10081 } keyremap;
10082
10083
10084
10085
10086
10087
10088
10089
10090
10091
10092
10093 static Lisp_Object
10094 access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
10095 bool do_funcall, unsigned int start, unsigned int end,
10096 Lisp_Object *keybuf)
10097 {
10098 Lisp_Object next;
10099 specpdl_ref count;
10100
10101 next = access_keymap (map, key, 1, 0, 1);
10102
10103
10104
10105 if (SYMBOLP (next) && !NILP (Ffboundp (next))
10106 && (ARRAYP (XSYMBOL (next)->u.s.function)
10107 || KEYMAPP (XSYMBOL (next)->u.s.function)))
10108 next = Fautoload_do_load (XSYMBOL (next)->u.s.function, next, Qnil);
10109
10110
10111
10112
10113 if (do_funcall && FUNCTIONP (next))
10114 {
10115 Lisp_Object tem, remap;
10116 tem = next;
10117
10118
10119 remap = Fvector (end - start + 1, keybuf + start);
10120
10121
10122
10123 count = SPECPDL_INDEX ();
10124 specbind (Qcurrent_key_remap_sequence, remap);
10125 next = unbind_to (count, call1 (next, prompt));
10126
10127
10128
10129 if (! (NILP (next) || VECTORP (next) || STRINGP (next)))
10130 signal_error ("Function returns invalid key sequence", tem);
10131 }
10132 return next;
10133 }
10134
10135
10136
10137
10138
10139
10140
10141
10142
10143
10144
10145
10146 static bool
10147 keyremap_step (Lisp_Object *keybuf, volatile keyremap *fkey,
10148 int input, bool doit, int *diff, Lisp_Object prompt)
10149 {
10150 Lisp_Object next, key;
10151 ptrdiff_t buf_start, buf_end;
10152
10153
10154 buf_start = fkey->start;
10155 buf_end = fkey->end;
10156
10157 key = keybuf[fkey->end++];
10158
10159 if (KEYMAPP (fkey->parent))
10160 next = access_keymap_keyremap (fkey->map, key, prompt, doit,
10161 buf_start, buf_end, keybuf);
10162 else
10163 next = Qnil;
10164
10165
10166
10167
10168 if ((VECTORP (next) || STRINGP (next)) && doit)
10169 {
10170 int len = XFIXNAT (Flength (next));
10171 int i;
10172
10173 *diff = len - (fkey->end - fkey->start);
10174
10175 if (READ_KEY_ELTS - input <= *diff)
10176 error ("Key sequence too long");
10177
10178
10179 if (*diff < 0)
10180 for (i = fkey->end; i < input; i++)
10181 keybuf[i + *diff] = keybuf[i];
10182 else if (*diff > 0)
10183 for (i = input - 1; i >= fkey->end; i--)
10184 keybuf[i + *diff] = keybuf[i];
10185
10186 for (i = 0; i < len; i++)
10187 keybuf[fkey->start + i]
10188 = Faref (next, make_fixnum (i));
10189
10190 fkey->start = fkey->end += *diff;
10191 fkey->map = fkey->parent;
10192
10193 return 1;
10194 }
10195
10196 fkey->map = get_keymap (next, 0, 1);
10197
10198
10199
10200 if (!CONSP (fkey->map))
10201 {
10202 fkey->end = ++fkey->start;
10203 fkey->map = fkey->parent;
10204 }
10205 return 0;
10206 }
10207
10208 static bool
10209 test_undefined (Lisp_Object binding)
10210 {
10211 return (NILP (binding)
10212 || EQ (binding, Qundefined)
10213 || (SYMBOLP (binding)
10214 && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined)));
10215 }
10216
10217 void init_raw_keybuf_count (void)
10218 {
10219 raw_keybuf_count = 0;
10220 }
10221
10222
10223
10224 #ifdef HAVE_TEXT_CONVERSION
10225
10226 static void
10227 restore_reading_key_sequence (int old_reading_key_sequence)
10228 {
10229 reading_key_sequence = old_reading_key_sequence;
10230
10231
10232
10233
10234 if (!old_reading_key_sequence)
10235 check_postponed_buffers ();
10236 }
10237
10238 #endif
10239
10240
10241
10242
10243
10244
10245
10246
10247
10248
10249
10250
10251
10252
10253
10254
10255
10256
10257
10258
10259
10260
10261
10262
10263
10264
10265
10266
10267
10268
10269
10270
10271
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283 static int
10284 read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
10285 bool dont_downcase_last, bool can_return_switch_frame,
10286 bool fix_current_buffer, bool prevent_redisplay,
10287 bool disable_text_conversion_p)
10288 {
10289 specpdl_ref count = SPECPDL_INDEX ();
10290
10291
10292 int t;
10293
10294
10295
10296 ptrdiff_t echo_start UNINIT;
10297 ptrdiff_t keys_start;
10298
10299 Lisp_Object current_binding = Qnil;
10300
10301
10302
10303 int first_unbound;
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313
10314
10315
10316
10317
10318 int mock_input = 0;
10319
10320
10321 bool used_mouse_menu_history[READ_KEY_ELTS] = {0};
10322
10323
10324
10325
10326
10327
10328
10329
10330
10331 keyremap fkey;
10332
10333
10334 keyremap keytran, indec;
10335
10336
10337
10338
10339 bool shift_translated = false;
10340
10341
10342
10343
10344 Lisp_Object delayed_switch_frame;
10345
10346 Lisp_Object original_uppercase UNINIT;
10347 int original_uppercase_position = -1;
10348
10349
10350 bool dummyflag = false;
10351
10352 #ifdef HAVE_TEXT_CONVERSION
10353 bool disabled_conversion;
10354
10355
10356 disabled_conversion = false;
10357 #endif
10358
10359 struct buffer *starting_buffer;
10360
10361
10362 Lisp_Object fake_prefixed_keys = Qnil;
10363
10364
10365
10366
10367
10368
10369
10370 delayed_switch_frame = Qnil;
10371
10372 if (INTERACTIVE)
10373 {
10374 if (!NILP (prompt))
10375 {
10376
10377
10378
10379 kset_echo_prompt (current_kboard, prompt);
10380
10381
10382
10383 current_kboard->immediate_echo = false;
10384 echo_now ();
10385 if (!echo_keystrokes_p ())
10386 current_kboard->immediate_echo = false;
10387 }
10388 else if (cursor_in_echo_area
10389
10390 && echo_keystrokes_p ())
10391
10392
10393 echo_dash ();
10394 }
10395
10396
10397
10398 if (INTERACTIVE)
10399 echo_start = echo_length ();
10400 keys_start = this_command_key_count;
10401 this_single_command_key_start = keys_start;
10402
10403 #ifdef HAVE_TEXT_CONVERSION
10404
10405
10406
10407
10408 record_unwind_protect_int (restore_reading_key_sequence,
10409 reading_key_sequence);
10410 reading_key_sequence = true;
10411 #endif
10412
10413
10414
10415 replay_entire_sequence:
10416
10417 indec.map = indec.parent = KVAR (current_kboard, Vinput_decode_map);
10418 fkey.map = fkey.parent = KVAR (current_kboard, Vlocal_function_key_map);
10419 keytran.map = keytran.parent = Vkey_translation_map;
10420 indec.start = indec.end = 0;
10421 fkey.start = fkey.end = 0;
10422 keytran.start = keytran.end = 0;
10423
10424
10425
10426
10427 replay_sequence:
10428
10429 starting_buffer = current_buffer;
10430 first_unbound = READ_KEY_ELTS + 1;
10431 Lisp_Object first_event = mock_input > 0 ? keybuf[0] : Qnil;
10432 Lisp_Object second_event = mock_input > 1 ? keybuf[1] : Qnil;
10433
10434
10435
10436
10437
10438
10439 current_binding = active_maps (first_event, second_event);
10440
10441
10442 t = 0;
10443 last_nonmenu_event = Qnil;
10444
10445
10446
10447 this_command_key_count = keys_start;
10448 if (INTERACTIVE && t < mock_input)
10449 echo_truncate (echo_start);
10450
10451
10452
10453
10454 #ifdef HAVE_TEXT_CONVERSION
10455 if (disable_text_conversion_p)
10456 {
10457 disable_text_conversion ();
10458 record_unwind_protect_void (resume_text_conversion);
10459 disabled_conversion = true;
10460 }
10461 #endif
10462
10463
10464
10465
10466 while (!NILP (current_binding)
10467
10468 ? KEYMAPP (current_binding)
10469
10470
10471
10472
10473
10474 : ( keytran.start < t))
10475 {
10476 Lisp_Object key;
10477 bool used_mouse_menu = false;
10478
10479
10480
10481
10482
10483
10484 int last_real_key_start;
10485
10486
10487
10488
10489
10490 ptrdiff_t echo_local_start UNINIT;
10491 int keys_local_start;
10492 Lisp_Object new_binding;
10493
10494 eassert (indec.end == t || (indec.end > t && indec.end <= mock_input));
10495 eassert (indec.start <= indec.end);
10496 eassert (fkey.start <= fkey.end);
10497 eassert (keytran.start <= keytran.end);
10498
10499
10500 eassert (fkey.end <= indec.start);
10501 eassert (keytran.end <= fkey.start);
10502
10503 if (
10504 first_unbound < keytran.start)
10505 {
10506
10507
10508
10509
10510 int i;
10511 for (i = first_unbound + 1; i < t; i++)
10512 keybuf[i - first_unbound - 1] = keybuf[i];
10513 mock_input = t - first_unbound - 1;
10514 indec.end = indec.start -= first_unbound + 1;
10515 indec.map = indec.parent;
10516 fkey.end = fkey.start -= first_unbound + 1;
10517 fkey.map = fkey.parent;
10518 keytran.end = keytran.start -= first_unbound + 1;
10519 keytran.map = keytran.parent;
10520 goto replay_sequence;
10521 }
10522
10523 if (t >= READ_KEY_ELTS)
10524 error ("Key sequence too long");
10525
10526 if (INTERACTIVE)
10527 echo_local_start = echo_length ();
10528 keys_local_start = this_command_key_count;
10529
10530 #ifdef HAVE_TEXT_CONVERSION
10531
10532
10533
10534
10535
10536
10537
10538
10539 if (!disabled_conversion && t && !used_mouse_menu
10540 && !disable_inhibit_text_conversion)
10541 {
10542 int i;
10543
10544
10545
10546
10547
10548
10549 for (i = 0; i < min (t, 10); ++i)
10550 {
10551 if (NUMBERP (keybuf[i])
10552 || (SYMBOLP (keybuf[i])
10553 && EQ (Fget (keybuf[i], Qevent_kind),
10554 Qfunction_key)))
10555 goto disable_text_conversion;
10556 }
10557
10558 goto replay_key;
10559
10560 disable_text_conversion:
10561 disable_text_conversion ();
10562 record_unwind_protect_void (resume_text_conversion);
10563 disabled_conversion = true;
10564 }
10565 #endif
10566
10567 replay_key:
10568
10569
10570
10571
10572 if (INTERACTIVE && t < mock_input)
10573 echo_truncate (echo_local_start);
10574 this_command_key_count = keys_local_start;
10575
10576
10577 last_real_key_start = t;
10578
10579
10580 if (t < mock_input)
10581 {
10582 key = keybuf[t];
10583 add_command_key (key);
10584 if (current_kboard->immediate_echo)
10585 {
10586
10587
10588 current_kboard->immediate_echo = false;
10589 echo_now ();
10590 }
10591 used_mouse_menu = used_mouse_menu_history[t];
10592 }
10593
10594
10595 else
10596 {
10597 {
10598 KBOARD *interrupted_kboard = current_kboard;
10599 struct frame *interrupted_frame = SELECTED_FRAME ();
10600
10601
10602 key = read_char (prevent_redisplay ? -2 : NILP (prompt),
10603 current_binding, last_nonmenu_event,
10604 &used_mouse_menu, NULL);
10605 used_mouse_menu_history[t] = used_mouse_menu;
10606 if ((FIXNUMP (key) && XFIXNUM (key) == -2)
10607
10608
10609
10610
10611
10612 || (interrupted_kboard != current_kboard))
10613 {
10614 bool found = false;
10615 struct kboard *k;
10616
10617 for (k = all_kboards; k; k = k->next_kboard)
10618 if (k == interrupted_kboard)
10619 found = true;
10620
10621 if (!found)
10622 {
10623
10624
10625 delayed_switch_frame = Qnil;
10626 goto replay_entire_sequence;
10627 }
10628
10629 if (!NILP (delayed_switch_frame))
10630 {
10631 kset_kbd_queue
10632 (interrupted_kboard,
10633 Fcons (delayed_switch_frame,
10634 KVAR (interrupted_kboard, kbd_queue)));
10635 delayed_switch_frame = Qnil;
10636 }
10637
10638 while (t > 0)
10639 kset_kbd_queue
10640 (interrupted_kboard,
10641 Fcons (keybuf[--t], KVAR (interrupted_kboard, kbd_queue)));
10642
10643
10644
10645 if (CONSP (KVAR (interrupted_kboard, kbd_queue))
10646 && (key = XCAR (KVAR (interrupted_kboard, kbd_queue)),
10647 !(EVENT_HAS_PARAMETERS (key)
10648 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (key)),
10649 Qswitch_frame))))
10650 {
10651 Lisp_Object frame;
10652 XSETFRAME (frame, interrupted_frame);
10653 kset_kbd_queue
10654 (interrupted_kboard,
10655 Fcons (make_lispy_switch_frame (frame),
10656 KVAR (interrupted_kboard, kbd_queue)));
10657 mock_input = 0;
10658 }
10659 else
10660 {
10661 if (FIXNUMP (key) && XFIXNUM (key) != -2)
10662 {
10663
10664
10665
10666 mock_input = 1;
10667 keybuf[0] = key;
10668 }
10669 else
10670 {
10671 mock_input = 0;
10672 }
10673 }
10674 goto replay_entire_sequence;
10675 }
10676 }
10677
10678
10679
10680 if (EQ (key, Qt))
10681 {
10682 unbind_to (count, Qnil);
10683 return -1;
10684 }
10685
10686
10687
10688
10689 if (FIXNUMP (key) && XFIXNUM (key) == -1)
10690 {
10691 t = 0;
10692
10693
10694 dummyflag = true;
10695 break;
10696 }
10697
10698
10699
10700 if (BUFFERP (key))
10701 {
10702 timer_resume_idle ();
10703
10704 mock_input = t;
10705
10706
10707
10708
10709 if (fix_current_buffer)
10710 {
10711 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10712 Fkill_emacs (Qnil, Qnil);
10713 if (XBUFFER (XWINDOW (selected_window)->contents)
10714 != current_buffer)
10715 Fset_buffer (XWINDOW (selected_window)->contents);
10716 }
10717
10718 goto replay_sequence;
10719 }
10720
10721
10722
10723
10724 if (FIXNUMP (key)
10725 && XFIXNUM (key) == quit_char
10726 && current_buffer != starting_buffer)
10727 {
10728 GROW_RAW_KEYBUF;
10729 ASET (raw_keybuf, raw_keybuf_count, key);
10730 raw_keybuf_count++;
10731 keybuf[t++] = key;
10732 mock_input = t;
10733 Vquit_flag = Qnil;
10734 goto replay_sequence;
10735 }
10736
10737 Vquit_flag = Qnil;
10738
10739 if (EVENT_HAS_PARAMETERS (key)
10740
10741 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (key)), Qswitch_frame))
10742 {
10743
10744
10745
10746 if (t > 0 || !can_return_switch_frame)
10747 {
10748 delayed_switch_frame = key;
10749 goto replay_key;
10750 }
10751 }
10752
10753 if (NILP (first_event))
10754 {
10755 first_event = key;
10756
10757
10758
10759
10760
10761
10762 if (fix_current_buffer
10763 && (XBUFFER (XWINDOW (selected_window)->contents)
10764 != current_buffer))
10765 Fset_buffer (XWINDOW (selected_window)->contents);
10766 current_binding = active_maps (first_event, Qnil);
10767 }
10768
10769 GROW_RAW_KEYBUF;
10770 ASET (raw_keybuf, raw_keybuf_count,
10771
10772
10773 CONSP (key) ? Fcopy_sequence (key) : key);
10774 raw_keybuf_count++;
10775 }
10776
10777
10778
10779
10780
10781
10782
10783
10784
10785
10786
10787
10788
10789
10790
10791 if (EVENT_HAS_PARAMETERS (key))
10792 {
10793 Lisp_Object kind = EVENT_HEAD_KIND (EVENT_HEAD (key));
10794 if (EQ (kind, Qmouse_click) || EQ (kind, Qtouchscreen))
10795 {
10796 Lisp_Object window = POSN_WINDOW (EVENT_START (key));
10797 Lisp_Object posn = POSN_POSN (EVENT_START (key));
10798
10799 if (CONSP (posn)
10800 || (!NILP (fake_prefixed_keys)
10801 && !NILP (Fmemq (key, fake_prefixed_keys))))
10802 {
10803
10804
10805
10806 if (t > 0)
10807 last_real_key_start = t - 1;
10808 }
10809
10810 if (last_real_key_start == 0)
10811 {
10812
10813
10814
10815
10816 if (WINDOWP (window)
10817 && BUFFERP (XWINDOW (window)->contents)
10818 && XBUFFER (XWINDOW (window)->contents) != current_buffer)
10819 {
10820 keybuf[t] = key;
10821 mock_input = t + 1;
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833 record_unwind_current_buffer ();
10834
10835 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10836 Fkill_emacs (Qnil, Qnil);
10837 set_buffer_internal (XBUFFER (XWINDOW (window)->contents));
10838 goto replay_sequence;
10839 }
10840 }
10841
10842
10843
10844 if (SYMBOLP (posn)
10845 && (NILP (fake_prefixed_keys)
10846 || NILP (Fmemq (key, fake_prefixed_keys))))
10847 {
10848 if (READ_KEY_ELTS - t <= 1)
10849 error ("Key sequence too long");
10850
10851 keybuf[t] = posn;
10852 keybuf[t + 1] = key;
10853 mock_input = t + 2;
10854
10855
10856
10857
10858
10859 fake_prefixed_keys = Fcons (key, fake_prefixed_keys);
10860 goto replay_key;
10861 }
10862 }
10863 else if (CONSP (XCDR (key))
10864 && CONSP (xevent_start (key))
10865 && CONSP (XCDR (xevent_start (key))))
10866 {
10867 Lisp_Object posn;
10868
10869 posn = POSN_POSN (xevent_start (key));
10870
10871
10872 if ((EQ (posn, Qmenu_bar) || EQ (posn, Qtab_bar)
10873 || EQ (posn, Qtool_bar))
10874
10875
10876
10877
10878
10879
10880 && (mock_input <= t))
10881 {
10882 if (READ_KEY_ELTS - t <= 1)
10883 error ("Key sequence too long");
10884 keybuf[t] = posn;
10885 keybuf[t + 1] = key;
10886
10887
10888
10889 POSN_SET_POSN (xevent_start (key), list1 (posn));
10890
10891 mock_input = t + 2;
10892 goto replay_sequence;
10893 }
10894 else if (CONSP (posn))
10895 {
10896
10897
10898
10899 if (last_real_key_start == t && t > 0)
10900 last_real_key_start = t - 1;
10901 }
10902 }
10903 }
10904
10905
10906
10907 new_binding = follow_key (current_binding, key);
10908
10909
10910 if (!NILP (new_binding))
10911
10912
10913
10914
10915
10916
10917 first_unbound = max (t + 1, first_unbound);
10918 else
10919 {
10920 Lisp_Object head;
10921
10922
10923 first_unbound = min (t, first_unbound);
10924
10925 head = EVENT_HEAD (key);
10926
10927 if (SYMBOLP (head))
10928 {
10929 Lisp_Object breakdown;
10930 int modifiers;
10931
10932 breakdown = parse_modifiers (head);
10933 modifiers = XFIXNUM (XCAR (XCDR (breakdown)));
10934
10935
10936
10937
10938
10939
10940
10941
10942
10943 if (modifiers & (up_modifier | down_modifier
10944 | drag_modifier
10945 | double_modifier | triple_modifier))
10946 {
10947 while (modifiers & (up_modifier | down_modifier
10948 | drag_modifier
10949 | double_modifier | triple_modifier))
10950 {
10951 Lisp_Object new_head, new_click;
10952 if (modifiers & triple_modifier)
10953 modifiers ^= (double_modifier | triple_modifier);
10954 else if (modifiers & double_modifier)
10955 modifiers &= ~double_modifier;
10956 else if (modifiers & drag_modifier)
10957 modifiers &= ~drag_modifier;
10958 else
10959 {
10960
10961
10962
10963
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979
10980
10981
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996
10997
10998
10999
11000
11001
11002
11003
11004 if (indec.end > last_real_key_start)
11005 {
11006 indec.end = indec.start
11007 = min (last_real_key_start, indec.start);
11008 indec.map = indec.parent;
11009 if (fkey.end > last_real_key_start)
11010 {
11011 fkey.end = fkey.start
11012 = min (last_real_key_start, fkey.start);
11013 fkey.map = fkey.parent;
11014 if (keytran.end > last_real_key_start)
11015 {
11016 keytran.end = keytran.start
11017 = min (last_real_key_start, keytran.start);
11018 keytran.map = keytran.parent;
11019 }
11020 }
11021 }
11022 if (t == last_real_key_start)
11023 {
11024 mock_input = 0;
11025 goto replay_key;
11026 }
11027 else
11028 {
11029 mock_input = last_real_key_start;
11030 goto replay_sequence;
11031 }
11032 }
11033
11034 new_head
11035 = apply_modifiers (modifiers, XCAR (breakdown));
11036 new_click = list2 (new_head, EVENT_START (key));
11037
11038
11039 new_binding = follow_key (current_binding, new_click);
11040
11041
11042 if (!NILP (new_binding))
11043 {
11044 current_binding = new_binding;
11045 key = new_click;
11046 break;
11047 }
11048
11049 }
11050 }
11051 }
11052 }
11053 current_binding = new_binding;
11054
11055 keybuf[t++] = key;
11056
11057
11058
11059
11060 if (!used_mouse_menu)
11061 last_nonmenu_event = key;
11062
11063
11064 this_single_command_key_start = this_command_key_count - t;
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075 if (this_single_command_key_start < 0)
11076 this_single_command_key_start = 0;
11077
11078
11079
11080 while (indec.end < t)
11081 {
11082 bool done;
11083 int diff;
11084
11085 done = keyremap_step (keybuf, &indec, max (t, mock_input),
11086 true, &diff, prompt);
11087 if (done)
11088 {
11089 mock_input = diff + max (t, mock_input);
11090 goto replay_sequence;
11091 }
11092 }
11093
11094 if (!KEYMAPP (current_binding)
11095 && !test_undefined (current_binding)
11096 && indec.start >= t)
11097
11098
11099
11100
11101
11102
11103 {
11104 if (fkey.start < t)
11105 (fkey.start = fkey.end = t, fkey.map = fkey.parent);
11106 }
11107 else
11108
11109
11110
11111 while (fkey.end < indec.start)
11112 {
11113 bool done;
11114 int diff;
11115
11116 done = keyremap_step (keybuf, &fkey,
11117 max (t, mock_input),
11118
11119
11120
11121 (fkey.end + 1 == t
11122 && test_undefined (current_binding)),
11123 &diff, prompt);
11124 if (done)
11125 {
11126 mock_input = diff + max (t, mock_input);
11127
11128 indec.end += diff;
11129 indec.start += diff;
11130
11131 goto replay_sequence;
11132 }
11133 }
11134
11135
11136
11137 while (keytran.end < fkey.start)
11138 {
11139 bool done;
11140 int diff;
11141
11142 done = keyremap_step (keybuf, &keytran, max (t, mock_input),
11143 true, &diff, prompt);
11144 if (done)
11145 {
11146 mock_input = diff + max (t, mock_input);
11147
11148 indec.end += diff;
11149 indec.start += diff;
11150 fkey.end += diff;
11151 fkey.start += diff;
11152
11153 goto replay_sequence;
11154 }
11155 }
11156
11157
11158
11159
11160
11161 if (NILP (current_binding)
11162 && keytran.start >= t
11163 && FIXNUMP (key)
11164 && translate_upper_case_key_bindings)
11165 {
11166 Lisp_Object new_key;
11167 EMACS_INT k = XFIXNUM (key);
11168
11169 if (k & shift_modifier)
11170 XSETINT (new_key, k & ~shift_modifier);
11171 else if (CHARACTERP (make_fixnum (k & ~CHAR_MODIFIER_MASK)))
11172 {
11173 int dc = downcase (k & ~CHAR_MODIFIER_MASK);
11174 if (dc == (k & ~CHAR_MODIFIER_MASK))
11175 goto not_upcase;
11176 XSETINT (new_key, dc | (k & CHAR_MODIFIER_MASK));
11177 }
11178 else
11179 goto not_upcase;
11180
11181 original_uppercase = key;
11182 original_uppercase_position = t - 1;
11183
11184
11185
11186
11187 keybuf[t - 1] = new_key;
11188 mock_input = max (t, mock_input);
11189 shift_translated = true;
11190
11191 goto replay_sequence;
11192 }
11193
11194 not_upcase:
11195 if (NILP (current_binding)
11196 && help_char_p (EVENT_HEAD (key)) && t > 1)
11197 {
11198 read_key_sequence_cmd = Vprefix_help_command;
11199
11200
11201 dummyflag = true;
11202 break;
11203 }
11204
11205
11206
11207
11208
11209 if (NILP (current_binding)
11210 && keytran.start >= t)
11211 {
11212 Lisp_Object breakdown = parse_modifiers (key);
11213 int modifiers
11214 = CONSP (breakdown) ? (XFIXNUM (XCAR (XCDR (breakdown)))) : 0;
11215
11216 if (translate_upper_case_key_bindings
11217 && (modifiers & shift_modifier
11218
11219 || (FIXNUMP (key)
11220 && (KEY_TO_CHAR (key)
11221 < XCHAR_TABLE (BVAR (current_buffer,
11222 downcase_table))->header.size)
11223 && uppercasep (KEY_TO_CHAR (key)))))
11224 {
11225 Lisp_Object new_key
11226 = (modifiers & shift_modifier
11227 ? apply_modifiers (modifiers & ~shift_modifier,
11228 XCAR (breakdown))
11229 : make_fixnum (downcase (KEY_TO_CHAR (key)) | modifiers));
11230
11231 original_uppercase = key;
11232 original_uppercase_position = t - 1;
11233
11234
11235
11236
11237 keybuf[t - 1] = new_key;
11238 mock_input = max (t, mock_input);
11239
11240
11241
11242
11243 fkey.start = fkey.end = 0;
11244 keytran.start = keytran.end = 0;
11245 shift_translated = true;
11246
11247 goto replay_sequence;
11248 }
11249 }
11250 }
11251 if (!dummyflag)
11252 read_key_sequence_cmd = current_binding;
11253 read_key_sequence_remapped
11254
11255
11256
11257 = SYMBOLP (read_key_sequence_cmd)
11258 ? Fcommand_remapping (read_key_sequence_cmd, Qnil, Qnil)
11259 : Qnil;
11260
11261 unread_switch_frame = delayed_switch_frame;
11262 unbind_to (count, Qnil);
11263
11264
11265
11266 if ((dont_downcase_last || NILP (current_binding))
11267 && t > 0
11268 && t - 1 == original_uppercase_position)
11269 {
11270 keybuf[t - 1] = original_uppercase;
11271 shift_translated = false;
11272 }
11273
11274 if (shift_translated)
11275 Vthis_command_keys_shift_translated = Qt;
11276
11277
11278
11279
11280
11281
11282
11283
11284
11285
11286 for (; t < mock_input; t++)
11287 add_command_key (keybuf[t]);
11288 echo_update ();
11289
11290 return t;
11291 }
11292
11293 static Lisp_Object
11294 read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo,
11295 Lisp_Object dont_downcase_last,
11296 Lisp_Object can_return_switch_frame,
11297 Lisp_Object cmd_loop, bool allow_string,
11298 bool disable_text_conversion)
11299 {
11300 specpdl_ref count = SPECPDL_INDEX ();
11301
11302 if (!NILP (prompt))
11303 CHECK_STRING (prompt);
11304 maybe_quit ();
11305
11306 specbind (Qinput_method_exit_on_first_char,
11307 (NILP (cmd_loop) ? Qt : Qnil));
11308 specbind (Qinput_method_use_echo_area,
11309 (NILP (cmd_loop) ? Qt : Qnil));
11310
11311 if (NILP (continue_echo))
11312 {
11313 this_command_key_count = 0;
11314 this_single_command_key_start = 0;
11315 }
11316
11317 #ifdef HAVE_WINDOW_SYSTEM
11318 if (display_hourglass_p)
11319 cancel_hourglass ();
11320 #endif
11321
11322 raw_keybuf_count = 0;
11323 Lisp_Object keybuf[READ_KEY_ELTS];
11324 int i = read_key_sequence (keybuf, prompt, ! NILP (dont_downcase_last),
11325 ! NILP (can_return_switch_frame), false, false,
11326 disable_text_conversion);
11327
11328 #if 0
11329
11330
11331 #ifdef HAVE_WINDOW_SYSTEM
11332 if (display_hourglass_p)
11333 start_hourglass ();
11334 #endif
11335 #endif
11336
11337 if (i == -1)
11338 {
11339 Vquit_flag = Qt;
11340 maybe_quit ();
11341 }
11342
11343 return unbind_to (count,
11344 ((allow_string ? make_event_array : Fvector)
11345 (i, keybuf)));
11346 }
11347
11348 DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 6, 0,
11349 doc:
11350
11351
11352
11353
11354
11355
11356
11357
11358
11359
11360
11361
11362
11363
11364
11365
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377
11378
11379
11380
11381
11382
11383
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395
11396
11397
11398
11399 )
11400 (Lisp_Object prompt, Lisp_Object continue_echo, Lisp_Object dont_downcase_last,
11401 Lisp_Object can_return_switch_frame, Lisp_Object cmd_loop,
11402 Lisp_Object disable_text_conversion)
11403 {
11404 return read_key_sequence_vs (prompt, continue_echo, dont_downcase_last,
11405 can_return_switch_frame, cmd_loop, true,
11406 !NILP (disable_text_conversion));
11407 }
11408
11409 DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector,
11410 Sread_key_sequence_vector, 1, 6, 0,
11411 doc: )
11412 (Lisp_Object prompt, Lisp_Object continue_echo, Lisp_Object dont_downcase_last,
11413 Lisp_Object can_return_switch_frame, Lisp_Object cmd_loop,
11414 Lisp_Object disable_text_conversion)
11415 {
11416 return read_key_sequence_vs (prompt, continue_echo, dont_downcase_last,
11417 can_return_switch_frame, cmd_loop, false,
11418 !NILP (disable_text_conversion));
11419 }
11420
11421
11422
11423 bool
11424 detect_input_pending (void)
11425 {
11426 return input_pending || get_input_pending (0);
11427 }
11428
11429
11430
11431
11432 bool
11433 detect_input_pending_ignore_squeezables (void)
11434 {
11435 return input_pending || get_input_pending (READABLE_EVENTS_IGNORE_SQUEEZABLES);
11436 }
11437
11438
11439
11440 bool
11441 detect_input_pending_run_timers (bool do_display)
11442 {
11443 unsigned old_timers_run = timers_run;
11444
11445 if (!input_pending)
11446 get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW);
11447
11448 if (old_timers_run != timers_run && do_display)
11449 redisplay_preserve_echo_area (8);
11450
11451 return input_pending;
11452 }
11453
11454
11455
11456
11457
11458 void
11459 clear_input_pending (void)
11460 {
11461 input_pending = false;
11462 }
11463
11464
11465
11466
11467
11468
11469
11470 bool
11471 requeued_events_pending_p (void)
11472 {
11473 return (CONSP (Vunread_command_events));
11474 }
11475
11476 DEFUN ("input-pending-p", Finput_pending_p, Sinput_pending_p, 0, 1, 0,
11477 doc:
11478
11479
11480
11481 )
11482 (Lisp_Object check_timers)
11483 {
11484 if (CONSP (Vunread_command_events)
11485 || !NILP (Vunread_post_input_method_events)
11486 || !NILP (Vunread_input_method_events))
11487 return (Qt);
11488
11489
11490 process_special_events ();
11491
11492 return (get_input_pending ((NILP (check_timers)
11493 ? 0 : READABLE_EVENTS_DO_TIMERS_NOW)
11494 | READABLE_EVENTS_FILTER_EVENTS)
11495 ? Qt : Qnil);
11496 }
11497
11498
11499
11500 static void
11501 update_recent_keys (int new_size, int kept_keys)
11502 {
11503 int osize = ASIZE (recent_keys);
11504 eassert (recent_keys_index < osize);
11505 eassert (kept_keys <= min (osize, new_size));
11506 Lisp_Object v = make_nil_vector (new_size);
11507 int i, idx;
11508 for (i = 0; i < kept_keys; ++i)
11509 {
11510 idx = recent_keys_index - kept_keys + i;
11511 while (idx < 0)
11512 idx += osize;
11513 ASET (v, i, AREF (recent_keys, idx));
11514 }
11515 recent_keys = v;
11516 total_keys = kept_keys;
11517 recent_keys_index = total_keys % new_size;
11518 lossage_limit = new_size;
11519
11520 }
11521
11522 DEFUN ("lossage-size", Flossage_size, Slossage_size, 0, 1,
11523 "(list (read-number \"Set maximum keystrokes to: \" (lossage-size)))",
11524 doc:
11525
11526
11527
11528 )
11529 (Lisp_Object arg)
11530 {
11531 if (NILP(arg))
11532 return make_fixnum (lossage_limit);
11533
11534 if (!FIXNATP (arg))
11535 user_error ("Value must be a positive integer");
11536 ptrdiff_t osize = ASIZE (recent_keys);
11537 eassert (lossage_limit == osize);
11538 int min_size = MIN_NUM_RECENT_KEYS;
11539 EMACS_INT new_size = XFIXNAT (arg);
11540
11541 if (new_size == osize)
11542 return make_fixnum (lossage_limit);
11543
11544 if (new_size < min_size)
11545 {
11546 AUTO_STRING (fmt, "Value must be >= %d");
11547 Fsignal (Quser_error, list1 (CALLN (Fformat, fmt, make_fixnum (min_size))));
11548 }
11549 if (new_size > MAX_NUM_RECENT_KEYS)
11550 {
11551 AUTO_STRING (fmt, "Value must be <= %d");
11552 Fsignal (Quser_error, list1 (CALLN (Fformat, fmt,
11553 make_fixnum (MAX_NUM_RECENT_KEYS))));
11554 }
11555
11556 int kept_keys = new_size > osize ? total_keys : min (new_size, total_keys);
11557 update_recent_keys (new_size, kept_keys);
11558
11559 return make_fixnum (lossage_limit);
11560 }
11561
11562 DEFUN ("recent-keys", Frecent_keys, Srecent_keys, 0, 1, 0,
11563 doc:
11564
11565 )
11566 (Lisp_Object include_cmds)
11567 {
11568 bool cmds = !NILP (include_cmds);
11569
11570 if (!total_keys
11571 || (cmds && total_keys < lossage_limit))
11572 return Fvector (total_keys,
11573 XVECTOR (recent_keys)->contents);
11574 else
11575 {
11576 Lisp_Object es = Qnil;
11577 int i = (total_keys < lossage_limit
11578 ? 0 : recent_keys_index);
11579 eassert (recent_keys_index < lossage_limit);
11580 do
11581 {
11582 Lisp_Object e = AREF (recent_keys, i);
11583 if (cmds || !CONSP (e) || !NILP (XCAR (e)))
11584 es = Fcons (e, es);
11585 if (++i >= lossage_limit)
11586 i = 0;
11587 } while (i != recent_keys_index);
11588 es = Fnreverse (es);
11589 return Fvconcat (1, &es);
11590 }
11591 }
11592
11593 DEFUN ("this-command-keys", Fthis_command_keys, Sthis_command_keys, 0, 0, 0,
11594 doc:
11595
11596
11597
11598
11599 )
11600 (void)
11601 {
11602 return make_event_array (this_command_key_count,
11603 XVECTOR (this_command_keys)->contents);
11604 }
11605
11606 DEFUN ("set--this-command-keys", Fset__this_command_keys,
11607 Sset__this_command_keys, 1, 1, 0,
11608 doc:
11609
11610 )
11611 (Lisp_Object keys)
11612 {
11613 CHECK_STRING (keys);
11614
11615 this_command_key_count = 0;
11616 this_single_command_key_start = 0;
11617
11618 ptrdiff_t charidx = 0, byteidx = 0;
11619 int key0 = fetch_string_char_advance (keys, &charidx, &byteidx);
11620 if (CHAR_BYTE8_P (key0))
11621 key0 = CHAR_TO_BYTE8 (key0);
11622
11623
11624
11625 if (key0 == 248)
11626 add_command_key (make_fixnum ('x' | meta_modifier));
11627 else
11628 add_command_key (make_fixnum (key0));
11629 for (ptrdiff_t i = 1; i < SCHARS (keys); i++)
11630 {
11631 int key_i = fetch_string_char_advance (keys, &charidx, &byteidx);
11632 if (CHAR_BYTE8_P (key_i))
11633 key_i = CHAR_TO_BYTE8 (key_i);
11634 add_command_key (make_fixnum (key_i));
11635 }
11636 return Qnil;
11637 }
11638
11639 DEFUN ("this-command-keys-vector", Fthis_command_keys_vector, Sthis_command_keys_vector, 0, 0, 0,
11640 doc:
11641
11642
11643
11644 )
11645 (void)
11646 {
11647 return Fvector (this_command_key_count,
11648 XVECTOR (this_command_keys)->contents);
11649 }
11650
11651 DEFUN ("this-single-command-keys", Fthis_single_command_keys,
11652 Sthis_single_command_keys, 0, 0, 0,
11653 doc:
11654
11655
11656 )
11657 (void)
11658 {
11659 ptrdiff_t nkeys = this_command_key_count - this_single_command_key_start;
11660 return Fvector (nkeys < 0 ? 0 : nkeys,
11661 (XVECTOR (this_command_keys)->contents
11662 + this_single_command_key_start));
11663 }
11664
11665 DEFUN ("this-single-command-raw-keys", Fthis_single_command_raw_keys,
11666 Sthis_single_command_raw_keys, 0, 0, 0,
11667 doc:
11668
11669
11670
11671
11672 )
11673 (void)
11674 {
11675 return Fvector (raw_keybuf_count, XVECTOR (raw_keybuf)->contents);
11676 }
11677
11678 DEFUN ("clear-this-command-keys", Fclear_this_command_keys,
11679 Sclear_this_command_keys, 0, 1, 0,
11680 doc:
11681
11682 )
11683 (Lisp_Object keep_record)
11684 {
11685 int i;
11686
11687 this_command_key_count = 0;
11688
11689 if (NILP (keep_record))
11690 {
11691 for (i = 0; i < ASIZE (recent_keys); ++i)
11692 ASET (recent_keys, i, Qnil);
11693 total_keys = 0;
11694 recent_keys_index = 0;
11695 }
11696 return Qnil;
11697 }
11698
11699 DEFUN ("recursion-depth", Frecursion_depth, Srecursion_depth, 0, 0, 0,
11700 doc: )
11701 (void)
11702 {
11703 EMACS_INT sum;
11704 ckd_add (&sum, command_loop_level, minibuf_level);
11705 return make_fixnum (sum);
11706 }
11707
11708 DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1,
11709 "FOpen dribble file: ",
11710 doc:
11711
11712
11713
11714
11715
11716
11717
11718
11719
11720
11721 )
11722 (Lisp_Object file)
11723 {
11724 if (dribble)
11725 {
11726 block_input ();
11727 emacs_fclose (dribble);
11728 unblock_input ();
11729 dribble = 0;
11730 }
11731 if (!NILP (file))
11732 {
11733 int fd;
11734 Lisp_Object encfile;
11735
11736 file = Fexpand_file_name (file, Qnil);
11737 encfile = ENCODE_FILE (file);
11738 fd = emacs_open (SSDATA (encfile), O_WRONLY | O_CREAT | O_EXCL, 0600);
11739 if (fd < 0 && errno == EEXIST
11740 && (emacs_unlink (SSDATA (encfile)) == 0 || errno == ENOENT))
11741 fd = emacs_open (SSDATA (encfile), O_WRONLY | O_CREAT | O_EXCL, 0600);
11742 dribble = fd < 0 ? 0 : emacs_fdopen (fd, "w");
11743 if (dribble == 0)
11744 report_file_error ("Opening dribble", file);
11745 }
11746 return Qnil;
11747 }
11748
11749 DEFUN ("discard-input", Fdiscard_input, Sdiscard_input, 0, 0, 0,
11750 doc:
11751 )
11752 (void)
11753 {
11754 if (!NILP (KVAR (current_kboard, defining_kbd_macro)))
11755 {
11756
11757 Fcancel_kbd_macro_events ();
11758 end_kbd_macro ();
11759 }
11760
11761 Vunread_command_events = Qnil;
11762
11763 discard_tty_input ();
11764
11765 kbd_fetch_ptr = kbd_store_ptr;
11766 input_pending = false;
11767
11768 return Qnil;
11769 }
11770
11771 DEFUN ("suspend-emacs", Fsuspend_emacs, Ssuspend_emacs, 0, 1, "",
11772 doc:
11773
11774
11775
11776
11777
11778
11779
11780
11781
11782
11783 )
11784 (Lisp_Object stuffstring)
11785 {
11786 specpdl_ref count = SPECPDL_INDEX ();
11787 int old_height, old_width;
11788 int width, height;
11789
11790 if (tty_list && tty_list->next)
11791 error ("There are other tty frames open; close them before suspending Emacs");
11792
11793 if (!NILP (stuffstring))
11794 CHECK_STRING (stuffstring);
11795
11796 run_hook (intern ("suspend-hook"));
11797
11798 get_tty_size (fileno (CURTTY ()->input), &old_width, &old_height);
11799 reset_all_sys_modes ();
11800
11801
11802 record_unwind_protect_void (init_all_sys_modes);
11803 stuff_buffered_input (stuffstring);
11804 if (cannot_suspend)
11805 sys_subshell ();
11806 else
11807 sys_suspend ();
11808 unbind_to (count, Qnil);
11809
11810
11811
11812
11813 get_tty_size (fileno (CURTTY ()->input), &width, &height);
11814 if (width != old_width || height != old_height)
11815 change_frame_size (SELECTED_FRAME (), width, height, false, false, false);
11816
11817 run_hook (intern ("suspend-resume-hook"));
11818
11819 return Qnil;
11820 }
11821
11822
11823
11824
11825 void
11826 stuff_buffered_input (Lisp_Object stuffstring)
11827 {
11828 #ifdef SIGTSTP
11829 register unsigned char *p;
11830
11831 if (STRINGP (stuffstring))
11832 {
11833 register ptrdiff_t count;
11834
11835 p = SDATA (stuffstring);
11836 count = SBYTES (stuffstring);
11837 while (count-- > 0)
11838 stuff_char (*p++);
11839 stuff_char ('\n');
11840 }
11841
11842
11843
11844
11845
11846
11847
11848 for (; kbd_fetch_ptr != kbd_store_ptr;
11849 kbd_fetch_ptr = next_kbd_event (kbd_fetch_ptr))
11850 {
11851
11852 if (kbd_fetch_ptr->kind == ASCII_KEYSTROKE_EVENT)
11853 stuff_char (kbd_fetch_ptr->ie.code);
11854
11855 clear_event (&kbd_fetch_ptr->ie);
11856 }
11857
11858 input_pending = false;
11859 #endif
11860 }
11861
11862 void
11863 set_waiting_for_input (struct timespec *time_to_clear)
11864 {
11865 input_available_clear_time = time_to_clear;
11866
11867
11868 waiting_for_input = true;
11869
11870
11871
11872 if (!NILP (Vquit_flag))
11873 quit_throw_to_read_char (0);
11874 }
11875
11876 void
11877 clear_waiting_for_input (void)
11878 {
11879
11880 waiting_for_input = false;
11881 input_available_clear_time = 0;
11882 }
11883
11884
11885
11886
11887
11888
11889
11890 static void
11891 handle_interrupt_signal (int sig)
11892 {
11893
11894 struct terminal *terminal = get_named_terminal (DEV_TTY);
11895 if (!terminal)
11896 {
11897
11898
11899
11900
11901 Vquit_flag = Qkill_emacs;
11902 }
11903 else
11904 {
11905
11906
11907
11908
11909
11910
11911 internal_last_event_frame = terminal->display_info.tty->top_frame;
11912
11913 handle_interrupt (1);
11914 }
11915 }
11916
11917 static void
11918 deliver_interrupt_signal (int sig)
11919 {
11920 deliver_process_signal (sig, handle_interrupt_signal);
11921 }
11922
11923
11924
11925 static void
11926 write_stdout (char const *msg)
11927 {
11928 ignore_value (write (STDOUT_FILENO, msg, strlen (msg)));
11929 }
11930
11931
11932 static int
11933 read_stdin (void)
11934 {
11935 char c;
11936 return read (STDIN_FILENO, &c, 1) == 1 ? c : EOF;
11937 }
11938
11939
11940
11941
11942 static int volatile force_quit_count;
11943
11944
11945
11946
11947
11948
11949
11950
11951
11952
11953
11954
11955 static void
11956 handle_interrupt (bool in_signal_handler)
11957 {
11958 char c;
11959
11960 cancel_echoing ();
11961
11962
11963 if (!NILP (Vquit_flag) && get_named_terminal (DEV_TTY))
11964 {
11965 if (! in_signal_handler)
11966 {
11967
11968
11969
11970 sigset_t blocked;
11971 sigemptyset (&blocked);
11972 sigaddset (&blocked, SIGINT);
11973 pthread_sigmask (SIG_BLOCK, &blocked, 0);
11974 fflush (stdout);
11975 }
11976
11977 reset_all_sys_modes ();
11978
11979 #ifdef SIGTSTP
11980
11981
11982
11983
11984
11985
11986
11987 sys_suspend ();
11988 #else
11989
11990
11991
11992 write_stdout ("No support for stopping a process"
11993 " on this operating system;\n"
11994 "you can continue or abort.\n");
11995 #endif
11996 #ifdef MSDOS
11997
11998
11999 cursor_to (SELECTED_FRAME (), 0, 0);
12000 #endif
12001
12002 write_stdout ("Emacs is resuming after an emergency escape.\n");
12003
12004
12005
12006 if (!gc_in_progress)
12007 {
12008 write_stdout ("Auto-save? (y or n) ");
12009 c = read_stdin ();
12010 if (c == 'y' || c == 'Y')
12011 {
12012 Fdo_auto_save (Qt, Qnil);
12013 #ifdef MSDOS
12014 write_stdout ("\r\nAuto-save done");
12015 #else
12016 write_stdout ("Auto-save done\n");
12017 #endif
12018 }
12019 while (c != '\n')
12020 c = read_stdin ();
12021 }
12022 else
12023 {
12024
12025 Vinhibit_quit = Qnil;
12026 write_stdout
12027 (
12028 #ifdef MSDOS
12029 "\r\n"
12030 #endif
12031 "Garbage collection in progress; cannot auto-save now\r\n"
12032 "but will instead do a real quit"
12033 " after garbage collection ends\r\n");
12034 }
12035
12036 #ifdef MSDOS
12037 write_stdout ("\r\nAbort? (y or n) ");
12038 #else
12039 write_stdout ("Abort (and dump core)? (y or n) ");
12040 #endif
12041 c = read_stdin ();
12042 if (c == 'y' || c == 'Y')
12043 emacs_abort ();
12044 while (c != '\n')
12045 c = read_stdin ();
12046 #ifdef MSDOS
12047 write_stdout ("\r\nContinuing...\r\n");
12048 #else
12049 write_stdout ("Continuing...\n");
12050 #endif
12051 init_all_sys_modes ();
12052 }
12053 else
12054 {
12055
12056 int count = NILP (Vquit_flag) ? 1 : force_quit_count + 1;
12057 force_quit_count = count;
12058 if (count == 3)
12059 Vinhibit_quit = Qnil;
12060 Vquit_flag = Qt;
12061 }
12062
12063 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
12064
12065
12066
12067
12068
12069
12070
12071
12072 #ifndef HAVE_NS
12073 #ifdef THREADS_ENABLED
12074
12075
12076
12077 if (in_signal_handler)
12078 maybe_reacquire_global_lock ();
12079 #endif
12080 if (waiting_for_input && !echoing)
12081 quit_throw_to_read_char (in_signal_handler);
12082 #endif
12083 }
12084
12085
12086
12087 static void
12088 quit_throw_to_read_char (bool from_signal)
12089 {
12090
12091
12092 if (!from_signal && EQ (Vquit_flag, Qkill_emacs))
12093 Fkill_emacs (Qnil, Qnil);
12094
12095
12096 clear_waiting_for_input ();
12097 input_pending = false;
12098
12099 Vunread_command_events = Qnil;
12100
12101 if (FRAMEP (internal_last_event_frame)
12102 && !EQ (internal_last_event_frame, selected_frame))
12103 do_switch_frame (make_lispy_switch_frame (internal_last_event_frame),
12104 0, 0, Qnil);
12105
12106 sys_longjmp (getcjmp, 1);
12107 }
12108
12109 DEFUN ("set-input-interrupt-mode", Fset_input_interrupt_mode,
12110 Sset_input_interrupt_mode, 1, 1, 0,
12111 doc:
12112
12113
12114
12115 )
12116 (Lisp_Object interrupt)
12117 {
12118 bool new_interrupt_input;
12119 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
12120 #ifdef HAVE_X_WINDOWS
12121 if (x_display_list != NULL)
12122 {
12123
12124
12125 new_interrupt_input = true;
12126 }
12127 else
12128 #endif
12129 new_interrupt_input = !NILP (interrupt);
12130 #else
12131 new_interrupt_input = false;
12132 #endif
12133
12134 if (new_interrupt_input != interrupt_input)
12135 {
12136 #ifdef POLL_FOR_INPUT
12137 stop_polling ();
12138 #endif
12139 #ifndef DOS_NT
12140
12141 reset_all_sys_modes ();
12142 interrupt_input = new_interrupt_input;
12143 init_all_sys_modes ();
12144 #else
12145 interrupt_input = new_interrupt_input;
12146 #endif
12147
12148 #ifdef POLL_FOR_INPUT
12149 poll_suppress_count = 1;
12150 start_polling ();
12151 #endif
12152 }
12153 return Qnil;
12154 }
12155
12156 DEFUN ("set-output-flow-control", Fset_output_flow_control, Sset_output_flow_control, 1, 2, 0,
12157 doc:
12158
12159
12160
12161
12162
12163
12164 )
12165 (Lisp_Object flow, Lisp_Object terminal)
12166 {
12167 struct terminal *t = decode_tty_terminal (terminal);
12168 struct tty_display_info *tty;
12169
12170 if (!t)
12171 return Qnil;
12172 tty = t->display_info.tty;
12173
12174 if (tty->flow_control != !NILP (flow))
12175 {
12176 #ifndef DOS_NT
12177
12178 reset_sys_modes (tty);
12179 #endif
12180
12181 tty->flow_control = !NILP (flow);
12182
12183 #ifndef DOS_NT
12184 init_sys_modes (tty);
12185 #endif
12186 }
12187 return Qnil;
12188 }
12189
12190 DEFUN ("set-input-meta-mode", Fset_input_meta_mode, Sset_input_meta_mode, 1, 2, 0,
12191 doc:
12192
12193
12194
12195
12196
12197
12198
12199
12200
12201
12202
12203
12204
12205
12206
12207
12208
12209
12210 )
12211 (Lisp_Object meta, Lisp_Object terminal)
12212 {
12213 struct terminal *t = decode_tty_terminal (terminal);
12214 struct tty_display_info *tty;
12215 int new_meta;
12216
12217 if (!t)
12218 return Qnil;
12219 tty = t->display_info.tty;
12220
12221 if (NILP (meta))
12222 new_meta = 0;
12223 else if (EQ (meta, Qt))
12224 new_meta = 1;
12225 else if (EQ (meta, Qencoded))
12226 new_meta = 3;
12227 else
12228 new_meta = 2;
12229
12230 if (tty->meta_key != new_meta)
12231 {
12232 #ifndef DOS_NT
12233
12234 reset_sys_modes (tty);
12235 #endif
12236
12237 tty->meta_key = new_meta;
12238
12239 #ifndef DOS_NT
12240 init_sys_modes (tty);
12241 #endif
12242 }
12243 return Qnil;
12244 }
12245
12246 DEFUN ("set-quit-char", Fset_quit_char, Sset_quit_char, 1, 1, 0,
12247 doc:
12248
12249
12250
12251
12252
12253 )
12254 (Lisp_Object quit)
12255 {
12256 struct terminal *t = get_named_terminal (DEV_TTY);
12257 struct tty_display_info *tty;
12258
12259 if (!t)
12260 return Qnil;
12261 tty = t->display_info.tty;
12262
12263 if (NILP (quit) || !FIXNUMP (quit) || XFIXNUM (quit) < 0 || XFIXNUM (quit) > 0400)
12264 error ("QUIT must be an ASCII character");
12265
12266 #ifndef DOS_NT
12267
12268 reset_sys_modes (tty);
12269 #endif
12270
12271
12272 quit_char = XFIXNUM (quit) & (tty->meta_key == 0 ? 0177 : 0377);
12273
12274 #ifndef DOS_NT
12275 init_sys_modes (tty);
12276 #endif
12277
12278 return Qnil;
12279 }
12280
12281 DEFUN ("set-input-mode", Fset_input_mode, Sset_input_mode, 3, 4, 0,
12282 doc:
12283
12284
12285
12286
12287
12288
12289
12290
12291
12292
12293 )
12294 (Lisp_Object interrupt, Lisp_Object flow, Lisp_Object meta, Lisp_Object quit)
12295 {
12296 Fset_input_interrupt_mode (interrupt);
12297 Fset_output_flow_control (flow, Qnil);
12298 Fset_input_meta_mode (meta, Qnil);
12299 if (!NILP (quit))
12300 Fset_quit_char (quit);
12301 return Qnil;
12302 }
12303
12304 DEFUN ("current-input-mode", Fcurrent_input_mode, Scurrent_input_mode, 0, 0, 0,
12305 doc:
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320 )
12321 (void)
12322 {
12323 struct frame *sf = XFRAME (selected_frame);
12324
12325 Lisp_Object interrupt = interrupt_input ? Qt : Qnil;
12326 Lisp_Object flow, meta;
12327 if (FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
12328 {
12329 flow = FRAME_TTY (sf)->flow_control ? Qt : Qnil;
12330 meta = (FRAME_TTY (sf)->meta_key == 2
12331 ? make_fixnum (0)
12332 : (CURTTY ()->meta_key == 1
12333 ? Qt
12334 : (CURTTY ()->meta_key == 3 ? Qencoded : Qnil)));
12335 }
12336 else
12337 {
12338 flow = Qnil;
12339 meta = Qt;
12340 }
12341 Lisp_Object quit = make_fixnum (quit_char);
12342
12343 return list4 (interrupt, flow, meta, quit);
12344 }
12345
12346 DEFUN ("posn-at-x-y", Fposn_at_x_y, Sposn_at_x_y, 2, 4, 0,
12347 doc:
12348
12349
12350
12351
12352
12353
12354
12355
12356
12357
12358 )
12359 (Lisp_Object x, Lisp_Object y, Lisp_Object frame_or_window, Lisp_Object whole)
12360 {
12361 CHECK_FIXNUM (x);
12362
12363
12364 if (XFIXNUM (x) != -1)
12365 CHECK_FIXNAT (x);
12366 CHECK_FIXNAT (y);
12367
12368 if (NILP (frame_or_window))
12369 frame_or_window = selected_window;
12370
12371 if (WINDOWP (frame_or_window))
12372 {
12373 struct window *w = decode_live_window (frame_or_window);
12374
12375 XSETINT (x, (XFIXNUM (x)
12376 + WINDOW_LEFT_EDGE_X (w)
12377 + (NILP (whole)
12378 ? window_box_left_offset (w, TEXT_AREA)
12379 : 0)));
12380 XSETINT (y, WINDOW_TO_FRAME_PIXEL_Y (w, XFIXNUM (y)));
12381 frame_or_window = w->frame;
12382 }
12383
12384 CHECK_LIVE_FRAME (frame_or_window);
12385
12386 return make_lispy_position (XFRAME (frame_or_window), x, y, 0);
12387 }
12388
12389 DEFUN ("posn-at-point", Fposn_at_point, Sposn_at_point, 0, 2, 0,
12390 doc:
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401
12402 )
12403 (Lisp_Object pos, Lisp_Object window)
12404 {
12405 Lisp_Object tem;
12406
12407 if (NILP (window))
12408 window = selected_window;
12409
12410 tem = Fpos_visible_in_window_p (pos, window, Qt);
12411 if (!NILP (tem))
12412 {
12413 Lisp_Object x = XCAR (tem);
12414 Lisp_Object y = XCAR (XCDR (tem));
12415 Lisp_Object aux_info = XCDR (XCDR (tem));
12416 int y_coord = XFIXNUM (y);
12417
12418
12419
12420 if (XFIXNUM (x) < -1)
12421 return Qnil;
12422 if (!NILP (aux_info) && y_coord < 0)
12423 {
12424 int rtop = XFIXNUM (XCAR (aux_info));
12425
12426 y = make_fixnum (y_coord + rtop);
12427 }
12428 tem = Fposn_at_x_y (x, y, window, Qnil);
12429 }
12430
12431 return tem;
12432 }
12433
12434
12435
12436
12437 static void
12438 init_kboard (KBOARD *kb, Lisp_Object type)
12439 {
12440 kset_overriding_terminal_local_map (kb, Qnil);
12441 kset_last_command (kb, Qnil);
12442 kset_real_last_command (kb, Qnil);
12443 kset_keyboard_translate_table (kb, Qnil);
12444 kset_last_repeatable_command (kb, Qnil);
12445 kset_prefix_arg (kb, Qnil);
12446 kset_last_prefix_arg (kb, Qnil);
12447 kset_kbd_queue (kb, Qnil);
12448 kb->kbd_queue_has_data = false;
12449 kb->immediate_echo = false;
12450 kset_echo_string (kb, Qnil);
12451 kset_echo_prompt (kb, Qnil);
12452 kb->kbd_macro_buffer = 0;
12453 kb->kbd_macro_bufsize = 0;
12454 kset_defining_kbd_macro (kb, Qnil);
12455 kset_last_kbd_macro (kb, Qnil);
12456 kb->reference_count = 0;
12457 kset_system_key_alist (kb, Qnil);
12458 kset_system_key_syms (kb, Qnil);
12459 kset_window_system (kb, type);
12460 kset_input_decode_map (kb, Fmake_sparse_keymap (Qnil));
12461 kset_local_function_key_map (kb, Fmake_sparse_keymap (Qnil));
12462 Fset_keymap_parent (KVAR (kb, Vlocal_function_key_map), Vfunction_key_map);
12463 kset_default_minibuffer_frame (kb, Qnil);
12464 }
12465
12466
12467
12468
12469 KBOARD *
12470 allocate_kboard (Lisp_Object type)
12471 {
12472 KBOARD *kb = xmalloc (sizeof *kb);
12473
12474 init_kboard (kb, type);
12475 kb->next_kboard = all_kboards;
12476 all_kboards = kb;
12477 return kb;
12478 }
12479
12480
12481
12482
12483
12484
12485 static void
12486 wipe_kboard (KBOARD *kb)
12487 {
12488 xfree (kb->kbd_macro_buffer);
12489 }
12490
12491
12492
12493 void
12494 delete_kboard (KBOARD *kb)
12495 {
12496 KBOARD **kbp;
12497
12498 for (kbp = &all_kboards; *kbp != kb; kbp = &(*kbp)->next_kboard)
12499 if (*kbp == NULL)
12500 emacs_abort ();
12501 *kbp = kb->next_kboard;
12502
12503
12504 if (kb == current_kboard
12505 && FRAMEP (selected_frame)
12506 && FRAME_LIVE_P (XFRAME (selected_frame)))
12507 {
12508 current_kboard = FRAME_KBOARD (XFRAME (selected_frame));
12509 single_kboard = false;
12510 if (current_kboard == kb)
12511 emacs_abort ();
12512 }
12513
12514 wipe_kboard (kb);
12515 xfree (kb);
12516 }
12517
12518 void
12519 init_keyboard (void)
12520 {
12521
12522 command_loop_level = -1;
12523 quit_char = Ctl ('g');
12524 Vunread_command_events = Qnil;
12525 timer_idleness_start_time = invalid_timespec ();
12526 total_keys = 0;
12527 recent_keys_index = 0;
12528 kbd_fetch_ptr = kbd_buffer;
12529 kbd_store_ptr = kbd_buffer;
12530 track_mouse = Qnil;
12531 input_pending = false;
12532 interrupt_input_blocked = 0;
12533 pending_signals = false;
12534
12535 virtual_core_pointer_name = build_string ("Virtual core pointer");
12536 virtual_core_keyboard_name = build_string ("Virtual core keyboard");
12537 Vlast_event_device = Qnil;
12538
12539
12540
12541 internal_last_event_frame = Qnil;
12542 Vlast_event_frame = internal_last_event_frame;
12543
12544 current_kboard = initial_kboard;
12545
12546 wipe_kboard (current_kboard);
12547
12548
12549 init_kboard (current_kboard, Qnil);
12550
12551 if (!noninteractive)
12552 {
12553
12554
12555
12556
12557
12558
12559 struct sigaction action;
12560 emacs_sigaction_init (&action, deliver_interrupt_signal);
12561 sigaction (SIGINT, &action, 0);
12562 #ifndef DOS_NT
12563
12564
12565 sigaction (SIGQUIT, &action, 0);
12566 #endif
12567 }
12568 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
12569 if (!noninteractive)
12570 {
12571 struct sigaction action;
12572 emacs_sigaction_init (&action, deliver_input_available_signal);
12573 #ifdef USABLE_SIGIO
12574 sigaction (SIGIO, &action, 0);
12575 #else
12576 sigaction (SIGPOLL, &action, 0);
12577 #endif
12578 }
12579 #endif
12580
12581
12582
12583
12584 #ifdef INTERRUPT_INPUT
12585 interrupt_input = 1;
12586 #else
12587 interrupt_input = 0;
12588 #endif
12589
12590 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
12591 dribble = 0;
12592
12593 if (keyboard_init_hook)
12594 (*keyboard_init_hook) ();
12595
12596 #ifdef POLL_FOR_INPUT
12597 poll_timer = NULL;
12598 poll_suppress_count = 1;
12599 start_polling ();
12600 #endif
12601 }
12602
12603
12604
12605 struct event_head
12606 {
12607 short var;
12608 short kind;
12609 };
12610
12611 static const struct event_head head_table[] = {
12612 {SYMBOL_INDEX (Qmouse_movement), SYMBOL_INDEX (Qmouse_movement)},
12613 {SYMBOL_INDEX (Qscroll_bar_movement), SYMBOL_INDEX (Qmouse_movement)},
12614
12615
12616 {SYMBOL_INDEX (Qswitch_frame), SYMBOL_INDEX (Qswitch_frame)},
12617
12618 {SYMBOL_INDEX (Qfocus_in), SYMBOL_INDEX (Qfocus_in)},
12619 {SYMBOL_INDEX (Qfocus_out), SYMBOL_INDEX (Qfocus_out)},
12620 {SYMBOL_INDEX (Qmove_frame), SYMBOL_INDEX (Qmove_frame)},
12621 {SYMBOL_INDEX (Qdelete_frame), SYMBOL_INDEX (Qdelete_frame)},
12622 {SYMBOL_INDEX (Qiconify_frame), SYMBOL_INDEX (Qiconify_frame)},
12623 {SYMBOL_INDEX (Qmake_frame_visible), SYMBOL_INDEX (Qmake_frame_visible)},
12624
12625
12626 {SYMBOL_INDEX (Qselect_window), SYMBOL_INDEX (Qswitch_frame)},
12627
12628 {SYMBOL_INDEX (Qtouchscreen_begin), SYMBOL_INDEX (Qtouchscreen)},
12629 {SYMBOL_INDEX (Qtouchscreen_end), SYMBOL_INDEX (Qtouchscreen)},
12630 };
12631
12632 static Lisp_Object
12633 init_while_no_input_ignore_events (void)
12634 {
12635 Lisp_Object events = listn (9, Qselect_window, Qhelp_echo, Qmove_frame,
12636 Qiconify_frame, Qmake_frame_visible,
12637 Qfocus_in, Qfocus_out, Qconfig_changed_event,
12638 Qselection_request);
12639
12640 #ifdef HAVE_DBUS
12641 events = Fcons (Qdbus_event, events);
12642 #endif
12643 #ifdef USE_FILE_NOTIFY
12644 events = Fcons (Qfile_notify, events);
12645 #endif
12646 #ifdef THREADS_ENABLED
12647 events = Fcons (Qthread_event, events);
12648 #endif
12649
12650 return events;
12651 }
12652
12653 static bool
12654 is_ignored_event (union buffered_input_event *event)
12655 {
12656 Lisp_Object ignore_event;
12657
12658 switch (event->kind)
12659 {
12660 case FOCUS_IN_EVENT: ignore_event = Qfocus_in; break;
12661 case FOCUS_OUT_EVENT: ignore_event = Qfocus_out; break;
12662 case HELP_EVENT: ignore_event = Qhelp_echo; break;
12663 case ICONIFY_EVENT: ignore_event = Qiconify_frame; break;
12664 case DEICONIFY_EVENT: ignore_event = Qmake_frame_visible; break;
12665 case SELECTION_REQUEST_EVENT: ignore_event = Qselection_request; break;
12666 #ifdef USE_FILE_NOTIFY
12667 case FILE_NOTIFY_EVENT: ignore_event = Qfile_notify; break;
12668 #endif
12669 #ifdef HAVE_DBUS
12670 case DBUS_EVENT: ignore_event = Qdbus_event; break;
12671 #endif
12672 default: ignore_event = Qnil; break;
12673 }
12674
12675 return !NILP (Fmemq (ignore_event, Vwhile_no_input_ignore_events));
12676 }
12677
12678 static void syms_of_keyboard_for_pdumper (void);
12679
12680 void
12681 syms_of_keyboard (void)
12682 {
12683 pending_funcalls = Qnil;
12684 staticpro (&pending_funcalls);
12685
12686 Vlispy_mouse_stem = build_pure_c_string ("mouse");
12687 staticpro (&Vlispy_mouse_stem);
12688
12689 regular_top_level_message = build_pure_c_string ("Back to top level");
12690 staticpro (®ular_top_level_message);
12691 #ifdef HAVE_STACK_OVERFLOW_HANDLING
12692 recover_top_level_message
12693 = build_pure_c_string ("Re-entering top level after C stack overflow");
12694 staticpro (&recover_top_level_message);
12695 #endif
12696 DEFVAR_LISP ("internal--top-level-message", Vinternal__top_level_message,
12697 doc: );
12698 Vinternal__top_level_message = regular_top_level_message;
12699
12700
12701 DEFSYM (QCimage, ":image");
12702 DEFSYM (Qhelp_echo, "help-echo");
12703 DEFSYM (Qhelp_echo_inhibit_substitution, "help-echo-inhibit-substitution");
12704 DEFSYM (QCrtl, ":rtl");
12705 DEFSYM (QCwrap, ":wrap");
12706
12707 staticpro (&item_properties);
12708 item_properties = Qnil;
12709
12710 staticpro (&tab_bar_item_properties);
12711 tab_bar_item_properties = Qnil;
12712 staticpro (&tab_bar_items_vector);
12713 tab_bar_items_vector = Qnil;
12714
12715 staticpro (&tool_bar_item_properties);
12716 tool_bar_item_properties = Qnil;
12717 staticpro (&tool_bar_items_vector);
12718 tool_bar_items_vector = Qnil;
12719
12720 DEFSYM (Qtimer_event_handler, "timer-event-handler");
12721
12722
12723
12724 DEFSYM (Qdisabled, "disabled");
12725
12726 DEFSYM (Qundefined, "undefined");
12727
12728
12729 DEFSYM (Qpre_command_hook, "pre-command-hook");
12730 DEFSYM (Qpost_command_hook, "post-command-hook");
12731 DEFSYM (Qlong_line_optimizations_in_command_hooks,
12732 "long-line-optimizations-in-command-hooks");
12733
12734
12735 DEFSYM (Qpost_select_region_hook, "post-select-region-hook");
12736
12737 DEFSYM (Qundo_auto__add_boundary, "undo-auto--add-boundary");
12738 DEFSYM (Qundo_auto__undoably_changed_buffers,
12739 "undo-auto--undoably-changed-buffers");
12740
12741 DEFSYM (Qdelayed_warnings_hook, "delayed-warnings-hook");
12742 DEFSYM (Qfunction_key, "function-key");
12743
12744
12745 DEFSYM (Qmouse_click, "mouse-click");
12746
12747 DEFSYM (Qdrag_n_drop, "drag-n-drop");
12748 DEFSYM (Qsave_session, "save-session");
12749 DEFSYM (Qconfig_changed_event, "config-changed-event");
12750
12751
12752 DEFSYM (Qmenu_enable, "menu-enable");
12753
12754 #ifdef HAVE_NTGUI
12755 DEFSYM (Qlanguage_change, "language-change");
12756 DEFSYM (Qend_session, "end-session");
12757 #endif
12758
12759 #ifdef HAVE_DBUS
12760 DEFSYM (Qdbus_event, "dbus-event");
12761 #endif
12762
12763 #ifdef THREADS_ENABLED
12764 DEFSYM (Qthread_event, "thread-event");
12765 #endif
12766
12767 #ifdef HAVE_XWIDGETS
12768 DEFSYM (Qxwidget_event, "xwidget-event");
12769 DEFSYM (Qxwidget_display_event, "xwidget-display-event");
12770 #endif
12771
12772 #ifdef USE_FILE_NOTIFY
12773 DEFSYM (Qfile_notify, "file-notify");
12774 #endif
12775
12776 DEFSYM (Qtouch_end, "touch-end");
12777
12778
12779 DEFSYM (QCenable, ":enable");
12780 DEFSYM (QCvisible, ":visible");
12781 DEFSYM (QChelp, ":help");
12782 DEFSYM (QCfilter, ":filter");
12783 DEFSYM (QCbutton, ":button");
12784 DEFSYM (QCkeys, ":keys");
12785 DEFSYM (QCkey_sequence, ":key-sequence");
12786
12787
12788
12789 DEFSYM (QCtoggle, ":toggle");
12790 DEFSYM (QCradio, ":radio");
12791 DEFSYM (QClabel, ":label");
12792 DEFSYM (QCvert_only, ":vert-only");
12793
12794
12795 DEFSYM (Qvertical_line, "vertical-line");
12796 DEFSYM (Qright_divider, "right-divider");
12797 DEFSYM (Qbottom_divider, "bottom-divider");
12798
12799 DEFSYM (Qmouse_fixup_help_message, "mouse-fixup-help-message");
12800
12801 DEFSYM (Qabove_handle, "above-handle");
12802 DEFSYM (Qhandle, "handle");
12803 DEFSYM (Qbelow_handle, "below-handle");
12804 DEFSYM (Qup, "up");
12805 DEFSYM (Qdown, "down");
12806 DEFSYM (Qtop, "top");
12807 DEFSYM (Qbottom, "bottom");
12808 DEFSYM (Qend_scroll, "end-scroll");
12809 DEFSYM (Qratio, "ratio");
12810 DEFSYM (Qbefore_handle, "before-handle");
12811 DEFSYM (Qhorizontal_handle, "horizontal-handle");
12812 DEFSYM (Qafter_handle, "after-handle");
12813 DEFSYM (Qleft, "left");
12814 DEFSYM (Qright, "right");
12815 DEFSYM (Qleftmost, "leftmost");
12816 DEFSYM (Qrightmost, "rightmost");
12817
12818
12819 DEFSYM (Qevent_kind, "event-kind");
12820 DEFSYM (Qevent_symbol_elements, "event-symbol-elements");
12821
12822
12823
12824
12825
12826
12827 DEFSYM (Qevent_symbol_element_mask, "event-symbol-element-mask");
12828
12829
12830
12831
12832
12833 DEFSYM (Qmodifier_cache, "modifier-cache");
12834
12835 DEFSYM (Qactivate_menubar_hook, "activate-menubar-hook");
12836
12837 DEFSYM (Qpolling_period, "polling-period");
12838
12839 DEFSYM (Qgui_set_selection, "gui-set-selection");
12840 DEFSYM (Qxterm__set_selection, "xterm--set-selection");
12841 DEFSYM (Qtty_select_active_regions, "tty-select-active-regions");
12842
12843
12844 DEFSYM (QPRIMARY, "PRIMARY");
12845
12846 DEFSYM (Qhandle_switch_frame, "handle-switch-frame");
12847 DEFSYM (Qhandle_select_window, "handle-select-window");
12848
12849 DEFSYM (Qinput_method_exit_on_first_char, "input-method-exit-on-first-char");
12850 DEFSYM (Qinput_method_use_echo_area, "input-method-use-echo-area");
12851
12852 DEFSYM (Qhelp_form_show, "help-form-show");
12853
12854 DEFSYM (Qhelp_key_binding, "help-key-binding");
12855
12856 DEFSYM (Qecho_keystrokes, "echo-keystrokes");
12857
12858 Fset (Qinput_method_exit_on_first_char, Qnil);
12859 Fset (Qinput_method_use_echo_area, Qnil);
12860
12861
12862 DEFSYM (Qdrag_internal_border, "drag-internal-border");
12863 DEFSYM (Qleft_edge, "left-edge");
12864 DEFSYM (Qtop_left_corner, "top-left-corner");
12865 DEFSYM (Qtop_edge, "top-edge");
12866 DEFSYM (Qtop_right_corner, "top-right-corner");
12867 DEFSYM (Qright_edge, "right-edge");
12868 DEFSYM (Qbottom_right_corner, "bottom-right-corner");
12869 DEFSYM (Qbottom_edge, "bottom-edge");
12870 DEFSYM (Qbottom_left_corner, "bottom-left-corner");
12871
12872
12873 DEFSYM (Qmouse_movement, "mouse-movement");
12874 DEFSYM (Qscroll_bar_movement, "scroll-bar-movement");
12875 DEFSYM (Qswitch_frame, "switch-frame");
12876 DEFSYM (Qfocus_in, "focus-in");
12877 DEFSYM (Qfocus_out, "focus-out");
12878 DEFSYM (Qmove_frame, "move-frame");
12879 DEFSYM (Qdelete_frame, "delete-frame");
12880 DEFSYM (Qiconify_frame, "iconify-frame");
12881 DEFSYM (Qmake_frame_visible, "make-frame-visible");
12882 DEFSYM (Qselect_window, "select-window");
12883 DEFSYM (Qselection_request, "selection-request");
12884 DEFSYM (Qwindow_edges, "window-edges");
12885 {
12886 int i;
12887
12888 for (i = 0; i < ARRAYELTS (head_table); i++)
12889 {
12890 const struct event_head *p = &head_table[i];
12891 Lisp_Object var = builtin_lisp_symbol (p->var);
12892 Lisp_Object kind = builtin_lisp_symbol (p->kind);
12893 Fput (var, Qevent_kind, kind);
12894 Fput (var, Qevent_symbol_elements, list1 (var));
12895 }
12896 }
12897 DEFSYM (Qno_record, "no-record");
12898 DEFSYM (Qencoded, "encoded");
12899
12900 DEFSYM (Qpreedit_text, "preedit-text");
12901
12902 button_down_location = make_nil_vector (5);
12903 staticpro (&button_down_location);
12904 staticpro (&frame_relative_event_pos);
12905 mouse_syms = make_nil_vector (5);
12906 staticpro (&mouse_syms);
12907 wheel_syms = make_nil_vector (ARRAYELTS (lispy_wheel_names));
12908 staticpro (&wheel_syms);
12909
12910 {
12911 int i;
12912 int len = ARRAYELTS (modifier_names);
12913
12914 modifier_symbols = make_nil_vector (len);
12915 for (i = 0; i < len; i++)
12916 if (modifier_names[i])
12917 ASET (modifier_symbols, i, intern_c_string (modifier_names[i]));
12918 staticpro (&modifier_symbols);
12919 }
12920
12921 recent_keys = make_nil_vector (lossage_limit);
12922 staticpro (&recent_keys);
12923
12924 this_command_keys = make_nil_vector (40);
12925 staticpro (&this_command_keys);
12926
12927 raw_keybuf = make_nil_vector (30);
12928 staticpro (&raw_keybuf);
12929
12930 DEFSYM (Qcommand_execute, "command-execute");
12931 DEFSYM (Qinternal_echo_keystrokes_prefix, "internal-echo-keystrokes-prefix");
12932
12933 accent_key_syms = Qnil;
12934 staticpro (&accent_key_syms);
12935
12936 func_key_syms = Qnil;
12937 staticpro (&func_key_syms);
12938
12939 drag_n_drop_syms = Qnil;
12940 staticpro (&drag_n_drop_syms);
12941
12942 pinch_syms = Qnil;
12943 staticpro (&pinch_syms);
12944
12945 unread_switch_frame = Qnil;
12946 staticpro (&unread_switch_frame);
12947
12948 internal_last_event_frame = Qnil;
12949 staticpro (&internal_last_event_frame);
12950
12951 read_key_sequence_cmd = Qnil;
12952 staticpro (&read_key_sequence_cmd);
12953 read_key_sequence_remapped = Qnil;
12954 staticpro (&read_key_sequence_remapped);
12955
12956 menu_bar_one_keymap_changed_items = Qnil;
12957 staticpro (&menu_bar_one_keymap_changed_items);
12958
12959 menu_bar_items_vector = Qnil;
12960 staticpro (&menu_bar_items_vector);
12961
12962 help_form_saved_window_configs = Qnil;
12963 staticpro (&help_form_saved_window_configs);
12964
12965 #ifdef POLL_FOR_INPUT
12966 poll_timer_time = Qnil;
12967 staticpro (&poll_timer_time);
12968 #endif
12969
12970 virtual_core_pointer_name = Qnil;
12971 staticpro (&virtual_core_pointer_name);
12972
12973 virtual_core_keyboard_name = Qnil;
12974 staticpro (&virtual_core_keyboard_name);
12975
12976 menu_bar_touch_id = Qnil;
12977 staticpro (&menu_bar_touch_id);
12978
12979 defsubr (&Scurrent_idle_time);
12980 defsubr (&Sevent_symbol_parse_modifiers);
12981 defsubr (&Sevent_convert_list);
12982 defsubr (&Sinternal_handle_focus_in);
12983 defsubr (&Sread_key_sequence);
12984 defsubr (&Sread_key_sequence_vector);
12985 defsubr (&Srecursive_edit);
12986 defsubr (&Sinternal_track_mouse);
12987 defsubr (&Sinput_pending_p);
12988 defsubr (&Slossage_size);
12989 defsubr (&Srecent_keys);
12990 defsubr (&Sthis_command_keys);
12991 defsubr (&Sthis_command_keys_vector);
12992 defsubr (&Sthis_single_command_keys);
12993 defsubr (&Sthis_single_command_raw_keys);
12994 defsubr (&Sset__this_command_keys);
12995 defsubr (&Sclear_this_command_keys);
12996 defsubr (&Ssuspend_emacs);
12997 defsubr (&Sabort_recursive_edit);
12998 defsubr (&Sexit_recursive_edit);
12999 defsubr (&Srecursion_depth);
13000 defsubr (&Scommand_error_default_function);
13001 defsubr (&Stop_level);
13002 defsubr (&Sdiscard_input);
13003 defsubr (&Sopen_dribble_file);
13004 defsubr (&Sset_input_interrupt_mode);
13005 defsubr (&Sset_output_flow_control);
13006 defsubr (&Sset_input_meta_mode);
13007 defsubr (&Sset_quit_char);
13008 defsubr (&Sset_input_mode);
13009 defsubr (&Scurrent_input_mode);
13010 defsubr (&Sposn_at_point);
13011 defsubr (&Sposn_at_x_y);
13012
13013 DEFVAR_LISP ("last-command-event", last_command_event,
13014 doc:
13015 );
13016
13017 DEFVAR_LISP ("last-nonmenu-event", last_nonmenu_event,
13018 doc:
13019
13020
13021 );
13022
13023 DEFVAR_LISP ("last-input-event", last_input_event,
13024 doc: );
13025
13026 DEFVAR_LISP ("unread-command-events", Vunread_command_events,
13027 doc:
13028
13029
13030
13031
13032
13033 );
13034 Vunread_command_events = Qnil;
13035
13036 DEFVAR_LISP ("unread-post-input-method-events", Vunread_post_input_method_events,
13037 doc:
13038
13039 );
13040 Vunread_post_input_method_events = Qnil;
13041
13042 DEFVAR_LISP ("unread-input-method-events", Vunread_input_method_events,
13043 doc:
13044
13045
13046
13047 );
13048 Vunread_input_method_events = Qnil;
13049
13050 DEFVAR_LISP ("meta-prefix-char", meta_prefix_char,
13051 doc:
13052 );
13053 XSETINT (meta_prefix_char, 033);
13054
13055 DEFVAR_KBOARD ("last-command", Vlast_command,
13056 doc:
13057
13058
13059
13060
13061
13062
13063
13064
13065
13066
13067
13068
13069
13070 );
13071
13072 DEFVAR_KBOARD ("real-last-command", Vreal_last_command,
13073 doc:
13074 );
13075
13076 DEFVAR_KBOARD ("last-repeatable-command", Vlast_repeatable_command,
13077 doc:
13078
13079
13080 );
13081
13082 DEFVAR_LISP ("this-command", Vthis_command,
13083 doc:
13084
13085 );
13086 Vthis_command = Qnil;
13087
13088 DEFVAR_LISP ("real-this-command", Vreal_this_command,
13089 doc: );
13090 Vreal_this_command = Qnil;
13091
13092 DEFSYM (Qcurrent_minibuffer_command, "current-minibuffer-command");
13093 DEFVAR_LISP ("current-minibuffer-command", Vcurrent_minibuffer_command,
13094 doc:
13095
13096 );
13097 Vcurrent_minibuffer_command = Qnil;
13098
13099 DEFVAR_LISP ("this-command-keys-shift-translated",
13100 Vthis_command_keys_shift_translated,
13101 doc:
13102
13103
13104 );
13105 Vthis_command_keys_shift_translated = Qnil;
13106
13107 DEFVAR_LISP ("this-original-command", Vthis_original_command,
13108 doc:
13109
13110
13111 );
13112 Vthis_original_command = Qnil;
13113
13114 DEFVAR_INT ("auto-save-interval", auto_save_interval,
13115 doc:
13116 );
13117 auto_save_interval = 300;
13118
13119 DEFVAR_BOOL ("auto-save-no-message", auto_save_no_message,
13120 doc: );
13121 auto_save_no_message = false;
13122
13123 DEFVAR_LISP ("auto-save-timeout", Vauto_save_timeout,
13124 doc:
13125
13126
13127 );
13128 XSETFASTINT (Vauto_save_timeout, 30);
13129
13130 DEFVAR_LISP ("echo-keystrokes", Vecho_keystrokes,
13131 doc:
13132
13133 );
13134 Vecho_keystrokes = make_fixnum (1);
13135
13136 DEFVAR_LISP ("polling-period", Vpolling_period,
13137 doc:
13138
13139
13140 );
13141 Vpolling_period = make_float (2.0);
13142
13143 DEFVAR_LISP ("double-click-time", Vdouble_click_time,
13144 doc:
13145
13146
13147
13148
13149
13150 );
13151 Vdouble_click_time = make_fixnum (500);
13152
13153 DEFVAR_INT ("double-click-fuzz", double_click_fuzz,
13154 doc:
13155
13156
13157
13158
13159
13160
13161 );
13162 double_click_fuzz = 3;
13163
13164 DEFVAR_INT ("num-input-keys", num_input_keys,
13165 doc:
13166
13167 );
13168 num_input_keys = 0;
13169
13170 DEFVAR_INT ("num-nonmacro-input-events", num_nonmacro_input_events,
13171 doc:
13172 );
13173 num_nonmacro_input_events = 0;
13174
13175 DEFVAR_LISP ("last-event-frame", Vlast_event_frame,
13176 doc:
13177 );
13178 Vlast_event_frame = Qnil;
13179
13180 DEFVAR_LISP ("last-event-device", Vlast_event_device,
13181 doc:
13182
13183
13184
13185
13186
13187
13188 );
13189 Vlast_event_device = Qnil;
13190
13191
13192 DEFVAR_LISP ("tty-erase-char", Vtty_erase_char,
13193 doc: );
13194
13195 DEFVAR_LISP ("help-char", Vhelp_char,
13196 doc:
13197
13198 );
13199 XSETINT (Vhelp_char, Ctl ('H'));
13200
13201 DEFVAR_LISP ("help-event-list", Vhelp_event_list,
13202 doc:
13203 );
13204 Vhelp_event_list = Qnil;
13205
13206 DEFVAR_LISP ("help-form", Vhelp_form,
13207 doc:
13208
13209 );
13210 Vhelp_form = Qnil;
13211
13212 DEFVAR_LISP ("prefix-help-command", Vprefix_help_command,
13213 doc:
13214
13215 );
13216 Vprefix_help_command = Qnil;
13217
13218 DEFVAR_LISP ("top-level", Vtop_level,
13219 doc:
13220 );
13221 Vtop_level = Qnil;
13222 XSYMBOL (Qtop_level)->u.s.declared_special = false;
13223
13224 DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table,
13225 doc:
13226
13227
13228
13229
13230
13231
13232
13233
13234
13235
13236
13237
13238 );
13239
13240 DEFVAR_BOOL ("cannot-suspend", cannot_suspend,
13241 doc:
13242 );
13243 cannot_suspend = false;
13244
13245 DEFVAR_BOOL ("menu-prompting", menu_prompting,
13246 doc:
13247
13248
13249
13250
13251
13252 );
13253 menu_prompting = true;
13254
13255 DEFVAR_LISP ("menu-prompt-more-char", menu_prompt_more_char,
13256 doc:
13257 );
13258 XSETINT (menu_prompt_more_char, ' ');
13259
13260 DEFVAR_INT ("extra-keyboard-modifiers", extra_keyboard_modifiers,
13261 doc:
13262
13263
13264
13265
13266
13267
13268
13269
13270 );
13271 extra_keyboard_modifiers = 0;
13272
13273 DEFSYM (Qdeactivate_mark, "deactivate-mark");
13274 DEFVAR_LISP ("deactivate-mark", Vdeactivate_mark,
13275 doc:
13276
13277
13278
13279
13280
13281
13282
13283
13284
13285 );
13286 Vdeactivate_mark = Qnil;
13287 Fmake_variable_buffer_local (Qdeactivate_mark);
13288
13289 DEFVAR_LISP ("pre-command-hook", Vpre_command_hook,
13290 doc:
13291
13292
13293
13294
13295
13296
13297
13298
13299
13300
13301
13302 );
13303 Vpre_command_hook = Qnil;
13304
13305 DEFVAR_LISP ("post-command-hook", Vpost_command_hook,
13306 doc:
13307
13308
13309
13310
13311
13312
13313
13314
13315
13316
13317
13318
13319
13320
13321
13322 );
13323 Vpost_command_hook = Qnil;
13324
13325 #if 0
13326 DEFVAR_LISP ("echo-area-clear-hook", ...,
13327 doc: );
13328 #endif
13329 DEFSYM (Qecho_area_clear_hook, "echo-area-clear-hook");
13330 DEFSYM (Qtouchscreen_begin, "touchscreen-begin");
13331 DEFSYM (Qtouchscreen_end, "touchscreen-end");
13332 DEFSYM (Qtouchscreen_update, "touchscreen-update");
13333 DEFSYM (Qpinch, "pinch");
13334 DEFSYM (Qdisplay_monitors_changed_functions,
13335 "display-monitors-changed-functions");
13336
13337 DEFSYM (Qcoding, "coding");
13338 DEFSYM (Qtouchscreen, "touchscreen");
13339 #ifdef HAVE_TEXT_CONVERSION
13340 DEFSYM (Qtext_conversion, "text-conversion");
13341 #endif
13342
13343 Fset (Qecho_area_clear_hook, Qnil);
13344
13345 #ifdef USE_LUCID
13346 DEFVAR_BOOL ("lucid--menu-grab-keyboard",
13347 lucid__menu_grab_keyboard,
13348 doc:
13349
13350 );
13351 lucid__menu_grab_keyboard = true;
13352 #endif
13353
13354 DEFVAR_LISP ("menu-bar-final-items", Vmenu_bar_final_items,
13355 doc:
13356
13357 );
13358 Vmenu_bar_final_items = Qnil;
13359
13360 DEFVAR_LISP ("tab-bar-separator-image-expression", Vtab_bar_separator_image_expression,
13361 doc:
13362
13363 );
13364 Vtab_bar_separator_image_expression = Qnil;
13365
13366 DEFVAR_LISP ("tool-bar-separator-image-expression", Vtool_bar_separator_image_expression,
13367 doc:
13368
13369 );
13370 Vtool_bar_separator_image_expression = Qnil;
13371
13372 DEFVAR_KBOARD ("overriding-terminal-local-map",
13373 Voverriding_terminal_local_map,
13374 doc:
13375
13376
13377
13378
13379 );
13380
13381 DEFVAR_LISP ("overriding-local-map", Voverriding_local_map,
13382 doc:
13383
13384
13385
13386
13387
13388 );
13389 Voverriding_local_map = Qnil;
13390
13391 DEFVAR_LISP ("overriding-local-map-menu-flag", Voverriding_local_map_menu_flag,
13392 doc:
13393
13394 );
13395 Voverriding_local_map_menu_flag = Qnil;
13396
13397 DEFVAR_LISP ("special-event-map", Vspecial_event_map,
13398 doc: );
13399 Vspecial_event_map = list1 (Qkeymap);
13400
13401 DEFVAR_LISP ("track-mouse", track_mouse,
13402 doc:
13403
13404
13405
13406
13407
13408
13409
13410
13411
13412
13413 );
13414 DEFVAR_KBOARD ("system-key-alist", Vsystem_key_alist,
13415 doc:
13416
13417
13418
13419
13420
13421 );
13422
13423 DEFVAR_KBOARD ("local-function-key-map", Vlocal_function_key_map,
13424 doc:
13425
13426
13427
13428
13429
13430
13431
13432
13433
13434
13435
13436
13437
13438
13439
13440
13441
13442
13443
13444
13445
13446
13447
13448
13449
13450 );
13451
13452 DEFVAR_KBOARD ("input-decode-map", Vinput_decode_map,
13453 doc:
13454
13455
13456
13457
13458
13459
13460
13461
13462
13463
13464
13465
13466
13467 );
13468
13469 DEFVAR_LISP ("function-key-map", Vfunction_key_map,
13470 doc:
13471
13472
13473
13474 );
13475 Vfunction_key_map = Fmake_sparse_keymap (Qnil);
13476
13477 DEFVAR_LISP ("key-translation-map", Vkey_translation_map,
13478 doc:
13479
13480 );
13481 Vkey_translation_map = Fmake_sparse_keymap (Qnil);
13482
13483 DEFVAR_LISP ("delayed-warnings-list", Vdelayed_warnings_list,
13484 doc:
13485
13486
13487
13488 );
13489 Vdelayed_warnings_list = Qnil;
13490
13491 DEFVAR_LISP ("timer-list", Vtimer_list,
13492 doc: );
13493 Vtimer_list = Qnil;
13494
13495 DEFVAR_LISP ("timer-idle-list", Vtimer_idle_list,
13496 doc: );
13497 Vtimer_idle_list = Qnil;
13498
13499 DEFVAR_LISP ("input-method-function", Vinput_method_function,
13500 doc:
13501
13502
13503
13504
13505
13506
13507
13508
13509
13510
13511
13512
13513
13514
13515
13516
13517
13518 );
13519 Vinput_method_function = Qlist;
13520
13521 DEFVAR_LISP ("input-method-previous-message",
13522 Vinput_method_previous_message,
13523 doc:
13524
13525 );
13526 Vinput_method_previous_message = Qnil;
13527
13528 DEFVAR_LISP ("show-help-function", Vshow_help_function,
13529 doc:
13530 );
13531 Vshow_help_function = Qnil;
13532
13533 DEFVAR_LISP ("disable-point-adjustment", Vdisable_point_adjustment,
13534 doc:
13535
13536
13537
13538
13539
13540
13541
13542 );
13543 Vdisable_point_adjustment = Qnil;
13544
13545 DEFVAR_LISP ("global-disable-point-adjustment",
13546 Vglobal_disable_point_adjustment,
13547 doc:
13548
13549
13550
13551 );
13552 Vglobal_disable_point_adjustment = Qnil;
13553
13554 DEFVAR_LISP ("minibuffer-message-timeout", Vminibuffer_message_timeout,
13555 doc:
13556
13557 );
13558 Vminibuffer_message_timeout = make_fixnum (2);
13559
13560 DEFVAR_LISP ("throw-on-input", Vthrow_on_input,
13561 doc:
13562
13563 );
13564 Vthrow_on_input = Qnil;
13565
13566 DEFVAR_LISP ("command-error-function", Vcommand_error_function,
13567 doc:
13568
13569
13570
13571
13572
13573
13574
13575
13576
13577
13578
13579
13580
13581
13582
13583 );
13584 Vcommand_error_function = intern ("command-error-default-function");
13585
13586 DEFVAR_LISP ("enable-disabled-menus-and-buttons",
13587 Venable_disabled_menus_and_buttons,
13588 doc:
13589
13590
13591 );
13592 Venable_disabled_menus_and_buttons = Qnil;
13593
13594 DEFVAR_LISP ("select-active-regions",
13595 Vselect_active_regions,
13596 doc:
13597
13598
13599
13600
13601
13602
13603
13604 );
13605 Vselect_active_regions = Qt;
13606
13607 DEFVAR_LISP ("saved-region-selection",
13608 Vsaved_region_selection,
13609 doc:
13610
13611
13612 );
13613 Vsaved_region_selection = Qnil;
13614
13615 DEFVAR_LISP ("selection-inhibit-update-commands",
13616 Vselection_inhibit_update_commands,
13617 doc:
13618
13619
13620
13621 );
13622 Vselection_inhibit_update_commands
13623 = list2 (Qhandle_switch_frame, Qhandle_select_window);
13624
13625 DEFVAR_LISP ("debug-on-event",
13626 Vdebug_on_event,
13627 doc:
13628
13629
13630
13631
13632
13633 );
13634 Vdebug_on_event = intern_c_string ("sigusr2");
13635
13636 DEFVAR_BOOL ("attempt-stack-overflow-recovery",
13637 attempt_stack_overflow_recovery,
13638 doc:
13639
13640
13641
13642 );
13643 attempt_stack_overflow_recovery = true;
13644
13645 DEFVAR_BOOL ("attempt-orderly-shutdown-on-fatal-signal",
13646 attempt_orderly_shutdown_on_fatal_signal,
13647 doc:
13648
13649
13650
13651
13652
13653
13654 );
13655 attempt_orderly_shutdown_on_fatal_signal = true;
13656
13657 DEFVAR_LISP ("while-no-input-ignore-events",
13658 Vwhile_no_input_ignore_events,
13659 doc:
13660
13661
13662 );
13663 Vwhile_no_input_ignore_events = init_while_no_input_ignore_events ();
13664
13665 DEFVAR_BOOL ("translate-upper-case-key-bindings",
13666 translate_upper_case_key_bindings,
13667 doc:
13668
13669
13670
13671
13672 );
13673 translate_upper_case_key_bindings = true;
13674
13675 DEFVAR_BOOL ("input-pending-p-filter-events",
13676 input_pending_p_filter_events,
13677 doc:
13678
13679
13680 );
13681 input_pending_p_filter_events = true;
13682
13683 DEFVAR_BOOL ("mwheel-coalesce-scroll-events", mwheel_coalesce_scroll_events,
13684 doc:
13685
13686 );
13687 mwheel_coalesce_scroll_events = true;
13688
13689 DEFVAR_LISP ("display-monitors-changed-functions", Vdisplay_monitors_changed_functions,
13690 doc:
13691
13692
13693
13694
13695 );
13696 Vdisplay_monitors_changed_functions = Qnil;
13697
13698 DEFVAR_BOOL ("inhibit--record-char",
13699 inhibit_record_char,
13700 doc:
13701
13702
13703 );
13704 inhibit_record_char = false;
13705
13706 DEFVAR_BOOL ("record-all-keys", record_all_keys,
13707 doc:
13708
13709
13710 );
13711 record_all_keys = false;
13712
13713 DEFVAR_LISP ("post-select-region-hook", Vpost_select_region_hook,
13714 doc:
13715
13716 );
13717 Vpost_select_region_hook = Qnil;
13718
13719 DEFVAR_BOOL ("disable-inhibit-text-conversion",
13720 disable_inhibit_text_conversion,
13721 doc:
13722
13723 );
13724 disable_inhibit_text_conversion = false;
13725
13726 DEFVAR_LISP ("current-key-remap-sequence",
13727 Vcurrent_key_remap_sequence,
13728 doc:
13729
13730
13731 );
13732 Vcurrent_key_remap_sequence = Qnil;
13733 DEFSYM (Qcurrent_key_remap_sequence, "current-key-remap-sequence");
13734
13735 pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper);
13736 }
13737
13738 static void
13739 syms_of_keyboard_for_pdumper (void)
13740 {
13741
13742
13743
13744
13745
13746 PDUMPER_RESET_LV (pending_funcalls, Qnil);
13747 PDUMPER_RESET_LV (unread_switch_frame, Qnil);
13748 PDUMPER_RESET_LV (internal_last_event_frame, Qnil);
13749 PDUMPER_RESET_LV (last_command_event, Qnil);
13750 PDUMPER_RESET_LV (last_nonmenu_event, Qnil);
13751 PDUMPER_RESET_LV (last_input_event, Qnil);
13752 PDUMPER_RESET_LV (Vunread_command_events, Qnil);
13753 PDUMPER_RESET_LV (Vunread_post_input_method_events, Qnil);
13754 PDUMPER_RESET_LV (Vunread_input_method_events, Qnil);
13755 PDUMPER_RESET_LV (Vthis_command, Qnil);
13756 PDUMPER_RESET_LV (Vreal_this_command, Qnil);
13757 PDUMPER_RESET_LV (Vthis_command_keys_shift_translated, Qnil);
13758 PDUMPER_RESET_LV (Vthis_original_command, Qnil);
13759 PDUMPER_RESET (num_input_keys, 0);
13760 PDUMPER_RESET (num_nonmacro_input_events, 0);
13761 PDUMPER_RESET_LV (Vlast_event_frame, Qnil);
13762 PDUMPER_RESET_LV (Vdelayed_warnings_list, Qnil);
13763
13764
13765 eassert (initial_kboard == NULL);
13766 initial_kboard = allocate_kboard (Qt);
13767 }
13768
13769 void
13770 keys_of_keyboard (void)
13771 {
13772 initial_define_lispy_key (Vspecial_event_map, "delete-frame",
13773 "handle-delete-frame");
13774 #ifdef HAVE_NTGUI
13775 initial_define_lispy_key (Vspecial_event_map, "end-session",
13776 "kill-emacs");
13777 #endif
13778 initial_define_lispy_key (Vspecial_event_map, "ns-put-working-text",
13779 "ns-put-working-text");
13780 initial_define_lispy_key (Vspecial_event_map, "ns-unput-working-text",
13781 "ns-unput-working-text");
13782
13783
13784
13785
13786
13787
13788
13789
13790
13791
13792
13793
13794
13795
13796
13797
13798
13799
13800
13801 initial_define_lispy_key (Vspecial_event_map, "iconify-frame",
13802 "ignore");
13803 initial_define_lispy_key (Vspecial_event_map, "make-frame-visible",
13804 "ignore");
13805
13806
13807
13808
13809
13810
13811 initial_define_lispy_key (Vspecial_event_map, "save-session",
13812 "handle-save-session");
13813
13814 #ifdef HAVE_DBUS
13815
13816
13817 initial_define_lispy_key (Vspecial_event_map, "dbus-event",
13818 "dbus-handle-event");
13819 #endif
13820
13821 #ifdef THREADS_ENABLED
13822
13823 initial_define_lispy_key (Vspecial_event_map, "thread-event",
13824 "thread-handle-event");
13825 #endif
13826
13827 #ifdef USE_FILE_NOTIFY
13828
13829
13830 initial_define_lispy_key (Vspecial_event_map, "file-notify",
13831 "file-notify-handle-event");
13832 #endif
13833
13834 initial_define_lispy_key (Vspecial_event_map, "config-changed-event",
13835 "ignore");
13836 #if defined (WINDOWSNT)
13837 initial_define_lispy_key (Vspecial_event_map, "language-change",
13838 "ignore");
13839 #endif
13840 initial_define_lispy_key (Vspecial_event_map, "focus-in",
13841 "handle-focus-in");
13842 initial_define_lispy_key (Vspecial_event_map, "focus-out",
13843 "handle-focus-out");
13844 initial_define_lispy_key (Vspecial_event_map, "move-frame",
13845 "handle-move-frame");
13846 }
13847
13848
13849
13850 void
13851 mark_kboards (void)
13852 {
13853 for (KBOARD *kb = all_kboards; kb; kb = kb->next_kboard)
13854 {
13855 if (kb->kbd_macro_buffer)
13856 mark_objects (kb->kbd_macro_buffer,
13857 kb->kbd_macro_ptr - kb->kbd_macro_buffer);
13858 mark_object (KVAR (kb, Voverriding_terminal_local_map));
13859 mark_object (KVAR (kb, Vlast_command));
13860 mark_object (KVAR (kb, Vreal_last_command));
13861 mark_object (KVAR (kb, Vkeyboard_translate_table));
13862 mark_object (KVAR (kb, Vlast_repeatable_command));
13863 mark_object (KVAR (kb, Vprefix_arg));
13864 mark_object (KVAR (kb, Vlast_prefix_arg));
13865 mark_object (KVAR (kb, kbd_queue));
13866 mark_object (KVAR (kb, defining_kbd_macro));
13867 mark_object (KVAR (kb, Vlast_kbd_macro));
13868 mark_object (KVAR (kb, Vsystem_key_alist));
13869 mark_object (KVAR (kb, system_key_syms));
13870 mark_object (KVAR (kb, Vwindow_system));
13871 mark_object (KVAR (kb, Vinput_decode_map));
13872 mark_object (KVAR (kb, Vlocal_function_key_map));
13873 mark_object (KVAR (kb, Vdefault_minibuffer_frame));
13874 mark_object (KVAR (kb, echo_string));
13875 mark_object (KVAR (kb, echo_prompt));
13876 }
13877
13878 for (union buffered_input_event *event = kbd_fetch_ptr;
13879 event != kbd_store_ptr; event = next_kbd_event (event))
13880 {
13881
13882 if (event->kind != SELECTION_REQUEST_EVENT
13883 #ifndef HAVE_HAIKU
13884 && event->kind != SELECTION_CLEAR_EVENT
13885 #endif
13886 )
13887 {
13888 mark_object (event->ie.x);
13889 mark_object (event->ie.y);
13890 mark_object (event->ie.frame_or_window);
13891 mark_object (event->ie.arg);
13892
13893
13894
13895
13896
13897 mark_object (event->ie.device);
13898 }
13899 }
13900 }