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