diff options
author | Daniel Stone <daniel@fooishbar.org> | 2008-10-18 20:59:30 +0100 |
---|---|---|
committer | Daniel Stone <daniel@fooishbar.org> | 2009-01-22 15:08:58 +1100 |
commit | f06a9d2e05e13466c115fc706966a90b1fb0518e (patch) | |
tree | abc6377267185b8e02fd81bc3bcc65dd66fa960b /dix | |
parent | 1d1a0f67eee330a286fbdef17e967ce8ea201548 (diff) |
Input: Clean up keymap change notifications
Keyboard map notifications are always generated from within XKB code,
which also takes care of copying the keysyms, etc. If you need to
mangle the keymap yourself, generate a new core keymap/modmap, and pass
it to XkbApplyMappingChange.
SendMappingNotify is renamed to SendPointerMappingNotify (and ditto its
Device variants), which still only _sends_ the notifications, as opposed
to also doing the copying a la XkbApplyMappingChange.
Also have the modmap change code traverse the device hierachy, rather
than just going off the core keyboard.
Signed-off-by: Daniel Stone <daniel@fooishbar.org>
Diffstat (limited to 'dix')
-rw-r--r-- | dix/devices.c | 150 | ||||
-rw-r--r-- | dix/inpututils.c | 24 |
2 files changed, 87 insertions, 87 deletions
diff --git a/dix/devices.c b/dix/devices.c index a4ff641a0..33f149ce4 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -1013,19 +1013,20 @@ QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode) } } +/* Notably, this function does not expand the destination's keycode range, or + * notify clients. */ Bool SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src) { int i, j; + KeySym *tmp; int rowDif = src->minKeyCode - dst->minKeyCode; /* if keysym map size changes, grow map first */ - if (src->mapWidth < dst->mapWidth) - { - for (i = src->minKeyCode; i <= src->maxKeyCode; i++) - { -#define SI(r, c) (((r-src->minKeyCode)*src->mapWidth) + (c)) -#define DI(r, c) (((r - dst->minKeyCode)*dst->mapWidth) + (c)) + if (src->mapWidth < dst->mapWidth) { + for (i = src->minKeyCode; i <= src->maxKeyCode; i++) { +#define SI(r, c) (((r - src->minKeyCode) * src->mapWidth) + (c)) +#define DI(r, c) (((r - dst->minKeyCode) * dst->mapWidth) + (c)) for (j = 0; j < src->mapWidth; j++) dst->map[DI(i, j)] = src->map[SI(i, j)]; for (j = src->mapWidth; j < dst->mapWidth; j++) @@ -1035,39 +1036,37 @@ SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src) } return TRUE; } - else if (src->mapWidth > dst->mapWidth) - { - KeySym *map; - int bytes = sizeof(KeySym) * src->mapWidth * - (dst->maxKeyCode - dst->minKeyCode + 1); - map = (KeySym *)xcalloc(1, bytes); - if (!map) - return FALSE; - if (dst->map) - { + else if (src->mapWidth > dst->mapWidth) { + i = sizeof(KeySym) * src->mapWidth * + (dst->maxKeyCode - dst->minKeyCode + 1); + tmp = xcalloc(sizeof(KeySym), i); + if (!tmp) + return FALSE; + + if (dst->map) { for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++) - memmove((char *)&map[i*src->mapWidth], - (char *)&dst->map[i*dst->mapWidth], - dst->mapWidth * sizeof(KeySym)); - xfree(dst->map); - } - dst->mapWidth = src->mapWidth; - dst->map = map; - } else if (!dst->map) - { - KeySym *map; - int bytes = sizeof(KeySym) * src->mapWidth * - (dst->maxKeyCode - dst->minKeyCode + 1); - map = (KeySym *)xcalloc(1, bytes); - if (!map) + memmove(&tmp[i * src->mapWidth], &dst->map[i * dst->mapWidth], + dst->mapWidth * sizeof(KeySym)); + xfree(dst->map); + } + dst->mapWidth = src->mapWidth; + dst->map = tmp; + } + else if (!dst->map) { + i = sizeof(KeySym) * src->mapWidth * + (dst->maxKeyCode - dst->minKeyCode + 1); + tmp = xcalloc(sizeof(KeySym), i); + if (!tmp) return FALSE; - dst->map = map; + + dst->map = tmp; dst->mapWidth = src->mapWidth; } - memmove((char *)&dst->map[rowDif * dst->mapWidth], - (char *)src->map, - (int)(src->maxKeyCode - src->minKeyCode + 1) * - dst->mapWidth * sizeof(KeySym)); + + memmove(&dst->map[rowDif * dst->mapWidth], src->map, + (src->maxKeyCode - src->minKeyCode + 1) * + dst->mapWidth * sizeof(KeySym)); + return TRUE; } @@ -1398,34 +1397,24 @@ InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons, } _X_EXPORT void -SendMappingNotify(DeviceIntPtr pDev, unsigned request, unsigned firstKeyCode, - unsigned count, ClientPtr client) +SendPointerMappingNotify(DeviceIntPtr pDev, ClientPtr client) { int i; xEvent event; - event.u.u.type = MappingNotify; - event.u.mappingNotify.request = request; - if (request == MappingKeyboard) - { - event.u.mappingNotify.firstKeyCode = firstKeyCode; - event.u.mappingNotify.count = count; - } - if (request == MappingKeyboard || request == MappingModifier) - XkbApplyMappingChange(pDev,request,firstKeyCode,count, client); + /* 0 is the server client. */ + for (i = 1; i < currentMaxClients; i++) { + /* Don't send irrelevant events to naïve clients. */ + if (PickPointer(clients[i]) != pDev) + continue; - /* 0 is the server client */ - for (i=1; i<currentMaxClients; i++) - { - if (clients[i] && clients[i]->clientState == ClientStateRunning) - { - if (request == MappingKeyboard && - clients[i]->xkbClientFlags != 0 && - (clients[i]->mapNotifyMask & XkbKeySymsMask)) - continue; - event.u.u.sequenceNumber = clients[i]->sequence; - WriteEventsToClient(clients[i], 1, &event); - } + if (clients[i] && clients[i]->clientState == ClientStateRunning) { + event.u.u.type = MappingNotify; + event.u.u.sequenceNumber = clients[i]->sequence; + event.u.mappingNotify.request = MappingPointer; + + WriteEventsToClient(clients[i], 1, &event); + } } } @@ -1516,7 +1505,7 @@ ProcChangeKeyboardMapping(ClientPtr client) unsigned len; KeySymsRec keysyms; KeySymsPtr curKeySyms = &PickKeyboard(client)->key->curKeySyms; - DeviceIntPtr pDev = NULL; + DeviceIntPtr pDev, tmp; int rc; REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq); @@ -1536,28 +1525,30 @@ ProcChangeKeyboardMapping(ClientPtr client) return BadValue; } - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) { - rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); - if (rc != Success) - return rc; - } - } - keysyms.minKeyCode = stuff->firstKeyCode; keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1; keysyms.mapWidth = stuff->keySymsPerKeyCode; - keysyms.map = (KeySym *)&stuff[1]; - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) - if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) - if (!SetKeySymsMap(&pDev->key->curKeySyms, &keysyms)) - return BadAlloc; - - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) - if (pDev->key && pDev->coreEvents) - SendDeviceMappingNotify(client, MappingKeyboard, - stuff->firstKeyCode, stuff->keyCodes, - pDev); + keysyms.map = (KeySym *) &stuff[1]; + + pDev = PickKeyboard(client); + rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); + if (rc != Success) + return rc; + + XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode, + stuff->keyCodes, NULL, client); + + for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { + if (tmp->isMaster || tmp->u.master != pDev) + continue; + + rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); + if (rc != Success) + continue; + + XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode, + stuff->keyCodes, NULL, client); + } return client->noClientException; } @@ -1639,7 +1630,8 @@ ProcSetPointerMapping(ClientPtr client) return Success; } - SendMappingNotify(ptr, MappingPointer, 0, 0, client); + /* FIXME: Send mapping notifies for masters/slaves as well. */ + SendPointerMappingNotify(ptr, client); WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep); return Success; } diff --git a/dix/inpututils.c b/dix/inpututils.c index 1b6458f45..309ef516d 100644 --- a/dix/inpututils.c +++ b/dix/inpututils.c @@ -132,8 +132,7 @@ check_modmap_change_slave(ClientPtr client, DeviceIntPtr master, static void do_modmap_change(ClientPtr client, DeviceIntPtr dev, CARD8 *modmap) { - memcpy(dev->key->xkbInfo->desc->map->modmap, modmap, MAP_LENGTH); - SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev); + XkbApplyMappingChange(dev, NULL, 0, 0, modmap, serverClient); } /* Rebuild modmap (key -> mod) from map (mod -> key). */ @@ -165,7 +164,7 @@ change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *modkeymap, { int ret; CARD8 modmap[MAP_LENGTH]; - DeviceIntPtr slave; + DeviceIntPtr tmp; ret = build_modmap_from_modkeymap(modmap, modkeymap, max_keys_per_mod); if (ret != Success) @@ -177,12 +176,21 @@ change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *modkeymap, return ret; do_modmap_change(client, dev, modmap); - /* If we're acting on a master, change the slaves as well. */ + /* Change any attached masters/slaves. */ if (dev->isMaster) { - for (slave = inputInfo.devices; slave; slave = slave->next) { - if (slave != dev && !slave->isMaster && slave->u.master == dev) - if (check_modmap_change_slave(client, dev, slave, modmap)) - do_modmap_change(client, slave, modmap); + for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { + if (!tmp->isMaster && tmp->u.master == dev) + if (check_modmap_change_slave(client, dev, tmp, modmap)) + do_modmap_change(client, tmp, modmap); + } + } + else { + for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { + if (tmp->isMaster && tmp->u.lastSlave == dev) { + /* If this fails, expect the results to be weird. */ + if (check_modmap_change(client, tmp, modmap)) + do_modmap_change(client, tmp, modmap); + } } } |