Mercurial > hg > xemacs-beta
comparison src/event-Xt.c @ 2:ac2d302a0011 r19-15b2
Import from CVS: tag r19-15b2
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:46:35 +0200 |
parents | 376386a54a3c |
children | 4b173ad71786 |
comparison
equal
deleted
inserted
replaced
1:c0c6a60d29db | 2:ac2d302a0011 |
---|---|
163 } | 163 } |
164 | 164 |
165 static CONST char * | 165 static CONST char * |
166 index_to_name (int indice) | 166 index_to_name (int indice) |
167 { | 167 { |
168 return ((indice == ShiftMapIndex ? "ModShift" | 168 switch (indice) |
169 : (indice == LockMapIndex ? "ModLock" | 169 { |
170 : (indice == ControlMapIndex ? "ModControl" | 170 case ShiftMapIndex: return "ModShift"; |
171 : (indice == Mod1MapIndex ? "Mod1" | 171 case LockMapIndex: return "ModLock"; |
172 : (indice == Mod2MapIndex ? "Mod2" | 172 case ControlMapIndex: return "ModControl"; |
173 : (indice == Mod3MapIndex ? "Mod3" | 173 case Mod1MapIndex: return "Mod1"; |
174 : (indice == Mod4MapIndex ? "Mod4" | 174 case Mod2MapIndex: return "Mod2"; |
175 : (indice == Mod5MapIndex ? "Mod5" | 175 case Mod3MapIndex: return "Mod3"; |
176 : "???"))))))))); | 176 case Mod4MapIndex: return "Mod4"; |
177 case Mod5MapIndex: return "Mod5"; | |
178 default: return "???"; | |
179 } | |
177 } | 180 } |
178 | 181 |
179 /* Boy, I really wish C had local functions... */ | 182 /* Boy, I really wish C had local functions... */ |
180 struct c_doesnt_have_closures /* #### not yet used */ | 183 struct c_doesnt_have_closures /* #### not yet used */ |
181 { | 184 { |
194 { | 197 { |
195 Display *display = DEVICE_X_DISPLAY (d); | 198 Display *display = DEVICE_X_DISPLAY (d); |
196 struct x_device *xd = DEVICE_X_DATA (d); | 199 struct x_device *xd = DEVICE_X_DATA (d); |
197 int modifier_index, modifier_key, column, mkpm; | 200 int modifier_index, modifier_key, column, mkpm; |
198 int warned_about_overlapping_modifiers = 0; | 201 int warned_about_overlapping_modifiers = 0; |
199 int warned_about_predefined_modifiers = 0; | 202 int warned_about_predefined_modifiers = 0; |
200 int warned_about_duplicate_modifiers = 0; | 203 int warned_about_duplicate_modifiers = 0; |
201 int meta_bit = 0; | 204 int meta_bit = 0; |
202 int hyper_bit = 0; | 205 int hyper_bit = 0; |
203 int super_bit = 0; | 206 int super_bit = 0; |
204 int alt_bit = 0; | 207 int alt_bit = 0; |
205 int mode_bit = 0; | 208 int mode_bit = 0; |
206 | 209 |
207 xd->lock_interpretation = 0; | 210 xd->lock_interpretation = 0; |
208 | 211 |
209 if (xd->x_modifier_keymap) | 212 if (xd->x_modifier_keymap) |
210 XFreeModifiermap (xd->x_modifier_keymap); | 213 XFreeModifiermap (xd->x_modifier_keymap); |
411 the modifier key again. */ | 414 the modifier key again. */ |
412 | 415 |
413 static void | 416 static void |
414 x_handle_sticky_modifiers (XEvent *ev, struct device *d) | 417 x_handle_sticky_modifiers (XEvent *ev, struct device *d) |
415 { | 418 { |
416 struct x_device *xd = DEVICE_X_DATA (d); | 419 struct x_device *xd; |
417 KeyCode keycode = ev->xkey.keycode; | 420 KeyCode keycode; |
418 int type = ev->xany.type; | 421 int type; |
419 int is_modifier = | 422 |
420 (type == KeyPress || type == KeyRelease) && | 423 if (!modifier_keys_are_sticky) /* Optimize for non-sticky modifiers */ |
421 x_key_is_modifier_p (keycode, d); | |
422 | |
423 if (!modifier_keys_are_sticky) | |
424 return; | 424 return; |
425 | 425 |
426 if (!is_modifier) | 426 xd = DEVICE_X_DATA (d); |
427 { | 427 keycode = ev->xkey.keycode; |
428 type = ev->type; | |
429 | |
430 if (! ((type == KeyPress || type == KeyRelease) && | |
431 x_key_is_modifier_p (keycode, d))) | |
432 { /* Not a modifier key */ | |
433 Bool key_event_p = (type == KeyPress || type == KeyRelease); | |
434 | |
428 if (type == KeyPress && !xd->last_downkey) | 435 if (type == KeyPress && !xd->last_downkey) |
429 xd->last_downkey = keycode; | 436 xd->last_downkey = keycode; |
430 else if (type == ButtonPress || | 437 else if (type == ButtonPress || |
431 (type == KeyPress && xd->last_downkey && | 438 (type == KeyPress && xd->last_downkey && |
432 (keycode != xd->last_downkey || | 439 (keycode != xd->last_downkey || |
438 if (type == KeyPress) | 445 if (type == KeyPress) |
439 xd->release_time = 0; | 446 xd->release_time = 0; |
440 if (type == KeyPress || type == ButtonPress) | 447 if (type == KeyPress || type == ButtonPress) |
441 xd->down_mask = 0; | 448 xd->down_mask = 0; |
442 | 449 |
443 ev->xkey.state |= xd->need_to_add_mask; | 450 if (key_event_p) |
451 ev->xkey.state |= xd->need_to_add_mask; | |
452 else | |
453 ev->xbutton.state |= xd->need_to_add_mask; | |
444 | 454 |
445 if (type == KeyRelease && keycode == xd->last_downkey) | 455 if (type == KeyRelease && keycode == xd->last_downkey) |
446 /* If I hold press-and-release the Control key and then press | 456 /* If I hold press-and-release the Control key and then press |
447 and hold down the right arrow, I want it to auto-repeat | 457 and hold down the right arrow, I want it to auto-repeat |
448 Control-Right. On the other hand, if I do the same but | 458 Control-Right. On the other hand, if I do the same but |
456 to provide an obvious way to distinguish these cases. | 466 to provide an obvious way to distinguish these cases. |
457 So we assume that if the release and the next press | 467 So we assume that if the release and the next press |
458 occur at the same time, the key was actually auto- | 468 occur at the same time, the key was actually auto- |
459 repeated. Under Open-Windows, at least, this works. | 469 repeated. Under Open-Windows, at least, this works. |
460 */ | 470 */ |
461 xd->release_time = ev->xkey.time; | 471 xd->release_time = key_event_p ? ev->xkey.time : ev->xbutton.time; |
462 } | 472 } |
463 else | 473 else /* Modifier key pressed */ |
464 { | 474 { |
475 int i; | |
465 KeySym *syms = &xd->x_keysym_map [(keycode - xd->x_keysym_map_min_code) * | 476 KeySym *syms = &xd->x_keysym_map [(keycode - xd->x_keysym_map_min_code) * |
466 xd->x_keysym_map_keysyms_per_code]; | 477 xd->x_keysym_map_keysyms_per_code]; |
467 int i; | 478 |
479 /* If a non-modifier key was pressed in the middle of a bunch | |
480 of modifiers, then it unsticks all the modifiers that were | |
481 previously pressed. We cannot unstick the modifiers until | |
482 now because we want to check for auto-repeat of the | |
483 non-modifier key. */ | |
484 | |
485 if (xd->last_downkey) | |
486 { | |
487 xd->last_downkey = 0; | |
488 xd->need_to_add_mask = 0; | |
489 } | |
468 | 490 |
469 #define FROB(mask) \ | 491 #define FROB(mask) \ |
470 do { \ | 492 do { \ |
471 if (type == KeyPress) \ | 493 if (type == KeyPress) \ |
472 { \ | 494 { \ |
491 xd->need_to_add_mask |= mask; \ | 513 xd->need_to_add_mask |= mask; \ |
492 } \ | 514 } \ |
493 } \ | 515 } \ |
494 } while (0) | 516 } while (0) |
495 | 517 |
496 /* If a non-modifier key was pressed in the middle of a bunch | |
497 of modifiers, then it unsticks all the modifiers that were | |
498 previously pressed. We cannot unstick the modifiers until | |
499 now because we want to check for auto-repeat of the | |
500 non-modifier key. */ | |
501 | |
502 if (xd->last_downkey) | |
503 { | |
504 xd->last_downkey = 0; | |
505 xd->need_to_add_mask = 0; | |
506 } | |
507 | |
508 for (i = 0; i < xd->x_keysym_map_keysyms_per_code; i++) | 518 for (i = 0; i < xd->x_keysym_map_keysyms_per_code; i++) |
509 { | 519 switch (syms[i]) |
510 if (syms[i] == XK_Control_L || syms[i] == XK_Control_R) | 520 { |
511 FROB (ControlMask); | 521 case XK_Control_L: case XK_Control_R: FROB (ControlMask); break; |
512 if (syms[i] == XK_Shift_L || syms[i] == XK_Shift_R) | 522 case XK_Shift_L: case XK_Shift_R: FROB (ShiftMask); break; |
513 FROB (ShiftMask); | 523 case XK_Meta_L: case XK_Meta_R: FROB (xd->MetaMask); break; |
514 if (syms[i] == XK_Meta_L || syms[i] == XK_Meta_R) | 524 case XK_Super_L: case XK_Super_R: FROB (xd->SuperMask); break; |
515 FROB (xd->MetaMask); | 525 case XK_Hyper_L: case XK_Hyper_R: FROB (xd->HyperMask); break; |
516 if (syms[i] == XK_Super_L || syms[i] == XK_Super_R) | 526 case XK_Alt_L: case XK_Alt_R: FROB (xd->AltMask); break; |
517 FROB (xd->SuperMask); | 527 } |
518 if (syms[i] == XK_Hyper_L || syms[i] == XK_Hyper_R) | |
519 FROB (xd->HyperMask); | |
520 if (syms[i] == XK_Alt_L || syms[i] == XK_Alt_R) | |
521 FROB (xd->AltMask); | |
522 } | |
523 } | 528 } |
524 #undef FROB | 529 #undef FROB |
525 } | 530 } |
526 | 531 |
527 static void | 532 static void |
537 | 542 |
538 static int | 543 static int |
539 keysym_obeys_caps_lock_p (KeySym sym, struct device *d) | 544 keysym_obeys_caps_lock_p (KeySym sym, struct device *d) |
540 { | 545 { |
541 struct x_device *xd = DEVICE_X_DATA (d); | 546 struct x_device *xd = DEVICE_X_DATA (d); |
542 /* Eeeeevil hack. Don't apply caps-lock to things that aren't alphabetic | 547 /* Eeeeevil hack. Don't apply Caps_Lock to things that aren't alphabetic |
543 characters, where "alphabetic" means something more than simply A-Z. | 548 characters, where "alphabetic" means something more than simply A-Z. |
544 That is, if caps-lock is down, typing ESC doesn't produce Shift-ESC. | 549 That is, if Caps_Lock is down, typing ESC doesn't produce Shift-ESC. |
545 But if shift-lock is down, then it does. | 550 But if shift-lock is down, then it does. |
546 */ | 551 */ |
547 if (xd->lock_interpretation == XK_Shift_Lock) | 552 if (xd->lock_interpretation == XK_Shift_Lock) |
548 return 1; | 553 return 1; |
549 if (((sym >= XK_A) && (sym <= XK_Z)) || | 554 |
550 ((sym >= XK_a) && (sym <= XK_z)) || | 555 return |
551 ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis)) || | 556 ((sym >= XK_A) && (sym <= XK_Z)) || |
552 ((sym >= XK_agrave) && (sym <= XK_odiaeresis)) || | 557 ((sym >= XK_a) && (sym <= XK_z)) || |
553 ((sym >= XK_Ooblique) && (sym <= XK_Thorn)) || | 558 ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis)) || |
554 ((sym >= XK_oslash) && (sym <= XK_thorn))) | 559 ((sym >= XK_agrave) && (sym <= XK_odiaeresis)) || |
555 return 1; | 560 ((sym >= XK_Ooblique) && (sym <= XK_Thorn)) || |
556 else | 561 ((sym >= XK_oslash) && (sym <= XK_thorn)); |
557 return 0; | |
558 } | 562 } |
559 | 563 |
560 /* called from EmacsFrame.c (actually from Xt itself) when a | 564 /* called from EmacsFrame.c (actually from Xt itself) when a |
561 MappingNotify event is received. For non-obvious reasons, | 565 MappingNotify event is received. In its infinite wisdom, Xt |
562 our event handler does not see these events, so we need a | 566 decided that Xt event handlers never get MappingNotify events. |
563 special translation. */ | 567 O'Reilly Xt Programming Manual 9.1.2 says: |
568 | |
569 MappingNotify is automatically handled by Xt, so it isn't passed | |
570 to event handlers and you don't need to worry about it. | |
571 | |
572 Of course, we DO worry about it, so we need a special translation. */ | |
564 void | 573 void |
565 emacs_Xt_mapping_action (Widget w, XEvent* event) | 574 emacs_Xt_mapping_action (Widget w, XEvent* event) |
566 { | 575 { |
567 struct device *d = get_device_from_display (event->xany.display); | 576 struct device *d = get_device_from_display (event->xany.display); |
568 #if 0 | 577 #if 0 |
572 /* xmodmap generates about a billion MappingKeyboard events, followed | 581 /* xmodmap generates about a billion MappingKeyboard events, followed |
573 by a single MappingModifier event, so it might be worthwhile to | 582 by a single MappingModifier event, so it might be worthwhile to |
574 take extra MappingKeyboard events out of the queue before requesting | 583 take extra MappingKeyboard events out of the queue before requesting |
575 the current keymap from the server. | 584 the current keymap from the server. |
576 */ | 585 */ |
577 if (event->xmapping.request == MappingKeyboard) | 586 switch (event->xmapping.request) |
578 x_reset_key_mapping (d); | 587 { |
579 else if (event->xmapping.request == MappingModifier) | 588 case MappingKeyboard: x_reset_key_mapping (d); break; |
580 x_reset_modifier_mapping (d); | 589 case MappingModifier: x_reset_modifier_mapping (d); break; |
590 case MappingPointer: /* Do something here? */ break; | |
591 default: abort(); | |
592 } | |
581 } | 593 } |
582 | 594 |
583 | 595 |
584 /************************************************************************/ | 596 /************************************************************************/ |
585 /* X to Emacs event conversion */ | 597 /* X to Emacs event conversion */ |
599 #endif /* !SUNOS_GCC_L0_BUG */ | 611 #endif /* !SUNOS_GCC_L0_BUG */ |
600 /* simple_p means don't try too hard (ASCII only) */ | 612 /* simple_p means don't try too hard (ASCII only) */ |
601 { | 613 { |
602 char *name; | 614 char *name; |
603 KeySym keysym = 0; | 615 KeySym keysym = 0; |
604 struct device *d = get_device_from_display (event->xany.display); | 616 /* struct device *d = get_device_from_display (event->xany.display); */ |
605 /* Apparently it's necessary to specify a dummy here (rather than | 617 /* Apparently it's necessary to specify a dummy here (rather than |
606 passing in 0) to avoid crashes on German IRIX */ | 618 passing in 0) to avoid crashes on German IRIX */ |
607 char dummy[256]; | 619 char dummy[256]; |
608 | 620 |
609 #ifdef SUNOS_GCC_L0_BUG | 621 #ifdef SUNOS_GCC_L0_BUG |
691 #endif | 703 #endif |
692 | 704 |
693 static void | 705 static void |
694 set_last_server_timestamp (struct device *d, XEvent *x_event) | 706 set_last_server_timestamp (struct device *d, XEvent *x_event) |
695 { | 707 { |
696 switch (x_event->xany.type) | 708 Time t; |
709 switch (x_event->type) | |
697 { | 710 { |
698 case KeyPress: | 711 case KeyPress: |
699 case KeyRelease: | 712 case KeyRelease: t = x_event->xkey.time; break; |
700 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = x_event->xkey.time; | |
701 break; | |
702 | |
703 case ButtonPress: | 713 case ButtonPress: |
704 case ButtonRelease: | 714 case ButtonRelease: t = x_event->xbutton.time; break; |
705 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = x_event->xbutton.time; | |
706 break; | |
707 | |
708 case MotionNotify: | |
709 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = x_event->xmotion.time; | |
710 break; | |
711 | |
712 case EnterNotify: | 715 case EnterNotify: |
713 case LeaveNotify: | 716 case LeaveNotify: t = x_event->xcrossing.time; break; |
714 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = x_event->xcrossing.time; | 717 case MotionNotify: t = x_event->xmotion.time; break; |
715 break; | 718 case PropertyNotify: t = x_event->xproperty.time; break; |
716 | 719 case SelectionClear: t = x_event->xselectionclear.time; break; |
717 case PropertyNotify: | 720 case SelectionRequest: t = x_event->xselectionrequest.time; break; |
718 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = x_event->xproperty.time; | 721 case SelectionNotify: t = x_event->xselection.time; break; |
719 break; | 722 default: return; |
720 | 723 } |
721 case SelectionClear: | 724 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = t; |
722 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = x_event->xselectionclear.time; | |
723 break; | |
724 | |
725 case SelectionRequest: | |
726 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = x_event->xselectionrequest.time; | |
727 break; | |
728 | |
729 case SelectionNotify: | |
730 DEVICE_X_LAST_SERVER_TIMESTAMP (d) = x_event->xselection.time; | |
731 break; | |
732 } | |
733 } | 725 } |
734 | 726 |
735 static int | 727 static int |
736 x_event_to_emacs_event (XEvent *x_event, struct Lisp_Event *emacs_event) | 728 x_event_to_emacs_event (XEvent *x_event, struct Lisp_Event *emacs_event) |
737 { | 729 { |
738 Display *display = x_event->xany.display; | 730 Display *display = x_event->xany.display; |
739 struct device *d = get_device_from_display (display); | 731 struct device *d = get_device_from_display (display); |
740 struct x_device *xd = DEVICE_X_DATA (d); | 732 struct x_device *xd = DEVICE_X_DATA (d); |
741 | 733 |
742 set_last_server_timestamp (d, x_event); | 734 set_last_server_timestamp (d, x_event); |
743 | 735 |
744 switch (x_event->xany.type) | 736 switch (x_event->type) |
745 { | 737 { |
746 case KeyRelease: | 738 case KeyRelease: |
747 x_handle_sticky_modifiers (x_event, d); | 739 x_handle_sticky_modifiers (x_event, d); |
748 return 0; | 740 return 0; |
749 | 741 |
750 case KeyPress: | 742 case KeyPress: |
751 case ButtonPress: | 743 case ButtonPress: |
752 case ButtonRelease: | 744 case ButtonRelease: |
753 { | 745 { |
754 unsigned int modifiers = 0; | 746 unsigned int modifiers = 0; |
755 int shift_p; | 747 int shift_p; |
756 int lock_p; | 748 int lock_p; |
749 Bool key_event_p = (x_event->type == KeyPress); | |
750 unsigned int *state = | |
751 key_event_p ? &x_event->xkey.state : &x_event->xbutton.state; | |
752 | |
753 /* If this is a synthetic KeyPress or Button event, and the user | |
754 has expressed a disinterest in this security hole, then drop | |
755 it on the floor. */ | |
756 if ((key_event_p | |
757 ? x_event->xkey.send_event | |
758 : x_event->xbutton.send_event) | |
757 #ifdef EXTERNAL_WIDGET | 759 #ifdef EXTERNAL_WIDGET |
758 struct frame *f = x_any_window_to_frame (d, x_event->xany.window); | 760 /* ben: events get sent to an ExternalShell using XSendEvent. |
761 This is not a perfect solution. */ | |
762 && !FRAME_X_EXTERNAL_WINDOW_P ( | |
763 x_any_window_to_frame (d, x_event->xany.window)) | |
759 #endif | 764 #endif |
760 | 765 && !x_allow_sendevents) |
761 /* If this is a synthetic KeyPress or Button event, and the user | 766 return 0; |
762 has expressed a disinterest in this security hole, then drop | 767 |
763 it on the floor. | 768 DEVICE_X_MOUSE_TIMESTAMP (d) = |
764 */ | 769 DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d) = |
765 if (((x_event->xany.type == KeyPress) | 770 key_event_p ? x_event->xkey.time : x_event->xbutton.time; |
766 ? x_event->xkey.send_event | 771 |
767 : x_event->xbutton.send_event) | 772 x_handle_sticky_modifiers (x_event, d); |
768 #ifdef EXTERNAL_WIDGET | 773 |
769 /* ben: events get sent to an ExternalShell using XSendEvent. | 774 if (*state & ControlMask) modifiers |= MOD_CONTROL; |
770 This is not a perfect solution. */ | 775 if (*state & xd->MetaMask) modifiers |= MOD_META; |
771 && !FRAME_X_EXTERNAL_WINDOW_P (f) | 776 if (*state & xd->SuperMask) modifiers |= MOD_SUPER; |
772 #endif | 777 if (*state & xd->HyperMask) modifiers |= MOD_HYPER; |
773 && !x_allow_sendevents) | 778 if (*state & xd->AltMask) modifiers |= MOD_ALT; |
774 return 0; | 779 |
775 | 780 /* Ignore the Caps_Lock key if: |
776 x_handle_sticky_modifiers (x_event, d); | 781 - any other modifiers are down, so that Caps_Lock doesn't |
777 | 782 turn C-x into C-X, which would suck. |
778 shift_p = x_event->xkey.state & ShiftMask; | 783 - the event was a mouse event. */ |
779 lock_p = x_event->xkey.state & LockMask; | 784 if (modifiers || ! key_event_p) |
780 | 785 *state &= (~LockMask); |
781 if (x_event->xany.type == KeyPress) | 786 |
782 DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d) = x_event->xkey.time; | 787 shift_p = *state & ShiftMask; |
783 else | 788 lock_p = *state & LockMask; |
784 DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d) = x_event->xbutton.time; | 789 |
785 | 790 if (shift_p || lock_p) |
786 /* Ignore the caps-lock key w.r.t. mouse presses and releases. */ | 791 modifiers |= MOD_SHIFT; |
787 if (x_event->xany.type != KeyPress) | 792 |
788 lock_p = 0; | 793 if (key_event_p) |
789 | 794 { |
790 if (x_event->xkey.state & ControlMask) modifiers |= MOD_CONTROL; | 795 Lisp_Object keysym; |
791 if (x_event->xkey.state & xd->MetaMask) modifiers |= MOD_META; | 796 XKeyEvent *ev = &x_event->xkey; |
792 if (x_event->xkey.state & xd->SuperMask) modifiers |= MOD_SUPER; | 797 KeyCode keycode = ev->keycode; |
793 if (x_event->xkey.state & xd->HyperMask) modifiers |= MOD_HYPER; | 798 |
794 if (x_event->xkey.state & xd->AltMask) modifiers |= MOD_ALT; | 799 |
795 | 800 if (x_key_is_modifier_p (keycode, d)) /* it's a modifier key */ |
796 /* Ignore the caps-lock key if any other modifiers are down; this is | 801 return 0; |
797 so that Caps doesn't turn C-x into C-X, which would suck. */ | 802 |
798 if (modifiers) | 803 /* This used to compute the frame from the given X window and |
799 { | 804 store it here, but we really don't care about the frame. */ |
800 x_event->xkey.state &= (~LockMask); | 805 emacs_event->channel = DEVICE_CONSOLE (d); |
801 lock_p = 0; | 806 keysym = x_to_emacs_keysym (x_event, 0); |
802 } | |
803 | |
804 if (shift_p || lock_p) | |
805 modifiers |= MOD_SHIFT; | |
806 | |
807 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d); | |
808 | |
809 switch (x_event->xany.type) | |
810 { | |
811 case KeyPress: | |
812 { | |
813 Lisp_Object keysym; | |
814 KeyCode keycode = x_event->xkey.keycode; | |
815 | 807 |
816 if (x_key_is_modifier_p (keycode, d)) /* it's a modifier key */ | 808 /* If the emacs keysym is nil, then that means that the |
817 return 0; | 809 X keysym was NoSymbol, which probably means that |
818 | 810 we're in the midst of reading a Multi_key sequence, |
819 /* This used to compute the frame from the given X window | 811 or a "dead" key prefix. Ignore it. */ |
820 and store it here, but we really don't care about the | 812 if (NILP (keysym)) |
821 frame. */ | 813 return 0; |
822 emacs_event->channel = DEVICE_CONSOLE (d); | |
823 keysym = x_to_emacs_keysym (x_event, 0); | |
824 | 814 |
825 /* If the emacs keysym is nil, then that means that the | 815 /* More Caps_Lock garbage: Caps_Lock should *only* add the |
826 X keysym was NoSymbol, which probably means that | 816 shift modifier to two-case keys (that is, A-Z and |
827 we're in the midst of reading a Multi_key sequence, | 817 related characters). So at this point (after looking up |
828 or a "dead" key prefix. Ignore it. */ | 818 the keysym) if the keysym isn't a dual-case alphabetic, |
829 if (NILP (keysym)) | 819 and if the caps lock key was down but the shift key |
830 return 0; | 820 wasn't, then turn off the shift modifier. Gag barf */ |
821 /* #### type lossage: assuming equivalence of emacs and | |
822 X keysyms */ | |
823 /* !!#### maybe fix for Mule */ | |
824 if (lock_p && !shift_p && | |
825 ! (CHAR_OR_CHAR_INTP (keysym) | |
826 && keysym_obeys_caps_lock_p | |
827 ((KeySym) XCHAR_OR_CHAR_INT (keysym), d))) | |
828 modifiers &= (~MOD_SHIFT); | |
831 | 829 |
832 /* More caps-lock garbage: caps-lock should *only* add | 830 /* If this key contains two distinct keysyms, that is, |
833 the shift modifier to two-case keys (that is, A-Z and | 831 "shift" generates a different keysym than the |
834 related characters). So at this point (after looking | 832 non-shifted key, then don't apply the shift modifier |
835 up the keysym) if the keysym isn't a dual-case | 833 bit: it's implicit. Otherwise, if there would be no |
836 alphabetic, and if the caps lock key was down but the | 834 other way to tell the difference between the shifted |
837 shift key wasn't, then turn off the shift modifier. | 835 and unshifted version of this key, apply the shift bit. |
838 Gag barf retch. */ | 836 Non-graphics, like Backspace and F1 get the shift bit |
839 /* #### type lossage: assuming equivalence of emacs and | 837 in the modifiers slot. Neither the characters "a", |
840 X keysyms */ | 838 "A", "2", nor "@" normally have the shift bit set. |
841 /* !!#### maybe fix for Mule */ | 839 However, "F1" normally does. */ |
842 if (! (CHAR_OR_CHAR_INTP (keysym) | 840 if (modifiers & MOD_SHIFT) |
843 && keysym_obeys_caps_lock_p | 841 { |
844 ((KeySym) XCHAR_OR_CHAR_INT (keysym), d)) | 842 int Mode_switch_p = *state & xd->ModeMask; |
845 && lock_p | 843 KeySym bot = XLookupKeysym (ev, Mode_switch_p ? 2 : 0); |
846 && !shift_p) | 844 KeySym top = XLookupKeysym (ev, Mode_switch_p ? 3 : 1); |
847 modifiers &= (~MOD_SHIFT); | 845 if (top && bot && top != bot) |
848 | 846 modifiers &= ~MOD_SHIFT; |
849 /* If this key contains two distinct keysyms, that is, | 847 } |
850 "shift" generates a different keysym than the | 848 emacs_event->event_type = key_press_event; |
851 non-shifted key, then don't apply the shift modifier | 849 emacs_event->timestamp = ev->time; |
852 bit: it's implicit. Otherwise, if there would be no | 850 emacs_event->event.key.modifiers = modifiers; |
853 other way to tell the difference between the shifted | 851 emacs_event->event.key.keysym = keysym; |
854 and unshifted version of this key, apply the shift | 852 } |
855 bit. Non-graphics, like Backspace and F1 get the | 853 else /* Mouse press/release event */ |
856 shift bit in the modifiers slot. Neither the | 854 { |
857 characters "a", "A", "2", nor "@" normally have the | 855 XButtonEvent *ev = &x_event->xbutton; |
858 shift bit set. However, "F1" normally does. */ | 856 struct frame *frame = x_window_to_frame (d, ev->window); |
859 if (modifiers & MOD_SHIFT) | 857 if (! frame) |
860 { | 858 return 0; /* not for us */ |
861 KeySym top, bot; | 859 XSETFRAME (emacs_event->channel, frame); |
862 if (x_event->xkey.state & xd->ModeMask) | 860 |
863 bot = XLookupKeysym (&x_event->xkey, 2), | 861 emacs_event->event_type = (x_event->type == ButtonPress) ? |
864 top = XLookupKeysym (&x_event->xkey, 3); | 862 button_press_event : button_release_event; |
865 else | 863 |
866 bot = XLookupKeysym (&x_event->xkey, 0), | 864 emacs_event->event.button.modifiers = modifiers; |
867 top = XLookupKeysym (&x_event->xkey, 1); | 865 emacs_event->timestamp = ev->time; |
868 if (top && bot && top != bot) | 866 emacs_event->event.button.button = ev->button; |
869 modifiers &= ~MOD_SHIFT; | 867 emacs_event->event.button.x = ev->x; |
870 } | 868 emacs_event->event.button.y = ev->y; |
871 emacs_event->event_type = key_press_event; | 869 } |
872 emacs_event->timestamp = x_event->xkey.time; | |
873 emacs_event->event.key.modifiers = modifiers; | |
874 emacs_event->event.key.keysym = keysym; | |
875 break; | |
876 } | |
877 case ButtonPress: | |
878 case ButtonRelease: | |
879 { | |
880 struct frame *frame = | |
881 x_window_to_frame (d, x_event->xbutton.window); | |
882 if (! frame) | |
883 return 0; /* not for us */ | |
884 XSETFRAME (emacs_event->channel, frame); | |
885 } | |
886 | |
887 if (x_event->type == ButtonPress) | |
888 emacs_event->event_type = button_press_event; | |
889 else emacs_event->event_type = button_release_event; | |
890 emacs_event->timestamp = x_event->xbutton.time; | |
891 emacs_event->event.button.modifiers = modifiers; | |
892 emacs_event->event.button.button = x_event->xbutton.button; | |
893 emacs_event->event.button.x = x_event->xbutton.x; | |
894 emacs_event->event.button.y = x_event->xbutton.y; | |
895 break; | |
896 } | |
897 } | 870 } |
898 break; | 871 break; |
899 | 872 |
900 case MotionNotify: | 873 case MotionNotify: |
901 { | 874 { |
902 Window w = x_event->xmotion.window; | 875 XMotionEvent *ev = &x_event->xmotion; |
903 struct frame *frame = x_window_to_frame (d, w); | 876 struct frame *frame = x_window_to_frame (d, ev->window); |
904 XEvent event2; | 877 unsigned int modifiers = 0; |
878 XMotionEvent event2; | |
905 | 879 |
906 if (! frame) | 880 if (! frame) |
907 return 0; /* not for us */ | 881 return 0; /* not for us */ |
908 | 882 |
909 /* We use MotionHintMask, so we will get only one motion event | 883 /* We use MotionHintMask, so we will get only one motion event |
910 until the next time we call XQueryPointer or the user clicks | 884 until the next time we call XQueryPointer or the user |
911 the mouse. So call XQueryPointer now (meaning that the event | 885 clicks the mouse. So call XQueryPointer now (meaning that |
912 will be in sync with the server just before Fnext_event() | 886 the event will be in sync with the server just before |
913 returns). If the mouse is still in motion, then the server | 887 Fnext_event() returns). If the mouse is still in motion, |
914 will immediately generate exactly one more motion event, which | 888 then the server will immediately generate exactly one more |
915 will be on the queue waiting for us next time around. | 889 motion event, which will be on the queue waiting for us |
916 */ | 890 next time around. */ |
917 event2 = *x_event; | 891 event2 = *ev; |
918 if (XQueryPointer (x_event->xmotion.display, event2.xmotion.window, | 892 if (XQueryPointer (event2.display, event2.window, |
919 &event2.xmotion.root, &event2.xmotion.subwindow, | 893 &event2.root, &event2.subwindow, |
920 &event2.xmotion.x_root, &event2.xmotion.y_root, | 894 &event2.x_root, &event2.y_root, |
921 &event2.xmotion.x, &event2.xmotion.y, | 895 &event2.x, &event2.y, |
922 &event2.xmotion.state)) | 896 &event2.state)) |
923 *x_event = event2; | 897 ev = &event2; /* only one structure copy */ |
924 | 898 |
925 DEVICE_X_MOUSE_TIMESTAMP (d) = x_event->xmotion.time; | 899 DEVICE_X_MOUSE_TIMESTAMP (d) = ev->time; |
926 | 900 |
927 XSETFRAME (emacs_event->channel, frame); | 901 XSETFRAME (emacs_event->channel, frame); |
928 emacs_event->event_type = pointer_motion_event; | 902 emacs_event->event_type = pointer_motion_event; |
929 emacs_event->timestamp = x_event->xmotion.time; | 903 emacs_event->timestamp = ev->time; |
930 emacs_event->event.motion.x = x_event->xmotion.x; | 904 emacs_event->event.motion.x = ev->x; |
931 emacs_event->event.motion.y = x_event->xmotion.y; | 905 emacs_event->event.motion.y = ev->y; |
932 { | 906 if (ev->state & ShiftMask) modifiers |= MOD_SHIFT; |
933 unsigned int modifiers = 0; | 907 if (ev->state & ControlMask) modifiers |= MOD_CONTROL; |
934 if (x_event->xmotion.state & ShiftMask) modifiers |= MOD_SHIFT; | 908 if (ev->state & xd->MetaMask) modifiers |= MOD_META; |
935 if (x_event->xmotion.state & ControlMask) modifiers |= MOD_CONTROL; | 909 if (ev->state & xd->SuperMask) modifiers |= MOD_SUPER; |
936 if (x_event->xmotion.state & xd->MetaMask) modifiers |= MOD_META; | 910 if (ev->state & xd->HyperMask) modifiers |= MOD_HYPER; |
937 if (x_event->xmotion.state & xd->SuperMask) modifiers |= MOD_SUPER; | 911 if (ev->state & xd->AltMask) modifiers |= MOD_ALT; |
938 if (x_event->xmotion.state & xd->HyperMask) modifiers |= MOD_HYPER; | 912 /* Currently ignores Shift_Lock but probably shouldn't |
939 if (x_event->xmotion.state & xd->AltMask) modifiers |= MOD_ALT; | 913 (but it definitely should ignore Caps_Lock). */ |
940 /* Currently ignores Shift_Lock but probably shouldn't | 914 emacs_event->event.motion.modifiers = modifiers; |
941 (but it definitely should ignore Caps_Lock). */ | |
942 emacs_event->event.motion.modifiers = modifiers; | |
943 } | |
944 } | 915 } |
945 break; | 916 break; |
946 | 917 |
947 case ClientMessage: | 918 case ClientMessage: |
948 /* Patch bogus TAKE_FOCUS messages from MWM; CurrentTime is passed as the | 919 { |
949 timestamp of the TAKE_FOCUS, which the ICCCM explicitly prohibits. */ | 920 /* Patch bogus TAKE_FOCUS messages from MWM; CurrentTime is |
950 if (x_event->xclient.message_type == DEVICE_XATOM_WM_PROTOCOLS (d) | 921 passed as the timestamp of the TAKE_FOCUS, which the ICCCM |
951 && x_event->xclient.data.l[0] == DEVICE_XATOM_WM_TAKE_FOCUS (d) | 922 explicitly prohibits. */ |
952 && x_event->xclient.data.l[1] == 0) | 923 XClientMessageEvent *ev = &x_event->xclient; |
953 { | 924 if (ev->message_type == DEVICE_XATOM_WM_PROTOCOLS (d) |
954 x_event->xclient.data.l[1] = DEVICE_X_LAST_SERVER_TIMESTAMP (d); | 925 && ev->data.l[0] == DEVICE_XATOM_WM_TAKE_FOCUS (d) |
955 } | 926 && ev->data.l[1] == 0) |
956 /* fall through */ | 927 { |
928 ev->data.l[1] = DEVICE_X_LAST_SERVER_TIMESTAMP (d); | |
929 } | |
930 } | |
931 /* fall through */ | |
957 | 932 |
958 default: /* it's a magic event */ | 933 default: /* it's a magic event */ |
959 { | 934 { |
960 struct frame *f; | 935 struct frame *frame; |
961 | 936 Window w; |
962 switch (x_event->type) | 937 |
963 { | 938 switch (x_event->type) |
964 /* Note: the number of cases could be reduced to two or | 939 { |
965 three by using xany.window, but it's perhaps clearer | 940 /* Note: the number of cases could be reduced to two or |
966 and potentially more robust this way */ | 941 three by using xany.window, but it's perhaps clearer |
967 case SelectionRequest: | 942 and potentially more robust this way */ |
968 f = x_window_to_frame (d, x_event->xselectionrequest.owner); | 943 case SelectionRequest: w = x_event->xselectionrequest.owner; break; |
969 break; | 944 case SelectionClear: w = x_event->xselectionclear.window; break; |
970 | 945 case SelectionNotify: w = x_event->xselection.requestor; break; |
971 case SelectionClear: | 946 case PropertyNotify: w = x_event->xproperty.window; break; |
972 f = x_window_to_frame (d, x_event->xselectionclear.window); | 947 case ClientMessage: w = x_event->xclient.window; break; |
973 break; | 948 case ConfigureNotify: w = x_event->xconfigure.window; break; |
974 | 949 case Expose: |
975 case SelectionNotify: | 950 case GraphicsExpose: w = x_event->xexpose.window; break; |
976 f = x_window_to_frame (d, x_event->xselection.requestor); | 951 case MapNotify: |
977 break; | 952 case UnmapNotify: w = x_event->xmap.window; break; |
978 | 953 case EnterNotify: |
979 case PropertyNotify: | 954 case LeaveNotify: w = x_event->xcrossing.window; break; |
980 f = x_window_to_frame (d, x_event->xproperty.window); | 955 case FocusIn: |
981 break; | 956 case FocusOut: w = x_event->xfocus.window; break; |
982 | 957 case VisibilityNotify: w = x_event->xvisibility.window; break; |
983 case Expose: | 958 default: w = x_event->xany.window; break; |
984 case GraphicsExpose: | 959 } |
985 f = x_window_to_frame (d, x_event->xexpose.window); | 960 frame = x_any_window_to_frame (d, w); |
986 break; | 961 |
987 | 962 if (!frame) |
988 case MapNotify: | 963 return 0; |
989 case UnmapNotify: | 964 |
990 f = x_any_window_to_frame (d, x_event->xmap.window); | 965 emacs_event->event_type = magic_event; |
991 break; | 966 XSETFRAME (emacs_event->channel, frame); |
992 | 967 emacs_event->event.magic.underlying_x_event = *x_event; |
993 case EnterNotify: | 968 break; |
994 case LeaveNotify: | |
995 f = x_any_window_to_frame (d, x_event->xcrossing.window); | |
996 break; | |
997 | |
998 case FocusIn: | |
999 case FocusOut: | |
1000 /* It's curious that we're using x_any_window_to_frame() | |
1001 here. I don't know if this causes problems. */ | |
1002 f = x_any_window_to_frame (d, x_event->xfocus.window); | |
1003 | |
1004 case ClientMessage: | |
1005 f = x_any_window_to_frame (d, x_event->xclient.window); | |
1006 break; | |
1007 | |
1008 case MappingNotify: | |
1009 case VisibilityNotify: | |
1010 f = x_any_window_to_frame (d, x_event->xvisibility.window); | |
1011 break; | |
1012 | |
1013 case ConfigureNotify: | |
1014 f = x_any_window_to_frame (d, x_event->xconfigure.window); | |
1015 break; | |
1016 | |
1017 default: | |
1018 f = x_any_window_to_frame (d, x_event->xany.window); | |
1019 break; | |
1020 } | |
1021 | |
1022 if (!f) | |
1023 return 0; | |
1024 | |
1025 emacs_event->event_type = magic_event; | |
1026 XSETFRAME (emacs_event->channel, f); | |
1027 memcpy ((char *) &emacs_event->event.magic.underlying_x_event, | |
1028 (char *) x_event, | |
1029 sizeof (XEvent)); | |
1030 break; | |
1031 } | 969 } |
1032 } | 970 } |
1033 return 1; | 971 return 1; |
1034 } | 972 } |
1035 | 973 |
1084 event->xfocus.window); | 1022 event->xfocus.window); |
1085 if (!f) | 1023 if (!f) |
1086 /* focus events are sometimes generated just before | 1024 /* focus events are sometimes generated just before |
1087 a frame is destroyed. */ | 1025 a frame is destroyed. */ |
1088 return; | 1026 return; |
1089 handle_focus_event_1 (f, event->xany.type == FocusIn); | 1027 handle_focus_event_1 (f, event->type == FocusIn); |
1090 } | 1028 } |
1091 | 1029 |
1092 static void | 1030 static void |
1093 handle_map_event (struct frame *f, XEvent *event) | 1031 handle_map_event (struct frame *f, XEvent *event) |
1094 { | 1032 { |
1095 Lisp_Object frame = Qnil; | 1033 Lisp_Object frame = Qnil; |
1096 | 1034 |
1097 XSETFRAME (frame, f); | 1035 XSETFRAME (frame, f); |
1098 if (event->xany.type == MapNotify) | 1036 if (event->type == MapNotify) |
1099 { | 1037 { |
1100 XWindowAttributes xwa; | 1038 XWindowAttributes xwa; |
1101 | 1039 |
1102 /* Bleagh!!!!!! Apparently some window managers (e.g. MWM) | 1040 /* Bleagh!!!!!! Apparently some window managers (e.g. MWM) |
1103 send synthetic MapNotify events when a window is first | 1041 send synthetic MapNotify events when a window is first |
1308 completely ignore all FocusIn/FocusOut events and depend only | 1246 completely ignore all FocusIn/FocusOut events and depend only |
1309 on notifications from the ExternalClient widget. */ | 1247 on notifications from the ExternalClient widget. */ |
1310 if (FRAME_X_EXTERNAL_WINDOW_P (f)) | 1248 if (FRAME_X_EXTERNAL_WINDOW_P (f)) |
1311 break; | 1249 break; |
1312 #endif | 1250 #endif |
1313 handle_focus_event_1 (f, event->xany.type == FocusIn); | 1251 handle_focus_event_1 (f, event->type == FocusIn); |
1314 break; | 1252 break; |
1315 | 1253 |
1316 case ClientMessage: | 1254 case ClientMessage: |
1317 handle_client_message (f, event); | 1255 handle_client_message (f, event); |
1318 break; | 1256 break; |
1319 | |
1320 #if 0 | |
1321 /* this is where we ought to be handling this event, but | |
1322 we don't see it here. --ben */ | |
1323 case MappingNotify: /* The user has run xmodmap */ | |
1324 #endif | |
1325 | 1257 |
1326 case VisibilityNotify: /* window visiblity has changed */ | 1258 case VisibilityNotify: /* window visiblity has changed */ |
1327 if (event->xvisibility.state == VisibilityUnobscured) | 1259 if (event->xvisibility.state == VisibilityUnobscured) |
1328 FRAME_X_TOTALLY_VISIBLE_P (f) = 1; | 1260 FRAME_X_TOTALLY_VISIBLE_P (f) = 1; |
1329 else | 1261 else |
1330 FRAME_X_TOTALLY_VISIBLE_P (f) = 0; | 1262 FRAME_X_TOTALLY_VISIBLE_P (f) = 0; |
1331 break; | 1263 break; |
1332 | 1264 |
1333 case ConfigureNotify: | 1265 case ConfigureNotify: |
1334 if (event->xconfigure.window != XtWindow (FRAME_X_SHELL_WIDGET (f))) | 1266 #ifdef HAVE_XIM |
1335 break; | 1267 XIC_SetGeometry (f); |
1336 FRAME_X_SHELL_WIDGET (f)->core.x = event->xconfigure.x; | 1268 #endif |
1337 FRAME_X_SHELL_WIDGET (f)->core.y = event->xconfigure.y; | 1269 /* ### If the following code fails to work, simply always call |
1270 x_smash_bastardly_shell_position always. In this case we no | |
1271 longer rely on the data in the events, merely on their | |
1272 occurrence. */ | |
1273 /* ### Well, actually we shouldn't have to ever call | |
1274 x_smash_bastardly_shell_position. We should just call | |
1275 XtTranslateCoordinates and only access the core.{x,y} fields | |
1276 using XtGetValue -- mrb */ | |
1277 { | |
1278 XConfigureEvent *ev = &event->xconfigure; | |
1279 if (ev->window == XtWindow (FRAME_X_SHELL_WIDGET (f)) && | |
1280 ! (ev->x == 0 && ev->y == 0 && !ev->send_event)) | |
1281 { | |
1282 FRAME_X_SHELL_WIDGET (f)->core.x = ev->x; | |
1283 FRAME_X_SHELL_WIDGET (f)->core.y = ev->y; | |
1284 } | |
1285 } | |
1338 break; | 1286 break; |
1339 | 1287 |
1340 default: | 1288 default: |
1341 break; | 1289 break; |
1342 } | 1290 } |
1757 static CONST char * | 1705 static CONST char * |
1758 XEvent_mode_to_string (int mode) | 1706 XEvent_mode_to_string (int mode) |
1759 { | 1707 { |
1760 switch (mode) | 1708 switch (mode) |
1761 { | 1709 { |
1762 case NotifyNormal: return "Normal"; | 1710 case NotifyNormal: return "Normal"; |
1763 case NotifyGrab: return "Grab"; | 1711 case NotifyGrab: return "Grab"; |
1764 case NotifyUngrab: return "Ungrab"; | 1712 case NotifyUngrab: return "Ungrab"; |
1765 case NotifyWhileGrabbed: return "WhileGrabbed"; | 1713 case NotifyWhileGrabbed: return "WhileGrabbed"; |
1766 default: | 1714 default: return "???"; |
1767 return "???"; | |
1768 } | 1715 } |
1769 } | 1716 } |
1770 | 1717 |
1771 static CONST char * | 1718 static CONST char * |
1772 XEvent_detail_to_string (int detail) | 1719 XEvent_detail_to_string (int detail) |
1773 { | 1720 { |
1774 switch (detail) | 1721 switch (detail) |
1775 { | 1722 { |
1776 case NotifyAncestor: return "Ancestor"; | 1723 case NotifyAncestor: return "Ancestor"; |
1777 case NotifyInferior: return "Inferior"; | 1724 case NotifyInferior: return "Inferior"; |
1778 case NotifyNonlinear: return "Nonlinear"; | 1725 case NotifyNonlinear: return "Nonlinear"; |
1779 case NotifyNonlinearVirtual: return "NonlinearVirtual"; | 1726 case NotifyNonlinearVirtual: return "NonlinearVirtual"; |
1780 case NotifyPointer: return "Pointer"; | 1727 case NotifyPointer: return "Pointer"; |
1781 case NotifyPointerRoot: return "PointerRoot"; | 1728 case NotifyPointerRoot: return "PointerRoot"; |
1782 case NotifyDetailNone: return "DetailNone"; | 1729 case NotifyDetailNone: return "DetailNone"; |
1783 default: | 1730 default: return "???"; |
1784 return "???"; | |
1785 } | 1731 } |
1786 } | 1732 } |
1787 | 1733 |
1788 static CONST char * | 1734 static CONST char * |
1789 XEvent_visibility_to_string (int state) | 1735 XEvent_visibility_to_string (int state) |
1790 { | 1736 { |
1791 switch (state) | 1737 switch (state) |
1792 { | 1738 { |
1793 case VisibilityFullyObscured: return "FullyObscured"; | 1739 case VisibilityFullyObscured: return "FullyObscured"; |
1794 case VisibilityPartiallyObscured: return "PartiallyObscured"; | 1740 case VisibilityPartiallyObscured: return "PartiallyObscured"; |
1795 case VisibilityUnobscured: return "Unobscured"; | 1741 case VisibilityUnobscured: return "Unobscured"; |
1796 default: | 1742 default: return "???"; |
1797 return "???"; | |
1798 } | 1743 } |
1799 } | 1744 } |
1800 | 1745 |
1801 static void | 1746 static void |
1802 describe_event (XEvent *event) | 1747 describe_event (XEvent *event) |
1852 stderr_out (" Modifier key"); | 1797 stderr_out (" Modifier key"); |
1853 stderr_out (" keycode: 0x%x\n", ev->keycode); | 1798 stderr_out (" keycode: 0x%x\n", ev->keycode); |
1854 keysym = x_to_emacs_keysym (event, 0); | 1799 keysym = x_to_emacs_keysym (event, 0); |
1855 if (CHAR_OR_CHAR_INTP (keysym)) | 1800 if (CHAR_OR_CHAR_INTP (keysym)) |
1856 { | 1801 { |
1857 if (XCHAR_OR_CHAR_INT (keysym) > 32 | 1802 Emchar c = XCHAR_OR_CHAR_INT (keysym); |
1858 && XCHAR_OR_CHAR_INT (keysym) < 127) | 1803 if (c > 32 && c < 127) |
1859 stderr_out (" keysym: %c\n", XCHAR_OR_CHAR_INT (keysym)); | 1804 stderr_out (" keysym: %c\n", c); |
1860 else | 1805 else |
1861 stderr_out (" keysym: %d\n", XCHAR_OR_CHAR_INT (keysym)); | 1806 stderr_out (" keysym: %d\n", c); |
1862 } | 1807 } |
1863 else | 1808 else |
1864 stderr_out (" keysym: %s\n", string_data (XSYMBOL (keysym)->name)); | 1809 stderr_out (" keysym: %s\n", string_data (XSYMBOL (keysym)->name)); |
1865 } | 1810 } |
1866 break; | 1811 break; |
1868 case Expose: | 1813 case Expose: |
1869 if (x_debug_events > 1) | 1814 if (x_debug_events > 1) |
1870 { | 1815 { |
1871 XExposeEvent *ev = &event->xexpose; | 1816 XExposeEvent *ev = &event->xexpose; |
1872 describe_event_window (ev->window, ev->display); | 1817 describe_event_window (ev->window, ev->display); |
1873 stderr_out (" region: %d %d %d %d\n", ev->x, ev->y, | 1818 stderr_out (" region: x=%d y=%d width=%d height=%d\n", |
1874 ev->width, ev->height); | 1819 ev->x, ev->y, ev->width, ev->height); |
1875 stderr_out (" count: %d\n", ev->count); | 1820 stderr_out (" count: %d\n", ev->count); |
1876 } | 1821 } |
1877 else | 1822 else |
1878 stderr_out ("\n"); | 1823 stderr_out ("\n"); |
1879 break; | 1824 break; |
1884 XGraphicsExposeEvent *ev = &event->xgraphicsexpose; | 1829 XGraphicsExposeEvent *ev = &event->xgraphicsexpose; |
1885 describe_event_window (ev->drawable, ev->display); | 1830 describe_event_window (ev->drawable, ev->display); |
1886 stderr_out (" major: %s\n", | 1831 stderr_out (" major: %s\n", |
1887 (ev ->major_code == X_CopyArea ? "CopyArea" : | 1832 (ev ->major_code == X_CopyArea ? "CopyArea" : |
1888 (ev->major_code == X_CopyPlane ? "CopyPlane" : "?"))); | 1833 (ev->major_code == X_CopyPlane ? "CopyPlane" : "?"))); |
1889 stderr_out (" region: %d %d %d %d\n", ev->x, ev->y, | 1834 stderr_out (" region: x=%d y=%d width=%d height=%d\n", |
1890 ev->width, ev->height); | 1835 ev->x, ev->y, ev->width, ev->height); |
1891 stderr_out (" count: %d\n", ev->count); | 1836 stderr_out (" count: %d\n", ev->count); |
1892 } | 1837 } |
1893 else | 1838 else |
1894 stderr_out ("\n"); | 1839 stderr_out ("\n"); |
1895 break; | 1840 break; |
2014 emacs_Xt_next_event (struct Lisp_Event *emacs_event) | 1959 emacs_Xt_next_event (struct Lisp_Event *emacs_event) |
2015 { | 1960 { |
2016 we_didnt_get_an_event: | 1961 we_didnt_get_an_event: |
2017 | 1962 |
2018 while (NILP (dispatch_event_queue) && | 1963 while (NILP (dispatch_event_queue) && |
2019 !completed_timeouts && | 1964 !completed_timeouts && |
2020 !fake_event_occurred && | 1965 !fake_event_occurred && |
2021 !process_events_occurred && | 1966 !process_events_occurred && |
2022 !tty_events_occurred) | 1967 !tty_events_occurred) |
2023 { | 1968 { |
2024 | 1969 |
2025 /* Stupid logic in XtAppProcessEvent() dictates that, if process | 1970 /* Stupid logic in XtAppProcessEvent() dictates that, if process |
2026 events and X events are both available, the process event gets | 1971 events and X events are both available, the process event gets |