Mercurial > hg > xemacs-beta
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); |