1 #define Uses_SCIM_EVENT
4 #include <X11/keysym.h>
7 #include "scim_private.h"
9 #include "scim_x11_utils.h"
13 static Time get_time (void);
14 static void initialize_modifier_bits (Display *display);
16 static Display *__current_display = 0;
17 static int __current_alt_mask = Mod1Mask;
18 static int __current_meta_mask = 0;
19 static int __current_super_mask = 0;
20 static int __current_hyper_mask = 0;
21 static int __current_numlock_mask = Mod2Mask;
28 struct timezone tz; /* is not used since ages */
29 gettimeofday (&tv, &tz);
30 tint = (int) tv.tv_sec * 1000;
31 tint = tint / 1000 * 1000;
32 tint = tint + tv.tv_usec / 1000;
37 initialize_modifier_bits (Display *display)
39 if (__current_display == display)
42 __current_display = display;
45 __current_alt_mask = Mod1Mask;
46 __current_meta_mask = ShiftMask | Mod1Mask;
47 __current_super_mask = 0;
48 __current_hyper_mask = 0;
49 __current_numlock_mask = Mod2Mask;
53 XModifierKeymap *mods;
55 ::KeyCode ctrl_l = XKeysymToKeycode (display, XK_Control_L);
56 ::KeyCode ctrl_r = XKeysymToKeycode (display, XK_Control_R);
57 ::KeyCode meta_l = XKeysymToKeycode (display, XK_Meta_L);
58 ::KeyCode meta_r = XKeysymToKeycode (display, XK_Meta_R);
59 ::KeyCode alt_l = XKeysymToKeycode (display, XK_Alt_L);
60 ::KeyCode alt_r = XKeysymToKeycode (display, XK_Alt_R);
61 ::KeyCode super_l = XKeysymToKeycode (display, XK_Super_L);
62 ::KeyCode super_r = XKeysymToKeycode (display, XK_Super_R);
63 ::KeyCode hyper_l = XKeysymToKeycode (display, XK_Hyper_L);
64 ::KeyCode hyper_r = XKeysymToKeycode (display, XK_Hyper_R);
65 ::KeyCode numlock = XKeysymToKeycode (display, XK_Num_Lock);
69 mods = XGetModifierMapping (display);
71 __current_alt_mask = 0;
72 __current_meta_mask = 0;
73 __current_super_mask = 0;
74 __current_hyper_mask = 0;
75 __current_numlock_mask = 0;
77 /* We skip the first three sets for Shift, Lock, and Control. The
78 remaining sets are for Mod1, Mod2, Mod3, Mod4, and Mod5. */
79 for (i = 3; i < 8; i++) {
80 for (j = 0; j < mods->max_keypermod; j++) {
81 ::KeyCode code = mods->modifiermap [i * mods->max_keypermod + j];
83 if (code == alt_l || code == alt_r)
84 __current_alt_mask |= (1 << i);
85 else if (code == meta_l || code == meta_r)
86 __current_meta_mask |= (1 << i);
87 else if (code == super_l || code == super_r)
88 __current_super_mask |= (1 << i);
89 else if (code == hyper_l || code == hyper_r)
90 __current_hyper_mask |= (1 << i);
91 else if (code == numlock)
92 __current_numlock_mask |= (1 << i);
96 /* Check whether there is a combine keys mapped to Meta */
97 if (__current_meta_mask == 0) {
100 KeySym keysym_l, keysym_r;
102 xkey.type = KeyPress;
103 xkey.display = display;
105 xkey.send_event = False;
106 xkey.x = xkey.y = xkey.x_root = xkey.y_root = 0;
108 xkey.same_screen = False;
109 xkey.subwindow = None;
111 xkey.root = DefaultRootWindow (display);
112 xkey.state = ShiftMask;
114 xkey.keycode = meta_l;
115 XLookupString (&xkey, buf, 32, &keysym_l, 0);
116 xkey.keycode = meta_r;
117 XLookupString (&xkey, buf, 32, &keysym_r, 0);
119 if ((meta_l == alt_l && keysym_l == XK_Meta_L) || (meta_r == alt_r && keysym_r == XK_Meta_R))
120 __current_meta_mask = ShiftMask + __current_alt_mask;
121 else if ((meta_l == ctrl_l && keysym_l == XK_Meta_L) || (meta_r == ctrl_r && keysym_r == XK_Meta_R))
122 __current_meta_mask = ShiftMask + ControlMask;
125 XFreeModifiermap (mods);
129 scim_x11_keyevent_x11_to_scim (Display *display, const XKeyEvent &xkey)
133 XKeyEvent key = xkey;
136 initialize_modifier_bits (display);
138 XLookupString (&key, buf, 32, &keysym, 0);
140 scimkey.code = keysym;
142 scimkey.mask = scim_x11_keymask_x11_to_scim (display, xkey.state);
144 if (key.type == KeyRelease) scimkey.mask |= SCIM_KEY_ReleaseMask;
146 if (scimkey.code == SCIM_KEY_backslash) {
148 KeySym *keysyms = XGetKeyboardMapping (display, xkey.keycode, 1, &keysym_size);
149 if (keysyms != NULL) {
150 if (keysyms[0] == XK_backslash &&
151 (keysym_size > 1 && keysyms[1] == XK_underscore))
152 scimkey.mask |= SCIM_KEY_QuirkKanaRoMask;
161 scim_x11_keyevent_scim_to_x11 (Display *display, const KeyEvent &scimkey)
165 initialize_modifier_bits (display);
167 xkey.type = (scimkey.mask & SCIM_KEY_ReleaseMask) ? KeyRelease : KeyPress;
168 xkey.display = display;
170 xkey.send_event = False;
171 xkey.x = xkey.y = xkey.x_root = xkey.y_root = 0;
172 xkey.time = get_time ();
173 xkey.same_screen = False;
174 xkey.subwindow = None;
178 xkey.root = DefaultRootWindow (display);
179 xkey.keycode = XKeysymToKeycode (display, (KeySym) scimkey.code);
185 xkey.state = scim_x11_keymask_scim_to_x11 (display, scimkey.mask);
191 scim_x11_keymask_x11_to_scim (Display *display, unsigned int xkeystate)
195 initialize_modifier_bits (display);
197 // Check Meta mask first, because it's maybe a mask combination.
198 if (__current_meta_mask && (xkeystate & __current_meta_mask) == __current_meta_mask) {
199 mask |= SCIM_KEY_MetaMask;
200 xkeystate &= ~__current_meta_mask;
203 if (xkeystate & ShiftMask) {
204 mask |= SCIM_KEY_ShiftMask;
205 xkeystate &= ~ShiftMask;
208 if (xkeystate & LockMask) {
209 mask |= SCIM_KEY_CapsLockMask;
210 xkeystate &= ~LockMask;
213 if (xkeystate & ControlMask) {
214 mask |= SCIM_KEY_ControlMask;
215 xkeystate &= ~ControlMask;
218 if (__current_alt_mask && (xkeystate & __current_alt_mask) == __current_alt_mask) {
219 mask |= SCIM_KEY_AltMask;
220 xkeystate &= ~__current_alt_mask;
223 if (__current_super_mask && (xkeystate & __current_super_mask) == __current_super_mask) {
224 mask |= SCIM_KEY_SuperMask;
225 xkeystate &= ~__current_super_mask;
228 if (__current_hyper_mask && (xkeystate & __current_hyper_mask) == __current_hyper_mask) {
229 mask |= SCIM_KEY_HyperMask;
230 xkeystate &= ~__current_hyper_mask;
233 if (__current_numlock_mask && (xkeystate & __current_numlock_mask) == __current_numlock_mask) {
234 mask |= SCIM_KEY_NumLockMask;
240 unsigned int scim_x11_keymask_scim_to_x11 (Display *display, uint16 scimkeymask)
242 unsigned int state = 0;
244 initialize_modifier_bits (display);
246 if (scimkeymask & SCIM_KEY_ShiftMask) state |= ShiftMask;
247 if (scimkeymask & SCIM_KEY_CapsLockMask) state |= LockMask;
248 if (scimkeymask & SCIM_KEY_ControlMask) state |= ControlMask;
249 if (scimkeymask & SCIM_KEY_AltMask) state |= __current_alt_mask;
250 if (scimkeymask & SCIM_KEY_MetaMask) state |= __current_meta_mask;
251 if (scimkeymask & SCIM_KEY_SuperMask) state |= __current_super_mask;
252 if (scimkeymask & SCIM_KEY_HyperMask) state |= __current_hyper_mask;
253 if (scimkeymask & SCIM_KEY_NumLockMask) state |= __current_numlock_mask;