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