comparison src/events.c @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children ac2d302a0011
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
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.
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 /* Synched up with: Not in FSF. */
23
24 /* This file has been Mule-ized. */
25
26 #include <config.h>
27 #include "lisp.h"
28 #include "buffer.h"
29 #include "console.h"
30 #include "console-tty.h" /* for stuff in character_to_event */
31 #include "device.h"
32 #include "console-x.h" /* for x_event_name prototype */
33 #include "extents.h" /* Just for the EXTENTP abort check... */
34 #include "events.h"
35 #include "frame.h"
36 #include "glyphs.h"
37 #include "keymap.h" /* for key_desc_list_to_event() */
38 #include "redisplay.h"
39 #include "window.h"
40
41 /* Where old events go when they are explicitly deallocated.
42 The event chain here is cut loose before GC, so these will be freed
43 eventually.
44 */
45 static Lisp_Object Vevent_resource;
46
47 Lisp_Object Qeventp;
48 Lisp_Object Qevent_live_p;
49 Lisp_Object Qkey_press_event_p;
50 Lisp_Object Qbutton_event_p;
51 Lisp_Object Qmouse_event_p;
52 Lisp_Object Qprocess_event_p;
53
54 Lisp_Object Qkey_press, Qbutton_press, Qbutton_release, Qmisc_user;
55 Lisp_Object Qascii_character;
56
57 /* #### Ad-hoc hack. Should be part of define_lrecord_implementation */
58 void
59 clear_event_resource (void)
60 {
61 Vevent_resource = Qnil;
62 }
63
64 static Lisp_Object mark_event (Lisp_Object, void (*) (Lisp_Object));
65 static void print_event (Lisp_Object, Lisp_Object, int);
66 static int event_equal (Lisp_Object, Lisp_Object, int);
67 static unsigned long event_hash (Lisp_Object obj, int depth);
68 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("event", event,
69 mark_event, print_event, 0, event_equal,
70 event_hash, struct Lisp_Event);
71
72 /* Make sure we lose quickly if we try to use this event */
73 static void
74 deinitialize_event (Lisp_Object ev)
75 {
76 int i;
77 struct Lisp_Event *event = XEVENT (ev);
78
79 for (i = 0; i < ((sizeof (struct Lisp_Event)) / sizeof (int)); i++)
80 ((int *) event) [i] = 0xdeadbeef;
81 event->event_type = dead_event;
82 event->channel = Qnil;
83 set_lheader_implementation (&(event->lheader), lrecord_event);
84 XSET_EVENT_NEXT (ev, Qnil);
85 }
86
87 /* Set everything to zero or nil so that it's predictable. */
88 void
89 zero_event (struct Lisp_Event *e)
90 {
91 memset (e, 0, sizeof (*e));
92 set_lheader_implementation (&(e->lheader), lrecord_event);
93 e->event_type = empty_event;
94 e->next = Qnil;
95 e->channel = Qnil;
96 }
97
98 static Lisp_Object
99 mark_event (Lisp_Object obj, void (*markobj) (Lisp_Object))
100 {
101 struct Lisp_Event *event = XEVENT (obj);
102
103 switch (event->event_type)
104 {
105 case key_press_event:
106 ((markobj) (event->event.key.keysym));
107 break;
108 case process_event:
109 ((markobj) (event->event.process.process));
110 break;
111 case timeout_event:
112 ((markobj) (event->event.timeout.function));
113 ((markobj) (event->event.timeout.object));
114 break;
115 case eval_event:
116 case misc_user_event:
117 ((markobj) (event->event.eval.function));
118 ((markobj) (event->event.eval.object));
119 break;
120 case magic_eval_event:
121 ((markobj) (event->event.magic_eval.object));
122 break;
123 case button_press_event:
124 case button_release_event:
125 case pointer_motion_event:
126 case magic_event:
127 case empty_event:
128 case dead_event:
129 break;
130 default:
131 abort ();
132 }
133 ((markobj) (event->channel));
134 return event->next;
135 }
136
137 static void
138 print_event_1 (CONST char *str, Lisp_Object obj, Lisp_Object printcharfun)
139 {
140 char buf[255];
141 write_c_string (str, printcharfun);
142 format_event_object (buf, XEVENT (obj), 0);
143 write_c_string (buf, printcharfun);
144 }
145
146 static void
147 print_event (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
148 {
149 if (print_readably)
150 error ("printing unreadable object #<event>");
151
152 switch (XEVENT (obj)->event_type)
153 {
154 case key_press_event:
155 print_event_1 ("#<keypress-event ", obj, printcharfun);
156 break;
157 case button_press_event:
158 print_event_1 ("#<buttondown-event ", obj, printcharfun);
159 break;
160 case button_release_event:
161 print_event_1 ("#<buttonup-event ", obj, printcharfun);
162 break;
163 case magic_event:
164 case magic_eval_event:
165 print_event_1 ("#<magic-event ", obj, printcharfun);
166 break;
167 case pointer_motion_event:
168 {
169 char buf[100];
170 sprintf (buf, "#<motion-event %d, %d",
171 XEVENT (obj)->event.motion.x, XEVENT (obj)->event.motion.y);
172 write_c_string (buf, printcharfun);
173 break;
174 }
175 case process_event:
176 {
177 write_c_string ("#<process-event ", printcharfun);
178 print_internal (XEVENT (obj)->event.process.process, printcharfun, 1);
179 break;
180 }
181 case timeout_event:
182 {
183 write_c_string ("#<timeout-event ", printcharfun);
184 print_internal (XEVENT (obj)->event.timeout.object, printcharfun, 1);
185 break;
186 }
187 case empty_event:
188 {
189 write_c_string ("#<empty-event", printcharfun);
190 break;
191 }
192 case misc_user_event:
193 case eval_event:
194 {
195 write_c_string ("#<", printcharfun);
196 if (XEVENT (obj)->event_type == misc_user_event)
197 write_c_string ("misc-user", printcharfun);
198 else
199 write_c_string ("eval", printcharfun);
200 write_c_string ("-event (", printcharfun);
201 print_internal (XEVENT (obj)->event.eval.function, printcharfun, 1);
202 write_c_string (" ", printcharfun);
203 print_internal (XEVENT (obj)->event.eval.object, printcharfun, 1);
204 write_c_string (")", printcharfun);
205 break;
206 }
207 case dead_event:
208 {
209 write_c_string ("#<DEALLOCATED-EVENT", printcharfun);
210 break;
211 }
212 default:
213 {
214 write_c_string ("#<UNKNOWN-EVENT-TYPE", printcharfun);
215 break;
216 }
217 }
218 write_c_string (">", printcharfun);
219 }
220
221 static int
222 event_equal (Lisp_Object o1, Lisp_Object o2, int depth)
223 {
224 struct Lisp_Event *e1 = XEVENT (o1);
225 struct Lisp_Event *e2 = XEVENT (o2);
226
227 if (e1->event_type != e2->event_type) return 0;
228 if (!EQ (e1->channel, e2->channel)) return 0;
229 /* if (e1->timestamp != e2->timestamp) return 0; */
230 switch (e1->event_type)
231 {
232 case process_event:
233 return (EQ (e1->event.process.process,
234 e2->event.process.process));
235
236 case timeout_event:
237 if (NILP (Fequal (e1->event.timeout.function,
238 e2->event.timeout.function)))
239 return 0;
240 if (NILP (Fequal (e1->event.timeout.object,
241 e2->event.timeout.object)))
242 return 0;
243 return 1;
244
245 case key_press_event:
246 return ((EQ (e1->event.key.keysym,
247 e2->event.key.keysym)
248 && (e1->event.key.modifiers
249 == e2->event.key.modifiers)));
250
251 case button_press_event:
252 case button_release_event:
253 return (((e1->event.button.button
254 == e2->event.button.button)
255 && (e1->event.button.modifiers
256 == e2->event.button.modifiers)));
257
258 case pointer_motion_event:
259 return ((e1->event.motion.x == e2->event.motion.x
260 && e1->event.motion.y == e2->event.motion.y));
261
262 case misc_user_event:
263 case eval_event:
264 if (NILP (Fequal (e1->event.eval.function,
265 e2->event.eval.function)))
266 return 0;
267 if (NILP (Fequal (e1->event.eval.object,
268 e2->event.eval.object)))
269 return 0;
270 return 1;
271
272 case magic_eval_event:
273 if (e1->event.magic_eval.internal_function !=
274 e2->event.magic_eval.internal_function)
275 return 0;
276 if (NILP (Fequal (e1->event.magic_eval.object,
277 e2->event.magic_eval.object)))
278 return 0;
279 return 1;
280
281 case magic_event:
282 {
283 Lisp_Object console;
284
285 console = CDFW_CONSOLE (e1->channel);
286
287 #ifdef HAVE_X_WINDOWS
288 /* XEvent is actually a union which means that we can't just use == */
289 if (CONSOLE_X_P (XCONSOLE (console)))
290 return (!memcmp ((XEvent *) &e1->event.magic.underlying_x_event,
291 (XEvent *) &e2->event.magic.underlying_x_event,
292 sizeof (e1->event.magic.underlying_x_event)));
293 #endif
294 #ifdef HAVE_NEXTSTEP
295 if (CONSOLE_NS_P (XCONSOLE (console)))
296 return (e1->event.magic.underlying_ns_event ==
297 e2->event.magic.underlying_ns_event);
298 #endif
299 return (e1->event.magic.underlying_tty_event ==
300 e2->event.magic.underlying_tty_event);
301 }
302
303 case empty_event: /* Empty and deallocated events are equal. */
304 case dead_event:
305 return 1;
306
307 default:
308 abort ();
309 return 0; /* not reached; warning suppression */
310 }
311 }
312
313 static unsigned long
314 event_hash (Lisp_Object obj, int depth)
315 {
316 struct Lisp_Event *e = XEVENT (obj);
317 unsigned long hash;
318
319 hash = HASH2 (e->event_type, LISP_HASH (e->channel));
320 switch (e->event_type)
321 {
322 case process_event:
323 return HASH2 (hash, LISP_HASH (e->event.process.process));
324
325 case timeout_event:
326 return HASH3 (hash, internal_hash (e->event.timeout.function, depth + 1),
327 internal_hash (e->event.timeout.object, depth + 1));
328
329 case key_press_event:
330 return HASH3 (hash, LISP_HASH (e->event.key.keysym),
331 e->event.key.modifiers);
332
333 case button_press_event:
334 case button_release_event:
335 return HASH3 (hash, e->event.button.button, e->event.button.modifiers);
336
337 case pointer_motion_event:
338 return HASH3 (hash, e->event.motion.x, e->event.motion.y);
339
340 case misc_user_event:
341 case eval_event:
342 return HASH3 (hash, internal_hash (e->event.eval.function, depth + 1),
343 internal_hash (e->event.eval.object, depth + 1));
344
345 case magic_eval_event:
346 return HASH3 (hash,
347 (unsigned long) e->event.magic_eval.internal_function,
348 internal_hash (e->event.magic_eval.object, depth + 1));
349
350 case magic_event:
351 {
352 Lisp_Object console = CDFW_CONSOLE (EVENT_CHANNEL (e));
353 #ifdef HAVE_X_WINDOWS
354 if (CONSOLE_X_P (XCONSOLE (console)))
355 return
356 HASH2 (hash,
357 memory_hash (&e->event.magic.underlying_x_event,
358 sizeof (e->event.magic.underlying_x_event)));
359 #endif
360 #ifdef HAVE_NEXTSTEP
361 if (CONSOLE_NS_P (XCONSOLE (console)))
362 return
363 HASH2 (hash,
364 memory_hash (&e->event.magic.underlying_ns_event,
365 sizeof (e->event.magic.underlying_ns_event)));
366 #endif
367 return
368 HASH2 (hash,
369 memory_hash (&e->event.magic.underlying_tty_event,
370 sizeof (e->event.magic.underlying_tty_event)));
371 }
372
373 case empty_event:
374 case dead_event:
375 return hash;
376
377 default:
378 abort ();
379 }
380
381 return 0;
382 }
383
384
385 /* #### This should accept a type and props (as returned by
386 event-properties) to allow creation of any type of event.
387 This is useful, for example, in Lisp code that might want
388 to determine if, for a given button-down event, what the
389 binding for the corresponding button-up event is. */
390
391 DEFUN ("make-event", Fmake_event, Smake_event, 0, 0, 0 /*
392 Create a new empty event.
393 WARNING, the event object returned may be a reused one; see the function
394 `deallocate-event'.
395 */ )
396 ()
397 {
398 Lisp_Object event;
399
400 if (!NILP (Vevent_resource))
401 {
402 event = Vevent_resource;
403 Vevent_resource = XEVENT_NEXT (event);
404 }
405 else
406 {
407 event = allocate_event ();
408 }
409 zero_event (XEVENT (event));
410 return event;
411 }
412
413 DEFUN ("deallocate-event", Fdeallocate_event, Sdeallocate_event, 1, 1, 0 /*
414 Allow the given event structure to be reused.
415 You MUST NOT use this event object after calling this function with it.
416 You will lose. It is not necessary to call this function, as event
417 objects are garbage-collected like all other objects; however, it may
418 be more efficient to explicitly deallocate events when you are sure
419 that that is safe.
420 */ )
421 (event)
422 Lisp_Object event;
423 {
424 CHECK_EVENT (event);
425
426 if (XEVENT_TYPE (event) == dead_event)
427 error ("this event is already deallocated!");
428
429 assert (XEVENT_TYPE (event) <= last_event_type);
430
431 #if 0
432 {
433 int i;
434 extern Lisp_Object Vlast_command_event;
435 extern Lisp_Object Vlast_input_event, Vunread_command_event;
436 extern Lisp_Object Vthis_command_keys, Vrecent_keys_ring;
437
438 if (EQ (event, Vlast_command_event))
439 abort ();
440 if (EQ (event, Vlast_input_event))
441 abort ();
442 if (EQ (event, Vunread_command_event))
443 abort ();
444 for (i = 0; i < XVECTOR (Vthis_command_keys)->size; i++)
445 if (EQ (event, vector_data (XVECTOR (Vthis_command_keys)) [i]))
446 abort ();
447 for (i = 0; i < XVECTOR (Vrecent_keys_ring)->size; i++)
448 if (EQ (event, vector_data (XVECTOR (Vrecent_keys_ring)) [i]))
449 abort ();
450 }
451 #endif /* 0 */
452
453 assert (!EQ (event, Vevent_resource));
454 deinitialize_event (event);
455 #ifndef ALLOC_NO_POOLS
456 XSET_EVENT_NEXT (event, Vevent_resource);
457 Vevent_resource = event;
458 #endif
459 return Qnil;
460 }
461
462 DEFUN ("copy-event", Fcopy_event, Scopy_event, 1, 2, 0 /*
463 Make a copy of the given event object.
464 If a second argument is given, the first event is copied into the second
465 and the second is returned. If the second argument is not supplied (or
466 is nil) then a new event will be made as with `allocate-event.' See also
467 the function `deallocate-event'.
468 */ )
469 (event1, event2)
470 Lisp_Object event1, event2;
471 {
472 CHECK_LIVE_EVENT (event1);
473 if (NILP (event2))
474 event2 = Fmake_event ();
475 else CHECK_LIVE_EVENT (event2);
476 if (EQ (event1, event2))
477 return signal_simple_continuable_error_2
478 ("copy-event called with `eq' events", event1, event2);
479
480 assert (XEVENT_TYPE (event1) <= last_event_type);
481 assert (XEVENT_TYPE (event2) <= last_event_type);
482
483 {
484 Lisp_Object save_next = XEVENT_NEXT (event2);
485
486 *XEVENT (event2) = *XEVENT (event1);
487 XSET_EVENT_NEXT (event2, save_next);
488 return (event2);
489 }
490 }
491
492
493
494 /* Given a chain of events (or possibly nil), deallocate them all. */
495
496 void
497 deallocate_event_chain (Lisp_Object event_chain)
498 {
499 while (!NILP (event_chain))
500 {
501 Lisp_Object next = XEVENT_NEXT (event_chain);
502 Fdeallocate_event (event_chain);
503 event_chain = next;
504 }
505 }
506
507 /* Return the last event in a chain.
508 NOTE: You cannot pass nil as a value here! The routine will
509 abort if you do. */
510
511 Lisp_Object
512 event_chain_tail (Lisp_Object event_chain)
513 {
514 while (1)
515 {
516 Lisp_Object next = XEVENT_NEXT (event_chain);
517 if (NILP (next))
518 return event_chain;
519 event_chain = next;
520 }
521 }
522
523 /* Enqueue a single event onto the end of a chain of events.
524 HEAD points to the first event in the chain, TAIL to the last event.
525 If the chain is empty, both values should be nil. */
526
527 void
528 enqueue_event (Lisp_Object event, Lisp_Object *head, Lisp_Object *tail)
529 {
530 assert (NILP (XEVENT_NEXT (event)));
531 assert (!EQ (*tail, event));
532
533 if (!NILP (*tail))
534 XSET_EVENT_NEXT (*tail, event);
535 else
536 *head = event;
537 *tail = event;
538
539 assert (!EQ (event, XEVENT_NEXT (event)));
540 }
541
542 /* Remove an event off the head of a chain of events and return it.
543 HEAD points to the first event in the chain, TAIL to the last event. */
544
545 Lisp_Object
546 dequeue_event (Lisp_Object *head, Lisp_Object *tail)
547 {
548 Lisp_Object event;
549
550 event = *head;
551 *head = XEVENT_NEXT (event);
552 XSET_EVENT_NEXT (event, Qnil);
553 if (NILP (*head))
554 *tail = Qnil;
555 return event;
556 }
557
558 /* Enqueue a chain of events (or possibly nil) onto the end of another
559 chain of events. HEAD points to the first event in the chain being
560 queued onto, TAIL to the last event. If the chain is empty, both values
561 should be nil. */
562
563 void
564 enqueue_event_chain (Lisp_Object event_chain, Lisp_Object *head,
565 Lisp_Object *tail)
566 {
567 if (NILP (event_chain))
568 return;
569
570 if (NILP (*head))
571 {
572 *head = event_chain;
573 *tail = event_chain;
574 }
575 else
576 {
577 XSET_EVENT_NEXT (*tail, event_chain);
578 *tail = event_chain_tail (event_chain);
579 }
580 }
581
582 /* Return the number of events (possibly 0) on an event chain. */
583
584 int
585 event_chain_count (Lisp_Object event_chain)
586 {
587 Lisp_Object event;
588 int n = 0;
589
590 EVENT_CHAIN_LOOP (event, event_chain)
591 n++;
592
593 return n;
594 }
595
596 /* Find the event before EVENT in an event chain. This aborts
597 if the event is not in the chain. */
598
599 Lisp_Object
600 event_chain_find_previous (Lisp_Object event_chain, Lisp_Object event)
601 {
602 Lisp_Object previous = Qnil;
603
604 while (!NILP (event_chain))
605 {
606 if (EQ (event_chain, event))
607 return previous;
608 previous = event_chain;
609 event_chain = XEVENT_NEXT (event_chain);
610 }
611
612 abort ();
613 return Qnil;
614 }
615
616 Lisp_Object
617 event_chain_nth (Lisp_Object event_chain, int n)
618 {
619 Lisp_Object event;
620 EVENT_CHAIN_LOOP (event, event_chain)
621 {
622 if (!n)
623 return event;
624 n--;
625 }
626 return Qnil;
627 }
628
629 Lisp_Object
630 copy_event_chain (Lisp_Object event_chain)
631 {
632 Lisp_Object new_chain = Qnil;
633 Lisp_Object new_chain_tail = Qnil;
634 Lisp_Object event;
635
636 EVENT_CHAIN_LOOP (event, event_chain)
637 {
638 Lisp_Object copy = Fcopy_event (event, Qnil);
639 enqueue_event (copy, &new_chain, &new_chain_tail);
640 }
641
642 return new_chain;
643 }
644
645
646
647 Lisp_Object QKbackspace, QKtab, QKlinefeed, QKreturn, QKescape,
648 QKspace, QKdelete;
649
650 int
651 command_event_p (Lisp_Object event)
652 {
653 switch (XEVENT_TYPE (event))
654 {
655 case key_press_event:
656 case button_press_event:
657 case button_release_event:
658 case misc_user_event:
659 return (1);
660 default:
661 return (0);
662 }
663 }
664
665
666 void
667 character_to_event (Emchar c, struct Lisp_Event *event, struct console *con,
668 int use_console_meta_flag)
669 {
670 Lisp_Object k = Qnil;
671 unsigned int m = 0;
672 if (event->event_type == dead_event)
673 error ("character-to-event called with a deallocated event!");
674
675 c &= 255;
676
677 if (c > 127 && c <= 255)
678 {
679 int meta_flag = 1;
680 if (use_console_meta_flag && CONSOLE_TTY_P (con))
681 meta_flag = TTY_FLAGS (con).meta_key;
682 switch (meta_flag)
683 {
684 case 0: /* ignore top bit; it's parity */
685 c -= 128;
686 break;
687 case 1: /* top bit is meta */
688 c -= 128;
689 m = MOD_META;
690 break;
691 default: /* this is a real character */
692 break;
693 }
694 }
695 if (c < ' ') c += '@', m |= MOD_CONTROL;
696 if (m & MOD_CONTROL)
697 {
698 switch (c)
699 {
700 case 'I': k = QKtab; m &= ~MOD_CONTROL; break;
701 case 'J': k = QKlinefeed; m &= ~MOD_CONTROL; break;
702 case 'M': k = QKreturn; m &= ~MOD_CONTROL; break;
703 case '[': k = QKescape; m &= ~MOD_CONTROL; break;
704 # if 0
705 /* This is probably too controversial... */
706 case 'H': k = QKbackspace; m &= ~MOD_CONTROL; break;
707 # endif
708 }
709 if (c >= 'A' && c <= 'Z') c -= 'A'-'a';
710 }
711 else if (c == 127)
712 k = QKdelete;
713 else if (c == ' ')
714 k = QKspace;
715
716 event->event_type = key_press_event;
717 event->timestamp = 0; /* #### */
718 event->channel = make_console (con);
719 event->event.key.keysym = (!NILP (k) ? k : make_char (c));
720 event->event.key.modifiers = m;
721 }
722
723
724 /* This variable controls what character name -> character code mapping
725 we are using. Window-system-specific code sets this to some symbol,
726 and we use that symbol as the plist key to convert keysyms into 8-bit
727 codes. In this way one can have several character sets predefined and
728 switch them by changing this.
729 */
730 Lisp_Object Vcharacter_set_property;
731
732 Emchar
733 event_to_character (struct Lisp_Event *event,
734 int allow_extra_modifiers,
735 int allow_meta,
736 int allow_non_ascii)
737 {
738 Emchar c = 0;
739 Lisp_Object code;
740
741 if (event->event_type != key_press_event)
742 {
743 if (event->event_type == dead_event) abort ();
744 return -1;
745 }
746 if (!allow_extra_modifiers &&
747 event->event.key.modifiers & (MOD_SUPER|MOD_HYPER|MOD_ALT))
748 return -1;
749 if (CHAR_OR_CHAR_INTP (event->event.key.keysym))
750 c = XCHAR_OR_CHAR_INT (event->event.key.keysym);
751 else if (!SYMBOLP (event->event.key.keysym))
752 abort ();
753 else if (allow_non_ascii && !NILP (Vcharacter_set_property)
754 /* Allow window-system-specific extensibility of
755 keysym->code mapping */
756 && CHAR_OR_CHAR_INTP (code = Fget (event->event.key.keysym,
757 Vcharacter_set_property,
758 Qnil)))
759 c = XCHAR_OR_CHAR_INT (code);
760 else if (CHAR_OR_CHAR_INTP (code = Fget (event->event.key.keysym,
761 Qascii_character, Qnil)))
762 c = XCHAR_OR_CHAR_INT (code);
763 else
764 return -1;
765
766 if (event->event.key.modifiers & MOD_CONTROL)
767 {
768 if (c >= 'a' && c <= 'z')
769 c -= ('a' - 'A');
770 else
771 /* reject Control-Shift- keys */
772 if (c >= 'A' && c <= 'Z' && !allow_extra_modifiers)
773 return -1;
774
775 if (c >= '@' && c <= '_')
776 c -= '@';
777 else if (c == ' ') /* C-space and C-@ are the same. */
778 c = 0;
779 else
780 /* reject keys that can't take Control- modifiers */
781 if (! allow_extra_modifiers) return -1;
782 }
783
784 if (event->event.key.modifiers & MOD_META)
785 {
786 if (! allow_meta) return -1;
787 if (c & 0200) return -1; /* don't allow M-oslash (overlap) */
788 c |= 0200;
789 }
790 return c;
791 }
792
793
794 DEFUN ("event-to-character", Fevent_to_character, Sevent_to_character,
795 1, 4, 0 /*
796 Return the closest ASCII approximation to the given event object.
797 If the event isn't a keypress, this returns nil.
798 If the ALLOW-EXTRA-MODIFIERS argument is non-nil, then this is lenient in
799 its translation; it will ignore modifier keys other than control and meta,
800 and will ignore the shift modifier on those characters which have no
801 shifted ASCII equivalent (Control-Shift-A for example, will be mapped to
802 the same ASCII code as Control-A).
803 If the ALLOW-META argument is non-nil, then the Meta modifier will be
804 represented by turning on the high bit of the byte returned; otherwise, nil
805 will be returned for events containing the Meta modifier.
806 If the ALLOW-NON-ASCII argument is non-nil, then characters which are
807 present in the prevailing character set (see the `character-set-property'
808 variable) will be returned as their code in that character set, instead of
809 the return value being restricted to ASCII.
810 Note that specifying both ALLOW-META and ALLOW-NON-ASCII is ambiguous, as
811 both use the high bit; `M-x' and `oslash' will be indistinguishable.
812 */ )
813 (event, allow_extra_modifiers, allow_meta, allow_non_ascii)
814 Lisp_Object event, allow_extra_modifiers, allow_meta, allow_non_ascii;
815 {
816 Emchar c;
817 CHECK_LIVE_EVENT (event);
818 c = event_to_character (XEVENT (event),
819 !NILP (allow_extra_modifiers),
820 !NILP (allow_meta),
821 !NILP (allow_non_ascii));
822 return (c < 0 ? Qnil : make_char (c));
823 }
824
825 DEFUN ("character-to-event", Fcharacter_to_event, Scharacter_to_event,
826 1, 4, 0 /*
827 Converts a keystroke specifier intoto an event structure, replete with
828 bucky bits. The keystroke is the first argument, and the event to fill
829 in is the second. This function contains knowledge about what the codes
830 ``mean'' -- for example, the number 9 is converted to the character ``Tab'',
831 not the distinct character ``Control-I''.
832
833 Note that CH (the keystroke specifier) can be an integer, a character,
834 a symbol such as 'clear, or a list such as '(control backspace).
835
836 If the optional second argument is an event, it is modified; otherwise, a
837 new event object is created.
838
839 Optional third arg CONSOLE is the console to store in the event, and defaults
840 to the selected console.
841
842 If CH is an integer or character, the high bit may be interpreted as the
843 meta key. (This is done for backward compatibility in lots of places.)
844 If USE-CONSOLE-META-FLAG is nil, this will always be the case. If
845 USE-CONSOLE-META-FLAG is non-nil, the `meta' flag for CONSOLE affects
846 whether the high bit is interpreted as a meta key. (See `set-input-mode'.)
847 If you don't want this silly meta interpretation done, you should pass
848 in a list containing the character.
849
850 Beware that character-to-event and event-to-character are not strictly
851 inverse functions, since events contain much more information than the
852 ASCII character set can encode.
853 */ )
854 (ch, event, console, use_console_meta_flag)
855 Lisp_Object ch, event, console, use_console_meta_flag;
856 {
857 struct console *con = decode_console (console);
858 if (NILP (event))
859 event = Fmake_event ();
860 else
861 CHECK_LIVE_EVENT (event);
862 if (CONSP (ch) || SYMBOLP (ch))
863 key_desc_list_to_event (ch, event, 1);
864 else
865 {
866 CHECK_CHAR_COERCE_INT (ch);
867 character_to_event (XCHAR (ch), XEVENT (event), con,
868 !NILP (use_console_meta_flag));
869 }
870 return event;
871 }
872
873 void
874 nth_of_key_sequence_as_event (Lisp_Object seq, int n, Lisp_Object event)
875 {
876 assert (STRINGP (seq) || VECTORP (seq));
877 assert (n < XINT (Flength (seq)));
878
879 if (STRINGP (seq))
880 {
881 Emchar ch = string_char (XSTRING (seq), n);
882 Fcharacter_to_event (make_char (ch), event, Qnil, Qnil);
883 }
884 else
885 {
886 Lisp_Object keystroke = vector_data (XVECTOR (seq))[n];
887 if (EVENTP (keystroke))
888 Fcopy_event (keystroke, event);
889 else
890 Fcharacter_to_event (keystroke, event, Qnil, Qnil);
891 }
892 }
893
894 Lisp_Object
895 key_sequence_to_event_chain (Lisp_Object seq)
896 {
897 int len = XINT (Flength (seq));
898 int i;
899 Lisp_Object head = Qnil, tail = Qnil;
900
901 for (i = 0; i < len; i++)
902 {
903 Lisp_Object event = Fmake_event ();
904 nth_of_key_sequence_as_event (seq, i, event);
905 enqueue_event (event, &head, &tail);
906 }
907
908 return head;
909 }
910
911 void
912 format_event_object (char *buf, struct Lisp_Event *event, int brief)
913 {
914 int mouse_p = 0;
915 int mod = 0;
916 Lisp_Object key;
917
918 switch (event->event_type)
919 {
920 case key_press_event:
921 {
922 mod = event->event.key.modifiers;
923 key = event->event.key.keysym;
924 /* Hack. */
925 if (! brief && CHARP (key) &&
926 mod & (MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER))
927 {
928 int k = XCHAR (key);
929 if (k >= 'a' && k <= 'z')
930 key = make_char (k - ('a' - 'A'));
931 else if (k >= 'A' && k <= 'Z')
932 mod |= MOD_SHIFT;
933 }
934 break;
935 }
936 case button_release_event:
937 mouse_p++;
938 /* Fall through */
939 case button_press_event:
940 {
941 mouse_p++;
942 mod = event->event.button.modifiers;
943 key = make_char (event->event.button.button + '0');
944 break;
945 }
946 case magic_event:
947 {
948 CONST char *name = 0;
949 Lisp_Object console = CDFW_CONSOLE (EVENT_CHANNEL (event));
950
951 #ifdef HAVE_X_WINDOWS
952 if (CONSOLE_X_P (XCONSOLE (console)))
953 name =
954 x_event_name (event->event.magic.underlying_x_event.xany.type);
955 #endif
956 #ifdef HAVE_NEXTSTEP
957 if (CONSOLE_NS_P (XCONSOLE (console)))
958 name = ns_event_name (event->event.magic.underlying_ns_event);
959 #endif
960 if (name) strcpy (buf, name);
961 else strcpy (buf, "???");
962 return;
963 }
964 case magic_eval_event: strcpy (buf, "magic-eval"); return;
965 case pointer_motion_event: strcpy (buf, "motion"); return;
966 case misc_user_event: strcpy (buf, "misc-user"); return;
967 case eval_event: strcpy (buf, "eval"); return;
968 case process_event: strcpy (buf, "process");return;
969 case timeout_event: strcpy (buf, "timeout");return;
970 case empty_event: strcpy (buf, "EMPTY-EVENT"); return;
971 case dead_event: strcpy (buf, "DEAD-EVENT"); return;
972 default:
973 abort ();
974 }
975 #define modprint1(x) { strcpy (buf, (x)); buf += sizeof (x)-1; }
976 #define modprint(x,y) { if (brief) modprint1 (y) else modprint1 (x) }
977 if (mod & MOD_CONTROL) modprint ("control-", "C-");
978 if (mod & MOD_META) modprint ("meta-", "M-");
979 if (mod & MOD_SUPER) modprint ("super-", "S-");
980 if (mod & MOD_HYPER) modprint ("hyper-", "H-");
981 if (mod & MOD_ALT) modprint ("alt-", "A-");
982 if (mod & MOD_SHIFT) modprint ("shift-", "Sh-");
983 if (mouse_p)
984 {
985 modprint1 ("button");
986 --mouse_p;
987 }
988 #undef modprint
989 #undef modprint1
990
991 if (CHARP (key))
992 {
993 buf += set_charptr_emchar ((Bufbyte *) buf, XCHAR (key));
994 *buf = 0;
995 }
996 else if (SYMBOLP (key))
997 {
998 CONST char *str = 0;
999 if (brief)
1000 {
1001 if (EQ (key, QKlinefeed)) str = "LFD";
1002 else if (EQ (key, QKtab)) str = "TAB";
1003 else if (EQ (key, QKreturn)) str = "RET";
1004 else if (EQ (key, QKescape)) str = "ESC";
1005 else if (EQ (key, QKdelete)) str = "DEL";
1006 else if (EQ (key, QKspace)) str = "SPC";
1007 else if (EQ (key, QKbackspace)) str = "BS";
1008 }
1009 if (str)
1010 {
1011 int i = strlen (str);
1012 memcpy (buf, str, i+1);
1013 str += i;
1014 }
1015 else
1016 {
1017 memcpy (buf, string_data (XSYMBOL (key)->name),
1018 string_length (XSYMBOL (key)->name) + 1);
1019 str += string_length (XSYMBOL (key)->name);
1020 }
1021 }
1022 else
1023 abort ();
1024 if (mouse_p)
1025 strncpy (buf, "up", 4);
1026 }
1027
1028 DEFUN ("eventp", Feventp, Seventp, 1, 1, 0 /*
1029 True if OBJECT is an event object.
1030 */ )
1031 (object)
1032 Lisp_Object object;
1033 {
1034 return ((EVENTP (object)) ? Qt : Qnil);
1035 }
1036
1037 DEFUN ("event-live-p", Fevent_live_p, Sevent_live_p, 1, 1, 0 /*
1038 True if OBJECT is an event object that has not been deallocated.
1039 */ )
1040 (object)
1041 Lisp_Object object;
1042 {
1043 return ((EVENTP (object) && XEVENT (object)->event_type != dead_event)
1044 ? Qt : Qnil);
1045 }
1046
1047 #if 0 /* debugging functions */
1048
1049 xxDEFUN ("event-next", Fevent_next, Sevent_next, 1, 1, 0 /*
1050 Return the event object's `next' event, or nil if it has none.
1051 The `next-event' field is changed by calling `set-next-event'.
1052 */ )
1053 (event)
1054 Lisp_Object event;
1055 {
1056 struct Lisp_Event *e;
1057 CHECK_LIVE_EVENT (event);
1058
1059 return XEVENT_NEXT (event);
1060 }
1061
1062 xxDEFUN ("set-event-next", Fset_event_next, Sset_event_next, 2, 2, 0 /*
1063 Set the `next event' of EVENT to NEXT-EVENT.
1064 NEXT-EVENT must be an event object or nil.
1065 */ )
1066 (event, next_event)
1067 Lisp_Object event, next_event;
1068 {
1069 Lisp_Object ev;
1070
1071 CHECK_LIVE_EVENT (event);
1072 if (NILP (next_event))
1073 {
1074 XSET_EVENT_NEXT (event, Qnil);
1075 return (Qnil);
1076 }
1077
1078 CHECK_LIVE_EVENT (next_event);
1079
1080 EVENT_CHAIN_LOOP (ev, XEVENT_NEXT (event))
1081 {
1082 QUIT;
1083 if (EQ (ev, event))
1084 signal_error (Qerror,
1085 list3 (build_string ("Cyclic event-next"),
1086 event,
1087 next_event));
1088 }
1089 XSET_EVENT_NEXT (event, next_event);
1090 return (next_event);
1091 }
1092
1093 #endif /* 0 */
1094
1095 DEFUN ("event-type", Fevent_type, Sevent_type, 1, 1, 0 /*
1096 Return the type of EVENT.
1097 This will be a symbol; one of
1098
1099 key-press A key was pressed.
1100 button-press A mouse button was pressed.
1101 button-release A mouse button was released.
1102 misc-user Some other user action happened; typically, this is
1103 a menu selection or scrollbar action.
1104 motion The mouse moved.
1105 process Input is available from a subprocess.
1106 timeout A timeout has expired.
1107 eval This causes a specified action to occur when dispatched.
1108 magic Some window-system-specific event has occurred.
1109 */ )
1110 (event)
1111 Lisp_Object event;
1112 {
1113 CHECK_LIVE_EVENT (event);
1114 switch (XEVENT (event)->event_type)
1115 {
1116 case key_press_event:
1117 return Qkey_press;
1118
1119 case button_press_event:
1120 return Qbutton_press;
1121
1122 case button_release_event:
1123 return Qbutton_release;
1124
1125 case misc_user_event:
1126 return Qmisc_user;
1127
1128 case pointer_motion_event:
1129 return Qmotion;
1130
1131 case process_event:
1132 return Qprocess;
1133
1134 case timeout_event:
1135 return Qtimeout;
1136
1137 case eval_event:
1138 return Qeval;
1139
1140 case magic_event:
1141 case magic_eval_event:
1142 return Qmagic;
1143
1144 default:
1145 abort ();
1146 return Qnil;
1147 }
1148 }
1149
1150 DEFUN ("event-timestamp", Fevent_timestamp, Sevent_timestamp, 1, 1, 0 /*
1151 Return the timestamp of the given event object.
1152 */ )
1153 (event)
1154 Lisp_Object event;
1155 {
1156 CHECK_LIVE_EVENT (event);
1157 /* This junk is so that timestamps don't get to be negative, but contain
1158 as many bits as this particular emacs will allow.
1159 */
1160 return make_int (((1L << (VALBITS - 1)) - 1) &
1161 XEVENT (event)->timestamp);
1162 }
1163
1164 #define CHECK_EVENT_TYPE(e,t1,sym) \
1165 { CHECK_LIVE_EVENT (e); \
1166 if (XEVENT(e)->event_type != (t1)) \
1167 e = wrong_type_argument ((sym),(e)); \
1168 }
1169
1170 #define CHECK_EVENT_TYPE2(e,t1,t2,sym) \
1171 { CHECK_LIVE_EVENT (e); \
1172 if (XEVENT(e)->event_type != (t1) && XEVENT(e)->event_type != (t2)) \
1173 e = wrong_type_argument ((sym),(e)); \
1174 }
1175
1176 DEFUN ("event-key", Fevent_key, Sevent_key, 1, 1, 0 /*
1177 Return the Keysym of the given key-press event.
1178 This will be the ASCII code of a printing character, or a symbol.
1179 */ )
1180 (event)
1181 Lisp_Object event;
1182 {
1183 CHECK_EVENT_TYPE (event, key_press_event, Qkey_press_event_p);
1184 return (XEVENT (event)->event.key.keysym);
1185 }
1186
1187 DEFUN ("event-button", Fevent_button, Sevent_button, 1, 1, 0 /*
1188 Return the button-number of the given mouse-button-press event.
1189 */ )
1190 (event)
1191 Lisp_Object event;
1192 {
1193 CHECK_EVENT_TYPE2 (event, button_press_event, button_release_event,
1194 Qbutton_event_p);
1195 #ifdef HAVE_WINDOW_SYSTEM
1196 return make_int (XEVENT (event)->event.button.button);
1197 #else /* !HAVE_WINDOW_SYSTEM */
1198 return Qzero;
1199 #endif /* !HAVE_WINDOW_SYSTEM */
1200 }
1201
1202 DEFUN ("event-modifier-bits", Fevent_modifier_bits, Sevent_modifier_bits,
1203 1, 1, 0 /*
1204 Return a number representing the modifier keys which were down
1205 when the given mouse or keyboard event was produced. See also the function
1206 event-modifiers.
1207 */ )
1208 (event)
1209 Lisp_Object event;
1210 {
1211 again:
1212 CHECK_LIVE_EVENT (event);
1213 if (XEVENT (event)->event_type == key_press_event)
1214 return make_int (XEVENT (event)->event.key.modifiers);
1215 else if (XEVENT (event)->event_type == button_press_event ||
1216 XEVENT (event)->event_type == button_release_event)
1217 return make_int (XEVENT (event)->event.button.modifiers);
1218 else if (XEVENT (event)->event_type == pointer_motion_event)
1219 return make_int (XEVENT (event)->event.motion.modifiers);
1220 else
1221 {
1222 event = wrong_type_argument (intern ("key-or-mouse-event-p"), event);
1223 goto again;
1224 }
1225 }
1226
1227 DEFUN ("event-modifiers", Fevent_modifiers, Sevent_modifiers, 1, 1, 0 /*
1228 Return a list of symbols, the names of the modifier keys
1229 which were down when the given mouse or keyboard event was produced.
1230 See also the function event-modifier-bits.
1231 */ )
1232 (event)
1233 Lisp_Object event;
1234 {
1235 int mod = XINT (Fevent_modifier_bits (event));
1236 Lisp_Object result = Qnil;
1237 if (mod & MOD_SHIFT) result = Fcons (Qshift, result);
1238 if (mod & MOD_ALT) result = Fcons (Qalt, result);
1239 if (mod & MOD_HYPER) result = Fcons (Qhyper, result);
1240 if (mod & MOD_SUPER) result = Fcons (Qsuper, result);
1241 if (mod & MOD_META) result = Fcons (Qmeta, result);
1242 if (mod & MOD_CONTROL) result = Fcons (Qcontrol, result);
1243 return result;
1244 }
1245
1246 static int
1247 event_x_y_pixel_internal (Lisp_Object event, int *x, int *y, int relative)
1248 {
1249 struct window *w;
1250 struct frame *f;
1251
1252 if (XEVENT (event)->event_type == pointer_motion_event)
1253 {
1254 *x = XEVENT (event)->event.motion.x;
1255 *y = XEVENT (event)->event.motion.y;
1256 }
1257 else if (XEVENT (event)->event_type == button_press_event ||
1258 XEVENT (event)->event_type == button_release_event)
1259 {
1260 *x = XEVENT (event)->event.button.x;
1261 *y = XEVENT (event)->event.button.y;
1262 }
1263 else
1264 return 0;
1265
1266 f = XFRAME (EVENT_CHANNEL (XEVENT (event)));
1267
1268 if (relative)
1269 {
1270 w = find_window_by_pixel_pos (*x, *y, f->root_window);
1271
1272 if (!w)
1273 return 1; /* #### What should really happen here. */
1274
1275 *x -= w->pixel_left;
1276 *y -= w->pixel_top;
1277 }
1278 else
1279 {
1280 *y -= FRAME_REAL_TOP_TOOLBAR_HEIGHT (f);
1281 *x -= FRAME_REAL_LEFT_TOOLBAR_WIDTH (f);
1282 }
1283
1284 return 1;
1285 }
1286
1287 DEFUN ("event-window-x-pixel", Fevent_window_x_pixel, Sevent_window_x_pixel,
1288 1, 1, 0 /*
1289 Return the X position in pixels of the given mouse event.
1290 The value returned is relative to the window the event occurred in.
1291 This will signal an error if the event is not a mouse-motion, button-press,
1292 or button-release event. See also `event-x-pixel'.
1293 */ )
1294 (event)
1295 Lisp_Object event;
1296 {
1297 int x, y;
1298
1299 CHECK_LIVE_EVENT (event);
1300
1301 if (!event_x_y_pixel_internal (event, &x, &y, 1))
1302 return wrong_type_argument (Qmouse_event_p, event);
1303 else
1304 return make_int (x);
1305 }
1306
1307 DEFUN ("event-window-y-pixel", Fevent_window_y_pixel, Sevent_window_y_pixel,
1308 1, 1, 0 /*
1309 Return the Y position in pixels of the given mouse event.
1310 The value returned is relative to the window the event occurred in.
1311 This will signal an error if the event is not a mouse-motion, button-press,
1312 or button-release event. See also `event-y-pixel'.
1313 */ )
1314 (event)
1315 Lisp_Object event;
1316 {
1317 int x, y;
1318
1319 CHECK_LIVE_EVENT (event);
1320
1321 if (!event_x_y_pixel_internal (event, &x, &y, 1))
1322 return wrong_type_argument (Qmouse_event_p, event);
1323 else
1324 return make_int (y);
1325 }
1326
1327 DEFUN ("event-x-pixel", Fevent_x_pixel, Sevent_x_pixel,
1328 1, 1, 0 /*
1329 Return the X position in pixels of the given mouse event.
1330 The value returned is relative to the frame the event occurred in.
1331 This will signal an error if the event is not a mouse-motion, button-press,
1332 or button-release event. See also `event-window-x-pixel'.
1333 */ )
1334 (event)
1335 Lisp_Object event;
1336 {
1337 int x, y;
1338
1339 CHECK_LIVE_EVENT (event);
1340
1341 if (!event_x_y_pixel_internal (event, &x, &y, 0))
1342 return wrong_type_argument (Qmouse_event_p, event);
1343 else
1344 return make_int (x);
1345 }
1346
1347 DEFUN ("event-y-pixel", Fevent_y_pixel, Sevent_y_pixel,
1348 1, 1, 0 /*
1349 Return the Y position in pixels of the given mouse event.
1350 The value returned is relative to the frame the event occurred in.
1351 This will signal an error if the event is not a mouse-motion, button-press,
1352 or button-release event. See also `event-window-y-pixel'.
1353 */ )
1354 (event)
1355 Lisp_Object event;
1356 {
1357 int x, y;
1358
1359 CHECK_LIVE_EVENT (event);
1360
1361 if (!event_x_y_pixel_internal (event, &x, &y, 0))
1362 return wrong_type_argument (Qmouse_event_p, event);
1363 else
1364 return make_int (y);
1365 }
1366
1367 /* Given an event, return a value:
1368
1369 OVER_TOOLBAR: over one of the 4 frame toolbars
1370 OVER_MODELINE: over a modeline
1371 OVER_BORDER: over an internal border
1372 OVER_NOTHING: over the text area, but not over text
1373 OVER_OUTSIDE: outside of the frame border
1374 OVER_TEXT: over text in the text area
1375
1376 and return:
1377
1378 The X char position in CHAR_X, if not a null pointer.
1379 The Y char position in CHAR_Y, if not a null pointer.
1380 (These last two values are relative to the window the event is over.)
1381 The window it's over in W, if not a null pointer.
1382 The buffer position it's over in BUFP, if not a null pointer.
1383 The closest buffer position in CLOSEST, if not a null pointer.
1384
1385 OBJ_X, OBJ_Y, OBJ1, and OBJ2 are as in pixel_to_glyph_translation().
1386 */
1387
1388 static int
1389 event_pixel_translation (Lisp_Object event, int *char_x, int *char_y,
1390 int *obj_x, int *obj_y,
1391 struct window **w, Bufpos *bufp, Bufpos *closest,
1392 Charcount *modeline_closest,
1393 Lisp_Object *obj1, Lisp_Object *obj2)
1394 {
1395 int pix_x = 0;
1396 int pix_y = 0;
1397 int result;
1398 Lisp_Object frame;
1399
1400 int ret_x, ret_y, ret_obj_x, ret_obj_y;
1401 struct window *ret_w;
1402 Bufpos ret_bufp, ret_closest;
1403 Charcount ret_modeline_closest;
1404 Lisp_Object ret_obj1, ret_obj2;
1405
1406 CHECK_LIVE_EVENT (event);
1407 if (XEVENT (event)->event_type == pointer_motion_event)
1408 {
1409 pix_x = XEVENT (event)->event.motion.x;
1410 pix_y = XEVENT (event)->event.motion.y;
1411 frame = XEVENT (event)->channel;
1412 }
1413 else if (XEVENT (event)->event_type == button_press_event ||
1414 XEVENT (event)->event_type == button_release_event)
1415 {
1416 pix_x = XEVENT (event)->event.button.x;
1417 pix_y = XEVENT (event)->event.button.y;
1418 frame = XEVENT (event)->channel;
1419 }
1420 else
1421 wrong_type_argument (Qmouse_event_p, event);
1422
1423 result = pixel_to_glyph_translation (XFRAME (frame), pix_x, pix_y,
1424 &ret_x, &ret_y, &ret_obj_x, &ret_obj_y,
1425 &ret_w, &ret_bufp, &ret_closest,
1426 &ret_modeline_closest,
1427 &ret_obj1, &ret_obj2);
1428
1429 if (result == OVER_NOTHING || result == OVER_OUTSIDE)
1430 ret_bufp = 0;
1431 else if (ret_w && NILP (ret_w->buffer))
1432 /* Why does this happen? (Does it still happen?)
1433 I guess the window has gotten reused as a non-leaf... */
1434 ret_w = 0;
1435
1436 /* #### pixel_to_glyph_translation() sometimes returns garbage...
1437 The word has type Lisp_Record (presumably meaning `extent') but the
1438 pointer points to random memory, often filled with 0, sometimes not.
1439 */
1440 /* #### Chuck, do we still need this crap? */
1441 if (!NILP (ret_obj1) && !(GLYPHP (ret_obj1)
1442 #ifdef HAVE_TOOLBARS
1443 || TOOLBAR_BUTTONP (ret_obj1)
1444 #endif
1445 ))
1446 abort ();
1447 if (!NILP (ret_obj2) && !(EXTENTP (ret_obj2)
1448 || CONSP (ret_obj2)))
1449 abort ();
1450
1451 if (char_x)
1452 *char_x = ret_x;
1453 if (char_y)
1454 *char_y = ret_y;
1455 if (obj_x)
1456 *obj_x = ret_obj_x;
1457 if (obj_y)
1458 *obj_y = ret_obj_y;
1459 if (w)
1460 *w = ret_w;
1461 if (bufp)
1462 *bufp = ret_bufp;
1463 if (closest)
1464 *closest = ret_closest;
1465 if (modeline_closest)
1466 *modeline_closest = ret_modeline_closest;
1467 if (obj1)
1468 *obj1 = ret_obj1;
1469 if (obj2)
1470 *obj2 = ret_obj2;
1471
1472 return result;
1473 }
1474
1475 DEFUN ("event-over-text-area-p", Fevent_over_text_area_p,
1476 Sevent_over_text_area_p, 1, 1, 0 /*
1477 Return whether the given mouse event occurred over the text area of a window.
1478 The modeline is not considered to be part of the text area.
1479 */ )
1480 (event)
1481 Lisp_Object event;
1482 {
1483 int result = event_pixel_translation (event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1484
1485 if (result == OVER_TEXT || result == OVER_NOTHING)
1486 return Qt;
1487 else
1488 return Qnil;
1489 }
1490
1491 DEFUN ("event-over-modeline-p", Fevent_over_modeline_p, Sevent_over_modeline_p,
1492 1, 1, 0 /*
1493 Return whether the given mouse event occurred over the modeline of a window.
1494 */ )
1495 (event)
1496 Lisp_Object event;
1497 {
1498 int result = event_pixel_translation (event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1499
1500 if (result == OVER_MODELINE)
1501 return Qt;
1502 else
1503 return Qnil;
1504 }
1505
1506 DEFUN ("event-over-border-p", Fevent_over_border_p, Sevent_over_border_p,
1507 1, 1, 0 /*
1508 Return whether the given mouse event occurred over an internal border.
1509 */ )
1510 (event)
1511 Lisp_Object event;
1512 {
1513 int result = event_pixel_translation (event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1514
1515 if (result == OVER_BORDER)
1516 return Qt;
1517 else
1518 return Qnil;
1519 }
1520
1521 DEFUN ("event-over-toolbar-p", Fevent_over_toolbar_p, Sevent_over_toolbar_p,
1522 1, 1, 0 /*
1523 Return whether the given mouse event occurred over a toolbar.
1524 */ )
1525 (event)
1526 Lisp_Object event;
1527 {
1528 int result = event_pixel_translation (event, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1529
1530 if (result == OVER_TOOLBAR)
1531 return Qt;
1532 else
1533 return Qnil;
1534 }
1535
1536 struct console *
1537 event_console_or_selected (Lisp_Object event)
1538 {
1539 Lisp_Object channel = EVENT_CHANNEL (XEVENT (event));
1540 Lisp_Object console = CDFW_CONSOLE (channel);
1541
1542 if (NILP (console))
1543 console = Vselected_console;
1544
1545 return XCONSOLE (console);
1546 }
1547
1548 DEFUN ("event-channel", Fevent_channel, Sevent_channel, 1, 1, 0 /*
1549 Return the channel that the given event occurred on.
1550 This will be a frame, device, console, or nil for some types
1551 of events (e.g. eval events).
1552 */ )
1553 (event)
1554 Lisp_Object event;
1555 {
1556 CHECK_LIVE_EVENT (event);
1557 return EVENT_CHANNEL (XEVENT (event));
1558 }
1559
1560 DEFUN ("event-window", Fevent_window, Sevent_window, 1, 1, 0 /*
1561 Return the window of the given mouse event.
1562 This may be nil if the event occurred in the border or over a toolbar.
1563 The modeline is considered to be in the window it represents.
1564 */ )
1565 (event)
1566 Lisp_Object event;
1567 {
1568 struct window *w;
1569 Lisp_Object window;
1570
1571 event_pixel_translation (event, 0, 0, 0, 0, &w, 0, 0, 0, 0, 0);
1572
1573 if (!w)
1574 return Qnil;
1575 else
1576 {
1577 XSETWINDOW (window, w);
1578 return window;
1579 }
1580 }
1581
1582 DEFUN ("event-point", Fevent_point, Sevent_point, 1, 1, 0 /*
1583 Return the character position of the given mouse event.
1584 If the event did not occur over a window, or did not occur over text,
1585 then this returns nil. Otherwise, it returns an index into the buffer
1586 visible in the event's window.
1587 */ )
1588 (event)
1589 Lisp_Object event;
1590 {
1591 Bufpos bufp;
1592 struct window *w;
1593
1594 event_pixel_translation (event, 0, 0, 0, 0, &w, &bufp, 0, 0, 0, 0);
1595
1596 if (!w)
1597 return Qnil;
1598 else if (!bufp)
1599 return Qnil;
1600 else
1601 return make_int (bufp);
1602 }
1603
1604 DEFUN ("event-closest-point", Fevent_closest_point, Sevent_closest_point,
1605 1, 1, 0 /*
1606 Return the character position of the given mouse event.
1607 If the event did not occur over a window or over text, return the
1608 closest point to the location of the event. If the Y pixel position
1609 overlaps a window and the X pixel position is to the left of that
1610 window, the closest point is the beginning of the line containing the
1611 Y position. If the Y pixel position overlaps a window and the X pixel
1612 position is to the right of that window, the closest point is the end
1613 of the line containing the Y position. If the Y pixel position is
1614 above a window, return 0. If it is below a window, return the value
1615 of (window-end).
1616 */ )
1617 (event)
1618 Lisp_Object event;
1619 {
1620 Bufpos bufp;
1621
1622 event_pixel_translation (event, 0, 0, 0, 0, 0, 0, &bufp, 0, 0, 0);
1623
1624 if (!bufp)
1625 return Qnil;
1626 else
1627 return make_int (bufp);
1628 }
1629
1630 DEFUN ("event-x", Fevent_x, Sevent_x, 1, 1, 0 /*
1631 Return the X position of the given mouse event in characters.
1632 This is relative to the window the event occurred over.
1633 */ )
1634 (event)
1635 Lisp_Object event;
1636 {
1637 int char_x;
1638
1639 event_pixel_translation (event, &char_x, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1640
1641 return make_int (char_x);
1642 }
1643
1644 DEFUN ("event-y", Fevent_y, Sevent_y, 1, 1, 0 /*
1645 Return the Y position of the given mouse event in characters.
1646 This is relative to the window the event occurred over.
1647 */ )
1648 (event)
1649 Lisp_Object event;
1650 {
1651 int char_y;
1652
1653 event_pixel_translation (event, 0, &char_y, 0, 0, 0, 0, 0, 0, 0, 0);
1654
1655 return make_int (char_y);
1656 }
1657
1658 DEFUN ("event-modeline-position", Fevent_modeline_position,
1659 Sevent_modeline_position, 1, 1, 0 /*
1660 Return the character position in the modeline that EVENT occurred over.
1661 EVENT should be a mouse event. If EVENT did not occur over a modeline,
1662 nil is returned. You can determine the actual character that the
1663 event occurred over by looking in `generated-modeline-string' at the
1664 returned character position. Note that `generated-modeline-string'
1665 is buffer-local, and you must use EVENT's buffer when retrieving
1666 `generated-modeline-string' in order to get accurate results.
1667 */ )
1668 (event)
1669 Lisp_Object event;
1670 {
1671 Charcount mbufp;
1672
1673 event_pixel_translation (event, 0, 0, 0, 0, 0, 0, 0, &mbufp, 0, 0);
1674
1675 if (mbufp < 0)
1676 return Qnil;
1677 else
1678 return make_int (mbufp);
1679 }
1680
1681 DEFUN ("event-glyph", Fevent_glyph, Sevent_glyph,
1682 1, 1, 0 /*
1683 Return the glyph that the given mouse event occurred over, or nil.
1684 */ )
1685 (event)
1686 Lisp_Object event;
1687 {
1688 Lisp_Object glyph;
1689 struct window *w;
1690
1691 event_pixel_translation (event, 0, 0, 0, 0, &w, 0, 0, 0, &glyph, 0);
1692
1693 if (!w)
1694 return Qnil;
1695 else if (GLYPHP (glyph))
1696 return glyph;
1697 else
1698 return Qnil;
1699 }
1700
1701 DEFUN ("event-glyph-extent", Fevent_glyph_extent, Sevent_glyph_extent,
1702 1, 1, 0 /*
1703 Return the extent of the glyph that the given mouse event occurred over.
1704 If the event did not occur over a glyph, nil is returned.
1705 */ )
1706 (event)
1707 Lisp_Object event;
1708 {
1709 Lisp_Object extent;
1710 struct window *w;
1711
1712 event_pixel_translation (event, 0, 0, 0, 0, &w, 0, 0, 0, 0, &extent);
1713
1714 if (!w)
1715 return Qnil;
1716 else if (EXTENTP (extent))
1717 return extent;
1718 else
1719 return Qnil;
1720 }
1721
1722 DEFUN ("event-glyph-x-pixel", Fevent_glyph_x_pixel, Sevent_glyph_x_pixel,
1723 1, 1, 0 /*
1724 Return the X pixel position of EVENT relative to the glyph it occurred over.
1725 EVENT should be a mouse event. If the event did not occur over a glyph,
1726 nil is returned.
1727 */ )
1728 (event)
1729 Lisp_Object event;
1730 {
1731 Lisp_Object extent;
1732 struct window *w;
1733 int obj_x;
1734
1735 event_pixel_translation (event, 0, 0, &obj_x, 0, &w, 0, 0, 0, 0, &extent);
1736
1737 if (w && EXTENTP (extent))
1738 return make_int (obj_x);
1739 else
1740 return Qnil;
1741 }
1742
1743 DEFUN ("event-glyph-y-pixel", Fevent_glyph_y_pixel, Sevent_glyph_y_pixel,
1744 1, 1, 0 /*
1745 Return the Y pixel position of EVENT relative to the glyph it occurred over.
1746 EVENT should be a mouse event. If the event did not occur over a glyph,
1747 nil is returned.
1748 */ )
1749 (event)
1750 Lisp_Object event;
1751 {
1752 Lisp_Object extent;
1753 struct window *w;
1754 int obj_y;
1755
1756 event_pixel_translation (event, 0, 0, 0, &obj_y, &w, 0, 0, 0, 0, &extent);
1757
1758 if (w && EXTENTP (extent))
1759 return make_int (obj_y);
1760 else
1761 return Qnil;
1762 }
1763
1764 DEFUN ("event-toolbar-button", Fevent_toolbar_button, Sevent_toolbar_button,
1765 1, 1, 0 /*
1766 Return the toolbar button that the given mouse event occurred over.
1767 If the event did not occur over a toolbar, nil is returned.
1768 */ )
1769 (event)
1770 Lisp_Object event;
1771 {
1772 #ifdef HAVE_TOOLBARS
1773 Lisp_Object button;
1774 int result;
1775
1776 result = event_pixel_translation (event, 0, 0, 0, 0, 0, 0, 0, 0, &button, 0);
1777
1778 if (result == OVER_TOOLBAR)
1779 {
1780 if (TOOLBAR_BUTTONP (button))
1781 return button;
1782 else
1783 return Qnil;
1784 }
1785 else
1786 #endif
1787 return Qnil;
1788 }
1789
1790 DEFUN ("event-process", Fevent_process, Sevent_process, 1, 1, 0 /*
1791 Return the process of the given process-output event.
1792 */ )
1793 (event)
1794 Lisp_Object event;
1795 {
1796 CHECK_EVENT_TYPE (event, process_event, Qprocess_event_p);
1797 return (XEVENT (event)->event.process.process);
1798 }
1799
1800 DEFUN ("event-function", Fevent_function, Sevent_function, 1, 1, 0 /*
1801 Return the callback function of EVENT.
1802 EVENT should be a timeout, misc-user, or eval event.
1803 */ )
1804 (event)
1805 Lisp_Object event;
1806 {
1807 CHECK_LIVE_EVENT (event);
1808 switch (XEVENT (event)->event_type)
1809 {
1810 case timeout_event:
1811 return (XEVENT (event)->event.timeout.function);
1812 case misc_user_event:
1813 case eval_event:
1814 return (XEVENT (event)->event.eval.function);
1815 default:
1816 return wrong_type_argument (intern ("timeout-or-eval-event-p"), event);
1817 }
1818 }
1819
1820 DEFUN ("event-object", Fevent_object, Sevent_object, 1, 1, 0 /*
1821 Return the callback function argument of EVENT.
1822 EVENT should be a timeout, misc-user, or eval event.
1823 */ )
1824 (event)
1825 Lisp_Object event;
1826 {
1827 again:
1828 CHECK_LIVE_EVENT (event);
1829 switch (XEVENT (event)->event_type)
1830 {
1831 case timeout_event:
1832 return (XEVENT (event)->event.timeout.object);
1833 case misc_user_event:
1834 case eval_event:
1835 return (XEVENT (event)->event.eval.object);
1836 default:
1837 event = wrong_type_argument (intern ("timeout-or-eval-event-p"), event);
1838 goto again;
1839 }
1840 }
1841
1842 DEFUN ("event-properties", Fevent_properties, Sevent_properties, 1, 1, 0 /*
1843 Return a list of all of the properties of EVENT.
1844 This is in the form of a property list (alternating keyword/value pairs).
1845 */ )
1846 (event)
1847 Lisp_Object event;
1848 {
1849 Lisp_Object props = Qnil;
1850 struct Lisp_Event *e;
1851 struct gcpro gcpro1;
1852
1853 CHECK_LIVE_EVENT (event);
1854 e = XEVENT (event);
1855 GCPRO1 (props);
1856
1857 props = Fcons (Qtimestamp, Fcons (Fevent_timestamp (event), props));
1858
1859 switch (e->event_type)
1860 {
1861 case process_event:
1862 props = Fcons (Qprocess, Fcons (e->event.process.process, props));
1863 break;
1864
1865 case timeout_event:
1866 props = Fcons (Qobject, Fcons (Fevent_object (event), props));
1867 props = Fcons (Qfunction, Fcons (Fevent_function (event), props));
1868 props = Fcons (Qid, Fcons (make_int (e->event.timeout.id_number),
1869 props));
1870 break;
1871
1872 case key_press_event:
1873 props = Fcons (Qmodifiers, Fcons (Fevent_modifiers (event), props));
1874 props = Fcons (Qkey, Fcons (Fevent_key (event), props));
1875 break;
1876
1877 case button_press_event:
1878 case button_release_event:
1879 props = Fcons (Qy, Fcons (Fevent_y_pixel (event), props));
1880 props = Fcons (Qx, Fcons (Fevent_x_pixel (event), props));
1881 props = Fcons (Qmodifiers, Fcons (Fevent_modifiers (event), props));
1882 props = Fcons (Qbutton, Fcons (Fevent_button (event), props));
1883 break;
1884
1885 case pointer_motion_event:
1886 props = Fcons (Qmodifiers, Fcons (Fevent_modifiers (event), props));
1887 props = Fcons (Qy, Fcons (Fevent_y_pixel (event), props));
1888 props = Fcons (Qx, Fcons (Fevent_x_pixel (event), props));
1889 break;
1890
1891 case misc_user_event:
1892 case eval_event:
1893 props = Fcons (Qobject, Fcons (Fevent_object (event), props));
1894 props = Fcons (Qfunction, Fcons (Fevent_function (event), props));
1895 break;
1896
1897 case magic_eval_event:
1898 case magic_event:
1899 break;
1900
1901 default:
1902 abort ();
1903 break; /* not reached; warning suppression */
1904 }
1905
1906 props = Fcons (Qchannel, Fcons (Fevent_channel (event), props));
1907 UNGCPRO;
1908
1909 return props;
1910 }
1911
1912
1913 /************************************************************************/
1914 /* initialization */
1915 /************************************************************************/
1916
1917 void
1918 syms_of_events (void)
1919 {
1920 defsubr (&Scharacter_to_event);
1921 defsubr (&Sevent_to_character);
1922
1923 defsubr (&Smake_event);
1924 defsubr (&Sdeallocate_event);
1925 defsubr (&Scopy_event);
1926 defsubr (&Seventp);
1927 defsubr (&Sevent_live_p);
1928 defsubr (&Sevent_type);
1929 defsubr (&Sevent_properties);
1930
1931 defsubr (&Sevent_timestamp);
1932 defsubr (&Sevent_key);
1933 defsubr (&Sevent_button);
1934 defsubr (&Sevent_modifier_bits);
1935 defsubr (&Sevent_modifiers);
1936 defsubr (&Sevent_x_pixel);
1937 defsubr (&Sevent_y_pixel);
1938 defsubr (&Sevent_window_x_pixel);
1939 defsubr (&Sevent_window_y_pixel);
1940 defsubr (&Sevent_over_text_area_p);
1941 defsubr (&Sevent_over_modeline_p);
1942 defsubr (&Sevent_over_border_p);
1943 defsubr (&Sevent_over_toolbar_p);
1944 defsubr (&Sevent_channel);
1945 defsubr (&Sevent_window);
1946 defsubr (&Sevent_point);
1947 defsubr (&Sevent_closest_point);
1948 defsubr (&Sevent_x);
1949 defsubr (&Sevent_y);
1950 defsubr (&Sevent_modeline_position);
1951 defsubr (&Sevent_glyph);
1952 defsubr (&Sevent_glyph_extent);
1953 defsubr (&Sevent_glyph_x_pixel);
1954 defsubr (&Sevent_glyph_y_pixel);
1955 defsubr (&Sevent_toolbar_button);
1956 defsubr (&Sevent_process);
1957 defsubr (&Sevent_function);
1958 defsubr (&Sevent_object);
1959
1960 defsymbol (&Qeventp, "eventp");
1961 defsymbol (&Qevent_live_p, "event-live-p");
1962 defsymbol (&Qkey_press_event_p, "key-press-event-p");
1963 defsymbol (&Qbutton_event_p, "button-event-p");
1964 defsymbol (&Qmouse_event_p, "mouse-event-p");
1965 defsymbol (&Qprocess_event_p, "process-event-p");
1966 defsymbol (&Qkey_press, "key-press");
1967 defsymbol (&Qbutton_press, "button-press");
1968 defsymbol (&Qbutton_release, "button-release");
1969 defsymbol (&Qmisc_user, "misc-user");
1970 defsymbol (&Qascii_character, "ascii-character");
1971 }
1972
1973 void
1974 vars_of_events (void)
1975 {
1976 DEFVAR_LISP ("character-set-property", &Vcharacter_set_property /*
1977 A symbol used to look up the 8-bit character of a keysym.
1978 To convert a keysym symbol to an 8-bit code, as when that key is
1979 bound to self-insert-command, we will look up the property that this
1980 variable names on the property list of the keysym-symbol. The window-
1981 system-specific code will set up appropriate properties and set this
1982 variable.
1983 */ );
1984 Vcharacter_set_property = Qnil;
1985
1986 Vevent_resource = Qnil;
1987
1988 QKbackspace = KEYSYM ("backspace");
1989 QKtab = KEYSYM ("tab");
1990 QKlinefeed = KEYSYM ("linefeed");
1991 QKreturn = KEYSYM ("return");
1992 QKescape = KEYSYM ("escape");
1993 QKspace = KEYSYM ("space");
1994 QKdelete = KEYSYM ("delete");
1995
1996 staticpro (&QKbackspace);
1997 staticpro (&QKtab);
1998 staticpro (&QKlinefeed);
1999 staticpro (&QKreturn);
2000 staticpro (&QKescape);
2001 staticpro (&QKspace);
2002 staticpro (&QKdelete);
2003 }