summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Huddleston <jeremyhu@freedesktop.org>2009-09-28 17:05:29 -0700
committerJeremy Huddleston <jeremyhu@freedesktop.org>2009-10-01 23:34:23 -0700
commitb6016134b53587b8f942243d95729bb902c58db4 (patch)
tree2d771a9705fb9044a20d96ceded5de139f193ab5
parent3808ecc99a8d64cdbe3fb4a3b57c59e7545e362c (diff)
XQuartz: Set the proper bitmap for key repeats...
XkbSetRepeatKeys lies and doesn't do what it says it will... (cherry picked from commits b9dfed9e88389cbd29406a20d38ee4297638649b and 873467adad479be02cd9cc6b43685919f5612d91)
-rw-r--r--hw/xquartz/quartzKeyboard.c147
1 files changed, 86 insertions, 61 deletions
diff --git a/hw/xquartz/quartzKeyboard.c b/hw/xquartz/quartzKeyboard.c
index d36d967a2..06b981e02 100644
--- a/hw/xquartz/quartzKeyboard.c
+++ b/hw/xquartz/quartzKeyboard.c
@@ -280,98 +280,123 @@ static void DarwinBuildModifierMaps(darwinKeyboardInfo *info) {
}
/*
- * DarwinLoadKeyboardMapping
- * Load the keyboard map from a file or system and convert
- * it to an equivalent X keyboard map and modifier map.
- */
-static void DarwinLoadKeyboardMapping(KeySymsRec *keySyms) {
- DarwinBuildModifierMaps(&keyInfo);
-
- keySyms->map = keyInfo.keyMap;
- keySyms->mapWidth = GLYPHS_PER_KEY;
- keySyms->minKeyCode = MIN_KEYCODE;
- keySyms->maxKeyCode = MAX_KEYCODE;
-}
-
-/*
- * DarwinKeyboardSetDeviceKeyMap
- * Load a keymap into the keyboard device
- */
-static void DarwinKeyboardSetDeviceKeyMap(KeySymsRec *keySyms, CARD8 *modmap) {
- DeviceIntPtr pDev;
-
- for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
- if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key)
- XkbApplyMappingChange(pDev, keySyms, keySyms->minKeyCode,
- keySyms->maxKeyCode - keySyms->minKeyCode + 1,
- modmap, serverClient);
-}
-
-/*
* DarwinKeyboardInit
* Get the Darwin keyboard map and compute an equivalent
* X keyboard map and modifier map. Set the new keyboard
* device structure.
*/
void DarwinKeyboardInit(DeviceIntPtr pDev) {
- KeySymsRec keySyms;
- XkbComponentNamesRec names;
- CFIndex value;
- BOOL ok;
-
// Open a shared connection to the HID System.
// Note that the Event Status Driver is really just a wrapper
// for a kIOHIDParamConnectType connection.
assert(darwinParamConnect = NXOpenEventStatus());
- bzero(&names, sizeof(names));
-
/* We need to really have rules... or something... */
//XkbSetRulesDflts("base", "pc105", "us", NULL, NULL);
InitKeyboardDeviceStruct(pDev, NULL, NULL, DarwinChangeKeyboardControl);
- pthread_mutex_lock(&keyInfo_mutex);
- DarwinLoadKeyboardMapping(&keySyms);
- DarwinKeyboardSetDeviceKeyMap(&keySyms, keyInfo.modMap);
- pthread_mutex_unlock(&keyInfo_mutex);
+ DarwinKeyboardReloadHandler();
- /* Get our key repeat settings from GlobalPreferences */
- (void)CFPreferencesAppSynchronize(CFSTR(".GlobalPreferences"));
- value = CFPreferencesGetAppIntegerValue(CFSTR("InitialKeyRepeat"), CFSTR(".GlobalPreferences"), &ok);
- if(!ok)
- value = 35;
+ CopyKeyClass(pDev, inputInfo.keyboard);
+}
- if(value == 300000) { // off
+/* Set the repeat rates based on global preferences and keycodes for modifiers.
+ * Precondition: Has the keyInfo_mutex lock.
+ */
+static void DarwinKeyboardSetRepeat(DeviceIntPtr pDev, int initialKeyRepeatValue, int keyRepeatValue) {
+ if(initialKeyRepeatValue == 300000) { // off
+ /* Turn off repeats globally */
XkbSetRepeatKeys(pDev, -1, AutoRepeatModeOff);
} else {
- pDev->key->xkbInfo->desc->ctrls->repeat_delay = value * 15;
-
- value = CFPreferencesGetAppIntegerValue(CFSTR("KeyRepeat"), CFSTR(".GlobalPreferences"), &ok);
- if(!ok)
- value = 6;
- pDev->key->xkbInfo->desc->ctrls->repeat_interval = value * 15;
+ int i;
+ XkbControlsPtr ctrl;
+ XkbControlsRec old;
+ /* Turn on repeats globally */
XkbSetRepeatKeys(pDev, -1, AutoRepeatModeOn);
- }
+
+ /* Setup the bit mask for individual key repeats */
+ ctrl = pDev->key->xkbInfo->desc->ctrls;
+ old= *ctrl;
+
+ ctrl->repeat_delay = initialKeyRepeatValue * 15;
+ ctrl->repeat_interval = keyRepeatValue * 15;
+
+ /* Turn off key-repeat for modifier keys, on for others */
+ /* First set them all on */
+ for(i=0; i < XkbPerKeyBitArraySize; i++)
+ ctrl->per_key_repeat[i] = -1;
+
+ /* Now turn off the modifiers */
+ for(i=0; i < 32; i++) {
+ unsigned char keycode;
+
+ keycode = keyInfo.modifierKeycodes[i][0];
+ if(keycode)
+ ClearBit(ctrl->per_key_repeat, keycode + MIN_KEYCODE);
+
+ keycode = keyInfo.modifierKeycodes[i][1];
+ if(keycode)
+ ClearBit(ctrl->per_key_repeat, keycode + MIN_KEYCODE);
+ }
- CopyKeyClass(pDev, inputInfo.keyboard);
+ /* Hurray for data duplication */
+ if (pDev->kbdfeed)
+ memcpy(pDev->kbdfeed->ctrl.autoRepeats, ctrl->per_key_repeat, XkbPerKeyBitArraySize);
+
+ //fprintf(stderr, "per_key_repeat =\n");
+ //for(i=0; i < XkbPerKeyBitArraySize; i++)
+ // fprintf(stderr, "%02x%s", ctrl->per_key_repeat[i], (i + 1) & 7 ? "" : "\n");
+
+ /* And now we notify the puppies about the changes */
+ XkbDDXChangeControls(pDev, &old, ctrl);
+ }
}
void DarwinKeyboardReloadHandler(void) {
KeySymsRec keySyms;
+ CFIndex initialKeyRepeatValue, keyRepeatValue;
+ BOOL ok;
+ DeviceIntPtr pDev = darwinKeyboard;
DEBUG_LOG("DarwinKeyboardReloadHandler\n");
-// if (pDev->key) {
-// if (pDev->key->curKeySyms.map) xfree(pDev->key->curKeySyms.map);
-// xfree(pDev->key);
-// }
+ /* Get our key repeat settings from GlobalPreferences */
+ (void)CFPreferencesAppSynchronize(CFSTR(".GlobalPreferences"));
- pthread_mutex_lock(&keyInfo_mutex);
- DarwinLoadKeyboardMapping(&keySyms);
- DarwinKeyboardSetDeviceKeyMap(&keySyms, keyInfo.modMap);
- pthread_mutex_unlock(&keyInfo_mutex);
+ initialKeyRepeatValue = CFPreferencesGetAppIntegerValue(CFSTR("InitialKeyRepeat"), CFSTR(".GlobalPreferences"), &ok);
+ if(!ok)
+ initialKeyRepeatValue = 35;
+
+ keyRepeatValue = CFPreferencesGetAppIntegerValue(CFSTR("KeyRepeat"), CFSTR(".GlobalPreferences"), &ok);
+ if(!ok)
+ keyRepeatValue = 6;
+
+ pthread_mutex_lock(&keyInfo_mutex); {
+ /* Initialize our keySyms */
+ DarwinBuildModifierMaps(&keyInfo);
+ keySyms.map = keyInfo.keyMap;
+ keySyms.mapWidth = GLYPHS_PER_KEY;
+ keySyms.minKeyCode = MIN_KEYCODE;
+ keySyms.maxKeyCode = MAX_KEYCODE;
+
+ /* Apply the mappings to darwinKeyboard */
+ XkbApplyMappingChange(darwinKeyboard, &keySyms, keySyms.minKeyCode,
+ keySyms.maxKeyCode - keySyms.minKeyCode + 1,
+ keyInfo.modMap, serverClient);
+ DarwinKeyboardSetRepeat(darwinKeyboard, initialKeyRepeatValue, keyRepeatValue);
+
+ /* Apply the mappings to the core keyboard */
+ for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
+ if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
+ XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode,
+ keySyms.maxKeyCode - keySyms.minKeyCode + 1,
+ keyInfo.modMap, serverClient);
+ DarwinKeyboardSetRepeat(pDev, initialKeyRepeatValue, keyRepeatValue);
+ }
+ }
+ } pthread_mutex_unlock(&keyInfo_mutex);
}
//-----------------------------------------------------------------------------