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) {
332 return EQ(e1->event.process.process, e2->event.process.process);
335 return (internal_equal(e1->event.timeout.function,
336 e2->event.timeout.function, 0) &&
337 internal_equal(e1->event.timeout.object,
338 e2->event.timeout.object, 0));
340 case key_press_event:
341 return (EQ(e1->event.key.keysym, e2->event.key.keysym) &&
342 (e1->event.key.modifiers == e2->event.key.modifiers));
344 case button_press_event:
345 case button_release_event:
346 return (e1->event.button.button == e2->event.button.button &&
347 e1->event.button.modifiers ==
348 e2->event.button.modifiers);
350 case pointer_motion_event:
351 return (e1->event.motion.x == e2->event.motion.x &&
352 e1->event.motion.y == e2->event.motion.y);
354 case misc_user_event:
355 return (internal_equal(e1->event.eval.function,
356 e2->event.eval.function, 0) &&
357 internal_equal(e1->event.eval.object,
358 e2->event.eval.object, 0) &&
359 /* is this really needed for equality
360 or is x and y also important? */
361 e1->event.misc.button == e2->event.misc.button &&
362 e1->event.misc.modifiers == e2->event.misc.modifiers);
365 return (internal_equal(e1->event.eval.function,
366 e2->event.eval.function, 0) &&
367 internal_equal(e1->event.eval.object,
368 e2->event.eval.object, 0));
370 case magic_eval_event:
371 return (e1->event.magic_eval.internal_function ==
372 e2->event.magic_eval.internal_function &&
373 internal_equal(e1->event.magic_eval.object,
374 e2->event.magic_eval.object, 0));
377 struct console *con =
378 XCONSOLE(CDFW_CONSOLE(e1->channel));
380 #ifdef HAVE_X_WINDOWS
381 if (CONSOLE_X_P(con))
382 return (e1->event.magic.underlying_x_event.xany.
384 e2->event.magic.underlying_x_event.xany.
388 if (CONSOLE_TTY_P(con))
389 return (e1->event.magic.underlying_tty_event ==
390 e2->event.magic.underlying_tty_event);
393 return 1; /* not reached */
397 /* worker thread mumbo jumbo is never equal */
398 case eaten_myself_event:
399 case work_started_event:
400 case work_finished_event:
402 #endif /* EF_USE_ASYNEQ */
404 /* Empty and deallocated events are equal. */
412 event_hash(Lisp_Object obj, int depth)
414 Lisp_Event *e = XEVENT(obj);
417 hash = HASH2(e->event_type, LISP_HASH(e->channel));
418 switch (e->event_type) {
420 return HASH2(hash, LISP_HASH(e->event.process.process));
424 internal_hash(e->event.timeout.function,
426 internal_hash(e->event.timeout.object, depth + 1));
428 case key_press_event:
429 return HASH3(hash, LISP_HASH(e->event.key.keysym),
430 e->event.key.modifiers);
432 case button_press_event:
433 case button_release_event:
434 return HASH3(hash, e->event.button.button,
435 e->event.button.modifiers);
437 case pointer_motion_event:
438 return HASH3(hash, e->event.motion.x, e->event.motion.y);
440 case misc_user_event:
442 internal_hash(e->event.misc.function, depth + 1),
443 internal_hash(e->event.misc.object, depth + 1),
444 e->event.misc.button, e->event.misc.modifiers);
448 internal_hash(e->event.eval.function, depth + 1),
449 internal_hash(e->event.eval.object, depth + 1));
451 case magic_eval_event:
453 (unsigned long)e->event.magic_eval.
455 internal_hash(e->event.magic_eval.object,
459 struct console *con =
460 XCONSOLE(CDFW_CONSOLE(EVENT_CHANNEL(e)));
461 #ifdef HAVE_X_WINDOWS
462 if (CONSOLE_X_P(con))
464 e->event.magic.underlying_x_event.
468 if (CONSOLE_TTY_P(con))
471 underlying_tty_event);
478 case eaten_myself_event:
479 case work_started_event:
480 case work_finished_event:
481 return (long unsigned int)obj;
482 #endif /* EF_USE_ASYNEQ */
492 return 0; /* unreached */
495 DEFINE_BASIC_LRECORD_IMPLEMENTATION("event", event,
496 mark_event, print_event, 0, event_equal,
497 event_hash, 0, Lisp_Event);
500 make_empty_event(void)
502 Lisp_Object event = Qnil;
505 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
507 event = allocate_event();
513 lock_Vevent_resource();
514 if (!NILP(Vevent_resource)) {
515 event = Vevent_resource;
516 Vevent_resource = XEVENT_NEXT(event);
518 event = allocate_event();
520 unlock_Vevent_resource();
525 e->event_type = empty_event;
527 EVENT_CHANNEL(e) = Qnil;
534 make_noseeum_event(emacs_event_type event_type)
536 sxe_event_t res = xnew_and_zero(Lisp_Event);
538 res->event_type = event_type;
540 EVENT_CHANNEL(res) = Qnil;
544 DEFUN("make-event", Fmake_event, 0, 2, 0, /*
545 Return a new event of type TYPE, with properties described by PLIST.
547 TYPE is a symbol, either `empty', `key-press', `button-press',
548 `button-release', `misc-user' or `motion'. If TYPE is nil, it
551 PLIST is a property list, the properties being compatible to those
552 returned by `event-properties'. The following properties are
555 channel -- The event channel, a frame or a console. For
556 button-press, button-release, misc-user and motion events,
557 this must be a frame. For key-press events, it must be
558 a console. If channel is unspecified, it will be set to
559 the selected frame or selected console, as appropriate.
560 key -- The event key, a symbol or character. Allowed only for
562 button -- The event button, integer 1, 2 or 3. Allowed for
563 button-press, button-release and misc-user events.
564 modifiers -- The event modifiers, a list of modifier symbols. Allowed
565 for key-press, button-press, button-release, motion and
567 function -- Function. Allowed for misc-user events only.
568 object -- An object, function's parameter. Allowed for misc-user
570 x -- The event X coordinate, an integer. This is relative
571 to the left of CHANNEL's root window. Allowed for
572 motion, button-press, button-release and misc-user events.
573 y -- The event Y coordinate, an integer. This is relative
574 to the top of CHANNEL's root window. Allowed for
575 motion, button-press, button-release and misc-user events.
576 timestamp -- The event timestamp, a non-negative integer. Allowed for
577 all types of events. If unspecified, it will be set to 0
580 For event type `empty', PLIST must be nil.
581 `button-release', or `motion'. If TYPE is left out, it defaults to
583 PLIST is a list of properties, as returned by `event-properties'. Not
584 all properties are allowed for all kinds of events, and some are
587 WARNING: the event object returned may be a reused one; see the function
592 Lisp_Object event = Qnil;
594 EMACS_INT coord_x = 0, coord_y = 0;
599 return make_empty_event();
602 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
603 event = allocate_event();
607 lock_Vevent_resource();
608 if (!NILP(Vevent_resource)) {
609 event = Vevent_resource;
610 Vevent_resource = XEVENT_NEXT(event);
612 event = allocate_event();
614 unlock_Vevent_resource();
619 if (EQ(type, Qempty)) {
620 /* For empty event, we return immediately, without processing
621 PLIST. In fact, processing PLIST would be wrong, because the
622 sanitizing process would fill in the properties
623 (e.g. CHANNEL), which we don't want in empty events. */
624 e->event_type = empty_event;
626 syntax_error("Cannot set properties of empty event",
630 } else if (EQ(type, Qkey_press)) {
631 e->event_type = key_press_event;
632 e->event.key.keysym = Qunbound;
633 } else if (EQ(type, Qbutton_press)) {
634 e->event_type = button_press_event;
635 } else if (EQ(type, Qbutton_release)) {
636 e->event_type = button_release_event;
637 } else if (EQ(type, Qmotion)) {
638 e->event_type = pointer_motion_event;
639 } else if (EQ(type, Qmisc_user)) {
640 e->event_type = misc_user_event;
641 e->event.eval.function = e->event.eval.object = Qnil;
644 Qprocess, Qtimeout, Qmagic, Qeval, Qmagic_eval. */
645 invalid_argument("Invalid event type", type);
648 EVENT_CHANNEL(e) = Qnil;
650 plist = Fcopy_sequence(plist);
651 Fcanonicalize_plist(plist, Qnil);
653 #define WRONG_EVENT_TYPE_FOR_PROPERTY(event_type, prop) \
654 syntax_error_2 ("Invalid property for event type", prop, event_type)
657 EXTERNAL_PROPERTY_LIST_LOOP_3(keyword, value, plist) {
658 if (EQ(keyword, Qchannel)) {
659 if (e->event_type == key_press_event) {
660 if (!CONSOLEP(value))
667 wrong_type_argument(Qframep,
670 EVENT_CHANNEL(e) = value;
671 } else if (EQ(keyword, Qkey)) {
672 switch (e->event_type) {
673 case key_press_event:
674 if (!SYMBOLP(value) && !CHARP(value))
676 ("Invalid event key",
678 e->event.key.keysym = value;
683 case button_press_event:
684 case button_release_event:
685 case pointer_motion_event:
689 case magic_eval_event:
691 case misc_user_event:
693 case eaten_myself_event:
694 case work_started_event:
695 case work_finished_event:
696 #endif /* EF_USE_ASYNEQ */
699 WRONG_EVENT_TYPE_FOR_PROPERTY(type,
703 } else if (EQ(keyword, Qbutton)) {
705 check_int_range(XINT(value), 0, 7);
707 switch (e->event_type) {
708 case button_press_event:
709 case button_release_event:
710 e->event.button.button = XINT(value);
712 case misc_user_event:
713 e->event.misc.button = XINT(value);
716 /* and the rest of that lot */
718 case key_press_event:
719 case pointer_motion_event:
723 case magic_eval_event:
726 case eaten_myself_event:
727 case work_started_event:
728 case work_finished_event:
729 #endif /* EF_USE_ASYNEQ */
732 WRONG_EVENT_TYPE_FOR_PROPERTY(type,
736 } else if (EQ(keyword, Qmodifiers)) {
739 EXTERNAL_LIST_LOOP_2(sym, value) {
740 if (EQ(sym, Qcontrol))
741 modifiers |= XEMACS_MOD_CONTROL;
742 else if (EQ(sym, Qmeta))
743 modifiers |= XEMACS_MOD_META;
744 else if (EQ(sym, Qsuper))
745 modifiers |= XEMACS_MOD_SUPER;
746 else if (EQ(sym, Qhyper))
747 modifiers |= XEMACS_MOD_HYPER;
748 else if (EQ(sym, Qalt))
749 modifiers |= XEMACS_MOD_ALT;
750 else if (EQ(sym, Qsymbol))
751 modifiers |= XEMACS_MOD_ALT;
752 else if (EQ(sym, Qshift))
753 modifiers |= XEMACS_MOD_SHIFT;
754 else if (EQ(sym, Qbutton1))
755 modifiers |= XEMACS_MOD_BUTTON1;
756 else if (EQ(sym, Qbutton2))
757 modifiers |= XEMACS_MOD_BUTTON2;
758 else if (EQ(sym, Qbutton3))
759 modifiers |= XEMACS_MOD_BUTTON3;
760 else if (EQ(sym, Qbutton4))
761 modifiers |= XEMACS_MOD_BUTTON4;
762 else if (EQ(sym, Qbutton5))
763 modifiers |= XEMACS_MOD_BUTTON5;
766 ("Invalid key modifier",
770 switch (e->event_type) {
771 case key_press_event:
772 e->event.key.modifiers = modifiers;
774 case button_press_event:
775 case button_release_event:
776 e->event.button.modifiers = modifiers;
778 case pointer_motion_event:
779 e->event.motion.modifiers = modifiers;
781 case misc_user_event:
782 e->event.misc.modifiers = modifiers;
785 /* here come the rest */
790 case magic_eval_event:
793 case eaten_myself_event:
794 case work_started_event:
795 case work_finished_event:
796 #endif /* EF_USE_ASYNEQ */
799 WRONG_EVENT_TYPE_FOR_PROPERTY(type,
803 } else if (EQ(keyword, Qx)) {
804 switch (e->event_type) {
805 case pointer_motion_event:
806 case button_press_event:
807 case button_release_event:
808 case misc_user_event:
809 /* Allow negative values, so we can specify toolbar
812 coord_x = XINT(value);
817 case key_press_event:
821 case magic_eval_event:
824 case eaten_myself_event:
825 case work_started_event:
826 case work_finished_event:
827 #endif /* EF_USE_ASYNEQ */
830 WRONG_EVENT_TYPE_FOR_PROPERTY(type,
834 } else if (EQ(keyword, Qy)) {
835 switch (e->event_type) {
836 case pointer_motion_event:
837 case button_press_event:
838 case button_release_event:
839 case misc_user_event:
840 /* Allow negative values; see above. */
842 coord_y = XINT(value);
847 case key_press_event:
851 case magic_eval_event:
854 case eaten_myself_event:
855 case work_started_event:
856 case work_finished_event:
857 #endif /* EF_USE_ASYNEQ */
860 WRONG_EVENT_TYPE_FOR_PROPERTY(type,
864 } else if (EQ(keyword, Qtimestamp)) {
866 e->timestamp = XINT(value);
867 } else if (EQ(keyword, Qfunction)) {
868 switch (e->event_type) {
869 case misc_user_event:
870 e->event.eval.function = value;
875 case key_press_event:
876 case button_press_event:
877 case button_release_event:
878 case pointer_motion_event:
882 case magic_eval_event:
885 case eaten_myself_event:
886 case work_started_event:
887 case work_finished_event:
888 #endif /* EF_USE_ASYNEQ */
891 WRONG_EVENT_TYPE_FOR_PROPERTY(type,
895 } else if (EQ(keyword, Qobject)) {
896 switch (e->event_type) {
897 case misc_user_event:
898 e->event.eval.object = value;
903 case key_press_event:
904 case button_press_event:
905 case button_release_event:
906 case pointer_motion_event:
910 case magic_eval_event:
913 case eaten_myself_event:
914 case work_started_event:
915 case work_finished_event:
916 #endif /* EF_USE_ASYNEQ */
919 WRONG_EVENT_TYPE_FOR_PROPERTY(type,
924 syntax_error_2("Invalid property", keyword,
929 /* Insert the channel, if missing. */
930 if (NILP(EVENT_CHANNEL(e))) {
931 if (e->event_type == key_press_event)
932 EVENT_CHANNEL(e) = Vselected_console;
934 EVENT_CHANNEL(e) = Fselected_frame(Qnil);
937 /* Fevent_properties, Fevent_x_pixel, etc. work with pixels relative
938 to the frame, so we must adjust accordingly. */
939 if (FRAMEP(EVENT_CHANNEL(e))) {
941 FRAME_REAL_LEFT_TOOLBAR_WIDTH(XFRAME(EVENT_CHANNEL(e)));
943 FRAME_REAL_TOP_TOOLBAR_HEIGHT(XFRAME(EVENT_CHANNEL(e)));
945 switch (e->event_type) {
946 case pointer_motion_event:
947 e->event.motion.x = coord_x;
948 e->event.motion.y = coord_y;
950 case button_press_event:
951 case button_release_event:
952 e->event.button.x = coord_x;
953 e->event.button.y = coord_y;
955 case misc_user_event:
956 e->event.misc.x = coord_x;
957 e->event.misc.y = coord_y;
962 case key_press_event:
966 case magic_eval_event:
969 case eaten_myself_event:
970 case work_started_event:
971 case work_finished_event:
972 #endif /* EF_USE_ASYNEQ */
979 /* Finally, do some more validation. */
980 switch (e->event_type) {
981 case key_press_event:
982 if (UNBOUNDP(e->event.key.keysym))
984 ("A key must be specified to make a "
985 "keypress event", plist);
987 case button_press_event:
988 if (!e->event.button.button)
990 ("A button must be specified to make a "
991 "button-press event", plist);
993 case button_release_event:
994 if (!e->event.button.button)
996 ("A button must be specified to make a "
997 "button-release event", plist);
999 case misc_user_event:
1000 if (NILP(e->event.misc.function))
1002 ("A function must be specified to make a "
1003 "misc-user event", plist);
1007 case pointer_motion_event:
1011 case magic_eval_event:
1013 #ifdef EF_USE_ASYNEQ
1014 case eaten_myself_event:
1015 case work_started_event:
1016 case work_finished_event:
1017 #endif /* EF_USE_ASYNEQ */
1027 DEFUN("deallocate-event", Fdeallocate_event, 1, 1, 0, /*
1028 Allow the given event structure to be reused.
1029 You MUST NOT use this event object after calling this function with it.
1030 You will lose. It is not necessary to call this function, as event
1031 objects are garbage-collected like all other objects; however, it may
1032 be more efficient to explicitly deallocate events when you are sure
1033 that it is safe to do so.
1039 if (XEVENT_TYPE(event) == dead_event)
1040 error("this event is already deallocated!");
1042 assert(XEVENT_TYPE(event) <= last_event_type);
1048 if (EQ(event, Vlast_command_event) ||
1049 EQ(event, Vlast_input_event) ||
1050 EQ(event, Vunread_command_event))
1053 len = XVECTOR_LENGTH(Vthis_command_keys);
1054 for (i = 0; i < len; i++)
1055 if (EQ(event, XVECTOR_DATA(Vthis_command_keys)[i]))
1057 if (!NILP(Vrecent_keys_ring)) {
1058 int recent_ring_len = XVECTOR_LENGTH(Vrecent_keys_ring);
1059 for (i = 0; i < recent_ring_len; i++)
1061 (event, XVECTOR_DATA(Vrecent_keys_ring)[i]))
1067 #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC
1068 lock_Vevent_resource();
1069 assert(!EQ(event, Vevent_resource));
1070 unlock_Vevent_resource();
1072 deinitialize_event(event);
1073 #if !defined ALLOC_NO_POOLS && !(defined HAVE_BDWGC && defined EF_USE_BDWGC)
1074 lock_Vevent_resource();
1075 XSET_EVENT_NEXT(event, Vevent_resource);
1076 Vevent_resource = event;
1077 unlock_Vevent_resource();
1082 DEFUN("copy-event", Fcopy_event, 1, 2, 0, /*
1083 Make a copy of the event object EVENT1.
1084 If a second event argument EVENT2 is given, EVENT1 is copied into
1085 EVENT2 and EVENT2 is returned. If EVENT2 is not supplied (or is nil)
1086 then a new event will be made as with `make-event'. See also the
1087 function `deallocate-event'.
1091 CHECK_LIVE_EVENT(event1);
1093 event2 = Fmake_event(Qnil, Qnil);
1095 CHECK_LIVE_EVENT(event2);
1096 if (EQ(event1, event2))
1097 return signal_simple_continuable_error_2
1098 ("copy-event called with `eq' events", event1,
1102 assert(XEVENT_TYPE(event1) <= last_event_type);
1103 assert(XEVENT_TYPE(event2) <= last_event_type);
1106 Lisp_Event *ev2 = XEVENT(event2);
1107 Lisp_Event *ev1 = XEVENT(event1);
1109 ev2->event_type = ev1->event_type;
1110 ev2->channel = ev1->channel;
1111 ev2->timestamp = ev1->timestamp;
1112 ev2->event = ev1->event;
1118 /* Given a chain of events (or possibly nil), deallocate them all. */
1120 void deallocate_event_chain(Lisp_Object event_chain)
1122 while (!NILP(event_chain)) {
1123 Lisp_Object next = XEVENT_NEXT(event_chain);
1124 Fdeallocate_event(event_chain);
1129 /* Return the last event in a chain.
1130 NOTE: You cannot pass nil as a value here! The routine will
1133 Lisp_Object event_chain_tail(Lisp_Object event_chain)
1136 Lisp_Object next = XEVENT_NEXT(event_chain);
1143 /* Enqueue a single event onto the end of a chain of events.
1144 HEAD points to the first event in the chain, TAIL to the last event.
1145 If the chain is empty, both values should be nil. */
1147 void enqueue_event(Lisp_Object event, Lisp_Object * head, Lisp_Object * tail)
1149 assert(NILP(XEVENT_NEXT(event)));
1150 assert(!EQ(*tail, event));
1153 XSET_EVENT_NEXT(*tail, event);
1158 assert(!EQ(event, XEVENT_NEXT(event)));
1161 /* Remove an event off the head of a chain of events and return it.
1162 HEAD points to the first event in the chain, TAIL to the last event. */
1164 Lisp_Object dequeue_event(Lisp_Object * head, Lisp_Object * tail)
1169 *head = XEVENT_NEXT(event);
1170 XSET_EVENT_NEXT(event, Qnil);
1176 /* Enqueue a chain of events (or possibly nil) onto the end of another
1177 chain of events. HEAD points to the first event in the chain being
1178 queued onto, TAIL to the last event. If the chain is empty, both values
1182 enqueue_event_chain(Lisp_Object event_chain, Lisp_Object * head,
1185 if (NILP(event_chain))
1189 *head = event_chain;
1190 *tail = event_chain;
1192 XSET_EVENT_NEXT(*tail, event_chain);
1193 *tail = event_chain_tail(event_chain);
1197 /* Return the number of events (possibly 0) on an event chain. */
1199 int event_chain_count(Lisp_Object event_chain)
1204 EVENT_CHAIN_LOOP(event, event_chain) {
1211 /* Find the event before EVENT in an event chain. This aborts
1212 if the event is not in the chain. */
1215 event_chain_find_previous(Lisp_Object event_chain, Lisp_Object event)
1217 Lisp_Object previous = Qnil;
1219 while (!NILP(event_chain)) {
1220 if (EQ(event_chain, event)) {
1223 previous = event_chain;
1224 event_chain = XEVENT_NEXT(event_chain);
1231 Lisp_Object event_chain_nth(Lisp_Object event_chain, int n)
1234 EVENT_CHAIN_LOOP(event, event_chain) {
1243 Lisp_Object copy_event_chain(Lisp_Object event_chain)
1245 Lisp_Object new_chain = Qnil;
1246 Lisp_Object new_chain_tail = Qnil;
1249 EVENT_CHAIN_LOOP(event, event_chain) {
1250 Lisp_Object copy = Fcopy_event(event, Qnil);
1251 enqueue_event(copy, &new_chain, &new_chain_tail);
1257 Lisp_Object QKbackspace, QKtab, QKlinefeed, QKreturn, QKescape,
1260 int command_event_p(Lisp_Object event)
1262 switch (XEVENT_TYPE(event)) {
1263 case key_press_event:
1264 case button_press_event:
1265 case button_release_event:
1266 case misc_user_event:
1270 case pointer_motion_event:
1274 case magic_eval_event:
1276 #ifdef EF_USE_ASYNEQ
1277 case eaten_myself_event:
1278 case work_started_event:
1279 case work_finished_event:
1280 #endif /* EF_USE_ASYNEQ */
1288 character_to_event(Emchar c, Lisp_Event * event, struct console *con,
1289 int use_console_meta_flag, int do_backspace_mapping)
1291 Lisp_Object k = Qnil;
1293 if (event->event_type == dead_event)
1294 error("character-to-event called with a deallocated event!");
1299 if (c > 127 && c <= 255) {
1302 if (use_console_meta_flag && CONSOLE_TTY_P(con)) {
1303 meta_flag = TTY_FLAGS(con).meta_key;
1305 switch (meta_flag) {
1306 case 0: /* ignore top bit; it's parity */
1309 case 1: /* top bit is meta */
1311 m = XEMACS_MOD_META;
1313 default: /* this is a real character */
1318 c += '@', m |= XEMACS_MOD_CONTROL;
1319 if (m & XEMACS_MOD_CONTROL) {
1323 m &= ~XEMACS_MOD_CONTROL;
1327 m &= ~XEMACS_MOD_CONTROL;
1331 m &= ~XEMACS_MOD_CONTROL;
1335 m &= ~XEMACS_MOD_CONTROL;
1338 #if defined(HAVE_TTY)
1339 if (do_backspace_mapping &&
1340 CHARP(con->tty_erase_char) &&
1341 c - '@' == XCHAR(con->tty_erase_char)) {
1343 m &= ~XEMACS_MOD_CONTROL;
1345 #endif /* defined(HAVE_TTY) */
1348 if (c >= 'A' && c <= 'Z')
1351 #if defined(HAVE_TTY)
1352 else if (do_backspace_mapping &&
1353 CHARP(con->tty_erase_char) && c == XCHAR(con->tty_erase_char))
1355 #endif /* defined(HAVE_TTY) */
1361 event->event_type = key_press_event;
1362 event->timestamp = 0; /* #### */
1363 event->channel = make_console(con);
1364 event->event.key.keysym = (!NILP(k) ? k : make_char(c));
1365 event->event.key.modifiers = m;
1368 /* This variable controls what character name -> character code mapping
1369 we are using. Window-system-specific code sets this to some symbol,
1370 and we use that symbol as the plist key to convert keysyms into 8-bit
1371 codes. In this way one can have several character sets predefined and
1372 switch them by changing this.
1374 #### This is utterly bogus and should be removed.
1376 Lisp_Object Vcharacter_set_property;
1379 event_to_character(Lisp_Event * event,
1380 int allow_extra_modifiers,
1381 int allow_meta, int allow_non_ascii)
1386 if (event->event_type != key_press_event) {
1387 assert(event->event_type != dead_event);
1390 if (!allow_extra_modifiers &&
1392 modifiers & (XEMACS_MOD_SUPER | XEMACS_MOD_HYPER | XEMACS_MOD_ALT))
1394 if (CHAR_OR_CHAR_INTP(event->event.key.keysym))
1395 c = XCHAR_OR_CHAR_INT(event->event.key.keysym);
1396 else if (!SYMBOLP(event->event.key.keysym))
1398 else if (allow_non_ascii && !NILP(Vcharacter_set_property)
1399 /* Allow window-system-specific extensibility of
1400 keysym->code mapping */
1401 && CHAR_OR_CHAR_INTP(code = Fget(event->event.key.keysym,
1402 Vcharacter_set_property,
1404 c = XCHAR_OR_CHAR_INT(code);
1405 else if (CHAR_OR_CHAR_INTP(code = Fget(event->event.key.keysym,
1406 Qascii_character, Qnil)))
1407 c = XCHAR_OR_CHAR_INT(code);
1411 if (event->event.key.modifiers & XEMACS_MOD_CONTROL) {
1412 if (c >= 'a' && c <= 'z')
1415 /* reject Control-Shift- keys */
1416 if (c >= 'A' && c <= 'Z' && !allow_extra_modifiers)
1419 if (c >= '@' && c <= '_')
1421 else if (c == ' ') /* C-space and C-@ are the same. */
1424 /* reject keys that can't take Control- modifiers */
1425 if (!allow_extra_modifiers)
1429 if (event->event.key.modifiers & XEMACS_MOD_META) {
1433 return -1; /* don't allow M-oslash (overlap) */
1443 DEFUN("event-to-character", Fevent_to_character, 1, 4, 0, /*
1444 Return the closest ASCII approximation to the given event object.
1445 If the event isn't a keypress, this returns nil.
1446 If the ALLOW-EXTRA-MODIFIERS argument is non-nil, then this is lenient in
1447 its translation; it will ignore modifier keys other than control and meta,
1448 and will ignore the shift modifier on those characters which have no
1449 shifted ASCII equivalent (Control-Shift-A for example, will be mapped to
1450 the same ASCII code as Control-A).
1451 If the ALLOW-META argument is non-nil, then the Meta modifier will be
1452 represented by turning on the high bit of the byte returned; otherwise, nil
1453 will be returned for events containing the Meta modifier.
1454 If the ALLOW-NON-ASCII argument is non-nil, then characters which are
1455 present in the prevailing character set (see the `character-set-property'
1456 variable) will be returned as their code in that character set, instead of
1457 the return value being restricted to ASCII.
1458 Note that specifying both ALLOW-META and ALLOW-NON-ASCII is ambiguous, as
1459 both use the high bit; `M-x' and `oslash' will be indistinguishable.
1461 (event, allow_extra_modifiers, allow_meta, allow_non_ascii))
1464 CHECK_LIVE_EVENT(event);
1465 c = event_to_character(XEVENT(event),
1466 !NILP(allow_extra_modifiers),
1467 !NILP(allow_meta), !NILP(allow_non_ascii));
1468 return c < 0 ? Qnil : make_char(c);
1471 DEFUN("character-to-event", Fcharacter_to_event, 1, 4, 0, /*
1472 Convert KEY-DESCRIPTION into an event structure, replete with bucky bits.
1474 KEY-DESCRIPTION is the first argument, and the event to fill in is the
1475 second. This function contains knowledge about what various kinds of
1476 arguments ``mean'' -- for example, the number 9 is converted to the
1477 character ``Tab'', not the distinct character ``Control-I''.
1479 KEY-DESCRIPTION can be an integer, a character, a symbol such as 'clear,
1480 or a list such as '(control backspace).
1482 If the optional second argument EVENT is an event, it is modified and
1483 returned; otherwise, a new event object is created and returned.
1485 Optional third arg CONSOLE is the console to store in the event, and
1486 defaults to the selected console.
1488 If KEY-DESCRIPTION is an integer or character, the high bit may be
1489 interpreted as the meta key. (This is done for backward compatibility
1490 in lots of places.) If USE-CONSOLE-META-FLAG is nil, this will always
1491 be the case. If USE-CONSOLE-META-FLAG is non-nil, the `meta' flag for
1492 CONSOLE affects whether the high bit is interpreted as a meta
1493 key. (See `set-input-mode'.) If you don't want this silly meta
1494 interpretation done, you should pass in a list containing the
1497 Beware that character-to-event and event-to-character are not strictly
1498 inverse functions, since events contain much more information than the
1499 Lisp character object type can encode.
1501 (keystroke, event, console, use_console_meta_flag))
1503 struct console *con = decode_console(console);
1505 event = Fmake_event(Qnil, Qnil);
1507 CHECK_LIVE_EVENT(event);
1508 if (CONSP(keystroke) || SYMBOLP(keystroke))
1509 key_desc_list_to_event(keystroke, event, 1);
1511 CHECK_CHAR_COERCE_INT(keystroke);
1512 character_to_event(XCHAR(keystroke), XEVENT(event), con,
1513 !NILP(use_console_meta_flag), 1);
1518 void nth_of_key_sequence_as_event(Lisp_Object seq, int n, Lisp_Object event)
1520 assert(STRINGP(seq) || VECTORP(seq));
1521 assert(n < XINT(Flength(seq)));
1524 Emchar ch = string_char(XSTRING(seq), n);
1525 Fcharacter_to_event(make_char(ch), event, Qnil, Qnil);
1527 Lisp_Object keystroke = XVECTOR_DATA(seq)[n];
1528 if (EVENTP(keystroke))
1529 Fcopy_event(keystroke, event);
1531 Fcharacter_to_event(keystroke, event, Qnil, Qnil);
1535 Lisp_Object key_sequence_to_event_chain(Lisp_Object seq)
1537 int len = XINT(Flength(seq));
1539 Lisp_Object head = Qnil, tail = Qnil;
1541 for (i = 0; i < len; i++) {
1542 Lisp_Object event = Fmake_event(Qnil, Qnil);
1543 nth_of_key_sequence_as_event(seq, i, event);
1544 enqueue_event(event, &head, &tail);
1550 void format_event_object(char *buf, Lisp_Event * event, int brief)
1556 switch (event->event_type) {
1557 case key_press_event: {
1558 mod = event->event.key.modifiers;
1559 key = event->event.key.keysym;
1561 if (!brief && CHARP(key) &&
1562 mod & (XEMACS_MOD_CONTROL | XEMACS_MOD_META |
1563 XEMACS_MOD_SUPER | XEMACS_MOD_HYPER)) {
1565 if (k >= 'a' && k <= 'z')
1566 key = make_char(k - ('a' - 'A'));
1567 else if (k >= 'A' && k <= 'Z')
1568 mod |= XEMACS_MOD_SHIFT;
1572 case button_release_event:
1575 case button_press_event: {
1577 mod = event->event.button.modifiers;
1578 key = make_char(event->event.button.button + '0');
1582 const char *name = NULL;
1584 #ifdef HAVE_X_WINDOWS
1585 Lisp_Object console = CDFW_CONSOLE(EVENT_CHANNEL(event));
1586 if (CONSOLE_X_P(XCONSOLE(console))) {
1587 name = x_event_name(event->event.magic.
1591 #endif /* HAVE_X_WINDOWS */
1600 case magic_eval_event:
1601 strcpy(buf, "magic-eval");
1603 case pointer_motion_event:
1604 strcpy(buf, "motion");
1606 case misc_user_event:
1607 strcpy(buf, "misc-user");
1610 strcpy(buf, "eval");
1613 strcpy(buf, "process");
1616 strcpy(buf, "timeout");
1619 strcpy(buf, "empty");
1622 strcpy(buf, "DEAD-EVENT");
1624 #ifdef EF_USE_ASYNEQ
1625 case eaten_myself_event:
1626 strcpy(buf, "suicide");
1628 case work_started_event:
1629 strcpy(buf, "started-work");
1631 case work_finished_event:
1632 strcpy(buf, "finished-work");
1634 #endif /* EF_USE_ASYNEQ */
1640 #define modprint1(x) do { strcpy (buf, (x)); buf += sizeof (x)-1; } while (0)
1641 #define modprint(x,y) do { if (brief) modprint1 (y); else modprint1 (x); } while (0)
1642 if (mod & XEMACS_MOD_CONTROL)
1643 modprint("control-", "C-");
1644 if (mod & XEMACS_MOD_META)
1645 modprint("meta-", "M-");
1646 if (mod & XEMACS_MOD_SUPER)
1647 modprint("super-", "S-");
1648 if (mod & XEMACS_MOD_HYPER)
1649 modprint("hyper-", "H-");
1650 if (mod & XEMACS_MOD_ALT)
1651 modprint("alt-", "A-");
1652 if (mod & XEMACS_MOD_SHIFT)
1653 modprint("shift-", "Sh-");
1655 modprint1("button");
1662 buf += set_charptr_emchar((Bufbyte *) buf, XCHAR(key));
1664 } else if (SYMBOLP(key)) {
1665 const char *str = 0;
1667 if (EQ(key, QKlinefeed))
1669 else if (EQ(key, QKtab))
1671 else if (EQ(key, QKreturn))
1673 else if (EQ(key, QKescape))
1675 else if (EQ(key, QKdelete))
1677 else if (EQ(key, QKspace))
1679 else if (EQ(key, QKbackspace))
1683 int i = strlen(str);
1684 memcpy(buf, str, i + 1);
1687 Lisp_String *name = XSYMBOL(key)->name;
1688 memcpy(buf, string_data(name), string_length(name) + 1);
1689 str += string_length(name);
1694 strncpy(buf, "up", 4);
1697 DEFUN("eventp", Feventp, 1, 1, 0, /*
1698 True if OBJECT is an event object.
1702 return EVENTP(object) ? Qt : Qnil;
1705 DEFUN("event-live-p", Fevent_live_p, 1, 1, 0, /*
1706 True if OBJECT is an event object that has not been deallocated.
1710 return EVENTP(object) && XEVENT(object)->event_type != dead_event ?
1714 #if 0 /* debugging functions */
1716 xxDEFUN("event-next", Fevent_next, 1, 1, 0, /*
1717 Return the event object's `next' event, or nil if it has none.
1718 The `next-event' field is changed by calling `set-next-event'.
1723 CHECK_LIVE_EVENT(event);
1725 return XEVENT_NEXT(event);
1728 xxDEFUN("set-event-next", Fset_event_next, 2, 2, 0, /*
1729 Set the `next event' of EVENT to NEXT-EVENT.
1730 NEXT-EVENT must be an event object or nil.
1732 (event, next_event))
1736 CHECK_LIVE_EVENT(event);
1737 if (NILP(next_event)) {
1738 XSET_EVENT_NEXT(event, Qnil);
1742 CHECK_LIVE_EVENT(next_event);
1744 EVENT_CHAIN_LOOP(ev, XEVENT_NEXT(event)) {
1747 signal_error(Qerror,
1748 list3(build_string("Cyclic event-next"),
1749 event, next_event));
1751 XSET_EVENT_NEXT(event, next_event);
1757 DEFUN("event-type", Fevent_type, 1, 1, 0, /*
1758 Return the type of EVENT.
1759 This will be a symbol; one of
1761 key-press A key was pressed.
1762 button-press A mouse button was pressed.
1763 button-release A mouse button was released.
1764 misc-user Some other user action happened; typically, this is
1765 a menu selection or scrollbar action.
1766 motion The mouse moved.
1767 process Input is available from a subprocess.
1768 timeout A timeout has expired.
1769 eval This causes a specified action to occur when dispatched.
1770 magic Some window-system-specific event has occurred.
1771 empty The event has been allocated but not assigned.
1776 CHECK_LIVE_EVENT(event);
1777 switch (XEVENT(event)->event_type) {
1778 case key_press_event:
1780 case button_press_event:
1781 return Qbutton_press;
1782 case button_release_event:
1783 return Qbutton_release;
1784 case misc_user_event:
1786 case pointer_motion_event:
1795 case magic_eval_event:
1798 #ifdef EF_USE_ASYNEQ
1799 case eaten_myself_event:
1800 return Qworker_suicide;
1801 case work_started_event:
1802 return Qworker_started_work;
1803 case work_finished_event:
1804 return Qworker_finished_work;
1805 #endif /* EF_USE_ASYNEQ */
1817 DEFUN("event-timestamp", Fevent_timestamp, 1, 1, 0, /*
1818 Return the timestamp of the event object EVENT.
1819 Timestamps are measured in milliseconds since the start of the window system.
1820 They are NOT related to any current time measurement.
1821 They should be compared with `event-timestamp<'.
1822 See also `current-event-timestamp'.
1826 CHECK_LIVE_EVENT(event);
1827 /* This junk is so that timestamps don't get to be negative, but contain
1828 as many bits as this particular emacs will allow.
1830 return make_int(EMACS_INT_MAX & XEVENT(event)->timestamp);
1833 #define TIMESTAMP_HALFSPACE (1L << (INT_VALBITS - 2))
1835 DEFUN("event-timestamp<", Fevent_timestamp_lessp, 2, 2, 0, /*
1836 Return true if timestamp TIME1 is earlier than timestamp TIME2.
1837 This correctly handles timestamp wrap.
1838 See also `event-timestamp' and `current-event-timestamp'.
1844 CHECK_NATNUM(time1);
1845 CHECK_NATNUM(time2);
1850 return t2 - t1 < TIMESTAMP_HALFSPACE ? Qt : Qnil;
1852 return t1 - t2 < TIMESTAMP_HALFSPACE ? Qnil : Qt;
1855 #define CHECK_EVENT_TYPE(e,t1,sym) do { \
1856 CHECK_LIVE_EVENT (e); \
1857 if (XEVENT(e)->event_type != (t1)) \
1858 e = wrong_type_argument (sym,e); \
1861 #define CHECK_EVENT_TYPE2(e,t1,t2,sym) do { \
1862 CHECK_LIVE_EVENT (e); \
1864 emacs_event_type CET_type = XEVENT (e)->event_type; \
1865 if (CET_type != (t1) && \
1867 e = wrong_type_argument (sym,e); \
1871 #define CHECK_EVENT_TYPE3(e,t1,t2,t3,sym) do { \
1872 CHECK_LIVE_EVENT (e); \
1874 emacs_event_type CET_type = XEVENT (e)->event_type; \
1875 if (CET_type != (t1) && \
1876 CET_type != (t2) && \
1878 e = wrong_type_argument (sym,e); \
1882 DEFUN("event-key", Fevent_key, 1, 1, 0, /*
1883 Return the Keysym of the key-press event EVENT.
1884 This will be a character if the event is associated with one, else a symbol.
1888 CHECK_EVENT_TYPE(event, key_press_event, Qkey_press_event_p);
1889 return XEVENT(event)->event.key.keysym;
1892 DEFUN("event-button", Fevent_button, 1, 1, 0, /*
1893 Return the button-number of the button-press or button-release event EVENT.
1898 CHECK_EVENT_TYPE3(event, button_press_event, button_release_event,
1899 misc_user_event, Qbutton_event_p);
1900 #ifdef HAVE_WINDOW_SYSTEM
1901 if (XEVENT(event)->event_type == misc_user_event)
1902 return make_int(XEVENT(event)->event.misc.button);
1904 return make_int(XEVENT(event)->event.button.button);
1905 #else /* !HAVE_WINDOW_SYSTEM */
1907 #endif /* !HAVE_WINDOW_SYSTEM */
1911 DEFUN("event-modifier-bits", Fevent_modifier_bits, 1, 1, 0, /*
1912 Return a number representing the modifier keys and buttons which were down
1913 when the given mouse or keyboard event was produced.
1914 See also the function `event-modifiers'.
1919 CHECK_LIVE_EVENT(event);
1920 switch (XEVENT(event)->event_type) {
1921 case key_press_event:
1922 return make_int(XEVENT(event)->event.key.modifiers);
1923 case button_press_event:
1924 case button_release_event:
1925 return make_int(XEVENT(event)->event.button.modifiers);
1926 case pointer_motion_event:
1927 return make_int(XEVENT(event)->event.motion.modifiers);
1928 case misc_user_event:
1929 return make_int(XEVENT(event)->event.misc.modifiers);
1935 case magic_eval_event:
1937 #ifdef EF_USE_ASYNEQ
1938 case eaten_myself_event:
1939 case work_started_event:
1940 case work_finished_event:
1941 #endif /* EF_USE_ASYNEQ */
1944 event = wrong_type_argument(
1945 intern("key-or-mouse-event-p"), event);
1950 DEFUN("event-modifiers", Fevent_modifiers, 1, 1, 0, /*
1951 Return a list of symbols, the names of the modifier keys and buttons
1952 which were down when the given mouse or keyboard event was produced.
1953 See also the function `event-modifier-bits'.
1955 The possible symbols in the list are
1957 `shift': The Shift key. Will not appear, in general, on key events
1958 where the keysym is an ASCII character, because using Shift
1959 on such a character converts it into another character rather
1960 than actually just adding a Shift modifier.
1962 `control': The Control key.
1964 `meta': The Meta key. On PC's and PC-style keyboards, this is generally
1965 labelled \"Alt\"; Meta is a holdover from early Lisp Machines and
1966 such, propagated through the X Window System. On Sun keyboards,
1967 this key is labelled with a diamond.
1969 `alt': The \"Alt\" key. Alt is in quotes because this does not refer
1970 to what it obviously should refer to, namely the Alt key on PC
1971 keyboards. Instead, it refers to the key labelled Alt on Sun
1972 keyboards, and to no key at all on PC keyboards.
1974 `super': The Super key. Most keyboards don't have any such key, but
1975 under X Windows using `xmodmap' you can assign any key (such as
1976 an underused right-shift, right-control, or right-alt key) to
1979 `hyper': The Hyper key. Works just like the Super key.
1981 `button1': The mouse buttons. This means that the specified button was held
1982 `button2': down at the time the event occurred. NOTE: For button-press
1983 `button3': events, the button that was just pressed down does NOT appear in
1984 `button4': the modifiers.
1987 Button modifiers are currently ignored when defining and looking up key and
1988 mouse strokes in keymaps. This could be changed, which would allow a user to
1989 create button-chord actions, use a button as a key modifier and do other
1994 int mod = XINT(Fevent_modifier_bits(event));
1995 Lisp_Object result = Qnil;
1996 struct gcpro gcpro1;
1999 if (mod & XEMACS_MOD_SHIFT)
2000 result = Fcons(Qshift, result);
2001 if (mod & XEMACS_MOD_ALT)
2002 result = Fcons(Qalt, result);
2003 if (mod & XEMACS_MOD_HYPER)
2004 result = Fcons(Qhyper, result);
2005 if (mod & XEMACS_MOD_SUPER)
2006 result = Fcons(Qsuper, result);
2007 if (mod & XEMACS_MOD_META)
2008 result = Fcons(Qmeta, result);
2009 if (mod & XEMACS_MOD_CONTROL)
2010 result = Fcons(Qcontrol, result);
2011 if (mod & XEMACS_MOD_BUTTON1)
2012 result = Fcons(Qbutton1, result);
2013 if (mod & XEMACS_MOD_BUTTON2)
2014 result = Fcons(Qbutton2, result);
2015 if (mod & XEMACS_MOD_BUTTON3)
2016 result = Fcons(Qbutton3, result);
2017 if (mod & XEMACS_MOD_BUTTON4)
2018 result = Fcons(Qbutton4, result);
2019 if (mod & XEMACS_MOD_BUTTON5)
2020 result = Fcons(Qbutton5, result);
2021 RETURN_UNGCPRO(Fnreverse(result));
2025 event_x_y_pixel_internal(Lisp_Object event, int *x, int *y, int relative)
2030 if (XEVENT(event)->event_type == pointer_motion_event) {
2031 *x = XEVENT(event)->event.motion.x;
2032 *y = XEVENT(event)->event.motion.y;
2033 } else if (XEVENT(event)->event_type == button_press_event ||
2034 XEVENT(event)->event_type == button_release_event) {
2035 *x = XEVENT(event)->event.button.x;
2036 *y = XEVENT(event)->event.button.y;
2037 } else if (XEVENT(event)->event_type == misc_user_event) {
2038 *x = XEVENT(event)->event.misc.x;
2039 *y = XEVENT(event)->event.misc.y;
2043 f = XFRAME(EVENT_CHANNEL(XEVENT(event)));
2046 w = find_window_by_pixel_pos(*x, *y, f->root_window);
2049 return 1; /* #### What should really happen here? */
2051 *x -= w->pixel_left;
2054 *y -= FRAME_REAL_TOP_TOOLBAR_HEIGHT(f) -
2055 FRAME_REAL_TOP_TOOLBAR_BORDER_WIDTH(f);
2056 *x -= FRAME_REAL_LEFT_TOOLBAR_WIDTH(f) -
2057 FRAME_REAL_LEFT_TOOLBAR_BORDER_WIDTH(f);
2063 DEFUN("event-window-x-pixel", Fevent_window_x_pixel, 1, 1, 0, /*
2064 Return the X position in pixels of mouse event EVENT.
2065 The value returned is relative to the window the event occurred in.
2066 This will signal an error if the event is not a mouse event.
2067 See also `mouse-event-p' and `event-x-pixel'.
2073 CHECK_LIVE_EVENT(event);
2075 if (!event_x_y_pixel_internal(event, &x, &y, 1))
2076 return wrong_type_argument(Qmouse_event_p, event);
2081 DEFUN("event-window-y-pixel", Fevent_window_y_pixel, 1, 1, 0, /*
2082 Return the Y position in pixels of mouse event EVENT.
2083 The value returned is relative to the window the event occurred in.
2084 This will signal an error if the event is not a mouse event.
2085 See also `mouse-event-p' and `event-y-pixel'.
2091 CHECK_LIVE_EVENT(event);
2093 if (!event_x_y_pixel_internal(event, &x, &y, 1))
2094 return wrong_type_argument(Qmouse_event_p, event);
2099 DEFUN("event-x-pixel", Fevent_x_pixel, 1, 1, 0, /*
2100 Return the X position in pixels of mouse event EVENT.
2101 The value returned is relative to the frame the event occurred in.
2102 This will signal an error if the event is not a mouse event.
2103 See also `mouse-event-p' and `event-window-x-pixel'.
2109 CHECK_LIVE_EVENT(event);
2111 if (!event_x_y_pixel_internal(event, &x, &y, 0))
2112 return wrong_type_argument(Qmouse_event_p, event);
2117 DEFUN("event-y-pixel", Fevent_y_pixel, 1, 1, 0, /*
2118 Return the Y position in pixels of mouse event EVENT.
2119 The value returned is relative to the frame the event occurred in.
2120 This will signal an error if the event is not a mouse event.
2121 See also `mouse-event-p' `event-window-y-pixel'.
2127 CHECK_LIVE_EVENT(event);
2129 if (!event_x_y_pixel_internal(event, &x, &y, 0))
2130 return wrong_type_argument(Qmouse_event_p, event);
2135 /* Given an event, return a value:
2137 OVER_TOOLBAR: over one of the 4 frame toolbars
2138 OVER_MODELINE: over a modeline
2139 OVER_BORDER: over an internal border
2140 OVER_NOTHING: over the text area, but not over text
2141 OVER_OUTSIDE: outside of the frame border
2142 OVER_TEXT: over text in the text area
2143 OVER_V_DIVIDER: over windows vertical divider
2147 The X char position in CHAR_X, if not a null pointer.
2148 The Y char position in CHAR_Y, if not a null pointer.
2149 (These last two values are relative to the window the event is over.)
2150 The window it's over in W, if not a null pointer.
2151 The buffer position it's over in BUFP, if not a null pointer.
2152 The closest buffer position in CLOSEST, if not a null pointer.
2154 OBJ_X, OBJ_Y, OBJ1, and OBJ2 are as in pixel_to_glyph_translation().
2158 event_pixel_translation(Lisp_Object event, int *char_x, int *char_y,
2159 int *obj_x, int *obj_y,
2160 struct window **w, Bufpos * bufp, Bufpos * closest,
2161 Charcount * modeline_closest,
2162 Lisp_Object * obj1, Lisp_Object * obj2)
2169 int ret_x, ret_y, ret_obj_x, ret_obj_y;
2170 struct window *ret_w;
2171 Bufpos ret_bufp, ret_closest;
2172 Charcount ret_modeline_closest;
2173 Lisp_Object ret_obj1, ret_obj2;
2175 CHECK_LIVE_EVENT(event);
2176 frame = XEVENT(event)->channel;
2177 switch (XEVENT(event)->event_type) {
2178 case pointer_motion_event:
2179 pix_x = XEVENT(event)->event.motion.x;
2180 pix_y = XEVENT(event)->event.motion.y;
2182 case button_press_event:
2183 case button_release_event:
2184 pix_x = XEVENT(event)->event.button.x;
2185 pix_y = XEVENT(event)->event.button.y;
2187 case misc_user_event:
2188 pix_x = XEVENT(event)->event.misc.x;
2189 pix_y = XEVENT(event)->event.misc.y;
2193 case key_press_event:
2197 case magic_eval_event:
2199 #ifdef EF_USE_ASYNEQ
2200 case eaten_myself_event:
2201 case work_started_event:
2202 case work_finished_event:
2203 #endif /* EF_USE_ASYNEQ */
2206 dead_wrong_type_argument(Qmouse_event_p, event);
2209 result = pixel_to_glyph_translation(XFRAME(frame), pix_x, pix_y,
2210 &ret_x, &ret_y, &ret_obj_x,
2211 &ret_obj_y, &ret_w, &ret_bufp,
2212 &ret_closest, &ret_modeline_closest,
2213 &ret_obj1, &ret_obj2);
2215 if (result == OVER_NOTHING || result == OVER_OUTSIDE)
2217 else if (ret_w && NILP(ret_w->buffer))
2218 /* Why does this happen? (Does it still happen?)
2219 I guess the window has gotten reused as a non-leaf... */
2222 /* #### pixel_to_glyph_translation() sometimes returns garbage...
2223 The word has type Lisp_Type_Record (presumably meaning `extent') but the
2224 pointer points to random memory, often filled with 0, sometimes not.
2226 /* #### Chuck, do we still need this crap? */
2227 if (!NILP(ret_obj1) && !(GLYPHP(ret_obj1)
2228 #ifdef HAVE_TOOLBARS
2229 || TOOLBAR_BUTTONP(ret_obj1)
2233 if (!NILP(ret_obj2) && !(EXTENTP(ret_obj2) || CONSP(ret_obj2)))
2249 *closest = ret_closest;
2250 if (modeline_closest)
2251 *modeline_closest = ret_modeline_closest;
2260 DEFUN("event-over-text-area-p", Fevent_over_text_area_p, 1, 1, 0, /*
2261 Return t if the mouse event EVENT occurred over the text area of a window.
2262 The modeline is not considered to be part of the text area.
2267 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2269 return result == OVER_TEXT || result == OVER_NOTHING ? Qt : Qnil;
2272 DEFUN("event-over-modeline-p", Fevent_over_modeline_p, 1, 1, 0, /*
2273 Return t if the mouse event EVENT occurred over the modeline of a window.
2278 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2280 return result == OVER_MODELINE ? Qt : Qnil;
2283 DEFUN("event-over-border-p", Fevent_over_border_p, 1, 1, 0, /*
2284 Return t if the mouse event EVENT occurred over an internal border.
2289 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2291 return result == OVER_BORDER ? Qt : Qnil;
2294 DEFUN("event-over-toolbar-p", Fevent_over_toolbar_p, 1, 1, 0, /*
2295 Return t if the mouse event EVENT occurred over a toolbar.
2300 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2302 return result == OVER_TOOLBAR ? Qt : Qnil;
2305 DEFUN("event-over-vertical-divider-p", Fevent_over_vertical_divider_p, 1, 1, 0, /*
2306 Return t if the mouse event EVENT occurred over a window divider.
2311 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2313 return result == OVER_V_DIVIDER ? Qt : Qnil;
2316 struct console *event_console_or_selected(Lisp_Object event)
2318 Lisp_Object channel = EVENT_CHANNEL(XEVENT(event));
2319 Lisp_Object console = CDFW_CONSOLE(channel);
2322 console = Vselected_console;
2324 return XCONSOLE(console);
2327 DEFUN("event-channel", Fevent_channel, 1, 1, 0, /*
2328 Return the channel that the event EVENT occurred on.
2329 This will be a frame, device, console, or nil for some types
2330 of events (e.g. eval events).
2334 CHECK_LIVE_EVENT(event);
2335 return EVENT_CHANNEL(XEVENT(event));
2338 DEFUN("event-window", Fevent_window, 1, 1, 0, /*
2339 Return the window over which mouse event EVENT occurred.
2340 This may be nil if the event occurred in the border or over a toolbar.
2341 The modeline is considered to be within the window it describes.
2347 event_pixel_translation(event, 0, 0, 0, 0, &w, 0, 0, 0, 0, 0);
2354 XSETWINDOW(window, w);
2359 DEFUN("event-point", Fevent_point, 1, 1, 0, /*
2360 Return the character position of the mouse event EVENT.
2361 If the event did not occur over a window, or did not occur over text,
2362 then this returns nil. Otherwise, it returns a position in the buffer
2363 visible in the event's window.
2370 event_pixel_translation(event, 0, 0, 0, 0, &w, &bufp, 0, 0, 0, 0);
2372 return w && bufp ? make_int(bufp) : Qnil;
2375 DEFUN("event-closest-point", Fevent_closest_point, 1, 1, 0, /*
2376 Return the character position closest to the mouse event EVENT.
2377 If the event did not occur over a window or over text, return the
2378 closest point to the location of the event. If the Y pixel position
2379 overlaps a window and the X pixel position is to the left of that
2380 window, the closest point is the beginning of the line containing the
2381 Y position. If the Y pixel position overlaps a window and the X pixel
2382 position is to the right of that window, the closest point is the end
2383 of the line containing the Y position. If the Y pixel position is
2384 above a window, return 0. If it is below the last character in a window,
2385 return the value of (window-end).
2391 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, &bufp, 0, 0, 0);
2393 return bufp ? make_int(bufp) : Qnil;
2396 DEFUN("event-x", Fevent_x, 1, 1, 0, /*
2397 Return the X position of the mouse event EVENT in characters.
2398 This is relative to the window the event occurred over.
2404 event_pixel_translation(event, &char_x, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2406 return make_int(char_x);
2409 DEFUN("event-y", Fevent_y, 1, 1, 0, /*
2410 Return the Y position of the mouse event EVENT in characters.
2411 This is relative to the window the event occurred over.
2417 event_pixel_translation(event, 0, &char_y, 0, 0, 0, 0, 0, 0, 0, 0);
2419 return make_int(char_y);
2422 DEFUN("event-modeline-position", Fevent_modeline_position, 1, 1, 0, /*
2423 Return the character position in the modeline that EVENT occurred over.
2424 EVENT should be a mouse event. If EVENT did not occur over a modeline,
2425 nil is returned. You can determine the actual character that the
2426 event occurred over by looking in `generated-modeline-string' at the
2427 returned character position. Note that `generated-modeline-string'
2428 is buffer-local, and you must use EVENT's buffer when retrieving
2429 `generated-modeline-string' in order to get accurate results.
2437 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, 0, &mbufp, 0, 0);
2439 return (mbufp < 0 || where != OVER_MODELINE) ? Qnil : make_int(mbufp);
2442 DEFUN("event-glyph", Fevent_glyph, 1, 1, 0, /*
2443 Return the glyph that the mouse event EVENT occurred over, or nil.
2450 event_pixel_translation(event, 0, 0, 0, 0, &w, 0, 0, 0, &glyph, 0);
2452 return w && GLYPHP(glyph) ? glyph : Qnil;
2455 DEFUN("event-glyph-extent", Fevent_glyph_extent, 1, 1, 0, /*
2456 Return the extent of the glyph that the mouse event EVENT occurred over.
2457 If the event did not occur over a glyph, nil is returned.
2464 event_pixel_translation(event, 0, 0, 0, 0, &w, 0, 0, 0, 0, &extent);
2466 return w && EXTENTP(extent) ? extent : Qnil;
2469 DEFUN("event-glyph-x-pixel", Fevent_glyph_x_pixel, 1, 1, 0, /*
2470 Return the X pixel position of EVENT relative to the glyph it occurred over.
2471 EVENT should be a mouse event. If the event did not occur over a glyph,
2480 event_pixel_translation(event, 0, 0, &obj_x, 0, &w, 0, 0, 0, 0,
2483 return w && EXTENTP(extent) ? make_int(obj_x) : Qnil;
2486 DEFUN("event-glyph-y-pixel", Fevent_glyph_y_pixel, 1, 1, 0, /*
2487 Return the Y pixel position of EVENT relative to the glyph it occurred over.
2488 EVENT should be a mouse event. If the event did not occur over a glyph,
2497 event_pixel_translation(event, 0, 0, 0, &obj_y, &w, 0, 0, 0, 0,
2500 return w && EXTENTP(extent) ? make_int(obj_y) : Qnil;
2503 DEFUN("event-toolbar-button", Fevent_toolbar_button, 1, 1, 0, /*
2504 Return the toolbar button that the mouse event EVENT occurred over.
2505 If the event did not occur over a toolbar button, nil is returned.
2509 #ifdef HAVE_TOOLBARS
2513 event_pixel_translation(event, 0, 0, 0, 0, 0, 0, 0, 0, &button, 0);
2515 return result == OVER_TOOLBAR
2516 && TOOLBAR_BUTTONP(button) ? button : Qnil;
2522 DEFUN("event-process", Fevent_process, 1, 1, 0, /*
2523 Return the process of the process-output event EVENT.
2527 CHECK_EVENT_TYPE(event, process_event, Qprocess_event_p);
2528 return XEVENT(event)->event.process.process;
2531 DEFUN("event-function", Fevent_function, 1, 1, 0, /*
2532 Return the callback function of EVENT.
2533 EVENT should be a timeout, misc-user, or eval event.
2538 CHECK_LIVE_EVENT(event);
2539 switch (XEVENT(event)->event_type) {
2541 return XEVENT(event)->event.timeout.function;
2542 case misc_user_event:
2543 return XEVENT(event)->event.misc.function;
2545 return XEVENT(event)->event.eval.function;
2548 case key_press_event:
2549 case button_press_event:
2550 case button_release_event:
2551 case pointer_motion_event:
2554 case magic_eval_event:
2555 #ifdef EF_USE_ASYNEQ
2556 case eaten_myself_event:
2557 case work_started_event:
2558 case work_finished_event:
2559 #endif /* EF_USE_ASYNEQ */
2563 wrong_type_argument(intern("timeout-or-eval-event-p"),
2569 DEFUN("event-object", Fevent_object, 1, 1, 0, /*
2570 Return the callback function argument of EVENT.
2571 EVENT should be a timeout, misc-user, or eval event.
2576 CHECK_LIVE_EVENT(event);
2577 switch (XEVENT(event)->event_type) {
2579 return XEVENT(event)->event.timeout.object;
2580 case misc_user_event:
2581 return XEVENT(event)->event.misc.object;
2583 return XEVENT(event)->event.eval.object;
2586 case key_press_event:
2587 case button_press_event:
2588 case button_release_event:
2589 case pointer_motion_event:
2592 case magic_eval_event:
2593 #ifdef EF_USE_ASYNEQ
2594 case eaten_myself_event:
2595 case work_started_event:
2596 case work_finished_event:
2597 #endif /* EF_USE_ASYNEQ */
2600 event = wrong_type_argument(
2601 intern("timeout-or-eval-event-p"), event);
2606 DEFUN("event-properties", Fevent_properties, 1, 1, 0, /*
2607 Return a list of all of the properties of EVENT.
2608 This is in the form of a property list (alternating keyword/value pairs).
2612 Lisp_Object props = Qnil;
2614 struct gcpro gcpro1;
2616 CHECK_LIVE_EVENT(event);
2620 props = cons3(Qtimestamp, Fevent_timestamp(event), props);
2622 switch (e->event_type) {
2627 props = cons3(Qprocess, e->event.process.process, props);
2631 props = cons3(Qobject, Fevent_object(event), props);
2632 props = cons3(Qfunction, Fevent_function(event), props);
2633 props = cons3(Qid, make_int(e->event.timeout.id_number), props);
2636 case key_press_event:
2637 props = cons3(Qmodifiers, Fevent_modifiers(event), props);
2638 props = cons3(Qkey, Fevent_key(event), props);
2641 case button_press_event:
2642 case button_release_event:
2643 props = cons3(Qy, Fevent_y_pixel(event), props);
2644 props = cons3(Qx, Fevent_x_pixel(event), props);
2645 props = cons3(Qmodifiers, Fevent_modifiers(event), props);
2646 props = cons3(Qbutton, Fevent_button(event), props);
2649 case pointer_motion_event:
2650 props = cons3(Qmodifiers, Fevent_modifiers(event), props);
2651 props = cons3(Qy, Fevent_y_pixel(event), props);
2652 props = cons3(Qx, Fevent_x_pixel(event), props);
2655 case misc_user_event:
2656 props = cons3(Qobject, Fevent_object(event), props);
2657 props = cons3(Qfunction, Fevent_function(event), props);
2658 props = cons3(Qy, Fevent_y_pixel(event), props);
2659 props = cons3(Qx, Fevent_x_pixel(event), props);
2660 props = cons3(Qmodifiers, Fevent_modifiers(event), props);
2661 props = cons3(Qbutton, Fevent_button(event), props);
2665 props = cons3(Qobject, Fevent_object(event), props);
2666 props = cons3(Qfunction, Fevent_function(event), props);
2669 #ifdef EF_USE_ASYNEQ
2670 /* are these right here? */
2671 case eaten_myself_event:
2672 case work_started_event:
2673 case work_finished_event:
2674 #endif /* EF_USE_ASYNEQ */
2677 case magic_eval_event:
2682 RETURN_UNGCPRO(Qnil);
2686 props = cons3(Qchannel, Fevent_channel(event), props);
2692 /************************************************************************/
2693 /* initialization */
2694 /************************************************************************/
2696 void syms_of_events(void)
2698 INIT_LRECORD_IMPLEMENTATION(event);
2700 DEFSUBR(Fcharacter_to_event);
2701 DEFSUBR(Fevent_to_character);
2703 DEFSUBR(Fmake_event);
2704 DEFSUBR(Fdeallocate_event);
2705 DEFSUBR(Fcopy_event);
2707 DEFSUBR(Fevent_live_p);
2708 DEFSUBR(Fevent_type);
2709 DEFSUBR(Fevent_properties);
2711 DEFSUBR(Fevent_timestamp);
2712 DEFSUBR(Fevent_timestamp_lessp);
2713 DEFSUBR(Fevent_key);
2714 DEFSUBR(Fevent_button);
2715 DEFSUBR(Fevent_modifier_bits);
2716 DEFSUBR(Fevent_modifiers);
2717 DEFSUBR(Fevent_x_pixel);
2718 DEFSUBR(Fevent_y_pixel);
2719 DEFSUBR(Fevent_window_x_pixel);
2720 DEFSUBR(Fevent_window_y_pixel);
2721 DEFSUBR(Fevent_over_text_area_p);
2722 DEFSUBR(Fevent_over_modeline_p);
2723 DEFSUBR(Fevent_over_border_p);
2724 DEFSUBR(Fevent_over_toolbar_p);
2725 DEFSUBR(Fevent_over_vertical_divider_p);
2726 DEFSUBR(Fevent_channel);
2727 DEFSUBR(Fevent_window);
2728 DEFSUBR(Fevent_point);
2729 DEFSUBR(Fevent_closest_point);
2732 DEFSUBR(Fevent_modeline_position);
2733 DEFSUBR(Fevent_glyph);
2734 DEFSUBR(Fevent_glyph_extent);
2735 DEFSUBR(Fevent_glyph_x_pixel);
2736 DEFSUBR(Fevent_glyph_y_pixel);
2737 DEFSUBR(Fevent_toolbar_button);
2738 DEFSUBR(Fevent_process);
2739 DEFSUBR(Fevent_function);
2740 DEFSUBR(Fevent_object);
2742 defsymbol(&Qeventp, "eventp");
2743 defsymbol(&Qevent_live_p, "event-live-p");
2744 defsymbol(&Qkey_press_event_p, "key-press-event-p");
2745 defsymbol(&Qbutton_event_p, "button-event-p");
2746 defsymbol(&Qmouse_event_p, "mouse-event-p");
2747 defsymbol(&Qprocess_event_p, "process-event-p");
2748 defsymbol(&Qkey_press, "key-press");
2749 defsymbol(&Qbutton_press, "button-press");
2750 defsymbol(&Qbutton_release, "button-release");
2751 defsymbol(&Qmisc_user, "misc-user");
2752 defsymbol(&Qascii_character, "ascii-character");
2754 defsymbol(&QKbackspace, "backspace");
2755 defsymbol(&QKtab, "tab");
2756 defsymbol(&QKlinefeed, "linefeed");
2757 defsymbol(&QKreturn, "return");
2758 defsymbol(&QKescape, "escape");
2759 defsymbol(&QKspace, "space");
2760 defsymbol(&QKdelete, "delete");
2763 void reinit_vars_of_events(void)
2765 init_Vevent_resource();
2768 void vars_of_events(void)
2770 reinit_vars_of_events();
2772 DEFVAR_LISP("character-set-property", &Vcharacter_set_property /*
2773 A symbol used to look up the 8-bit character of a keysym.
2774 To convert a keysym symbol to an 8-bit code, as when that key is
2775 bound to self-insert-command, we will look up the property that this
2776 variable names on the property list of the keysym-symbol. The window-
2777 system-specific code will set up appropriate properties and set this
2780 Vcharacter_set_property = Qnil;