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