From 6323a11d0db4d3cf0317af83f0362730142f5325 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Wed, 23 Aug 2006 18:53:04 +0300 Subject: [PATCH] XkbCopyKeymap: optionally send NewKeyboardNotify/MapNotify events Optionally send a NewKeyboardNotify or MapNotify event when copying the keymap; modify GetKeyboardValuatorEvents to make use of this. --- dix/events.c | 26 +---------------- xkb/xkb.h | 3 +- xkb/xkbUtils.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 76 insertions(+), 28 deletions(-) diff --git a/dix/events.c b/dix/events.c index 808694d79..6372a207d 100644 --- a/dix/events.c +++ b/dix/events.c @@ -4655,9 +4655,6 @@ int GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, deviceKeyButtonPointer *kbp = NULL; deviceValuator *xv = NULL; KeyClassPtr ckeyc; -#ifdef XKB - xkbMapNotify mn; -#endif if (!events) return 0; @@ -4781,28 +4778,7 @@ int GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, #ifdef XKB if (!noXkbExtension && pDev->key->xkbInfo && pDev->key->xkbInfo->desc) { - mn.deviceID = inputInfo.keyboard->id; - mn.minKeyCode = pDev->key->xkbInfo->desc->min_key_code; - mn.maxKeyCode = pDev->key->xkbInfo->desc->max_key_code; - mn.firstType = 0; - mn.nTypes = pDev->key->xkbInfo->desc->map->num_types; - mn.firstKeySym = pDev->key->xkbInfo->desc->min_key_code; - mn.nKeySyms = XkbNumKeys(pDev->key->xkbInfo->desc); - mn.firstKeyAct = pDev->key->xkbInfo->desc->min_key_code; - mn.nKeyActs = XkbNumKeys(pDev->key->xkbInfo->desc); - /* Cargo-culted from ProcXkbGetMap. */ - mn.firstKeyBehavior = pDev->key->xkbInfo->desc->min_key_code; - mn.nKeyBehaviors = XkbNumKeys(pDev->key->xkbInfo->desc); - mn.firstKeyExplicit = pDev->key->xkbInfo->desc->min_key_code; - mn.nKeyExplicit = XkbNumKeys(pDev->key->xkbInfo->desc); - mn.firstModMapKey = pDev->key->xkbInfo->desc->min_key_code; - mn.nModMapKeys = XkbNumKeys(pDev->key->xkbInfo->desc); - mn.firstVModMapKey = pDev->key->xkbInfo->desc->min_key_code; - mn.nVModMapKeys = XkbNumKeys(pDev->key->xkbInfo->desc); - mn.virtualMods = ~0; /* ??? */ - mn.changed = XkbAllMapComponentsMask; - - if (!XkbCopyKeymap(pDev->key->xkbInfo, ckeyc->xkbInfo)) + if (!XkbCopyKeymap(pDev->key->xkbInfo, ckeyc->xkbInfo, True)) FatalError("Couldn't pivot keymap from device to core!\n"); } #endif diff --git a/xkb/xkb.h b/xkb/xkb.h index a85df8e6f..2be42582d 100644 --- a/xkb/xkb.h +++ b/xkb/xkb.h @@ -75,4 +75,5 @@ extern Bool XkbDDXCompileKeymapByNames( extern Bool XkbCopyKeymap( XkbDescPtr src, - XkbDescPtr dst); + XkbDescPtr dst, + Bool sendNotifies); diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c index 4fa536968..da790f933 100644 --- a/xkb/xkbUtils.c +++ b/xkb/xkbUtils.c @@ -985,13 +985,16 @@ XkbConvertCase(register KeySym sym, KeySym *lower, KeySym *upper) * to remain valid, but part of the map may be from src and part from dst. */ Bool -XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst) +XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) { int i = 0, j = 0; void *tmp = NULL; XkbKeyTypePtr stype = NULL, dtype = NULL; + DeviceIntPtr pDev = NULL, tmpDev = NULL; + xkbMapNotify mn; + xkbNewKeyboardNotify nkn; - if (!src || !dst) + if (!src || !dst || src == dst) return FALSE; /* client map */ @@ -1368,6 +1371,74 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst) } } + if (inputInfo.keyboard->key->xkbInfo && + inputInfo.keyboard->key->xkbInfo->desc == dst) { + pDev = inputInfo.keyboard; + } + else { + for (tmpDev = inputInfo.devices; tmpDev && !pDev; + tmpDev = tmpDev->next) { + if (tmpDev->key && tmpDev->key->xkbInfo && + tmpDev->key->xkbInfo->desc == dst) { + pDev = tmpDev; + break; + } + } + for (tmpDev = inputInfo.off_devices; tmpDev && !pDev; + tmpDev = tmpDev->next) { + if (tmpDev->key && tmpDev->key->xkbInfo && + tmpDev->key->xkbInfo->desc == dst) { + pDev = tmpDev; + break; + } + } + } + + if (sendNotifies) { + if (!pDev) { + ErrorF("XkbCopyKeymap: asked for notifies, but can't find device!\n"); + } + else { + /* send NewKeyboardNotify if the keycode range changed, else + * just MapNotify. */ + if (src->min_key_code != dst->min_key_code || + src->max_key_code != dst->max_key_code && sendNotifies) { + nkn.oldMinKeyCode = dst->min_key_code; + nkn.oldMaxKeyCode = dst->max_key_code; + nkn.deviceID = nkn.oldDeviceID = pDev->id; + nkn.minKeyCode = src->min_key_code; + nkn.maxKeyCode = src->max_key_code; + nkn.requestMajor = XkbReqCode; + nkn.requestMinor = X_kbSetMap; /* XXX bare-faced lie */ + nkn.changed = XkbAllNewKeyboardEventsMask; + XkbSendNewKeyboardNotify(pDev, &nkn); + } + else if (sendNotifies) { + mn.deviceID = pDev->id; + mn.minKeyCode = src->min_key_code; + mn.maxKeyCode = src->max_key_code; + mn.firstType = 0; + mn.nTypes = dst->map->num_types; + mn.firstKeySym = dst->min_key_code; + mn.nKeySyms = XkbNumKeys(dst); + mn.firstKeyAct = dst->min_key_code; + mn.nKeyActs = XkbNumKeys(dst); + /* Cargo-culted from ProcXkbGetMap. */ + mn.firstKeyBehavior = dst->min_key_code; + mn.nKeyBehaviors = XkbNumKeys(dst); + mn.firstKeyExplicit = dst->min_key_code; + mn.nKeyExplicit = XkbNumKeys(dst); + mn.firstModMapKey = dst->min_key_code; + mn.nModMapKeys = XkbNumKeys(dst); + mn.firstVModMapKey = dst->min_key_code; + mn.nVModMapKeys = XkbNumKeys(dst); + mn.virtualMods = ~0; /* ??? */ + mn.changed = XkbAllMapComponentsMask; + XkbSendMapNotify(pDev, &mn); + } + } + } + dst->min_key_code = src->min_key_code; dst->max_key_code = src->max_key_code;