1 /* Events: printing them, converting them to and from characters.
2 Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
3 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
5 This file is part of SXEmacs
7 SXEmacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 SXEmacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 /* Synched up with: Not in FSF. */
23 /* This file has been Mule-ized. */
28 #include "ui/console.h"
29 #include "ui/TTY/console-tty.h" /* for stuff in
30 character_to_event. needs
32 #include "ui/device.h"
33 #include "ui/X11/console-x.h" /* for x_event_name prototype in
34 format_event_object. Needs refactoring */
35 #include "extents.h" /* Just for the EXTENTP abort check... */
36 #define INCLUDE_EVENTS_H_PRIVATE_SPHERE
39 #include "ui/glyphs.h"
40 #include "ui/keymap.h" /* for key_desc_list_to_event() */
41 #include "ui/redisplay.h"
42 #include "ui/window.h"
43 #include "events-mod.h"
45 /* Where old events go when they are explicitly deallocated.
46 The event chain here is cut loose before GC, so these will be freed
49 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
50 static Lisp_Object Vevent_resource;
52 static sxe_mutex_t Vevent_resource_mtx;
53 #endif /* EF_USE_ASYNEQ */
57 Lisp_Object Qevent_live_p;
58 Lisp_Object Qkey_press_event_p;
59 Lisp_Object Qbutton_event_p;
60 Lisp_Object Qmouse_event_p;
61 Lisp_Object Qprocess_event_p;
63 Lisp_Object Qkey_press, Qbutton_press, Qbutton_release, Qmisc_user;
64 Lisp_Object Qascii_character;
66 EXFUN(Fevent_x_pixel, 1);
67 EXFUN(Fevent_y_pixel, 1);
70 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
72 init_Vevent_resource(void)
78 fini_Vevent_resource(void)
84 lock_Vevent_resource(void)
90 unlock_Vevent_resource(void)
94 #elif defined EF_USE_ASYNEQ
96 init_Vevent_resource(void)
98 Vevent_resource = Qnil;
99 SXE_MUTEX_INIT(&Vevent_resource_mtx);
103 fini_Vevent_resource(void)
105 SXE_MUTEX_FINI(&Vevent_resource_mtx);
106 Vevent_resource = Qnil;
110 lock_Vevent_resource(void)
112 SXE_MUTEX_LOCK(&Vevent_resource_mtx);
116 unlock_Vevent_resource(void)
118 SXE_MUTEX_UNLOCK(&Vevent_resource_mtx);
123 init_Vevent_resource(void)
125 Vevent_resource = Qnil;
129 fini_Vevent_resource(void)
131 Vevent_resource = Qnil;
135 lock_Vevent_resource(void)
140 unlock_Vevent_resource(void)
145 /* #### Ad-hoc hack. Should be part of define_lrecord_implementation */
146 void clear_event_resource(void)
148 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
149 lock_Vevent_resource();
150 Vevent_resource = Qnil;
151 unlock_Vevent_resource();
155 /* Make sure we lose quickly if we try to use this event */
156 static void deinitialize_event(Lisp_Object ev)
158 Lisp_Event *event = XEVENT(ev);
160 for (sxe_index_t i = 0; i < (sizeof(Lisp_Event) / sizeof(int)); i++) {
161 ((int*)event)[i] = 0xdeadbeef;
163 event->event_type = dead_event;
164 event->channel = Qnil;
165 set_lheader_implementation(&event->lheader, &lrecord_event);
166 XSET_EVENT_NEXT(ev, Qnil);
169 /* Set everything to zero or nil so that it's predictable. */
170 void zero_event(Lisp_Event * e)
173 set_lheader_implementation(&e->lheader, &lrecord_event);
174 e->event_type = empty_event;
179 static Lisp_Object mark_event(Lisp_Object obj)
181 Lisp_Event *event = XEVENT(obj);
183 switch (event->event_type) {
184 case key_press_event:
185 mark_object(event->event.key.keysym);
188 mark_object(event->event.process.process);
191 mark_object(event->event.timeout.function);
192 mark_object(event->event.timeout.object);
195 case misc_user_event:
196 mark_object(event->event.eval.function);
197 mark_object(event->event.eval.object);
199 case magic_eval_event:
200 mark_object(event->event.magic_eval.object);
203 case work_started_event:
204 if (event->event.work_started.job)
205 mark_object(event->event.work_started.job);
207 case work_finished_event:
208 if (event->event.work_finished.job)
209 mark_object(event->event.work_finished.job);
211 case eaten_myself_event:
213 case button_press_event:
214 case button_release_event:
215 case pointer_motion_event:
223 mark_object(event->channel);
228 print_event_1(const char *str, Lisp_Object obj, Lisp_Object printcharfun)
231 write_c_string(str, printcharfun);
232 format_event_object(buf, XEVENT(obj), 0);
233 write_c_string(buf, printcharfun);
237 print_event(Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
240 error("Printing unreadable object #<event>");
242 switch (XEVENT(obj)->event_type) {
243 case key_press_event:
244 print_event_1("#<keypress-event ", obj, printcharfun);
246 case button_press_event:
247 print_event_1("#<buttondown-event ", obj, printcharfun);
249 case button_release_event:
250 print_event_1("#<buttonup-event ", obj, printcharfun);
253 case magic_eval_event:
254 print_event_1("#<magic-event ", obj, printcharfun);
256 case pointer_motion_event: {
258 Vx = Fevent_x_pixel(obj);
260 Vy = Fevent_y_pixel(obj);
262 write_fmt_str(printcharfun, "#<motion-event %ld, %ld", (long)XINT(Vx),
267 write_c_string("#<process-event ", printcharfun);
268 print_internal(XEVENT(obj)->event.process.process, printcharfun,
272 write_c_string("#<timeout-event ", printcharfun);
273 print_internal(XEVENT(obj)->event.timeout.object, printcharfun,
277 write_c_string("#<empty-event", printcharfun);
279 case misc_user_event:
280 write_c_string("#<misc-user-event (", printcharfun);
281 print_internal(XEVENT(obj)->event.misc.function, printcharfun,
283 write_c_string(" ", printcharfun);
284 print_internal(XEVENT(obj)->event.misc.object, printcharfun, 1);
285 write_c_string(")", printcharfun);
288 write_c_string("#<eval-event (", printcharfun);
289 print_internal(XEVENT(obj)->event.eval.function, printcharfun,
291 write_c_string(" ", printcharfun);
292 print_internal(XEVENT(obj)->event.eval.object, printcharfun, 1);
293 write_c_string(")", printcharfun);
296 write_c_string("#<DEALLOCATED-EVENT", printcharfun);
299 case eaten_myself_event:
300 write_c_string("#<worker-suidice-event", printcharfun);
302 case work_started_event:
303 write_c_string("#<worker-work-started-event", printcharfun);
305 case work_finished_event:
306 write_c_string("#<worker-work-finished-event", printcharfun);
308 #endif /* EF_USE_ASYNEQ */
310 write_c_string("#<UNKNOWN-EVENT-TYPE", printcharfun);
313 write_c_string(">", printcharfun);
317 event_equal(Lisp_Object obj1, Lisp_Object obj2, int depth)
319 Lisp_Event *e1 = XEVENT(obj1);
320 Lisp_Event *e2 = XEVENT(obj2);
322 if (e1->event_type != e2->event_type)
324 if (!EQ(e1->channel, e2->channel))
326 /* if (e1->timestamp != e2->timestamp) return 0; */
327 switch (e1->event_type) {
330 return 1; /* not reached */
333 return EQ(e1->event.process.process, e2->event.process.process);
336 return (internal_equal(e1->event.timeout.function,
337 e2->event.timeout.function, 0) &&
338 internal_equal(e1->event.timeout.object,
339 e2->event.timeout.object, 0));
341 case key_press_event:
342 return (EQ(e1->event.key.keysym, e2->event.key.keysym) &&
343 (e1->event.key.modifiers == e2->event.key.modifiers));
345 case button_press_event:
346 case button_release_event:
347 return (e1->event.button.button == e2->event.button.button &&
348 e1->event.button.modifiers ==
349 e2->event.button.modifiers);
351 case pointer_motion_event:
352 return (e1->event.motion.x == e2->event.motion.x &&
353 e1->event.motion.y == e2->event.motion.y);
355 case misc_user_event:
356 return (internal_equal(e1->event.eval.function,
357 e2->event.eval.function, 0) &&
358 internal_equal(e1->event.eval.object,
359 e2->event.eval.object, 0) &&
360 /* is this really needed for equality
361 or is x and y also important? */
362 e1->event.misc.button == e2->event.misc.button &&
363 e1->event.misc.modifiers == e2->event.misc.modifiers);
366 return (internal_equal(e1->event.eval.function,
367 e2->event.eval.function, 0) &&
368 internal_equal(e1->event.eval.object,
369 e2->event.eval.object, 0));
371 case magic_eval_event:
372 return (e1->event.magic_eval.internal_function ==
373 e2->event.magic_eval.internal_function &&
374 internal_equal(e1->event.magic_eval.object,
375 e2->event.magic_eval.object, 0));
378 struct console *con =
379 XCONSOLE(CDFW_CONSOLE(e1->channel));
381 #ifdef HAVE_X_WINDOWS
382 if (CONSOLE_X_P(con))
383 return (e1->event.magic.underlying_x_event.xany.
385 e2->event.magic.underlying_x_event.xany.
389 if (CONSOLE_TTY_P(con))
390 return (e1->event.magic.underlying_tty_event ==
391 e2->event.magic.underlying_tty_event);
394 return 1; /* not reached */
398 /* worker thread mumbo jumbo is never equal */
399 case eaten_myself_event:
400 case work_started_event:
401 case work_finished_event:
403 #endif /* EF_USE_ASYNEQ */
405 /* Empty and deallocated events are equal. */
413 event_hash(Lisp_Object obj, int depth)
415 Lisp_Event *e = XEVENT(obj);
418 hash = HASH2(e->event_type, LISP_HASH(e->channel));
419 switch (e->event_type) {
421 return HASH2(hash, LISP_HASH(e->event.process.process));
425 internal_hash(e->event.timeout.function,
427 internal_hash(e->event.timeout.object, depth + 1));
429 case key_press_event:
430 return HASH3(hash, LISP_HASH(e->event.key.keysym),
431 e->event.key.modifiers);
433 case button_press_event:
434 case button_release_event:
435 return HASH3(hash, e->event.button.button,
436 e->event.button.modifiers);
438 case pointer_motion_event:
439 return HASH3(hash, e->event.motion.x, e->event.motion.y);
441 case misc_user_event:
443 internal_hash(e->event.misc.function, depth + 1),
444 internal_hash(e->event.misc.object, depth + 1),
445 e->event.misc.button, e->event.misc.modifiers);
449 internal_hash(e->event.eval.function, depth + 1),
450 internal_hash(e->event.eval.object, depth + 1));
452 case magic_eval_event:
454 (unsigned long)e->event.magic_eval.
456 internal_hash(e->event.magic_eval.object,
460 struct console *con =
461 XCONSOLE(CDFW_CONSOLE(EVENT_CHANNEL(e)));
462 #ifdef HAVE_X_WINDOWS
463 if (CONSOLE_X_P(con))
465 e->event.magic.underlying_x_event.
469 if (CONSOLE_TTY_P(con))
472 underlying_tty_event);
479 case eaten_myself_event:
480 case work_started_event:
481 case work_finished_event:
482 return (long unsigned int)obj;
483 #endif /* EF_USE_ASYNEQ */
493 return 0; /* unreached */
496 DEFINE_BASIC_LRECORD_IMPLEMENTATION("event", event,
497 mark_event, print_event, 0, event_equal,
498 event_hash, 0, Lisp_Event);
501 make_empty_event(void)
503 Lisp_Object event = Qnil;
506 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
508 event = allocate_event();
514 lock_Vevent_resource();
515 if (!NILP(Vevent_resource)) {
516 event = Vevent_resource;
517 Vevent_resource = XEVENT_NEXT(event);
519 event = allocate_event();
521 unlock_Vevent_resource();
526 e->event_type = empty_event;
528 EVENT_CHANNEL(e) = Qnil;
535 make_noseeum_event(emacs_event_type event_type)
537 sxe_event_t res = xnew_and_zero(Lisp_Event);
539 res->event_type = event_type;
541 EVENT_CHANNEL(res) = Qnil;
545 DEFUN("make-event", Fmake_event, 0, 2, 0, /*
546 Return a new event of type TYPE, with properties described by PLIST.
548 TYPE is a symbol, either `empty', `key-press', `button-press',
549 `button-release', `misc-user' or `motion'. If TYPE is nil, it
552 PLIST is a property list, the properties being compatible to those
553 returned by `event-properties'. The following properties are
556 channel -- The event channel, a frame or a console. For
557 button-press, button-release, misc-user and motion events,
558 this must be a frame. For key-press events, it must be
559 a console. If channel is unspecified, it will be set to
560 the selected frame or selected console, as appropriate.
561 key -- The event key, a symbol or character. Allowed only for
563 button -- The event button, integer 1, 2 or 3. Allowed for
564 button-press, button-release and misc-user events.
565 modifiers -- The event modifiers, a list of modifier symbols. Allowed
566 for key-press, button-press, button-release, motion and
568 function -- Function. Allowed for misc-user events only.
569 object -- An object, function's parameter. Allowed for misc-user
571 x -- The event X coordinate, an integer. This is relative
572 to the left of CHANNEL's root window. Allowed for
573 motion, button-press, button-release and misc-user events.
574 y -- The event Y coordinate, an integer. This is relative
575 to the top of CHANNEL's root window. Allowed for
576 motion, button-press, button-release and misc-user events.
577 timestamp -- The event timestamp, a non-negative integer. Allowed for
578 all types of events. If unspecified, it will be set to 0
581 For event type `empty', PLIST must be nil.
582 `button-release', or `motion'. If TYPE is left out, it defaults to
584 PLIST is a list of properties, as returned by `event-properties'. Not
585 all properties are allowed for all kinds of events, and some are
588 WARNING: the event object returned may be a reused one; see the function
593 Lisp_Object event = Qnil;
595 EMACS_INT coord_x = 0, coord_y = 0;
600 return make_empty_event();
603 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
604 event = allocate_event();
608 lock_Vevent_resource();
609 if (!NILP(Vevent_resource)) {
610 event = Vevent_resource;
611 Vevent_resource = XEVENT_NEXT(event);
613 event = allocate_event();
615 unlock_Vevent_resource();
620 if (EQ(type, Qempty)) {
621 /* For empty event, we return immediately, without processing
622 PLIST. In fact, processing PLIST would be wrong, because the
623 sanitizing process would fill in the properties
624 (e.g. CHANNEL), which we don't want in empty events. */
625 e->event_type = empty_event;
627 syntax_error("Cannot set properties of empty event",
631 } else if (EQ(type, Qkey_press)) {
632 e->event_type = key_press_event;
633 e->event.key.keysym = Qunbound;
634 } else if (EQ(type, Qbutton_press)) {
635 e->event_type = button_press_event;
636 } else if (EQ(type, Qbutton_release)) {
637 e->event_type = button_release_event;
638 } else if (EQ(type, Qmotion)) {
639 e->event_type = pointer_motion_event;
640 } else if (EQ(type, Qmisc_user)) {
641 e->event_type = misc_user_event;
642 e->event.eval.function = e->event.eval.object = Qnil;
645 Qprocess, Qtimeout, Qmagic, Qeval, Qmagic_eval. */
646 invalid_argument("Invalid event type", type);
649 EVENT_CHANNEL(e) = Qnil;
651 plist = Fcopy_sequence(plist);
652 Fcanonicalize_plist(plist, Qnil);
654 #define WRONG_EVENT_TYPE_FOR_PROPERTY(event_type, prop) \
655 syntax_error_2 ("Invalid property for event type", prop, event_type)
658 EXTERNAL_PROPERTY_LIST_LOOP_3(keyword, value, plist) {
659 if (EQ(keyword, Qchannel)) {
660 if (e->event_type == key_press_event) {
661 if (!CONSOLEP(value))
668 wrong_type_argument(Qframep,
671 EVENT_CHANNEL(e) = value;
672 } else if (EQ(keyword, Qkey)) {
673 switch (e->event_type) {
674 case key_press_event:
675 if (!SYMBOLP(value) && !CHARP(value))
677 ("Invalid event key",
679 e->event.key.keysym = value;
684 case button_press_event:
685 case button_release_event:
686 case pointer_motion_event:
690 case magic_eval_event:
692 case misc_user_event:
694 case eaten_myself_event:
695 case work_started_event:
696 case work_finished_event:
697 #endif /* EF_USE_ASYNEQ */
700 WRONG_EVENT_TYPE_FOR_PROPERTY(type,
704 } else if (EQ(keyword, Qbutton)) {
706 check_int_range(XINT(value), 0, 7);
708 switch (e->event_type) {
709 case button_press_event:
710 case button_release_event:
711 e->event.button.button = XINT(value);
713 case misc_user_event:
714 e->event.misc.button = XINT(value);
717 /* and the rest of that lot */
719 case key_press_event:
720 case pointer_motion_event:
724 case magic_eval_event:
727 case eaten_myself_event:
728 case work_started_event:
729 case work_finished_event:
730 #endif /* EF_USE_ASYNEQ */
733 WRONG_EVENT_TYPE_FOR_PROPERTY(type,
737 } else if (EQ(keyword, Qmodifiers)) {
740 EXTERNAL_LIST_LOOP_2(sym, value) {
741 if (EQ(sym, Qcontrol))
742 modifiers |= XEMACS_MOD_CONTROL;
743 else if (EQ(sym, Qmeta))
744 modifiers |= XEMACS_MOD_META;
745 else if (EQ(sym, Qsuper))
746 modifiers |= XEMACS_MOD_SUPER;
747 else if (EQ(sym, Qhyper))
748 modifiers |= XEMACS_MOD_HYPER;
749 else if (EQ(sym, Qalt))
750 modifiers |= XEMACS_MOD_ALT;
751 else if (EQ(sym, Qsymbol))
752 modifiers |= XEMACS_MOD_ALT;
753 else if (EQ(sym, Qshift))
754 modifiers |= XEMACS_MOD_SHIFT;
755 else if (EQ(sym, Qbutton1))
756 modifiers |= XEMACS_MOD_BUTTON1;
757 else if (EQ(sym, Qbutton2))
758 modifiers |= XEMACS_MOD_BUTTON2;
759 else if (EQ(sym, Qbutton3))
760 modifiers |= XEMACS_MOD_BUTTON3;
761 else if (EQ(sym, Qbutton4))
762 modifiers |= XEMACS_MOD_BUTTON4;
763 else if (EQ(sym, Qbutton5))
764 modifiers |= XEMACS_MOD_BUTTON5;
767 ("Invalid key modifier",
771 switch (e->event_type) {
772 case key_press_event:
773 e->event.key.modifiers = modifiers;
775 case button_press_event:
776 case button_release_event:
777 e->event.button.modifiers = modifiers;
779 case pointer_motion_event:
780 e->event.motion.modifiers = modifiers;
782 case misc_user_event:
783 e->event.misc.modifiers = modifiers;
786 /* here come the rest */
791 case magic_eval_event:
794 case eaten_myself_event:
795 case work_started_event:
796 case work_finished_event:
797 #endif /* EF_USE_ASYNEQ */
800 WRONG_EVENT_TYPE_FOR_PROPERTY(type,
804 } else if (EQ(keyword, Qx)) {
805 switch (e->event_type) {
806 case pointer_motion_event:
807 case button_press_event:
808 case button_release_event:
809 case misc_user_event:
810 /* Allow negative values, so we can specify toolbar
813 coord_x = XINT(value);
818 case key_press_event:
822 case magic_eval_event:
825 case eaten_myself_event:
826 case work_started_event:
827 case work_finished_event:
828 #endif /* EF_USE_ASYNEQ */
831 WRONG_EVENT_TYPE_FOR_PROPERTY(type,
835 } else if (EQ(keyword, Qy)) {
836 switch (e->event_type) {
837 case pointer_motion_event:
838 case button_press_event:
839 case button_release_event:
840 case misc_user_event:
841 /* Allow negative values; see above. */
843 coord_y = XINT(value);
848 case key_press_event:
852 case magic_eval_event:
855 case eaten_myself_event:
856 case work_started_event:
857 case work_finished_event:
858 #endif /* EF_USE_ASYNEQ */
861 WRONG_EVENT_TYPE_FOR_PROPERTY(type,
865 } else if (EQ(keyword, Qtimestamp)) {
867 e->timestamp = XINT(value);
868 } else if (EQ(keyword, Qfunction)) {
869 switch (e->event_type) {
870 case misc_user_event:
871 e->event.eval.function = value;
876 case key_press_event:
877 case button_press_event:
878 case button_release_event:
879 case pointer_motion_event:
883 case magic_eval_event:
886 case eaten_myself_event:
887 case work_started_event:
888 case work_finished_event:
889 #endif /* EF_USE_ASYNEQ */
892 WRONG_EVENT_TYPE_FOR_PROPERTY(type,
896 } else if (EQ(keyword, Qobject)) {
897 switch (e->event_type) {
898 case misc_user_event:
899 e->event.eval.object = value;
904 case key_press_event:
905 case button_press_event:
906 case button_release_event:
907 case pointer_motion_event:
911 case magic_eval_event:
914 case eaten_myself_event:
915 case work_started_event:
916 case work_finished_event:
917 #endif /* EF_USE_ASYNEQ */
920 WRONG_EVENT_TYPE_FOR_PROPERTY(type,
925 syntax_error_2("Invalid property", keyword,
930 /* Insert the channel, if missing. */
931 if (NILP(EVENT_CHANNEL(e))) {
932 if (e->event_type == key_press_event)
933 EVENT_CHANNEL(e) = Vselected_console;
935 EVENT_CHANNEL(e) = Fselected_frame(Qnil);
938 /* Fevent_properties, Fevent_x_pixel, etc. work with pixels relative
939 to the frame, so we must adjust accordingly. */
940 if (FRAMEP(EVENT_CHANNEL(e))) {
942 FRAME_REAL_LEFT_TOOLBAR_WIDTH(XFRAME(EVENT_CHANNEL(e)));
944 FRAME_REAL_TOP_TOOLBAR_HEIGHT(XFRAME(EVENT_CHANNEL(e)));
946 switch (e->event_type) {
947 case pointer_motion_event:
948 e->event.motion.x = coord_x;
949 e->event.motion.y = coord_y;
951 case button_press_event:
952 case button_release_event:
953 e->event.button.x = coord_x;
954 e->event.button.y = coord_y;
956 case misc_user_event:
957 e->event.misc.x = coord_x;
958 e->event.misc.y = coord_y;
963 case key_press_event:
967 case magic_eval_event:
970 case eaten_myself_event:
971 case work_started_event:
972 case work_finished_event:
973 #endif /* EF_USE_ASYNEQ */
980 /* Finally, do some more validation. */
981 switch (e->event_type) {
982 case key_press_event:
983 if (UNBOUNDP(e->event.key.keysym))
985 ("A key must be specified to make a "
986 "keypress event", plist);
988 case button_press_event:
989 if (!e->event.button.button)
991 ("A button must be specified to make a "
992 "button-press event", plist);
994 case button_release_event:
995 if (!e->event.button.button)
997 ("A button must be specified to make a "
998 "button-release event", plist);
1000 case misc_user_event:
1001 if (NILP(e->event.misc.function))
1003 ("A function must be specified to make a "
1004 "misc-user event", plist);
1008 case pointer_motion_event:
1012 case magic_eval_event:
1014 #ifdef EF_USE_ASYNEQ
1015 case eaten_myself_event:
1016 case work_started_event:
1017 case work_finished_event:
1018 #endif /* EF_USE_ASYNEQ */
1028 DEFUN("deallocate-event", Fdeallocate_event, 1, 1, 0, /*
1029 Allow the given event structure to be reused.
1030 You MUST NOT use this event object after calling this function with it.
1031 You will lose. It is not necessary to call this function, as event
1032 objects are garbage-collected like all other objects; however, it may
1033 be more efficient to explicitly deallocate events when you are sure
1034 that it is safe to do so.
1040 if (XEVENT_TYPE(event) == dead_event)
1041 error("this event is already deallocated!");
1043 assert(XEVENT_TYPE(event) <= last_event_type);
1049 if (EQ(event, Vlast_command_event) ||
1050 EQ(event, Vlast_input_event) ||
1051 EQ(event, Vunread_command_event))
1054 len = XVECTOR_LENGTH(Vthis_command_keys);
1055 for (i = 0; i < len; i++)
1056 if (EQ(event, XVECTOR_DATA(Vthis_command_keys)[i]))
1058 if (!NILP(Vrecent_keys_ring)) {
1059 int recent_ring_len = XVECTOR_LENGTH(Vrecent_keys_ring);
1060 for (i = 0; i < recent_ring_len; i++)
1062 (event, XVECTOR_DATA(Vrecent_keys_ring)[i]))
1068 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
1069 lock_Vevent_resource();
1070 assert(!EQ(event, Vevent_resource));
1071 unlock_Vevent_resource();
1073 deinitialize_event(event);
1074 #if !defined ALLOC_NO_POOLS && !(defined HAVE_BDWGC && defined EF_USE_BDWGC)
1075 lock_Vevent_resource();
1076 XSET_EVENT_NEXT(event, Vevent_resource);
1077 Vevent_resource = event;
1078 unlock_Vevent_resource();
1083 DEFUN("copy-event", Fcopy_event, 1, 2, 0, /*
1084 Make a copy of the event object EVENT1.
1085 If a second event argument EVENT2 is given, EVENT1 is copied into
1086 EVENT2 and EVENT2 is returned. If EVENT2 is not supplied (or is nil)
1087 then a new event will be made as with `make-event'. See also the
1088 function `deallocate-event'.
1092 CHECK_LIVE_EVENT(event1);
1094 event2 = Fmake_event(Qnil, Qnil);
1096 CHECK_LIVE_EVENT(event2);
1097 if (EQ(event1, event2))
1098 return signal_simple_continuable_error_2
1099 ("copy-event called with `eq' events", event1,
1103 assert(XEVENT_TYPE(event1) <= last_event_type);
1104 assert(XEVENT_TYPE(event2) <= last_event_type);
1107 Lisp_Event *ev2 = XEVENT(event2);
1108 Lisp_Event *ev1 = XEVENT(event1);
1110 ev2->event_type = ev1->event_type;
1111 ev2->channel = ev1->channel;
1112 ev2->timestamp = ev1->timestamp;
1113 ev2->event = ev1->event;
1119 /* Given a chain of events (or possibly nil), deallocate them all. */
1121 void deallocate_event_chain(Lisp_Object event_chain)
1123 while (!NILP(event_chain)) {
1124 Lisp_Object next = XEVENT_NEXT(event_chain);
1125 Fdeallocate_event(event_chain);
1130 /* Return the last event in a chain.
1131 NOTE: You cannot pass nil as a value here! The routine will
1134 Lisp_Object event_chain_tail(Lisp_Object event_chain)
1137 Lisp_Object next = XEVENT_NEXT(event_chain);
1144 /* Enqueue a single event onto the end of a chain of events.
1145 HEAD points to the first event in the chain, TAIL to the last event.
1146 If the chain is empty, both values should be nil. */
1148 void enqueue_event(Lisp_Object event, Lisp_Object * head, Lisp_Object * tail)
1150 assert(NILP(XEVENT_NEXT(event)));
1151 assert(!EQ(*tail, event));
1154 XSET_EVENT_NEXT(*tail, event);
1159 assert(!EQ(event, XEVENT_NEXT(event)));
1162 /* Remove an event off the head of a chain of events and return it.
1163 HEAD points to the first event in the chain, TAIL to the last event. */
1165 Lisp_Object dequeue_event(Lisp_Object * head, Lisp_Object * tail)
1170 *head = XEVENT_NEXT(event);
1171 XSET_EVENT_NEXT(event, Qnil);
1177 /* Enqueue a chain of events (or possibly nil) onto the end of another
1178 chain of events. HEAD points to the first event in the chain being
1179 queued onto, TAIL to the last event. If the chain is empty, both values
1183 enqueue_event_chain(Lisp_Object event_chain, Lisp_Object * head,
1186 if (NILP(event_chain))
1190 *head = event_chain;
1191 *tail = event_chain;
1193 XSET_EVENT_NEXT(*tail, event_chain);
1194 *tail = event_chain_tail(event_chain);
1198 /* Return the number of events (possibly 0) on an event chain. */
1200 int event_chain_count(Lisp_Object event_chain)
1205 EVENT_CHAIN_LOOP(event, event_chain) {
1212 /* Find the event before EVENT in an event chain. This aborts
1213 if the event is not in the chain. */
1216 event_chain_find_previous(Lisp_Object event_chain, Lisp_Object event)
1218 Lisp_Object previous = Qnil;
1220 while (!NILP(event_chain)) {
1221 if (EQ(event_chain, event)) {
1224 previous = event_chain;
1225 event_chain = XEVENT_NEXT(event_chain);
1232 Lisp_Object event_chain_nth(Lisp_Object event_chain, int n)
1235 EVENT_CHAIN_LOOP(event, event_chain) {
1244 Lisp_Object copy_event_chain(Lisp_Object event_chain)
1246 Lisp_Object new_chain = Qnil;
1247 Lisp_Object new_chain_tail = Qnil;
1250 EVENT_CHAIN_LOOP(event, event_chain) {
1251 Lisp_Object copy = Fcopy_event(event, Qnil);
1252 enqueue_event(copy, &new_chain, &new_chain_tail);
1258 Lisp_Object QKbackspace, QKtab, QKlinefeed, QKreturn, QKescape,
1261 int command_event_p(Lisp_Object event)
1263 switch (XEVENT_TYPE(event)) {
1264 case key_press_event:
1265 case button_press_event:
1266 case button_release_event:
1267 case misc_user_event:
1271 case pointer_motion_event:
1275 case magic_eval_event:
1277 #ifdef EF_USE_ASYNEQ
1278 case eaten_myself_event:
1279 case work_started_event:
1280 case work_finished_event:
1281 #endif /* EF_USE_ASYNEQ */
1289 character_to_event(Emchar c, Lisp_Event * event, struct console *con,
1290 int use_console_meta_flag, int do_backspace_mapping)
1292 Lisp_Object k = Qnil;
1294 if (event->event_type == dead_event)
1295 error("character-to-event called with a deallocated event!");
1300 if (c > 127 && c <= 255) {
1303 if (use_console_meta_flag && CONSOLE_TTY_P(con)) {
1304 meta_flag = TTY_FLAGS(con).meta_key;
1306 switch (meta_flag) {
1307 case 0: /* ignore top bit; it's parity */
1310 case 1: /* top bit is meta */
1312 m = XEMACS_MOD_META;
1314 default: /* this is a real character */
1319 c += '@', m |= XEMACS_MOD_CONTROL;
1320 if (m & XEMACS_MOD_CONTROL) {
1324 m &= ~XEMACS_MOD_CONTROL;
1328 m &= ~XEMACS_MOD_CONTROL;
1332 m &= ~XEMACS_MOD_CONTROL;
1336 m &= ~XEMACS_MOD_CONTROL;
1339 #if defined(HAVE_TTY)
1340 if (do_backspace_mapping &&
1341 CHARP(con->tty_erase_char) &&
1342 c - '@' == XCHAR(con->tty_erase_char)) {
1344 m &= ~XEMACS_MOD_CONTROL;
1346 #endif /* defined(HAVE_TTY) */
1349 if (c >= 'A' && c <= 'Z')
1352 #if defined(HAVE_TTY)
1353 else if (do_backspace_mapping &&
1354 CHARP(con->tty_erase_char) && c == XCHAR(con->tty_erase_char))
1356 #endif /* defined(HAVE_TTY) */
1362 event->event_type = key_press_event;
1363 event->timestamp = 0; /* #### */
1364 event->channel = make_console(con);
1365 event->event.key.keysym = (!NILP(k) ? k : make_char(c));
1366 event->event.key.modifiers = m;
1369 /* This variable controls what character name -> character code mapping
1370 we are using. Window-system-specific code sets this to some symbol,
1371 and we use that symbol as the plist key to convert keysyms into 8-bit
1372 codes. In this way one can have several character sets predefined and
1373 switch them by changing this.
1375 #### This is utterly bogus and should be removed.
1377 Lisp_Object Vcharacter_set_property;
1380 event_to_character(Lisp_Event * event,
1381 int allow_extra_modifiers,
1382 int allow_meta, int allow_non_ascii)
1387 if (event->event_type != key_press_event) {
1388 assert(event->event_type != dead_event);
1391 if (!allow_extra_modifiers &&
1393 modifiers & (XEMACS_MOD_SUPER | XEMACS_MOD_HYPER | XEMACS_MOD_ALT))
1395 if (CHAR_OR_CHAR_INTP(event->event.key.keysym))
1396 c = XCHAR_OR_CHAR_INT(event->event.key.keysym);
1397 else if (!SYMBOLP(event->event.key.keysym))
1399 else if (allow_non_ascii && !NILP(Vcharacter_set_property)
1400 /* Allow window-system-specific extensibility of
1401 keysym->code mapping */
1402 && CHAR_OR_CHAR_INTP(code = Fget(event->event.key.keysym,
1403 Vcharacter_set_property,
1405 c = XCHAR_OR_CHAR_INT(code);
1406 else if (CHAR_OR_CHAR_INTP(code = Fget(event->event.key.keysym,
1407 Qascii_character, Qnil)))
1408 c = XCHAR_OR_CHAR_INT(code);
1412 if (event->event.key.modifiers & XEMACS_MOD_CONTROL) {
1413 if (c >= 'a' && c <= 'z')
1416 /* reject Control-Shift- keys */
1417 if (c >= 'A' && c <= 'Z' && !allow_extra_modifiers)
1420 if (c >= '@' && c <= '_')
1422 else if (c == ' ') /* C-space and C-@ are the same. */
1425 /* reject keys that can't take Control- modifiers */
1426 if (!allow_extra_modifiers)
1430 if (event->event.key.modifiers & XEMACS_MOD_META) {
1434 return -1; /* don't allow M-oslash (overlap) */
1444 DEFUN("event-to-character", Fevent_to_character, 1, 4, 0, /*
1445 Return the closest ASCII approximation to the given event object.
1446 If the event isn't a keypress, this returns nil.
1447 If the ALLOW-EXTRA-MODIFIERS argument is non-nil, then this is lenient in
1448 its translation; it will ignore modifier keys other than control and meta,
1449 and will ignore the shift modifier on those characters which have no
1450 shifted ASCII equivalent (Control-Shift-A for example, will be mapped to
1451 the same ASCII code as Control-A).
1452 If the ALLOW-META argument is non-nil, then the Meta modifier will be
1453 represented by turning on the high bit of the byte returned; otherwise, nil
1454 will be returned for events containing the Meta modifier.
1455 If the ALLOW-NON-ASCII argument is non-nil, then characters which are
1456 present in the prevailing character set (see the `character-set-property'
1457 variable) will be returned as their code in that character set, instead of
1458 the return value being restricted to ASCII.
1459 Note that specifying both ALLOW-META and ALLOW-NON-ASCII is ambiguous, as
1460 both use the high bit; `M-x' and `oslash' will be indistinguishable.
1462 (event, allow_extra_modifiers, allow_meta, allow_non_ascii))
1465 CHECK_LIVE_EVENT(event);
1466 c = event_to_character(XEVENT(event),
1467 !NILP(allow_extra_modifiers),
1468 !NILP(allow_meta), !NILP(allow_non_ascii));
1469 return c < 0 ? Qnil : make_char(c);
1472 DEFUN("character-to-event", Fcharacter_to_event, 1, 4, 0, /*
1473 Convert KEY-DESCRIPTION into an event structure, replete with bucky bits.
1475 KEY-DESCRIPTION is the first argument, and the event to fill in is the
1476 second. This function contains knowledge about what various kinds of
1477 arguments ``mean'' -- for example, the number 9 is converted to the
1478 character ``Tab'', not the distinct character ``Control-I''.
1480 KEY-DESCRIPTION can be an integer, a character, a symbol such as 'clear,
1481 or a list such as '(control backspace).
1483 If the optional second argument EVENT is an event, it is modified and
1484 returned; otherwise, a new event object is created and returned.
1486 Optional third arg CONSOLE is the console to store in the event, and
1487 defaults to the selected console.
1489 If KEY-DESCRIPTION is an integer or character, the high bit may be
1490 interpreted as the meta key. (This is done for backward compatibility
1491 in lots of places.) If USE-CONSOLE-META-FLAG is nil, this will always
1492 be the case. If USE-CONSOLE-META-FLAG is non-nil, the `meta' flag for
1493 CONSOLE affects whether the high bit is interpreted as a meta
1494 key. (See `set-input-mode'.) If you don't want this silly meta
1495 interpretation done, you should pass in a list containing the
1498 Beware that character-to-event and event-to-character are not strictly
1499 inverse functions, since events contain much more information than the
1500 Lisp character object type can encode.
1502 (keystroke, event, console, use_console_meta_flag))
1504 struct console *con = decode_console(console);
1506 event = Fmake_event(Qnil, Qnil);
1508 CHECK_LIVE_EVENT(event);
1509 if (CONSP(keystroke) || SYMBOLP(keystroke))
1510 key_desc_list_to_event(keystroke, event, 1);
1512 CHECK_CHAR_COERCE_INT(keystroke);
1513 character_to_event(XCHAR(keystroke), XEVENT(event), con,
1514 !NILP(use_console_meta_flag), 1);
1519 void nth_of_key_sequence_as_event(Lisp_Object seq, int n, Lisp_Object event)
1521 assert(STRINGP(seq) || VECTORP(seq));
1522 assert(n < XINT(Flength(seq)));
1525 Emchar ch = string_char(XSTRING(seq), n);
1526 Fcharacter_to_event(make_char(ch), event, Qnil, Qnil);
1528 Lisp_Object keystroke = XVECTOR_DATA(seq)[n];
1529 if (EVENTP(keystroke))
1530 Fcopy_event(keystroke, event);
1532 Fcharacter_to_event(keystroke, event, Qnil, Qnil);
1536 Lisp_Object key_sequence_to_event_chain(Lisp_Object seq)
1538 int len = XINT(Flength(seq));
1540 Lisp_Object head = Qnil, tail = Qnil;
1542 for (i = 0; i < len; i++) {
1543 Lisp_Object event = Fmake_event(Qnil, Qnil);
1544 nth_of_key_sequence_as_event(seq, i, event);
1545 enqueue_event(event, &head, &tail);
1551 void format_event_object(char *buf, Lisp_Event * event, int brief)
1557 switch (event->event_type) {
1558 case key_press_event: {
1559 mod = event->event.key.modifiers;
1560 key = event->event.key.keysym;
1562 if (!brief && CHARP(key) &&
1563 mod & (XEMACS_MOD_CONTROL | XEMACS_MOD_META |
1564 XEMACS_MOD_SUPER | XEMACS_MOD_HYPER)) {
1566 if (k >= 'a' && k <= 'z')
1567 key = make_char(k - ('a' - 'A'));
1568 else if (k >= 'A' && k <= 'Z')
1569 mod |= XEMACS_MOD_SHIFT;
1573 case button_release_event:
1576 case button_press_event: {
1578 mod = event->event.button.modifiers;
1579 key = make_char(event->event.button.button + '0');
1583 const char *name = NULL;
1585 #ifdef HAVE_X_WINDOWS
1586 Lisp_Object console = CDFW_CONSOLE(EVENT_CHANNEL(event));
1587 if (CONSOLE_X_P(XCONSOLE(console))) {
1588 name = x_event_name(event->event.magic.
1592 #endif /* HAVE_X_WINDOWS */
1601 case magic_eval_event:
1602 strcpy(buf, "magic-eval");
1604 case pointer_motion_event:
1605 strcpy(buf, "motion");
1607 case misc_user_event:
1608 strcpy(buf, "misc-user");
1611 strcpy(buf, "eval");
1614 strcpy(buf, "process");
1617 strcpy(buf, "timeout");
1620 strcpy(buf, "empty");
1623 strcpy(buf, "DEAD-EVENT");
1625 #ifdef EF_USE_ASYNEQ
1626 case eaten_myself_event:
1627 strcpy(buf, "suicide");
1629 case work_started_event:
1630 strcpy(buf, "started-work");
1632 case work_finished_event:
1633 strcpy(buf, "finished-work");
1635 #endif /* EF_USE_ASYNEQ */
1641 #define modprint1(x) do { strcpy (buf, (x)); buf += sizeof (x)-1; } while (0)
1642 #define modprint(x,y) do { if (brief) modprint1 (y); else modprint1 (x); } while (0)
1643 if (mod & XEMACS_MOD_CONTROL)
1644 modprint("control-", "C-");
1645 if (mod & XEMACS_MOD_META)
1646 modprint("meta-", "M-");
1647 if (mod & XEMACS_MOD_SUPER)
1648 modprint("super-", "S-");
1649 if (mod & XEMACS_MOD_HYPER)
1650 modprint("hyper-", "H-");
1651 if (mod & XEMACS_MOD_ALT)
1652 modprint("alt-", "A-");
1653 if (mod & XEMACS_MOD_SHIFT)
1654 modprint("shift-", "Sh-");
1656 modprint1("button");
1663 buf += set_charptr_emchar((Bufbyte *) buf, XCHAR(key));
1665 } else if (SYMBOLP(key)) {
1666 const char *str = 0;
1668 if (EQ(key, QKlinefeed))
1670 else if (EQ(key, QKtab))
1672 else if (EQ(key, QKreturn))
1674 else if (EQ(key, QKescape))
1676 else if (EQ(key, QKdelete))
1678 else if (EQ(key, QKspace))
1680 else if (EQ(key, QKbackspace))
1684 int i = strlen(str);
1685 memcpy(buf, str, i + 1);
1688 Lisp_String *name = XSYMBOL(key)->name;
1689 memcpy(buf, string_data(name), string_length(name) + 1);
1690 str += string_length(name);
1695 strncpy(buf, "up", 4);
1698 DEFUN("eventp", Feventp, 1, 1, 0, /*
1699 True if OBJECT is an event object.
1703 return EVENTP(object) ? Qt : Qnil;
1706 DEFUN("event-live-p", Fevent_live_p, 1, 1, 0, /*
1707 True if OBJECT is an event object that has not been deallocated.
1711 return EVENTP(object) && XEVENT(object)->event_type != dead_event ?
1715 #if 0 /* debugging functions */
1717 xxDEFUN("event-next", Fevent_next, 1, 1, 0, /*
1718 Return the event object's `next' event, or nil if it has none.
1719 The `next-event' field is changed by calling `set-next-event'.
1724 CHECK_LIVE_EVENT(event);
1726 return XEVENT_NEXT(event);
1729 xxDEFUN("set-event-next", Fset_event_next, 2, 2, 0, /*
1730 Set the `next event' of EVENT to NEXT-EVENT.
1731 NEXT-EVENT must be an event object or nil.
1733 (event, next_event))
1737 CHECK_LIVE_EVENT(event);
1738 if (NILP(next_event)) {
1739 XSET_EVENT_NEXT(event, Qnil);
1743 CHECK_LIVE_EVENT(next_event);
1745 EVENT_CHAIN_LOOP(ev, XEVENT_NEXT(event)) {
1748 signal_error(Qerror,
1749 list3(build_string("Cyclic event-next"),
1750 event, next_event));
1752 XSET_EVENT_NEXT(event, next_event);
1758 DEFUN("event-type", Fevent_type, 1, 1, 0, /*
1759 Return the type of EVENT.
1760 This will be a symbol; one of
1762 key-press A key was pressed.
1763 button-press A mouse button was pressed.
1764 button-release A mouse button was released.
1765 misc-user Some other user action happened; typically, this is
1766 a menu selection or scrollbar action.
1767 motion The mouse moved.
1768 process Input is available from a subprocess.
1769 timeout A timeout has expired.
1770 eval This causes a specified action to occur when dispatched.
1771 magic Some window-system-specific event has occurred.
1772 empty The event has been allocated but not assigned.
1777 CHECK_LIVE_EVENT(event);
1778 switch (XEVENT(event)->event_type) {
1779 case key_press_event:
1781 case button_press_event:
1782 return Qbutton_press;
1783 case button_release_event:
1784 return Qbutton_release;
1785 case misc_user_event:
1787 case pointer_motion_event:
1796 case magic_eval_event:
1799 #ifdef EF_USE_ASYNEQ
1800 case eaten_myself_event:
1801 return Qworker_suicide;
1802 case work_started_event:
1803 return Qworker_started_work;
1804 case work_finished_event:
1805 return Qworker_finished_work;
1806 #endif /* EF_USE_ASYNEQ */
1818 DEFUN("event-timestamp", Fevent_timestamp, 1, 1, 0, /*
1819 Return the timestamp of the event object EVENT.
1820 Timestamps are measured in milliseconds since the start of the window system.
1821 They are NOT related to any current time measurement.
1822 They should be compared with `event-timestamp<'.
1823 See also `current-event-timestamp'.
1827 CHECK_LIVE_EVENT(event);
1828 /* This junk is so that timestamps don't get to be negative, but contain
1829 as many bits as this particular emacs will allow.
1831 return make_int(EMACS_INT_MAX & XEVENT(event)->timestamp);
1834 #define TIMESTAMP_HALFSPACE (1L << (INT_VALBITS - 2))
1836 DEFUN("event-timestamp<", Fevent_timestamp_lessp, 2, 2, 0, /*
1837 Return true if timestamp TIME1 is earlier than timestamp TIME2.
1838 This correctly handles timestamp wrap.
1839 See also `event-timestamp' and `current-event-timestamp'.
1845 CHECK_NATNUM(time1);
1846 CHECK_NATNUM(time2);
1851 return t2 - t1 < TIMESTAMP_HALFSPACE ? Qt : Qnil;
1853 return t1 - t2 < TIMESTAMP_HALFSPACE ? Qnil : Qt;
1856 #define CHECK_EVENT_TYPE(e,t1,sym) do { \
1857 CHECK_LIVE_EVENT (e); \
1858 if (XEVENT(e)->event_type != (t1)) \
1859 e = wrong_type_argument (sym,e); \
1862 #define CHECK_EVENT_TYPE2(e,t1,t2,sym) do { \
1863 CHECK_LIVE_EVENT (e); \
1865 emacs_event_type CET_type = XEVENT (e)->event_type; \
1866 if (CET_type != (t1) && \
1868 e = wrong_type_argument (sym,e); \
1872 #define CHECK_EVENT_TYPE3(e,t1,t2,t3,sym) do { \
1873 CHECK_LIVE_EVENT (e); \
1875 emacs_event_type CET_type = XEVENT (e)->event_type; \
1876 if (CET_type != (t1) && \
1877 CET_type != (t2) && \
1879 e = wrong_type_argument (sym,e); \
1883 DEFUN("event-key", Fevent_key, 1, 1, 0, /*
1884 Return the Keysym of the key-press event EVENT.
1885 This will be a character if the event is associated with one, else a symbol.
1889 CHECK_EVENT_TYPE(event, key_press_event, Qkey_press_event_p);
1890 return XEVENT(event)->event.key.keysym;
1893 DEFUN("event-button", Fevent_button, 1, 1, 0, /*
1894 Return the button-number of the button-press or button-release event EVENT.
1899 CHECK_EVENT_TYPE3(event, button_press_event, button_release_event,
1900 misc_user_event, Qbutton_event_p);
1901 #ifdef HAVE_WINDOW_SYSTEM
1902 if (XEVENT(event)->event_type == misc_user_event)
1903 return make_int(XEVENT(event)->event.misc.button);
1905 return make_int(XEVENT(event)->event.button.button);
1906 #else /* !HAVE_WINDOW_SYSTEM */
1908 #endif /* !HAVE_WINDOW_SYSTEM */
1912 DEFUN("event-modifier-bits", Fevent_modifier_bits, 1, 1, 0, /*
1913 Return a number representing the modifier keys and buttons which were down
1914 when the given mouse or keyboard event was produced.
1915 See also the function `event-modifiers'.
1920 CHECK_LIVE_EVENT(event);
1921 switch (XEVENT(event)->event_type) {
1922 case key_press_event:
1923 return make_int(XEVENT(event)->event.key.modifiers);
1924 case button_press_event:
1925 case button_release_event:
1926 return make_int(XEVENT(event)->event.button.modifiers);
1927 case pointer_motion_event:
1928 return make_int(XEVENT(event)->event.motion.modifiers);
1929 case misc_user_event:
1930 return make_int(XEVENT(event)->event.misc.modifiers);
1936 case magic_eval_event:
1938 #ifdef EF_USE_ASYNEQ
1939 case eaten_myself_event:
1940 case work_started_event:
1941 case work_finished_event:
1942 #endif /* EF_USE_ASYNEQ */
1945 event = wrong_type_argument(
1946 intern("key-or-mouse-event-p"), event);
1951 DEFUN("event-modifiers", Fevent_modifiers, 1, 1, 0, /*
1952 Return a list of symbols, the names of the modifier keys and buttons
1953 which were down when the given mouse or keyboard event was produced.
1954 See also the function `event-modifier-bits'.
1956 The possible symbols in the list are
1958 `shift': The Shift key. Will not appear, in general, on key events
1959 where the keysym is an ASCII character, because using Shift
1960 on such a character converts it into another character rather
1961 than actually just adding a Shift modifier.
1963 `control': The Control key.
1965 `meta': The Meta key. On PC's and PC-style keyboards, this is generally
1966 labelled \"Alt\"; Meta is a holdover from early Lisp Machines and
1967 such, propagated through the X Window System. On Sun keyboards,
1968 this key is labelled with a diamond.
1970 `alt': The \"Alt\" key. Alt is in quotes because this does not refer
1971 to what it obviously should refer to, namely the Alt key on PC
1972 keyboards. Instead, it refers to the key labelled Alt on Sun
1973 keyboards, and to no key at all on PC keyboards.
1975 `super': The Super key. Most keyboards don't have any such key, but
1976 under X Windows using `xmodmap' you can assign any key (such as
1977 an underused right-shift, right-control, or right-alt key) to
1980 `hyper': The Hyper key. Works just like the Super key.
1982 `button1': The mouse buttons. This means that the specified button was held
1983 `button2': down at the time the event occurred. NOTE: For button-press
1984 `button3': events, the button that was just pressed down does NOT appear in
1985 `button4': the modifiers.
1988 Button modifiers are currently ignored when defining and looking up key and
1989 mouse strokes in keymaps. This could be changed, which would allow a user to
1990 create button-chord actions, use a button as a key modifier and do other
1995 int mod = XINT(Fevent_modifier_bits(event));
1996 Lisp_Object result = Qnil;
1997 struct gcpro gcpro1;
2000 if (mod & XEMACS_MOD_SHIFT)
2001 result = Fcons(Qshift, result);
2002 if (mod & XEMACS_MOD_ALT)
2003 result = Fcons(Qalt, result);
2004 if (mod & XEMACS_MOD_HYPER)
2005 result = Fcons(Qhyper, result);
2006 if (mod & XEMACS_MOD_SUPER)
2007 result = Fcons(Qsuper, result);
2008 if (mod & XEMACS_MOD_META)
2009 result = Fcons(Qmeta, result);
2010 if (mod & XEMACS_MOD_CONTROL)
2011 result = Fcons(Qcontrol, result);
2012 if (mod & XEMACS_MOD_BUTTON1)
2013 result = Fcons(Qbutton1, result);
2014 if (mod & XEMACS_MOD_BUTTON2)
2015 result = Fcons(Qbutton2, result);
2016 if (mod & XEMACS_MOD_BUTTON3)
2017 result = Fcons(Qbutton3, result);
2018 if (mod & XEMACS_MOD_BUTTON4)
2019 result = Fcons(Qbutton4, result);
2020 if (mod & XEMACS_MOD_BUTTON5)
2021 result = Fcons(Qbutton5, result);
2022 RETURN_UNGCPRO(Fnreverse(result));
2026 event_x_y_pixel_internal(Lisp_Object event, int *x, int *y, int relative)
2031 if (XEVENT(event)->event_type == pointer_motion_event) {
2032 *x = XEVENT(event)->event.motion.x;
2033 *y = XEVENT(event)->event.motion.y;
2034 } else if (XEVENT(event)->event_type == button_press_event ||
2035 XEVENT(event)->event_type == button_release_event) {
2036 *x = XEVENT(event)->event.button.x;
2037 *y = XEVENT(event)->event.button.y;
2038 } else if (XEVENT(event)->event_type == misc_user_event) {
2039 *x = XEVENT(event)->event.misc.x;
2040 *y = XEVENT(event)->event.misc.y;
2044 f = XFRAME(EVENT_CHANNEL(XEVENT(event)));
2047 w = find_window_by_pixel_pos(*x, *y, f->root_window);
2050 return 1; /* #### What should really happen here? */
2052 *x -= w->pixel_left;
2055 *y -= FRAME_REAL_TOP_TOOLBAR_HEIGHT(f) -
2056 FRAME_REAL_TOP_TOOLBAR_BORDER_WIDTH(f);
2057 *x -= FRAME_REAL_LEFT_TOOLBAR_WIDTH(f) -
2058 FRAME_REAL_LEFT_TOOLBAR_BORDER_WIDTH(f);
2064 DEFUN("event-window-x-pixel", Fevent_window_x_pixel, 1, 1, 0, /*
2065 Return the X position in pixels of mouse event EVENT.
2066 The value returned is relative to the window the event occurred in.
2067 This will signal an error if the event is not a mouse event.
2068 See also `mouse-event-p' and `event-x-pixel'.
2074 CHECK_LIVE_EVENT(event);
2076 if (!event_x_y_pixel_internal(event, &x, &y, 1))
2077 return wrong_type_argument(Qmouse_event_p, event);
2082 DEFUN("event-window-y-pixel", Fevent_window_y_pixel, 1, 1, 0, /*
2083 Return the Y position in pixels of mouse event EVENT.
2084 The value returned is relative to the window the event occurred in.
2085 This will signal an error if the event is not a mouse event.
2086 See also `mouse-event-p' and `event-y-pixel'.
2092 CHECK_LIVE_EVENT(event);
2094 if (!event_x_y_pixel_internal(event, &x, &y, 1))
2095 return wrong_type_argument(Qmouse_event_p, event);
2100 DEFUN("event-x-pixel", Fevent_x_pixel, 1, 1, 0, /*
2101 Return the X position in pixels of mouse event EVENT.
2102 The value returned is relative to the frame the event occurred in.
2103 This will signal an error if the event is not a mouse event.
2104 See also `mouse-event-p' and `event-window-x-pixel'.
2110 CHECK_LIVE_EVENT(event);
2112 if (!event_x_y_pixel_internal(event, &x, &y, 0))
2113 return wrong_type_argument(Qmouse_event_p, event);
2118 DEFUN("event-y-pixel", Fevent_y_pixel, 1, 1, 0, /*
2119 Return the Y position in pixels of mouse event EVENT.
2120 The value returned is relative to the frame the event occurred in.
2121 This will signal an error if the event is not a mouse event.
2122 See also `mouse-event-p' `event-window-y-pixel'.
2128 CHECK_LIVE_EVENT(event);
2130 if (!event_x_y_pixel_internal(event, &x, &y, 0))
2131 return wrong_type_argument(Qmouse_event_p, event);
2136 /* Given an event, return a value:
2138 OVER_TOOLBAR: over one of the 4 frame toolbars
2139 OVER_MODELINE: over a modeline
2140 OVER_BORDER: over an internal border
2141 OVER_NOTHING: over the text area, but not over text
2142 OVER_OUTSIDE: outside of the frame border
2143 OVER_TEXT: over text in the text area
2144 OVER_V_DIVIDER: over windows vertical divider
2148 The X char position in CHAR_X, if not a null pointer.
2149 The Y char position in CHAR_Y, if not a null pointer.
2150 (These last two values are relative to the window the event is over.)
2151 The window it's over in W, if not a null pointer.
2152 The buffer position it's over in BUFP, if not a null pointer.
2153 The closest buffer position in CLOSEST, if not a null pointer.
2155 OBJ_X, OBJ_Y, OBJ1, and OBJ2 are as in pixel_to_glyph_translation().
2159 event_pixel_translation(Lisp_Object event, int *char_x, int *char_y,
2160 int *obj_x, int *obj_y,
2161 struct window **w, Bufpos * bufp, Bufpos * closest,
2162 Charcount * modeline_closest,
2163 Lisp_Object * obj1, Lisp_Object * obj2)
2170 int ret_x, ret_y, ret_obj_x, ret_obj_y;
2171 struct window *ret_w;
2172 Bufpos ret_bufp, ret_closest;
2173 Charcount ret_modeline_closest;
2174 Lisp_Object ret_obj1, ret_obj2;
2176 CHECK_LIVE_EVENT(event);
2177 frame = XEVENT(event)->channel;
2178 switch (XEVENT(event)->event_type) {
2179 case pointer_motion_event:
2180 pix_x = XEVENT(event)->event.motion.x;
2181 pix_y = XEVENT(event)->event.motion.y;
2183 case button_press_event:
2184 case button_release_event:
2185 pix_x = XEVENT(event)->event.button.x;
2186 pix_y = XEVENT(event)->event.button.y;
2188 case misc_user_event:
2189 pix_x = XEVENT(event)->event.misc.x;
2190 pix_y = XEVENT(event)->event.misc.y;
2194 case key_press_event:
2198 case magic_eval_event:
2200 #ifdef EF_USE_ASYNEQ
2201 case eaten_myself_event:
2202 case work_started_event:
2203 case work_finished_event:
2204 #endif /* EF_USE_ASYNEQ */
2207 dead_wrong_type_argument(Qmouse_event_p, event);
2210 result = pixel_to_glyph_translation(XFRAME(frame), pix_x, pix_y,
2211 &ret_x, &ret_y, &ret_obj_x,
2212 &ret_obj_y, &ret_w, &ret_bufp,
2213 &ret_closest, &ret_modeline_closest,
2214 &ret_obj1, &ret_obj2);
2216 if (result == OVER_NOTHING || result == OVER_OUTSIDE)
2218 else if (ret_w && NILP(ret_w->buffer))
2219 /* Why does this happen? (Does it still happen?)
2220 I guess the window has gotten reused as a non-leaf... */
2223 /* #### pixel_to_glyph_translation() sometimes returns garbage...
2224 The word has type Lisp_Type_Record (presumably meaning `extent') but the
2225 pointer points to random memory, often filled with 0, sometimes not.
2227 /* #### Chuck, do we still need this crap? */
2228 if (!NILP(ret_obj1) && !(GLYPHP(ret_obj1)
2229 #ifdef HAVE_TOOLBARS
2230 || TOOLBAR_BUTTONP(ret_obj1)
2234 if (!NILP(ret_obj2) && !(EXTENTP(ret_obj2) || CONSP(ret_obj2)))
2250 *closest = ret_closest;
2251 if (modeline_closest)
2252 *modeline_closest = ret_modeline_closest;
2261 DEFUN("event-over-text-area-p", Fevent_over_text_area_p, 1, 1, 0, /*
2262 Return t if the mouse event EVENT occurred over the text area of a window.
2263 The modeline is not considered to be part of the text area.
2268 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2270 return result == OVER_TEXT || result == OVER_NOTHING ? Qt : Qnil;
2273 DEFUN("event-over-modeline-p", Fevent_over_modeline_p, 1, 1, 0, /*
2274 Return t if the mouse event EVENT occurred over the modeline of a window.
2279 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2281 return result == OVER_MODELINE ? Qt : Qnil;
2284 DEFUN("event-over-border-p", Fevent_over_border_p, 1, 1, 0, /*
2285 Return t if the mouse event EVENT occurred over an internal border.
2290 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2292 return result == OVER_BORDER ? Qt : Qnil;
2295 DEFUN("event-over-toolbar-p", Fevent_over_toolbar_p, 1, 1, 0, /*
2296 Return t if the mouse event EVENT occurred over a toolbar.
2301 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2303 return result == OVER_TOOLBAR ? Qt : Qnil;
2306 DEFUN("event-over-vertical-divider-p", Fevent_over_vertical_divider_p, 1, 1, 0, /*
2307 Return t if the mouse event EVENT occurred over a window divider.
2312 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2314 return result == OVER_V_DIVIDER ? Qt : Qnil;
2317 struct console *event_console_or_selected(Lisp_Object event)
2319 Lisp_Object channel = EVENT_CHANNEL(XEVENT(event));
2320 Lisp_Object console = CDFW_CONSOLE(channel);
2323 console = Vselected_console;
2325 return XCONSOLE(console);
2328 DEFUN("event-channel", Fevent_channel, 1, 1, 0, /*
2329 Return the channel that the event EVENT occurred on.
2330 This will be a frame, device, console, or nil for some types
2331 of events (e.g. eval events).
2335 CHECK_LIVE_EVENT(event);
2336 return EVENT_CHANNEL(XEVENT(event));
2339 DEFUN("event-window", Fevent_window, 1, 1, 0, /*
2340 Return the window over which mouse event EVENT occurred.
2341 This may be nil if the event occurred in the border or over a toolbar.
2342 The modeline is considered to be within the window it describes.
2348 event_pixel_translation(event, 0, 0, 0, 0, &w, 0, 0, 0, 0, 0);
2355 XSETWINDOW(window, w);
2360 DEFUN("event-point", Fevent_point, 1, 1, 0, /*
2361 Return the character position of the mouse event EVENT.
2362 If the event did not occur over a window, or did not occur over text,
2363 then this returns nil. Otherwise, it returns a position in the buffer
2364 visible in the event's window.
2371 event_pixel_translation(event, 0, 0, 0, 0, &w, &bufp, 0, 0, 0, 0);
2373 return w && bufp ? make_int(bufp) : Qnil;
2376 DEFUN("event-closest-point", Fevent_closest_point, 1, 1, 0, /*
2377 Return the character position closest to the mouse event EVENT.
2378 If the event did not occur over a window or over text, return the
2379 closest point to the location of the event. If the Y pixel position
2380 overlaps a window and the X pixel position is to the left of that
2381 window, the closest point is the beginning of the line containing the
2382 Y position. If the Y pixel position overlaps a window and the X pixel
2383 position is to the right of that window, the closest point is the end
2384 of the line containing the Y position. If the Y pixel position is
2385 above a window, return 0. If it is below the last character in a window,
2386 return the value of (window-end).
2392 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, &bufp, 0, 0, 0);
2394 return bufp ? make_int(bufp) : Qnil;
2397 DEFUN("event-x", Fevent_x, 1, 1, 0, /*
2398 Return the X position of the mouse event EVENT in characters.
2399 This is relative to the window the event occurred over.
2405 event_pixel_translation(event, &char_x, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2407 return make_int(char_x);
2410 DEFUN("event-y", Fevent_y, 1, 1, 0, /*
2411 Return the Y position of the mouse event EVENT in characters.
2412 This is relative to the window the event occurred over.
2418 event_pixel_translation(event, 0, &char_y, 0, 0, 0, 0, 0, 0, 0, 0);
2420 return make_int(char_y);
2423 DEFUN("event-modeline-position", Fevent_modeline_position, 1, 1, 0, /*
2424 Return the character position in the modeline that EVENT occurred over.
2425 EVENT should be a mouse event. If EVENT did not occur over a modeline,
2426 nil is returned. You can determine the actual character that the
2427 event occurred over by looking in `generated-modeline-string' at the
2428 returned character position. Note that `generated-modeline-string'
2429 is buffer-local, and you must use EVENT's buffer when retrieving
2430 `generated-modeline-string' in order to get accurate results.
2438 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, 0, &mbufp, 0, 0);
2440 return (mbufp < 0 || where != OVER_MODELINE) ? Qnil : make_int(mbufp);
2443 DEFUN("event-glyph", Fevent_glyph, 1, 1, 0, /*
2444 Return the glyph that the mouse event EVENT occurred over, or nil.
2451 event_pixel_translation(event, 0, 0, 0, 0, &w, 0, 0, 0, &glyph, 0);
2453 return w && GLYPHP(glyph) ? glyph : Qnil;
2456 DEFUN("event-glyph-extent", Fevent_glyph_extent, 1, 1, 0, /*
2457 Return the extent of the glyph that the mouse event EVENT occurred over.
2458 If the event did not occur over a glyph, nil is returned.
2465 event_pixel_translation(event, 0, 0, 0, 0, &w, 0, 0, 0, 0, &extent);
2467 return w && EXTENTP(extent) ? extent : Qnil;
2470 DEFUN("event-glyph-x-pixel", Fevent_glyph_x_pixel, 1, 1, 0, /*
2471 Return the X pixel position of EVENT relative to the glyph it occurred over.
2472 EVENT should be a mouse event. If the event did not occur over a glyph,
2481 event_pixel_translation(event, 0, 0, &obj_x, 0, &w, 0, 0, 0, 0,
2484 return w && EXTENTP(extent) ? make_int(obj_x) : Qnil;
2487 DEFUN("event-glyph-y-pixel", Fevent_glyph_y_pixel, 1, 1, 0, /*
2488 Return the Y pixel position of EVENT relative to the glyph it occurred over.
2489 EVENT should be a mouse event. If the event did not occur over a glyph,
2498 event_pixel_translation(event, 0, 0, 0, &obj_y, &w, 0, 0, 0, 0,
2501 return w && EXTENTP(extent) ? make_int(obj_y) : Qnil;
2504 DEFUN("event-toolbar-button", Fevent_toolbar_button, 1, 1, 0, /*
2505 Return the toolbar button that the mouse event EVENT occurred over.
2506 If the event did not occur over a toolbar button, nil is returned.
2510 #ifdef HAVE_TOOLBARS
2514 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, 0, 0, &button, 0);
2516 return result == OVER_TOOLBAR
2517 && TOOLBAR_BUTTONP(button) ? button : Qnil;
2523 DEFUN("event-process", Fevent_process, 1, 1, 0, /*
2524 Return the process of the process-output event EVENT.
2528 CHECK_EVENT_TYPE(event, process_event, Qprocess_event_p);
2529 return XEVENT(event)->event.process.process;
2532 DEFUN("event-function", Fevent_function, 1, 1, 0, /*
2533 Return the callback function of EVENT.
2534 EVENT should be a timeout, misc-user, or eval event.
2539 CHECK_LIVE_EVENT(event);
2540 switch (XEVENT(event)->event_type) {
2542 return XEVENT(event)->event.timeout.function;
2543 case misc_user_event:
2544 return XEVENT(event)->event.misc.function;
2546 return XEVENT(event)->event.eval.function;
2549 case key_press_event:
2550 case button_press_event:
2551 case button_release_event:
2552 case pointer_motion_event:
2555 case magic_eval_event:
2556 #ifdef EF_USE_ASYNEQ
2557 case eaten_myself_event:
2558 case work_started_event:
2559 case work_finished_event:
2560 #endif /* EF_USE_ASYNEQ */
2564 wrong_type_argument(intern("timeout-or-eval-event-p"),
2570 DEFUN("event-object", Fevent_object, 1, 1, 0, /*
2571 Return the callback function argument of EVENT.
2572 EVENT should be a timeout, misc-user, or eval event.
2577 CHECK_LIVE_EVENT(event);
2578 switch (XEVENT(event)->event_type) {
2580 return XEVENT(event)->event.timeout.object;
2581 case misc_user_event:
2582 return XEVENT(event)->event.misc.object;
2584 return XEVENT(event)->event.eval.object;
2587 case key_press_event:
2588 case button_press_event:
2589 case button_release_event:
2590 case pointer_motion_event:
2593 case magic_eval_event:
2594 #ifdef EF_USE_ASYNEQ
2595 case eaten_myself_event:
2596 case work_started_event:
2597 case work_finished_event:
2598 #endif /* EF_USE_ASYNEQ */
2601 event = wrong_type_argument(
2602 intern("timeout-or-eval-event-p"), event);
2607 DEFUN("event-properties", Fevent_properties, 1, 1, 0, /*
2608 Return a list of all of the properties of EVENT.
2609 This is in the form of a property list (alternating keyword/value pairs).
2613 Lisp_Object props = Qnil;
2615 struct gcpro gcpro1;
2617 CHECK_LIVE_EVENT(event);
2621 props = cons3(Qtimestamp, Fevent_timestamp(event), props);
2623 switch (e->event_type) {
2629 props = cons3(Qprocess, e->event.process.process, props);
2633 props = cons3(Qobject, Fevent_object(event), props);
2634 props = cons3(Qfunction, Fevent_function(event), props);
2635 props = cons3(Qid, make_int(e->event.timeout.id_number), props);
2638 case key_press_event:
2639 props = cons3(Qmodifiers, Fevent_modifiers(event), props);
2640 props = cons3(Qkey, Fevent_key(event), props);
2643 case button_press_event:
2644 case button_release_event:
2645 props = cons3(Qy, Fevent_y_pixel(event), props);
2646 props = cons3(Qx, Fevent_x_pixel(event), props);
2647 props = cons3(Qmodifiers, Fevent_modifiers(event), props);
2648 props = cons3(Qbutton, Fevent_button(event), props);
2651 case pointer_motion_event:
2652 props = cons3(Qmodifiers, Fevent_modifiers(event), props);
2653 props = cons3(Qy, Fevent_y_pixel(event), props);
2654 props = cons3(Qx, Fevent_x_pixel(event), props);
2657 case misc_user_event:
2658 props = cons3(Qobject, Fevent_object(event), props);
2659 props = cons3(Qfunction, Fevent_function(event), props);
2660 props = cons3(Qy, Fevent_y_pixel(event), props);
2661 props = cons3(Qx, Fevent_x_pixel(event), props);
2662 props = cons3(Qmodifiers, Fevent_modifiers(event), props);
2663 props = cons3(Qbutton, Fevent_button(event), props);
2667 props = cons3(Qobject, Fevent_object(event), props);
2668 props = cons3(Qfunction, Fevent_function(event), props);
2671 #ifdef EF_USE_ASYNEQ
2672 /* are these right here? */
2673 case eaten_myself_event:
2674 case work_started_event:
2675 case work_finished_event:
2676 #endif /* EF_USE_ASYNEQ */
2679 case magic_eval_event:
2684 RETURN_UNGCPRO(Qnil);
2688 props = cons3(Qchannel, Fevent_channel(event), props);
2694 /************************************************************************/
2695 /* initialization */
2696 /************************************************************************/
2698 void syms_of_events(void)
2700 INIT_LRECORD_IMPLEMENTATION(event);
2702 DEFSUBR(Fcharacter_to_event);
2703 DEFSUBR(Fevent_to_character);
2705 DEFSUBR(Fmake_event);
2706 DEFSUBR(Fdeallocate_event);
2707 DEFSUBR(Fcopy_event);
2709 DEFSUBR(Fevent_live_p);
2710 DEFSUBR(Fevent_type);
2711 DEFSUBR(Fevent_properties);
2713 DEFSUBR(Fevent_timestamp);
2714 DEFSUBR(Fevent_timestamp_lessp);
2715 DEFSUBR(Fevent_key);
2716 DEFSUBR(Fevent_button);
2717 DEFSUBR(Fevent_modifier_bits);
2718 DEFSUBR(Fevent_modifiers);
2719 DEFSUBR(Fevent_x_pixel);
2720 DEFSUBR(Fevent_y_pixel);
2721 DEFSUBR(Fevent_window_x_pixel);
2722 DEFSUBR(Fevent_window_y_pixel);
2723 DEFSUBR(Fevent_over_text_area_p);
2724 DEFSUBR(Fevent_over_modeline_p);
2725 DEFSUBR(Fevent_over_border_p);
2726 DEFSUBR(Fevent_over_toolbar_p);
2727 DEFSUBR(Fevent_over_vertical_divider_p);
2728 DEFSUBR(Fevent_channel);
2729 DEFSUBR(Fevent_window);
2730 DEFSUBR(Fevent_point);
2731 DEFSUBR(Fevent_closest_point);
2734 DEFSUBR(Fevent_modeline_position);
2735 DEFSUBR(Fevent_glyph);
2736 DEFSUBR(Fevent_glyph_extent);
2737 DEFSUBR(Fevent_glyph_x_pixel);
2738 DEFSUBR(Fevent_glyph_y_pixel);
2739 DEFSUBR(Fevent_toolbar_button);
2740 DEFSUBR(Fevent_process);
2741 DEFSUBR(Fevent_function);
2742 DEFSUBR(Fevent_object);
2744 defsymbol(&Qeventp, "eventp");
2745 defsymbol(&Qevent_live_p, "event-live-p");
2746 defsymbol(&Qkey_press_event_p, "key-press-event-p");
2747 defsymbol(&Qbutton_event_p, "button-event-p");
2748 defsymbol(&Qmouse_event_p, "mouse-event-p");
2749 defsymbol(&Qprocess_event_p, "process-event-p");
2750 defsymbol(&Qkey_press, "key-press");
2751 defsymbol(&Qbutton_press, "button-press");
2752 defsymbol(&Qbutton_release, "button-release");
2753 defsymbol(&Qmisc_user, "misc-user");
2754 defsymbol(&Qascii_character, "ascii-character");
2756 defsymbol(&QKbackspace, "backspace");
2757 defsymbol(&QKtab, "tab");
2758 defsymbol(&QKlinefeed, "linefeed");
2759 defsymbol(&QKreturn, "return");
2760 defsymbol(&QKescape, "escape");
2761 defsymbol(&QKspace, "space");
2762 defsymbol(&QKdelete, "delete");
2765 void reinit_vars_of_events(void)
2767 init_Vevent_resource();
2770 void vars_of_events(void)
2772 reinit_vars_of_events();
2774 DEFVAR_LISP("character-set-property", &Vcharacter_set_property /*
2775 A symbol used to look up the 8-bit character of a keysym.
2776 To convert a keysym symbol to an 8-bit code, as when that key is
2777 bound to self-insert-command, we will look up the property that this
2778 variable names on the property list of the keysym-symbol. The window-
2779 system-specific code will set up appropriate properties and set this
2782 Vcharacter_set_property = Qnil;