diff options
| author | Jess VanDerwalker <washu@sonic.net> | 2012-08-10 10:42:38 -0700 | 
|---|---|---|
| committer | Jess VanDerwalker <washu@sonic.net> | 2012-08-29 09:15:52 -0700 | 
| commit | c91cbdc819e0849673233d27a2e8cbbde0797edb (patch) | |
| tree | ceaa8af9c6879f223d4174f3e7e24134098ad127 | |
| parent | 01b15ed290db6a8ae3d06a44b67ead55ad8076f6 (diff) | |
libxcwm: Building and setting modifier keymap.
Modifer keymap is built in XtoQBuildModifierMaps() taking advantage of
existing logic to determine keysyms in key map.
Call to xcb_set_modifier_mapping() added to set mapping of modifiers.
Signed-off-by: Jess VanDerwalker <washu@sonic.net>
Reviewed-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
| -rw-r--r-- | src/xtoq/keymap.c | 97 | 
1 files changed, 90 insertions, 7 deletions
diff --git a/src/xtoq/keymap.c b/src/xtoq/keymap.c index 65c53d7..a8bccf3 100644 --- a/src/xtoq/keymap.c +++ b/src/xtoq/keymap.c @@ -51,7 +51,6 @@  #include <assert.h> -/* FIXME: Use xcb instead */  #include <xcb/xcb.h>  #include <X11/X.h>  #include <X11/keysym.h> @@ -71,6 +70,22 @@  #define MIN_KEYCODE    XkbMinLegalKeyCode      // unfortunately, this isn't 0...  #define MAX_KEYCODE    NUM_KEYCODES + MIN_KEYCODE - 1 +/* Number of keys per modifier and number of modifiers */ +#define KEYS_PER_MODIFIER 2     /* Only allow 2 keys for each modifier */ +#define NUM_MODIFIERS 8         /* Total number of modifers: shift, +                                 * lock, control, mod1, mod2, mod3, +                                 * mod4, mod5 */ +/* Offsets into the modKeymap array. Use: offset * KEYS_PER_MODIFIER + * to get the position in the array for modifier key */ +#define SHIFT_MOD_OFFSET 0 +#define LOCK_MOD_OFFSET 1 +#define CTRL_MOD_OFFSET 2 +#define MOD1_MOD_OFFSET 3 +#define MOD2_MOD_OFFSET 4 +#define MOD3_MOD_OFFSET 5 +#define MOD4_MOD_OFFSET 6 +#define MOD5_MOD_OFFSET 7 +  // FIXME: Don't rely on this  #define MAP_LENGTH 256 @@ -195,6 +210,7 @@ typedef struct XtoQKeymapInfo_struct {      char modMap[MAP_LENGTH];      xcb_keysym_t keyMap[MAP_LENGTH * GLYPHS_PER_KEY];      unsigned char modifierKeycodes[32][2]; +    xcb_keycode_t modKeymap[KEYS_PER_MODIFIER * NUM_MODIFIERS];  } XtoQKeymapInfo;  XtoQKeymapInfo keyInfo; @@ -217,9 +233,18 @@ XtoQBuildModifierMaps(XtoQKeymapInfo *info)  {      int i;      xcb_keysym_t *k; +    /* Counters used to build modKeymap and make sure we only put +     * KEYS_PER_MODIFIER number of keys in each spot */ +    int shift_cnt = 0; +    int lock_cnt = 0; +    int ctrl_cnt = 0; +    int mod1_cnt = 0; +    int mod2_cnt = 0; +    int mod3_cnt = 0;      memset(info->modMap, NoSymbol, sizeof(info->modMap));      memset(info->modifierKeycodes, 0, sizeof(info->modifierKeycodes)); +    memset(info->modKeymap, 0, sizeof(info->modKeymap));      for (i = 0; i < NUM_KEYCODES; i++) {          k = info->keyMap + i * GLYPHS_PER_KEY; @@ -228,6 +253,11 @@ XtoQBuildModifierMaps(XtoQKeymapInfo *info)          case XK_Shift_L:              info->modifierKeycodes[NX_MODIFIERKEY_SHIFT][0] = i;              info->modMap[MIN_KEYCODE + i] = ShiftMask; +            if (shift_cnt < KEYS_PER_MODIFIER) { +                info->modKeymap[SHIFT_MOD_OFFSET * KEYS_PER_MODIFIER + shift_cnt] +                    = MIN_KEYCODE + i; +                shift_cnt++; +            }              break;          case XK_Shift_R: @@ -237,11 +267,21 @@ XtoQBuildModifierMaps(XtoQKeymapInfo *info)              info->modifierKeycodes[NX_MODIFIERKEY_SHIFT][0] = i;  #endif              info->modMap[MIN_KEYCODE + i] = ShiftMask; +            if (shift_cnt < KEYS_PER_MODIFIER) { +                info->modKeymap[SHIFT_MOD_OFFSET * KEYS_PER_MODIFIER + shift_cnt] +                    = MIN_KEYCODE + i; +                shift_cnt++; +            }              break;          case XK_Control_L:              info->modifierKeycodes[NX_MODIFIERKEY_CONTROL][0] = i;              info->modMap[MIN_KEYCODE + i] = ControlMask; +            if (ctrl_cnt < KEYS_PER_MODIFIER) { +                info->modKeymap[CTRL_MOD_OFFSET * KEYS_PER_MODIFIER + ctrl_cnt] +                    = MIN_KEYCODE + i; +                ctrl_cnt++; +            }              break;          case XK_Control_R: @@ -251,11 +291,21 @@ XtoQBuildModifierMaps(XtoQKeymapInfo *info)              info->modifierKeycodes[NX_MODIFIERKEY_CONTROL][0] = i;  #endif              info->modMap[MIN_KEYCODE + i] = ControlMask; +            if (ctrl_cnt < KEYS_PER_MODIFIER) { +                info->modKeymap[CTRL_MOD_OFFSET * KEYS_PER_MODIFIER + ctrl_cnt] +                    = MIN_KEYCODE + i; +                ctrl_cnt++; +            }              break;          case XK_Caps_Lock:              info->modifierKeycodes[NX_MODIFIERKEY_ALPHALOCK][0] = i;              info->modMap[MIN_KEYCODE + i] = LockMask; +            if (lock_cnt < KEYS_PER_MODIFIER) { +                info->modKeymap[LOCK_MOD_OFFSET * KEYS_PER_MODIFIER + lock_cnt] +                    = MIN_KEYCODE + i; +                lock_cnt++; +            }              break;          case XK_Alt_L: @@ -266,6 +316,11 @@ XtoQBuildModifierMaps(XtoQKeymapInfo *info)              if (!XQuartzOptionSendsAlt)                  *k = XK_Mode_switch;     // Yes, this is ugly.  This needs to be cleaned up when we integrate quartzKeyboard with this code and refactor.  #endif +            if (mod1_cnt < KEYS_PER_MODIFIER) { +                info->modKeymap[MOD1_MOD_OFFSET * KEYS_PER_MODIFIER + mod1_cnt] +                    = MIN_KEYCODE + i; +                mod1_cnt++; +            }              break;          case XK_Alt_R: @@ -280,7 +335,11 @@ XtoQBuildModifierMaps(XtoQKeymapInfo *info)                  *k = XK_Mode_switch;     // Yes, this is ugly.  This needs to be cleaned up when we integrate quartzKeyboard with this code and refactor.  #endif              info->modMap[MIN_KEYCODE + i] = Mod1Mask; -            break; +            if (mod1_cnt < KEYS_PER_MODIFIER) { +                info->modKeymap[MOD1_MOD_OFFSET * KEYS_PER_MODIFIER + mod1_cnt] +                    = MIN_KEYCODE + i; +                mod1_cnt++; +            }            break;          case XK_Mode_switch:              ErrorF( @@ -295,6 +354,11 @@ XtoQBuildModifierMaps(XtoQKeymapInfo *info)          case XK_Meta_L:              info->modifierKeycodes[NX_MODIFIERKEY_COMMAND][0] = i;              info->modMap[MIN_KEYCODE + i] = Mod2Mask; +            if (mod2_cnt < KEYS_PER_MODIFIER) { +                info->modKeymap[MOD2_MOD_OFFSET * KEYS_PER_MODIFIER + mod2_cnt] +                    = MIN_KEYCODE + i; +                mod2_cnt++; +            }              break;          case XK_Meta_R: @@ -304,10 +368,20 @@ XtoQBuildModifierMaps(XtoQKeymapInfo *info)              info->modifierKeycodes[NX_MODIFIERKEY_COMMAND][0] = i;  #endif              info->modMap[MIN_KEYCODE + i] = Mod2Mask; +            if (mod2_cnt < KEYS_PER_MODIFIER) { +                info->modKeymap[MOD2_MOD_OFFSET * KEYS_PER_MODIFIER + mod2_cnt] +                    = MIN_KEYCODE + i; +                mod2_cnt++; +            }              break;          case XK_Num_Lock:              info->modMap[MIN_KEYCODE + i] = Mod3Mask; +            if (mod3_cnt < KEYS_PER_MODIFIER) { +                info->modKeymap[MOD3_MOD_OFFSET * KEYS_PER_MODIFIER + mod3_cnt] +                    = MIN_KEYCODE + i; +                mod3_cnt++; +            }              break;          }      } @@ -406,16 +480,14 @@ XtoQKeyboardReloadHandler(xcb_connection_t *conn)          keyRepeatValue = 6; -    //FIXME: Use Xi's ChangeDeviceKeyMapping (note that this won't handle modMap). -    //       modMap needs to be sent using the core SetModifierMapping request, -    //       and it probably needs to be in a different format than it is currently. -    //FIXME: Disabled XtoQKeyboardSetRepeat(darwinKeyboard, initialKeyRepeatValue, keyRepeatValue) -      /* FIXME: Set the keymap through XCB call. Once this is and       * modifier mapping is working, this will be replaced by call to       * xcwm */      xcb_void_cookie_t cookie;      xcb_generic_error_t *error; +    xcb_set_modifier_mapping_cookie_t map_cookie; +    xcb_set_modifier_mapping_reply_t *map_reply; +          cookie = xcb_change_keyboard_mapping_checked(conn,                                                   NUM_KEYCODES,                                                   MIN_KEYCODE, @@ -427,6 +499,17 @@ XtoQKeyboardReloadHandler(xcb_connection_t *conn)          fprintf(stderr, "ERROR: Failed to change keyboard mapping");          fprintf(stderr, "\nError code: %d\n", error->error_code);      } + +    /* Set the modifier mapping */ +    map_cookie = xcb_set_modifier_mapping(conn, +                                          KEYS_PER_MODIFIER, +                                          keyInfo.modKeymap); +    map_reply = xcb_set_modifier_mapping_reply(conn, map_cookie, &error); +    if (error) { +        fprintf(stderr, "ERROR: Failed to change keyboard modifier mapping"); +        fprintf(stderr, "\nError code: %d\n", error->error_code); +    } +    free(map_reply);      xcb_flush(conn);  #if 0 /* FIXME: Don't worry about xmodmap until we're done with everything else */  | 
