Mercurial > hg > xemacs-beta
comparison src/event-Xt.c @ 20:859a2309aef8 r19-15b93
Import from CVS: tag r19-15b93
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:50:05 +0200 |
parents | 0293115a14e9 |
children | 8fc7fe29b841 |
comparison
equal
deleted
inserted
replaced
19:ac1f612d5250 | 20:859a2309aef8 |
---|---|
46 #include "xintrinsicp.h" /* CoreP.h needs this */ | 46 #include "xintrinsicp.h" /* CoreP.h needs this */ |
47 #include <X11/CoreP.h> /* Numerous places access the fields of | 47 #include <X11/CoreP.h> /* Numerous places access the fields of |
48 a core widget directly. We could | 48 a core widget directly. We could |
49 use XtVaGetValues(), but ... */ | 49 use XtVaGetValues(), but ... */ |
50 | 50 |
51 static void enqueue_Xt_dispatch_event (Lisp_Object event); | |
52 | |
51 static struct event_stream *Xt_event_stream; | 53 static struct event_stream *Xt_event_stream; |
52 | 54 |
53 /* With the new event model, all events go through XtDispatchEvent() | 55 /* With the new event model, all events go through XtDispatchEvent() |
54 and are picked up by an event handler that is added to each frame | 56 and are picked up by an event handler that is added to each frame |
55 widget. (This is how it's supposed to be.) In the old method, | 57 widget. (This is how it's supposed to be.) In the old method, |
87 0 | 89 0 |
88 }; | 90 }; |
89 | 91 |
90 void emacs_Xt_mapping_action (Widget w, XEvent *event); | 92 void emacs_Xt_mapping_action (Widget w, XEvent *event); |
91 void debug_process_finalization (struct Lisp_Process *p); | 93 void debug_process_finalization (struct Lisp_Process *p); |
92 Lisp_Object dequeue_Xt_dispatch_event (void); | |
93 void emacs_Xt_event_handler (Widget wid, XtPointer closure, XEvent *event, | 94 void emacs_Xt_event_handler (Widget wid, XtPointer closure, XEvent *event, |
94 Boolean *continue_to_dispatch); | 95 Boolean *continue_to_dispatch); |
95 | 96 |
96 #ifdef EPOCH | 97 #ifdef EPOCH |
97 void dispatch_epoch_event (struct frame *f, XEvent *event, Lisp_Object type); | 98 void dispatch_epoch_event (struct frame *f, XEvent *event, Lisp_Object type); |
292 | 293 |
293 /* It probably doesn't make any sense for a modifier bit to be | 294 /* It probably doesn't make any sense for a modifier bit to be |
294 assigned to a key that is not one of the above, but OpenWindows | 295 assigned to a key that is not one of the above, but OpenWindows |
295 assigns modifier bits to a couple of random function keys for | 296 assigns modifier bits to a couple of random function keys for |
296 no reason that I can discern, so printing a warning here would | 297 no reason that I can discern, so printing a warning here would |
297 be annoying. | 298 be annoying. */ |
298 */ | |
299 } | 299 } |
300 } | 300 } |
301 } | 301 } |
302 #undef store_modifier | 302 #undef store_modifier |
303 #undef check_modifier | 303 #undef check_modifier |
304 #undef modwarn | 304 #undef modwarn |
305 #undef modbarf | 305 #undef modbarf |
306 | 306 |
307 /* If there was no Meta key, then try using the Alt key instead. | 307 /* If there was no Meta key, then try using the Alt key instead. |
308 If there is both a Meta key and an Alt key, then the Alt key | 308 If there is both a Meta key and an Alt key, then the Alt key |
309 is not disturbed and remains an Alt key. | 309 is not disturbed and remains an Alt key. */ |
310 */ | |
311 if (! meta_bit && alt_bit) | 310 if (! meta_bit && alt_bit) |
312 meta_bit = alt_bit, alt_bit = 0; | 311 meta_bit = alt_bit, alt_bit = 0; |
313 | 312 |
314 /* mode_bit overrides everything, since it's processed down inside of | 313 /* mode_bit overrides everything, since it's processed down inside of |
315 XLookupString() instead of by us. If Meta and Mode_switch both | 314 XLookupString() instead of by us. If Meta and Mode_switch both |
316 generate the same modifier bit (which is an error), then we don't | 315 generate the same modifier bit (which is an error), then we don't |
317 interpret that bit as Meta, because we can't make XLookupString() | 316 interpret that bit as Meta, because we can't make XLookupString() |
318 not interpret it as Mode_switch; and interpreting it as both would | 317 not interpret it as Mode_switch; and interpreting it as both would |
319 be totally wrong. | 318 be totally wrong. */ |
320 */ | |
321 if (mode_bit) | 319 if (mode_bit) |
322 { | 320 { |
323 CONST char *warn = 0; | 321 CONST char *warn = 0; |
324 if (mode_bit == meta_bit) warn = "Meta", meta_bit = 0; | 322 if (mode_bit == meta_bit) warn = "Meta", meta_bit = 0; |
325 else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0; | 323 else if (mode_bit == hyper_bit) warn = "Hyper", hyper_bit = 0; |
361 " bits to the \"control\" keysyms other than ModControl. You can't\n" | 359 " bits to the \"control\" keysyms other than ModControl. You can't\n" |
362 " turn a \"control\" key into a \"meta\" key (or vice versa) by simply\n" | 360 " turn a \"control\" key into a \"meta\" key (or vice versa) by simply\n" |
363 " assigning the key a different modifier bit. You must also make that\n" | 361 " assigning the key a different modifier bit. You must also make that\n" |
364 " key generate an appropriate keysym (Control_L, Meta_L, etc)."); | 362 " key generate an appropriate keysym (Control_L, Meta_L, etc)."); |
365 | 363 |
366 /* Don\'t need to say anything more for warned_about_duplicate_modifiers. */ | 364 /* No need to say anything more for warned_about_duplicate_modifiers. */ |
367 | 365 |
368 if (warned_about_overlapping_modifiers || warned_about_predefined_modifiers) | 366 if (warned_about_overlapping_modifiers || warned_about_predefined_modifiers) |
369 warn_when_safe (Qkey_mapping, Qwarning, "\n" | 367 warn_when_safe (Qkey_mapping, Qwarning, "\n" |
370 " The meanings of the modifier bits Mod1 through Mod5 are determined\n" | 368 " The meanings of the modifier bits Mod1 through Mod5 are determined\n" |
371 " by the keysyms used to control those bits. Mod1 does NOT always\n" | 369 " by the keysyms used to control those bits. Mod1 does NOT always\n" |
464 | 462 |
465 Naturally, the designers of the X spec didn't see fit | 463 Naturally, the designers of the X spec didn't see fit |
466 to provide an obvious way to distinguish these cases. | 464 to provide an obvious way to distinguish these cases. |
467 So we assume that if the release and the next press | 465 So we assume that if the release and the next press |
468 occur at the same time, the key was actually auto- | 466 occur at the same time, the key was actually auto- |
469 repeated. Under Open-Windows, at least, this works. | 467 repeated. Under Open-Windows, at least, this works. */ |
470 */ | |
471 xd->release_time = key_event_p ? ev->xkey.time : ev->xbutton.time; | 468 xd->release_time = key_event_p ? ev->xkey.time : ev->xbutton.time; |
472 } | 469 } |
473 else /* Modifier key pressed */ | 470 else /* Modifier key pressed */ |
474 { | 471 { |
475 int i; | 472 int i; |
533 clear_sticky_modifiers (struct device *d) | 530 clear_sticky_modifiers (struct device *d) |
534 { | 531 { |
535 struct x_device *xd = DEVICE_X_DATA (d); | 532 struct x_device *xd = DEVICE_X_DATA (d); |
536 | 533 |
537 xd->need_to_add_mask = 0; | 534 xd->need_to_add_mask = 0; |
538 xd->last_downkey = 0; | 535 xd->last_downkey = 0; |
539 xd->release_time = 0; | 536 xd->release_time = 0; |
540 xd->down_mask = 0; | 537 xd->down_mask = 0; |
541 } | 538 } |
542 | 539 |
543 static int | 540 static int |
544 keysym_obeys_caps_lock_p (KeySym sym, struct device *d) | 541 keysym_obeys_caps_lock_p (KeySym sym, struct device *d) |
545 { | 542 { |
546 struct x_device *xd = DEVICE_X_DATA (d); | 543 struct x_device *xd = DEVICE_X_DATA (d); |
547 /* Eeeeevil hack. Don't apply Caps_Lock to things that aren't alphabetic | 544 /* Eeeeevil hack. Don't apply Caps_Lock to things that aren't alphabetic |
548 characters, where "alphabetic" means something more than simply A-Z. | 545 characters, where "alphabetic" means something more than simply A-Z. |
549 That is, if Caps_Lock is down, typing ESC doesn't produce Shift-ESC. | 546 That is, if Caps_Lock is down, typing ESC doesn't produce Shift-ESC. |
550 But if shift-lock is down, then it does. | 547 But if shift-lock is down, then it does. */ |
551 */ | |
552 if (xd->lock_interpretation == XK_Shift_Lock) | 548 if (xd->lock_interpretation == XK_Shift_Lock) |
553 return 1; | 549 return 1; |
554 | 550 |
555 return | 551 return |
556 ((sym >= XK_A) && (sym <= XK_Z)) || | 552 ((sym >= XK_A) && (sym <= XK_Z)) || |
564 /* called from EmacsFrame.c (actually from Xt itself) when a | 560 /* called from EmacsFrame.c (actually from Xt itself) when a |
565 MappingNotify event is received. In its infinite wisdom, Xt | 561 MappingNotify event is received. In its infinite wisdom, Xt |
566 decided that Xt event handlers never get MappingNotify events. | 562 decided that Xt event handlers never get MappingNotify events. |
567 O'Reilly Xt Programming Manual 9.1.2 says: | 563 O'Reilly Xt Programming Manual 9.1.2 says: |
568 | 564 |
569 MappingNotify is automatically handled by Xt, so it isn't passed | 565 MappingNotify is automatically handled by Xt, so it isn't passed |
570 to event handlers and you don't need to worry about it. | 566 to event handlers and you don't need to worry about it. |
571 | 567 |
572 Of course, we DO worry about it, so we need a special translation. */ | 568 Of course, we DO worry about it, so we need a special translation. */ |
573 void | 569 void |
574 emacs_Xt_mapping_action (Widget w, XEvent* event) | 570 emacs_Xt_mapping_action (Widget w, XEvent* event) |
575 { | 571 { |
579 XRefreshKeyboardMapping (&event->xmapping); | 575 XRefreshKeyboardMapping (&event->xmapping); |
580 #endif | 576 #endif |
581 /* xmodmap generates about a billion MappingKeyboard events, followed | 577 /* xmodmap generates about a billion MappingKeyboard events, followed |
582 by a single MappingModifier event, so it might be worthwhile to | 578 by a single MappingModifier event, so it might be worthwhile to |
583 take extra MappingKeyboard events out of the queue before requesting | 579 take extra MappingKeyboard events out of the queue before requesting |
584 the current keymap from the server. | 580 the current keymap from the server. */ |
585 */ | |
586 switch (event->xmapping.request) | 581 switch (event->xmapping.request) |
587 { | 582 { |
588 case MappingKeyboard: x_reset_key_mapping (d); break; | 583 case MappingKeyboard: x_reset_key_mapping (d); break; |
589 case MappingModifier: x_reset_modifier_mapping (d); break; | 584 case MappingModifier: x_reset_modifier_mapping (d); break; |
590 case MappingPointer: /* Do something here? */ break; | 585 case MappingPointer: /* Do something here? */ break; |
605 static void | 600 static void |
606 x_to_emacs_keysym_sunos_bug (Lisp_Object *return_value_sunos_bug, /* #### */ | 601 x_to_emacs_keysym_sunos_bug (Lisp_Object *return_value_sunos_bug, /* #### */ |
607 XEvent *event, int simple_p) | 602 XEvent *event, int simple_p) |
608 #else /* !SUNOS_GCC_L0_BUG */ | 603 #else /* !SUNOS_GCC_L0_BUG */ |
609 static Lisp_Object | 604 static Lisp_Object |
610 x_to_emacs_keysym (XEvent *event, int simple_p) | 605 x_to_emacs_keysym (XKeyPressedEvent *event, int simple_p) |
611 #endif /* !SUNOS_GCC_L0_BUG */ | 606 #endif /* !SUNOS_GCC_L0_BUG */ |
612 /* simple_p means don't try too hard (ASCII only) */ | 607 /* simple_p means don't try too hard (ASCII only) */ |
613 { | 608 { |
614 char *name; | 609 char *name; |
615 KeySym keysym = 0; | 610 KeySym keysym = 0; |
616 /* struct device *d = get_device_from_display (event->xany.display); */ | |
617 /* Apparently it's necessary to specify a dummy here (rather than | 611 /* Apparently it's necessary to specify a dummy here (rather than |
618 passing in 0) to avoid crashes on German IRIX */ | 612 passing in 0) to avoid crashes on German IRIX */ |
619 char dummy[256]; | 613 char dummy[256]; |
620 | 614 |
621 #ifdef SUNOS_GCC_L0_BUG | 615 #ifdef SUNOS_GCC_L0_BUG |
623 do {*return_value_sunos_bug = (lose); goto return_it; } while (0) | 617 do {*return_value_sunos_bug = (lose); goto return_it; } while (0) |
624 #endif | 618 #endif |
625 | 619 |
626 /* ### FIX this by replacing with calls to XmbLookupString. | 620 /* ### FIX this by replacing with calls to XmbLookupString. |
627 XLookupString should never be called. --mrb */ | 621 XLookupString should never be called. --mrb */ |
628 XLookupString (&event->xkey, dummy, 200, &keysym, 0); | 622 XLookupString (event, dummy, 200, &keysym, 0); |
629 | |
630 /* &DEVICE_X_X_COMPOSE_STATUS (d)); */ | |
631 | 623 |
632 if (keysym >= XK_exclam && keysym <= XK_asciitilde) | 624 if (keysym >= XK_exclam && keysym <= XK_asciitilde) |
633 /* We must assume that the X keysym numbers for the ASCII graphic | 625 /* We must assume that the X keysym numbers for the ASCII graphic |
634 characters are the same as their ASCII codes. */ | 626 characters are the same as their ASCII codes. */ |
635 return (make_char (keysym)); | 627 return make_char (keysym); |
636 | 628 |
637 switch (keysym) | 629 switch (keysym) |
638 { | 630 { |
639 /* These would be handled correctly by the default case, but by | 631 /* These would be handled correctly by the default case, but by |
640 special-casing them here we don't garbage a string or call intern(). | 632 special-casing them here we don't garbage a string or call intern(). |
641 */ | 633 */ |
642 case XK_BackSpace: return (QKbackspace); | 634 case XK_BackSpace: return QKbackspace; |
643 case XK_Tab: return (QKtab); | 635 case XK_Tab: return QKtab; |
644 case XK_Linefeed: return (QKlinefeed); | 636 case XK_Linefeed: return QKlinefeed; |
645 case XK_Return: return (QKreturn); | 637 case XK_Return: return QKreturn; |
646 case XK_Escape: return (QKescape); | 638 case XK_Escape: return QKescape; |
647 case XK_space: return (QKspace); | 639 case XK_space: return QKspace; |
648 case XK_Delete: return (QKdelete); | 640 case XK_Delete: return QKdelete; |
649 case 0: return (Qnil); | 641 case 0: return Qnil; |
650 /* This kludge prevents bogus Xlib compose conversions. | 642 /* This kludge prevents bogus Xlib compose conversions. |
651 Don't ask why. The following case must be removed when we | 643 Don't ask why. The following case must be removed when we |
652 switch to using XmbLookupString */ | 644 switch to using XmbLookupString */ |
653 case XK_Multi_key: XLookupString (&event->xkey, dummy, 200, &keysym, 0); | 645 case XK_Multi_key: XLookupString (event, dummy, 200, &keysym, 0); |
654 /* Fallthrough!! */ | 646 /* Fallthrough!! */ |
655 default: | 647 default: |
656 if (simple_p) return (Qnil); | 648 if (simple_p) return Qnil; |
657 /* #### without return_value_sunos_bug, %l0 (GCC struct return pointer) | 649 /* #### without return_value_sunos_bug, %l0 (GCC struct return pointer) |
658 * #### gets roached (top 8 bits cleared) around this call. | 650 * #### gets roached (top 8 bits cleared) around this call. |
659 */ | 651 */ |
660 /* !!#### not Mule-ized */ | 652 /* !!#### not Mule-ized */ |
661 name = XKeysymToString (keysym); | 653 name = XKeysymToString (keysym); |
662 if (!name || !name[0]) /* this shouldn't happen... */ | 654 if (!name || !name[0]) /* this shouldn't happen... */ |
663 { | 655 { |
664 char buf [255]; | 656 char buf [255]; |
665 sprintf (buf, "unknown_keysym_0x%X", (int) keysym); | 657 sprintf (buf, "unknown_keysym_0x%X", (int) keysym); |
666 return (KEYSYM (buf)); | 658 return KEYSYM (buf); |
667 } | 659 } |
668 /* If it's got a one-character name, that's good enough. */ | 660 /* If it's got a one-character name, that's good enough. */ |
669 if (!name[1]) return (make_char (name[0])); | 661 if (!name[1]) |
662 return make_char (name[0]); | |
670 | 663 |
671 /* If it's in the "Keyboard" character set, downcase it. | 664 /* If it's in the "Keyboard" character set, downcase it. |
672 The case of those keysyms is too totally random for us to | 665 The case of those keysyms is too totally random for us to |
673 force anyone to remember them. | 666 force anyone to remember them. |
674 The case of the other character sets is significant, however. | 667 The case of the other character sets is significant, however. |
675 */ | 668 */ |
676 if ((((unsigned int) keysym) & (~0xFF)) == ((unsigned int) 0xFF00)) | 669 if ((((unsigned int) keysym) & (~0xFF)) == ((unsigned int) 0xFF00)) |
677 { | 670 { |
678 char buf [255]; | 671 char buf [255]; |
679 char *s1, *s2; | 672 char *s1, *s2; |
680 for (s1 = name, s2 = buf; *s1; s1++, s2++) { | 673 for (s1 = name, s2 = buf; *s1; s1++, s2++) { |
683 } else { | 676 } else { |
684 *s2 = tolower (* (unsigned char *) s1); | 677 *s2 = tolower (* (unsigned char *) s1); |
685 } | 678 } |
686 } | 679 } |
687 *s2 = 0; | 680 *s2 = 0; |
688 return (KEYSYM (buf)); | 681 return KEYSYM (buf); |
689 } | 682 } |
690 return (KEYSYM (name)); | 683 return KEYSYM (name); |
691 } | 684 } |
692 #ifdef SUNOS_GCC_L0_BUG | 685 #ifdef SUNOS_GCC_L0_BUG |
693 # undef return | 686 # undef return |
694 return_it: | 687 return_it: |
695 return; | 688 return; |
746 | 739 |
747 case KeyPress: | 740 case KeyPress: |
748 case ButtonPress: | 741 case ButtonPress: |
749 case ButtonRelease: | 742 case ButtonRelease: |
750 { | 743 { |
751 unsigned int modifiers = 0; | 744 unsigned int modifiers = 0; |
752 int shift_p; | 745 int shift_p, lock_p; |
753 int lock_p; | 746 Bool key_event_p = (x_event->type == KeyPress); |
754 Bool key_event_p = (x_event->type == KeyPress); | 747 unsigned int *state = |
755 unsigned int *state = | 748 key_event_p ? &x_event->xkey.state : &x_event->xbutton.state; |
756 key_event_p ? &x_event->xkey.state : &x_event->xbutton.state; | 749 |
750 /* If this is a synthetic KeyPress or Button event, and the user | |
751 has expressed a disinterest in this security hole, then drop | |
752 it on the floor. */ | |
753 if ((key_event_p | |
754 ? x_event->xkey.send_event | |
755 : x_event->xbutton.send_event) | |
756 #ifdef EXTERNAL_WIDGET | |
757 /* ben: events get sent to an ExternalShell using XSendEvent. | |
758 This is not a perfect solution. */ | |
759 && !FRAME_X_EXTERNAL_WINDOW_P | |
760 (x_any_window_to_frame (d, x_event->xany.window)) | |
761 #endif | |
762 && !x_allow_sendevents) | |
763 return 0; | |
764 | |
765 DEVICE_X_MOUSE_TIMESTAMP (d) = | |
766 DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d) = | |
767 key_event_p ? x_event->xkey.time : x_event->xbutton.time; | |
768 | |
769 x_handle_sticky_modifiers (x_event, d); | |
757 | 770 |
758 /* If this is a synthetic KeyPress or Button event, and the user | 771 if (*state & ControlMask) modifiers |= MOD_CONTROL; |
759 has expressed a disinterest in this security hole, then drop | 772 if (*state & xd->MetaMask) modifiers |= MOD_META; |
760 it on the floor. */ | 773 if (*state & xd->SuperMask) modifiers |= MOD_SUPER; |
761 if ((key_event_p | 774 if (*state & xd->HyperMask) modifiers |= MOD_HYPER; |
762 ? x_event->xkey.send_event | 775 if (*state & xd->AltMask) modifiers |= MOD_ALT; |
763 : x_event->xbutton.send_event) | 776 |
764 #ifdef EXTERNAL_WIDGET | 777 /* Ignore the Caps_Lock key if: |
765 /* ben: events get sent to an ExternalShell using XSendEvent. | 778 - any other modifiers are down, so that Caps_Lock doesn't |
766 This is not a perfect solution. */ | 779 turn C-x into C-X, which would suck. |
767 && !FRAME_X_EXTERNAL_WINDOW_P ( | 780 - the event was a mouse event. */ |
768 x_any_window_to_frame (d, x_event->xany.window)) | 781 if (modifiers || ! key_event_p) |
769 #endif | 782 *state &= (~LockMask); |
770 && !x_allow_sendevents) | 783 |
771 return 0; | 784 shift_p = *state & ShiftMask; |
772 | 785 lock_p = *state & LockMask; |
773 DEVICE_X_MOUSE_TIMESTAMP (d) = | 786 |
774 DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d) = | 787 if (shift_p || lock_p) |
775 key_event_p ? x_event->xkey.time : x_event->xbutton.time; | 788 modifiers |= MOD_SHIFT; |
776 | 789 |
777 x_handle_sticky_modifiers (x_event, d); | 790 if (key_event_p) |
778 | 791 { |
779 if (*state & ControlMask) modifiers |= MOD_CONTROL; | 792 Lisp_Object keysym; |
780 if (*state & xd->MetaMask) modifiers |= MOD_META; | 793 XKeyEvent *ev = &x_event->xkey; |
781 if (*state & xd->SuperMask) modifiers |= MOD_SUPER; | 794 KeyCode keycode = ev->keycode; |
782 if (*state & xd->HyperMask) modifiers |= MOD_HYPER; | 795 |
783 if (*state & xd->AltMask) modifiers |= MOD_ALT; | 796 if (x_key_is_modifier_p (keycode, d)) /* it's a modifier key */ |
784 | 797 return 0; |
785 /* Ignore the Caps_Lock key if: | 798 |
786 - any other modifiers are down, so that Caps_Lock doesn't | 799 /* This used to compute the frame from the given X window and |
787 turn C-x into C-X, which would suck. | 800 store it here, but we really don't care about the frame. */ |
788 - the event was a mouse event. */ | 801 emacs_event->channel = DEVICE_CONSOLE (d); |
789 if (modifiers || ! key_event_p) | 802 keysym = x_to_emacs_keysym (&x_event->xkey, 0); |
790 *state &= (~LockMask); | 803 |
791 | 804 /* If the emacs keysym is nil, then that means that the |
792 shift_p = *state & ShiftMask; | 805 X keysym was NoSymbol, which probably means that |
793 lock_p = *state & LockMask; | 806 we're in the midst of reading a Multi_key sequence, |
794 | 807 or a "dead" key prefix. Ignore it. */ |
795 if (shift_p || lock_p) | 808 if (NILP (keysym)) |
796 modifiers |= MOD_SHIFT; | 809 return 0; |
797 | 810 |
798 if (key_event_p) | 811 /* More Caps_Lock garbage: Caps_Lock should *only* add the |
799 { | 812 shift modifier to two-case keys (that is, A-Z and |
800 Lisp_Object keysym; | 813 related characters). So at this point (after looking up |
801 XKeyEvent *ev = &x_event->xkey; | 814 the keysym) if the keysym isn't a dual-case alphabetic, |
802 KeyCode keycode = ev->keycode; | 815 and if the caps lock key was down but the shift key |
803 | 816 wasn't, then turn off the shift modifier. Gag barf */ |
804 | 817 /* #### type lossage: assuming equivalence of emacs and |
805 if (x_key_is_modifier_p (keycode, d)) /* it's a modifier key */ | 818 X keysyms */ |
806 return 0; | 819 /* !!#### maybe fix for Mule */ |
807 | 820 if (lock_p && !shift_p && |
808 /* This used to compute the frame from the given X window and | 821 ! (CHAR_OR_CHAR_INTP (keysym) |
809 store it here, but we really don't care about the frame. */ | 822 && keysym_obeys_caps_lock_p |
810 emacs_event->channel = DEVICE_CONSOLE (d); | 823 ((KeySym) XCHAR_OR_CHAR_INT (keysym), d))) |
811 keysym = x_to_emacs_keysym (x_event, 0); | 824 modifiers &= (~MOD_SHIFT); |
812 | 825 |
813 /* If the emacs keysym is nil, then that means that the | 826 /* If this key contains two distinct keysyms, that is, |
814 X keysym was NoSymbol, which probably means that | 827 "shift" generates a different keysym than the |
815 we're in the midst of reading a Multi_key sequence, | 828 non-shifted key, then don't apply the shift modifier |
816 or a "dead" key prefix. Ignore it. */ | 829 bit: it's implicit. Otherwise, if there would be no |
817 if (NILP (keysym)) | 830 other way to tell the difference between the shifted |
818 return 0; | 831 and unshifted version of this key, apply the shift bit. |
819 | 832 Non-graphics, like Backspace and F1 get the shift bit |
820 /* More Caps_Lock garbage: Caps_Lock should *only* add the | 833 in the modifiers slot. Neither the characters "a", |
821 shift modifier to two-case keys (that is, A-Z and | 834 "A", "2", nor "@" normally have the shift bit set. |
822 related characters). So at this point (after looking up | 835 However, "F1" normally does. */ |
823 the keysym) if the keysym isn't a dual-case alphabetic, | 836 if (modifiers & MOD_SHIFT) |
824 and if the caps lock key was down but the shift key | 837 { |
825 wasn't, then turn off the shift modifier. Gag barf */ | 838 int Mode_switch_p = *state & xd->ModeMask; |
826 /* #### type lossage: assuming equivalence of emacs and | 839 KeySym bot = XLookupKeysym (ev, Mode_switch_p ? 2 : 0); |
827 X keysyms */ | 840 KeySym top = XLookupKeysym (ev, Mode_switch_p ? 3 : 1); |
828 /* !!#### maybe fix for Mule */ | 841 if (top && bot && top != bot) |
829 if (lock_p && !shift_p && | 842 modifiers &= ~MOD_SHIFT; |
830 ! (CHAR_OR_CHAR_INTP (keysym) | 843 } |
831 && keysym_obeys_caps_lock_p | 844 emacs_event->event_type = key_press_event; |
832 ((KeySym) XCHAR_OR_CHAR_INT (keysym), d))) | 845 emacs_event->timestamp = ev->time; |
833 modifiers &= (~MOD_SHIFT); | 846 emacs_event->event.key.modifiers = modifiers; |
834 | 847 emacs_event->event.key.keysym = keysym; |
835 /* If this key contains two distinct keysyms, that is, | 848 } |
836 "shift" generates a different keysym than the | 849 else /* Mouse press/release event */ |
837 non-shifted key, then don't apply the shift modifier | 850 { |
838 bit: it's implicit. Otherwise, if there would be no | 851 XButtonEvent *ev = &x_event->xbutton; |
839 other way to tell the difference between the shifted | 852 struct frame *frame = x_window_to_frame (d, ev->window); |
840 and unshifted version of this key, apply the shift bit. | 853 if (! frame) |
841 Non-graphics, like Backspace and F1 get the shift bit | 854 return 0; /* not for us */ |
842 in the modifiers slot. Neither the characters "a", | 855 XSETFRAME (emacs_event->channel, frame); |
843 "A", "2", nor "@" normally have the shift bit set. | 856 |
844 However, "F1" normally does. */ | 857 emacs_event->event_type = (x_event->type == ButtonPress) ? |
845 if (modifiers & MOD_SHIFT) | 858 button_press_event : button_release_event; |
846 { | 859 |
847 int Mode_switch_p = *state & xd->ModeMask; | 860 emacs_event->event.button.modifiers = modifiers; |
848 KeySym bot = XLookupKeysym (ev, Mode_switch_p ? 2 : 0); | 861 emacs_event->timestamp = ev->time; |
849 KeySym top = XLookupKeysym (ev, Mode_switch_p ? 3 : 1); | 862 emacs_event->event.button.button = ev->button; |
850 if (top && bot && top != bot) | 863 emacs_event->event.button.x = ev->x; |
851 modifiers &= ~MOD_SHIFT; | 864 emacs_event->event.button.y = ev->y; |
852 } | |
853 emacs_event->event_type = key_press_event; | |
854 emacs_event->timestamp = ev->time; | |
855 emacs_event->event.key.modifiers = modifiers; | |
856 emacs_event->event.key.keysym = keysym; | |
857 } | |
858 else /* Mouse press/release event */ | |
859 { | |
860 XButtonEvent *ev = &x_event->xbutton; | |
861 struct frame *frame = x_window_to_frame (d, ev->window); | |
862 if (! frame) | |
863 return 0; /* not for us */ | |
864 XSETFRAME (emacs_event->channel, frame); | |
865 | |
866 emacs_event->event_type = (x_event->type == ButtonPress) ? | |
867 button_press_event : button_release_event; | |
868 | |
869 emacs_event->event.button.modifiers = modifiers; | |
870 emacs_event->timestamp = ev->time; | |
871 emacs_event->event.button.button = ev->button; | |
872 emacs_event->event.button.x = ev->x; | |
873 emacs_event->event.button.y = ev->y; | |
874 } | 865 } |
875 } | 866 } |
876 break; | 867 break; |
877 | 868 |
878 case MotionNotify: | 869 case MotionNotify: |
1139 have been sent as a result of mouse motion or some other implicit | 1130 have been sent as a result of mouse motion or some other implicit |
1140 action. (Call this a "heuristic"...) The reason for caring about | 1131 action. (Call this a "heuristic"...) The reason for caring about |
1141 this is so that clicking on the close-box will make emacs prompt | 1132 this is so that clicking on the close-box will make emacs prompt |
1142 using a dialog box instead of the minibuffer if there are unsaved | 1133 using a dialog box instead of the minibuffer if there are unsaved |
1143 buffers. | 1134 buffers. |
1144 */ | 1135 */ |
1145 enqueue_misc_user_event (frame, Qeval, | 1136 enqueue_misc_user_event (frame, Qeval, |
1146 list3 (Qdelete_frame, frame, Qt)); | 1137 list3 (Qdelete_frame, frame, Qt)); |
1147 } | 1138 } |
1148 else if (event->xclient.message_type == DEVICE_XATOM_WM_PROTOCOLS (d) && | 1139 else if (event->xclient.message_type == DEVICE_XATOM_WM_PROTOCOLS (d) && |
1149 event->xclient.data.l[0] == DEVICE_XATOM_WM_TAKE_FOCUS (d)) | 1140 event->xclient.data.l[0] == DEVICE_XATOM_WM_TAKE_FOCUS (d)) |
1259 case ClientMessage: | 1250 case ClientMessage: |
1260 handle_client_message (f, event); | 1251 handle_client_message (f, event); |
1261 break; | 1252 break; |
1262 | 1253 |
1263 case VisibilityNotify: /* window visiblity has changed */ | 1254 case VisibilityNotify: /* window visiblity has changed */ |
1264 if (event->xvisibility.window == XtWindow (FRAME_X_SHELL_WIDGET (f))) | 1255 if (event->xvisibility.window == XtWindow (FRAME_X_SHELL_WIDGET (f))) |
1265 FRAME_X_TOTALLY_VISIBLE_P (f) = | 1256 FRAME_X_TOTALLY_VISIBLE_P (f) = |
1266 (event->xvisibility.state == VisibilityUnobscured); | 1257 (event->xvisibility.state == VisibilityUnobscured); |
1267 break; | 1258 break; |
1268 | 1259 |
1269 case ConfigureNotify: | 1260 case ConfigureNotify: |
1270 #ifdef HAVE_XIM | 1261 #ifdef HAVE_XIM |
1271 XIC_SetGeometry (f); | 1262 XIM_SetGeometry (f); |
1272 #endif | 1263 #endif |
1273 /* ### If the following code fails to work, simply always call | 1264 /* ### If the following code fails to work, simply always call |
1274 x_smash_bastardly_shell_position always. In this case we no | 1265 x_smash_bastardly_shell_position always. In this case we no |
1275 longer rely on the data in the events, merely on their | 1266 longer rely on the data in the events, merely on their |
1276 occurrence. */ | 1267 occurrence. */ |
1775 unsigned int state = ev->state; | 1766 unsigned int state = ev->state; |
1776 | 1767 |
1777 describe_event_window (ev->window, ev->display); | 1768 describe_event_window (ev->window, ev->display); |
1778 stderr_out (" subwindow: %ld\n", ev->subwindow); | 1769 stderr_out (" subwindow: %ld\n", ev->subwindow); |
1779 stderr_out (" state: "); | 1770 stderr_out (" state: "); |
1771 /* Complete list of modifier key masks */ | |
1780 if (state & ShiftMask) stderr_out ("Shift "); | 1772 if (state & ShiftMask) stderr_out ("Shift "); |
1781 if (state & LockMask) stderr_out ("Lock "); | 1773 if (state & LockMask) stderr_out ("Lock "); |
1782 if (state & ControlMask) stderr_out ("Control "); | 1774 if (state & ControlMask) stderr_out ("Control "); |
1783 if (state & Mod1Mask) stderr_out ("Mod1 "); | 1775 if (state & Mod1Mask) stderr_out ("Mod1 "); |
1784 if (state & Mod2Mask) stderr_out ("Mod2 "); | 1776 if (state & Mod2Mask) stderr_out ("Mod2 "); |
1785 if (state & Mod3Mask) stderr_out ("Mod3 "); | 1777 if (state & Mod3Mask) stderr_out ("Mod3 "); |
1786 if (state & Mod4Mask) stderr_out ("Mod4 "); | 1778 if (state & Mod4Mask) stderr_out ("Mod4 "); |
1787 if (state & Mod5Mask) stderr_out ("Mod5 "); | 1779 if (state & Mod5Mask) stderr_out ("Mod5 "); |
1788 #if 0 /* Apparently these don't exist? */ | |
1789 if (state & MetaMask) stderr_out ("Meta "); | |
1790 if (state & SuperMask) stderr_out ("Super "); | |
1791 if (state & HyperMask) stderr_out ("Hyper "); | |
1792 if (state & AltMask) stderr_out ("Alt "); | |
1793 if (state & ModeMask) stderr_out ("Mode_switch "); | |
1794 #endif | |
1795 | 1780 |
1796 if (! state) | 1781 if (! state) |
1797 stderr_out ("vanilla\n"); | 1782 stderr_out ("vanilla\n"); |
1798 else | 1783 else |
1799 stderr_out ("\n"); | 1784 stderr_out ("\n"); |
1800 if (x_key_is_modifier_p (ev->keycode, d)) | 1785 if (x_key_is_modifier_p (ev->keycode, d)) |
1801 stderr_out (" Modifier key"); | 1786 stderr_out (" Modifier key"); |
1802 stderr_out (" keycode: 0x%x\n", ev->keycode); | 1787 stderr_out (" keycode: 0x%x\n", ev->keycode); |
1803 keysym = x_to_emacs_keysym (event, 0); | |
1804 if (CHAR_OR_CHAR_INTP (keysym)) | |
1805 { | |
1806 Emchar c = XCHAR_OR_CHAR_INT (keysym); | |
1807 if (c > 32 && c < 127) | |
1808 stderr_out (" keysym: %c\n", c); | |
1809 else | |
1810 stderr_out (" keysym: %d\n", c); | |
1811 } | |
1812 else | |
1813 stderr_out (" keysym: %s\n", string_data (XSYMBOL (keysym)->name)); | |
1814 } | 1788 } |
1815 break; | 1789 break; |
1816 | 1790 |
1817 case Expose: | 1791 case Expose: |
1818 if (x_debug_events > 1) | 1792 if (x_debug_events > 1) |
1926 enqueue_Xt_dispatch_event (Lisp_Object event) | 1900 enqueue_Xt_dispatch_event (Lisp_Object event) |
1927 { | 1901 { |
1928 enqueue_event (event, &dispatch_event_queue, &dispatch_event_queue_tail); | 1902 enqueue_event (event, &dispatch_event_queue, &dispatch_event_queue_tail); |
1929 } | 1903 } |
1930 | 1904 |
1931 Lisp_Object | 1905 static Lisp_Object |
1932 dequeue_Xt_dispatch_event (void) | 1906 dequeue_Xt_dispatch_event (void) |
1933 { | 1907 { |
1934 return dequeue_event (&dispatch_event_queue, &dispatch_event_queue_tail); | 1908 return dequeue_event (&dispatch_event_queue, &dispatch_event_queue_tail); |
1935 } | 1909 } |
1936 | 1910 |
2079 return 0; | 2053 return 0; |
2080 | 2054 |
2081 /* This duplicates some code that exists elsewhere, but it's relatively | 2055 /* This duplicates some code that exists elsewhere, but it's relatively |
2082 fast and doesn't cons. | 2056 fast and doesn't cons. |
2083 */ | 2057 */ |
2084 keysym = x_to_emacs_keysym (event, 1); | 2058 keysym = x_to_emacs_keysym (&event->xkey, 1); |
2085 if (NILP (keysym)) return 0; | 2059 if (NILP (keysym)) return 0; |
2086 if (CHAR_OR_CHAR_INTP (keysym)) | 2060 if (CHAR_OR_CHAR_INTP (keysym)) |
2087 c = XCHAR_OR_CHAR_INT (keysym); | 2061 c = XCHAR_OR_CHAR_INT (keysym); |
2088 /* Highly doubtful that these are the quit character, but... */ | 2062 /* Highly doubtful that these are the quit character, but... */ |
2089 else if (EQ (keysym, QKbackspace)) c = '\b'; | 2063 else if (EQ (keysym, QKbackspace)) c = '\b'; |