comparison src/event-Xt.c @ 5559:f3ab0c29c246

Use a better, more portable approach to the shift-F11 problem. src/ChangeLog addition: 2011-08-28 Aidan Kehoe <kehoea@parhasard.net> * event-Xt.c (x_to_emacs_keysym): Take a new pointer argument, X_KEYSYM_OUT, where we store the X11 keysym that we actually used. * event-Xt.c (x_event_to_emacs_event): Call x_to_emacs_keysym with its new pointer argument, so we have access to the X11 keysym used. When checking whether a keysym obeys caps lock, use the X11 keysym rather than the XEmacs keysym. When checking whether a key has two distinct keysyms depending on whether shift is pressed or not, use the X11 keysym passed back by x_to_emacs_keysym rather than working it out again using XLookupKeysym(). * event-Xt.c (keysym_obeys_caps_lock_p): Use XConvertCase() in this function, now we're receiving the actual X keysym used.
author Aidan Kehoe <kehoea@parhasard.net>
date Sun, 28 Aug 2011 10:34:54 +0100
parents 10455659ab64
children 56144c8593a8
comparison
equal deleted inserted replaced
5558:10455659ab64 5559:f3ab0c29c246
693 693
694 static int 694 static int
695 keysym_obeys_caps_lock_p (KeySym sym, struct device *d) 695 keysym_obeys_caps_lock_p (KeySym sym, struct device *d)
696 { 696 {
697 struct x_device *xd = DEVICE_X_DATA (d); 697 struct x_device *xd = DEVICE_X_DATA (d);
698 KeySym upper, lower;
698 /* Eeeeevil hack. Don't apply Caps_Lock to things that aren't alphabetic 699 /* Eeeeevil hack. Don't apply Caps_Lock to things that aren't alphabetic
699 characters, where "alphabetic" means something more than simply A-Z. 700 characters, where "alphabetic" means something more than simply A-Z.
700 That is, if Caps_Lock is down, typing ESC doesn't produce Shift-ESC. 701 That is, if Caps_Lock is down, typing ESC doesn't produce Shift-ESC.
701 But if shift-lock is down, then it does. */ 702 But if shift-lock is down, then it does. */
702 if (xd->lock_interpretation == XK_Shift_Lock) 703 if (xd->lock_interpretation == XK_Shift_Lock)
703 return 1; 704 return 1;
704 705
705 return 706 XConvertCase (sym, &lower, &upper);
706 ((sym >= XK_A) && (sym <= XK_Z)) || 707
707 ((sym >= XK_a) && (sym <= XK_z)) || 708 return !(sym == lower && sym == upper);
708 ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis)) ||
709 ((sym >= XK_agrave) && (sym <= XK_odiaeresis)) ||
710 ((sym >= XK_Ooblique) && (sym <= XK_Thorn)) ||
711 ((sym >= XK_oslash) && (sym <= XK_thorn));
712 } 709 }
713 710
714 /* called from EmacsFrame.c (actually from Xt itself) when a 711 /* called from EmacsFrame.c (actually from Xt itself) when a
715 MappingNotify event is received. In its infinite wisdom, Xt 712 MappingNotify event is received. In its infinite wisdom, Xt
716 decided that Xt event handlers never get MappingNotify events. 713 decided that Xt event handlers never get MappingNotify events.
838 return KEYSYM ((const CIbyte *) eidata (einame)); 835 return KEYSYM ((const CIbyte *) eidata (einame));
839 } 836 }
840 } 837 }
841 838
842 static Lisp_Object 839 static Lisp_Object
843 x_to_emacs_keysym (XKeyPressedEvent *event, int simple_p) 840 x_to_emacs_keysym (XKeyPressedEvent *event, int simple_p, KeySym *x_keysym_out)
844 /* simple_p means don't try too hard (ASCII only) */ 841 /* simple_p means don't try too hard (ASCII only) */
845 { 842 {
846 KeySym keysym = 0; 843 KeySym keysym = NoSymbol;
847 844
848 #ifdef HAVE_XIM 845 #ifdef HAVE_XIM
849 int len = 0; 846 int len = 0;
850 /* Some implementations of XmbLookupString don't return 847 /* Some implementations of XmbLookupString don't return
851 XBufferOverflow correctly, so increase the size of the xim input 848 XBufferOverflow correctly, so increase the size of the xim input
860 (get_device_from_display (event->display), 857 (get_device_from_display (event->display),
861 event->window)); 858 event->window));
862 #endif /* XIM_XLIB */ 859 #endif /* XIM_XLIB */
863 #endif /* HAVE_XIM */ 860 #endif /* HAVE_XIM */
864 861
862 *x_keysym_out = NoSymbol;
863
865 /* We use XLookupString if we're not using XIM, or are using 864 /* We use XLookupString if we're not using XIM, or are using
866 XIM_XLIB but input context creation failed. */ 865 XIM_XLIB but input context creation failed. */
867 #if ! (defined (HAVE_XIM) && defined (XIM_MOTIF)) 866 #if ! (defined (HAVE_XIM) && defined (XIM_MOTIF))
868 #if defined (HAVE_XIM) && defined (XIM_XLIB) 867 #if defined (HAVE_XIM) && defined (XIM_XLIB)
869 if (!xic) 868 if (!xic)
871 { 870 {
872 /* Apparently it's necessary to specify a dummy here (rather 871 /* Apparently it's necessary to specify a dummy here (rather
873 than passing in 0) to avoid crashes on German IRIX */ 872 than passing in 0) to avoid crashes on German IRIX */
874 char dummy[256]; 873 char dummy[256];
875 XLookupString (event, dummy, 200, &keysym, 0); 874 XLookupString (event, dummy, 200, &keysym, 0);
875 *x_keysym_out = keysym;
876 return (IsModifierKey (keysym) || keysym == XK_Mode_switch ) 876 return (IsModifierKey (keysym) || keysym == XK_Mode_switch )
877 ? Qnil : x_keysym_to_emacs_keysym (keysym, simple_p); 877 ? Qnil : x_keysym_to_emacs_keysym (keysym, simple_p);
878 } 878 }
879 #endif /* ! XIM_MOTIF */ 879 #endif /* ! XIM_MOTIF */
880 880
931 931
932 switch (status) 932 switch (status)
933 { 933 {
934 case XLookupKeySym: 934 case XLookupKeySym:
935 case XLookupBoth: 935 case XLookupBoth:
936 *x_keysym_out = keysym;
936 return (IsModifierKey (keysym) || keysym == XK_Mode_switch ) 937 return (IsModifierKey (keysym) || keysym == XK_Mode_switch )
937 ? Qnil : x_keysym_to_emacs_keysym (keysym, simple_p); 938 ? Qnil : x_keysym_to_emacs_keysym (keysym, simple_p);
938 939
939 case XLookupChars: 940 case XLookupChars:
940 { 941 {
1112 1113
1113 if (key_event_p) 1114 if (key_event_p)
1114 { 1115 {
1115 Lisp_Object keysym; 1116 Lisp_Object keysym;
1116 XKeyEvent *ev = &x_event->xkey; 1117 XKeyEvent *ev = &x_event->xkey;
1118 KeySym x_keysym = NoSymbol;
1117 /* This used to compute the frame from the given X window and 1119 /* This used to compute the frame from the given X window and
1118 store it here, but we really don't care about the frame. */ 1120 store it here, but we really don't care about the frame. */
1119 SET_EVENT_CHANNEL (emacs_event, DEVICE_CONSOLE (d)); 1121 SET_EVENT_CHANNEL (emacs_event, DEVICE_CONSOLE (d));
1120 keysym = x_to_emacs_keysym (&x_event->xkey, 0); 1122 keysym = x_to_emacs_keysym (&x_event->xkey, 0, &x_keysym);
1121 1123
1122 /* If the emacs keysym is nil, then that means that the X 1124 /* If the emacs keysym is nil, then that means that the X
1123 keysym was either a Modifier or NoSymbol, which 1125 keysym was either a Modifier or NoSymbol, which
1124 probably means that we're in the midst of reading a 1126 probably means that we're in the midst of reading a
1125 Multi_key sequence, or a "dead" key prefix, or XIM 1127 Multi_key sequence, or a "dead" key prefix, or XIM
1190 related characters). So at this point (after looking up 1192 related characters). So at this point (after looking up
1191 the keysym) if the keysym isn't a dual-case alphabetic, 1193 the keysym) if the keysym isn't a dual-case alphabetic,
1192 and if the caps lock key was down but the shift key 1194 and if the caps lock key was down but the shift key
1193 wasn't, then turn off the shift modifier. Gag barf */ 1195 wasn't, then turn off the shift modifier. Gag barf */
1194 1196
1195 /* #### type lossage: assuming equivalence of emacs and
1196 X keysyms
1197
1198 The right thing to do here is to have pass a third, pointer,
1199 argument to x_to_emacs_keysym, where it should store the
1200 intermediate KeySym it used to calculate the string XEmacs
1201 keysym. Then we can call keysym_obeys_caps_lock_p with
1202 exactly the right argument. */
1203
1204 /* !!#### maybe fix for Mule
1205
1206 Hard, in the absence of a full case infrastructure for
1207 Mule characters. When
1208 (downcase (make-char 'cyrillic-iso8859-5 73))
1209 works, we should revisit it. */
1210
1211 if (lock_p && !shift_p && 1197 if (lock_p && !shift_p &&
1212 ! (CHAR_OR_CHAR_INTP (keysym) 1198 ! (x_keysym && keysym_obeys_caps_lock_p (x_keysym, d)))
1213 && keysym_obeys_caps_lock_p
1214 ((KeySym) XCHAR_OR_CHAR_INT (keysym), d)))
1215 modifiers &= (~XEMACS_MOD_SHIFT); 1199 modifiers &= (~XEMACS_MOD_SHIFT);
1216 1200
1217 /* If this key contains two distinct keysyms, that is, 1201 /* If this key contains two distinct keysyms, that is,
1218 "shift" generates a different keysym than the 1202 "shift" generates a different keysym than the
1219 non-shifted key, then don't apply the shift modifier 1203 non-shifted key, then don't apply the shift modifier
1227 1211
1228 if (modifiers & XEMACS_MOD_SHIFT) 1212 if (modifiers & XEMACS_MOD_SHIFT)
1229 { 1213 {
1230 int Mode_switch_p = *state & xd->ModeMask; 1214 int Mode_switch_p = *state & xd->ModeMask;
1231 KeySym bot = XLookupKeysym (ev, Mode_switch_p ? 2 : 0); 1215 KeySym bot = XLookupKeysym (ev, Mode_switch_p ? 2 : 0);
1232 KeySym top = XLookupKeysym (ev, Mode_switch_p ? 3 : 1); 1216 if (x_keysym && bot && x_keysym != bot)
1233 if (top && bot && top != bot)
1234 modifiers &= ~XEMACS_MOD_SHIFT; 1217 modifiers &= ~XEMACS_MOD_SHIFT;
1235 } 1218 }
1236 set_event_type (emacs_event, key_press_event); 1219 set_event_type (emacs_event, key_press_event);
1237 SET_EVENT_TIMESTAMP (emacs_event, ev->time); 1220 SET_EVENT_TIMESTAMP (emacs_event, ev->time);
1238 SET_EVENT_KEY_MODIFIERS (emacs_event, modifiers); 1221 SET_EVENT_KEY_MODIFIERS (emacs_event, modifiers);