summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dix/events.c26
-rw-r--r--xkb/xkb.h3
-rw-r--r--xkb/xkbUtils.c75
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;