Input: Remove modifierKeyMap
Since modifierKeyMap is generated from modifierMap, just remove it, and only generate it when we need to send the modifier map to the client. Signed-off-by: Daniel Stone <daniel@fooishbar.org> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
cf6a2fc2bd
commit
f062e90a95
|
@ -201,21 +201,6 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
|
||||||
|
|
||||||
memcpy(mk->modifierMap, dk->modifierMap, MAP_LENGTH);
|
memcpy(mk->modifierMap, dk->modifierMap, MAP_LENGTH);
|
||||||
|
|
||||||
if (dk->maxKeysPerModifier)
|
|
||||||
{
|
|
||||||
mk->modifierKeyMap = xrealloc(mk->modifierKeyMap,
|
|
||||||
8 * dk->maxKeysPerModifier);
|
|
||||||
if (!mk->modifierKeyMap)
|
|
||||||
FatalError("[Xi] no memory for class shift.\n");
|
|
||||||
memcpy(mk->modifierKeyMap, dk->modifierKeyMap,
|
|
||||||
(8 * dk->maxKeysPerModifier));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
xfree(mk->modifierKeyMap);
|
|
||||||
mk->modifierKeyMap = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mk->maxKeysPerModifier = dk->maxKeysPerModifier;
|
|
||||||
mk->curKeySyms.minKeyCode = dk->curKeySyms.minKeyCode;
|
mk->curKeySyms.minKeyCode = dk->curKeySyms.minKeyCode;
|
||||||
mk->curKeySyms.maxKeyCode = dk->curKeySyms.maxKeyCode;
|
mk->curKeySyms.maxKeyCode = dk->curKeySyms.maxKeyCode;
|
||||||
SetKeySymsMap(&mk->curKeySyms, &dk->curKeySyms);
|
SetKeySymsMap(&mk->curKeySyms, &dk->curKeySyms);
|
||||||
|
@ -498,7 +483,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
|
||||||
|
|
||||||
if (from->key)
|
if (from->key)
|
||||||
{
|
{
|
||||||
KeyCode *oldModKeyMap;
|
|
||||||
KeySym *oldMap;
|
KeySym *oldMap;
|
||||||
struct _XkbSrvInfo *oldXkbInfo;
|
struct _XkbSrvInfo *oldXkbInfo;
|
||||||
if (!to->key)
|
if (!to->key)
|
||||||
|
@ -515,7 +499,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
|
||||||
classes->key = NULL;
|
classes->key = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
oldModKeyMap = to->key->modifierKeyMap;
|
|
||||||
oldMap = to->key->curKeySyms.map;
|
oldMap = to->key->curKeySyms.map;
|
||||||
oldXkbInfo = to->key->xkbInfo;
|
oldXkbInfo = to->key->xkbInfo;
|
||||||
|
|
||||||
|
@ -528,7 +511,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
|
||||||
memcpy(oldMap, from->key->curKeySyms.map, bytes);
|
memcpy(oldMap, from->key->curKeySyms.map, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
to->key->modifierKeyMap = oldModKeyMap;
|
|
||||||
to->key->curKeySyms.map = oldMap;
|
to->key->curKeySyms.map = oldMap;
|
||||||
to->key->xkbInfo = oldXkbInfo;
|
to->key->xkbInfo = oldXkbInfo;
|
||||||
|
|
||||||
|
@ -1664,86 +1646,6 @@ SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map)
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
SetModifierMapping(ClientPtr client, DeviceIntPtr dev, int len, int rlen,
|
|
||||||
int numKeyPerModifier, KeyCode * inputMap, KeyClassPtr * k)
|
|
||||||
{
|
|
||||||
KeyCode *map = NULL;
|
|
||||||
int inputMapLen;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
*k = dev->key;
|
|
||||||
if (*k == NULL)
|
|
||||||
return BadMatch;
|
|
||||||
if (len != ((numKeyPerModifier << 1) + rlen))
|
|
||||||
return BadLength;
|
|
||||||
|
|
||||||
inputMapLen = 8 * numKeyPerModifier;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now enforce the restriction that "all of the non-zero keycodes must be
|
|
||||||
* in the range specified by min-keycode and max-keycode in the
|
|
||||||
* connection setup (else a Value error)"
|
|
||||||
*/
|
|
||||||
i = inputMapLen;
|
|
||||||
while (i--) {
|
|
||||||
if (inputMap[i]
|
|
||||||
&& (inputMap[i] < (*k)->curKeySyms.minKeyCode
|
|
||||||
|| inputMap[i] > (*k)->curKeySyms.maxKeyCode)) {
|
|
||||||
client->errorValue = inputMap[i];
|
|
||||||
return -1; /* BadValue collides with MappingFailed */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now enforce the restriction that none of the old or new
|
|
||||||
* modifier keys may be down while we change the mapping, and
|
|
||||||
* that the DDX layer likes the choice.
|
|
||||||
*/
|
|
||||||
if (!AllModifierKeysAreUp(dev, (*k)->modifierKeyMap,
|
|
||||||
(int)(*k)->maxKeysPerModifier, inputMap,
|
|
||||||
(int)numKeyPerModifier)
|
|
||||||
|| !AllModifierKeysAreUp(dev, inputMap, (int)numKeyPerModifier,
|
|
||||||
(*k)->modifierKeyMap,
|
|
||||||
(int)(*k)->maxKeysPerModifier)) {
|
|
||||||
return MappingBusy;
|
|
||||||
} else {
|
|
||||||
for (i = 0; i < inputMapLen; i++) {
|
|
||||||
if (inputMap[i] && !LegalModifier(inputMap[i], dev)) {
|
|
||||||
return MappingFailed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now build the keyboard's modifier bitmap from the
|
|
||||||
* list of keycodes.
|
|
||||||
*/
|
|
||||||
if (inputMapLen) {
|
|
||||||
map = (KeyCode *) xalloc(inputMapLen);
|
|
||||||
if (!map)
|
|
||||||
return BadAlloc;
|
|
||||||
}
|
|
||||||
if ((*k)->modifierKeyMap)
|
|
||||||
xfree((*k)->modifierKeyMap);
|
|
||||||
if (inputMapLen) {
|
|
||||||
(*k)->modifierKeyMap = map;
|
|
||||||
memmove((char *)(*k)->modifierKeyMap, (char *)inputMap, inputMapLen);
|
|
||||||
} else
|
|
||||||
(*k)->modifierKeyMap = NULL;
|
|
||||||
|
|
||||||
(*k)->maxKeysPerModifier = numKeyPerModifier;
|
|
||||||
for (i = 0; i < MAP_LENGTH; i++)
|
|
||||||
(*k)->modifierMap[i] = 0;
|
|
||||||
for (i = 0; i < inputMapLen; i++)
|
|
||||||
if (inputMap[i]) {
|
|
||||||
(*k)->modifierMap[inputMap[i]]
|
|
||||||
|= (1 << (i / (*k)->maxKeysPerModifier));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (MappingSuccess);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SendDeviceMappingNotify(ClientPtr client, CARD8 request,
|
SendDeviceMappingNotify(ClientPtr client, CARD8 request,
|
||||||
KeyCode firstKeyCode, CARD8 count, DeviceIntPtr dev)
|
KeyCode firstKeyCode, CARD8 count, DeviceIntPtr dev)
|
||||||
|
|
28
Xi/getmmap.c
28
Xi/getmmap.c
|
@ -87,36 +87,34 @@ SProcXGetDeviceModifierMapping(ClientPtr client)
|
||||||
int
|
int
|
||||||
ProcXGetDeviceModifierMapping(ClientPtr client)
|
ProcXGetDeviceModifierMapping(ClientPtr client)
|
||||||
{
|
{
|
||||||
CARD8 maxkeys;
|
|
||||||
DeviceIntPtr dev;
|
DeviceIntPtr dev;
|
||||||
xGetDeviceModifierMappingReply rep;
|
xGetDeviceModifierMappingReply rep;
|
||||||
KeyClassPtr kp;
|
KeyCode *modkeymap = NULL;
|
||||||
int rc;
|
int ret, max_keys_per_mod;
|
||||||
|
|
||||||
REQUEST(xGetDeviceModifierMappingReq);
|
REQUEST(xGetDeviceModifierMappingReq);
|
||||||
REQUEST_SIZE_MATCH(xGetDeviceModifierMappingReq);
|
REQUEST_SIZE_MATCH(xGetDeviceModifierMappingReq);
|
||||||
|
|
||||||
rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
|
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
|
||||||
if (rc != Success)
|
if (ret != Success)
|
||||||
return rc;
|
return ret;
|
||||||
|
|
||||||
kp = dev->key;
|
ret = generate_modkeymap(client, dev, &modkeymap, &max_keys_per_mod);
|
||||||
if (kp == NULL)
|
if (ret != Success)
|
||||||
return BadMatch;
|
return ret;
|
||||||
|
|
||||||
maxkeys = kp->maxKeysPerModifier;
|
|
||||||
|
|
||||||
rep.repType = X_Reply;
|
rep.repType = X_Reply;
|
||||||
rep.RepType = X_GetDeviceModifierMapping;
|
rep.RepType = X_GetDeviceModifierMapping;
|
||||||
rep.numKeyPerModifier = maxkeys;
|
rep.numKeyPerModifier = max_keys_per_mod;
|
||||||
rep.sequenceNumber = client->sequence;
|
rep.sequenceNumber = client->sequence;
|
||||||
/* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
|
/* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
|
||||||
rep.length = 2 * maxkeys;
|
rep.length = max_keys_per_mod << 1;
|
||||||
|
|
||||||
WriteReplyToClient(client, sizeof(xGetDeviceModifierMappingReply), &rep);
|
WriteReplyToClient(client, sizeof(xGetDeviceModifierMappingReply), &rep);
|
||||||
|
WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap);
|
||||||
|
|
||||||
|
xfree(modkeymap);
|
||||||
|
|
||||||
/* Reply with the (modified by DDX) map that SetModifierMapping passed in */
|
|
||||||
WriteToClient(client, 8 * maxkeys, (char *)kp->modifierKeyMap);
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
30
Xi/setmmap.c
30
Xi/setmmap.c
|
@ -91,33 +91,39 @@ ProcXSetDeviceModifierMapping(ClientPtr client)
|
||||||
int ret;
|
int ret;
|
||||||
xSetDeviceModifierMappingReply rep;
|
xSetDeviceModifierMappingReply rep;
|
||||||
DeviceIntPtr dev;
|
DeviceIntPtr dev;
|
||||||
KeyClassPtr kp;
|
|
||||||
|
|
||||||
REQUEST(xSetDeviceModifierMappingReq);
|
REQUEST(xSetDeviceModifierMappingReq);
|
||||||
REQUEST_AT_LEAST_SIZE(xSetDeviceModifierMappingReq);
|
REQUEST_AT_LEAST_SIZE(xSetDeviceModifierMappingReq);
|
||||||
|
|
||||||
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
|
if (stuff->length != ((sizeof(xSetDeviceModifierMappingReq) >> 2) +
|
||||||
if (ret != Success)
|
(stuff->numKeyPerModifier << 1)))
|
||||||
return ret;
|
return BadLength;
|
||||||
|
|
||||||
rep.repType = X_Reply;
|
rep.repType = X_Reply;
|
||||||
rep.RepType = X_SetDeviceModifierMapping;
|
rep.RepType = X_SetDeviceModifierMapping;
|
||||||
rep.length = 0;
|
rep.length = 0;
|
||||||
rep.sequenceNumber = client->sequence;
|
rep.sequenceNumber = client->sequence;
|
||||||
|
|
||||||
ret = SetModifierMapping(client, dev, stuff->length,
|
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
|
||||||
(sizeof(xSetDeviceModifierMappingReq) >> 2),
|
if (ret != Success)
|
||||||
stuff->numKeyPerModifier, (BYTE *) & stuff[1],
|
return ret;
|
||||||
&kp);
|
|
||||||
|
ret = change_modmap(client, dev, (KeyCode *) &stuff[1],
|
||||||
|
stuff->numKeyPerModifier);
|
||||||
|
if (ret == Success)
|
||||||
|
ret = MappingSuccess;
|
||||||
|
|
||||||
if (ret == MappingSuccess || ret == MappingBusy || ret == MappingFailed) {
|
if (ret == MappingSuccess || ret == MappingBusy || ret == MappingFailed) {
|
||||||
rep.success = ret;
|
rep.success = ret;
|
||||||
if (ret == MappingSuccess)
|
|
||||||
SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev);
|
|
||||||
WriteReplyToClient(client, sizeof(xSetDeviceModifierMappingReply),
|
WriteReplyToClient(client, sizeof(xSetDeviceModifierMappingReply),
|
||||||
&rep);
|
&rep);
|
||||||
} else if (ret == -1)
|
}
|
||||||
return BadValue;
|
else if (ret == -1) {
|
||||||
|
return BadValue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ libdix_la_SOURCES = \
|
||||||
glyphcurs.c \
|
glyphcurs.c \
|
||||||
grabs.c \
|
grabs.c \
|
||||||
initatoms.c \
|
initatoms.c \
|
||||||
|
inpututils.c \
|
||||||
main.c \
|
main.c \
|
||||||
pixmap.c \
|
pixmap.c \
|
||||||
privates.c \
|
privates.c \
|
||||||
|
|
136
dix/devices.c
136
dix/devices.c
|
@ -620,7 +620,6 @@ FreeDeviceClass(int type, pointer *class)
|
||||||
(*k)->xkbInfo = NULL;
|
(*k)->xkbInfo = NULL;
|
||||||
}
|
}
|
||||||
xfree((*k)->curKeySyms.map);
|
xfree((*k)->curKeySyms.map);
|
||||||
xfree((*k)->modifierKeyMap);
|
|
||||||
xfree((*k));
|
xfree((*k));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1453,109 +1452,10 @@ BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
|
||||||
AllModifierKeysAreUp(DeviceIntPtr dev, CARD8 *map1, int per1,
|
|
||||||
CARD8 *map2, int per2)
|
|
||||||
{
|
|
||||||
int i, j, k;
|
|
||||||
CARD8 *down = dev->key->down;
|
|
||||||
|
|
||||||
for (i = 8; --i >= 0; map2 += per2)
|
|
||||||
{
|
|
||||||
for (j = per1; --j >= 0; map1++)
|
|
||||||
{
|
|
||||||
if (*map1 && BitIsOn(down, *map1))
|
|
||||||
{
|
|
||||||
for (k = per2; (--k >= 0) && (*map1 != map2[k]);)
|
|
||||||
;
|
|
||||||
if (k < 0)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
DoSetModifierMapping(ClientPtr client, KeyCode *inputMap,
|
|
||||||
int numKeyPerModifier, xSetModifierMappingReply *rep)
|
|
||||||
{
|
|
||||||
DeviceIntPtr pDev = NULL;
|
|
||||||
DeviceIntPtr cp = PickKeyboard(client); /* ClientPointer keyboard */
|
|
||||||
int rc, i = 0, inputMapLen = numKeyPerModifier * 8;
|
|
||||||
|
|
||||||
for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
|
|
||||||
if (pDev == cp || (!pDev->isMaster && (pDev->u.master == cp) && pDev->key)) {
|
|
||||||
for (i = 0; i < inputMapLen; i++) {
|
|
||||||
/* Check that all the new modifiers fall within the advertised
|
|
||||||
* keycode range, and are okay with the DDX. */
|
|
||||||
if (inputMap[i] && ((inputMap[i] < pDev->key->curKeySyms.minKeyCode ||
|
|
||||||
inputMap[i] > pDev->key->curKeySyms.maxKeyCode) ||
|
|
||||||
!LegalModifier(inputMap[i], pDev))) {
|
|
||||||
client->errorValue = inputMap[i];
|
|
||||||
return BadValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
|
|
||||||
if (rc != Success)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
/* None of the modifiers (old or new) may be down while we change
|
|
||||||
* the map. */
|
|
||||||
if (!AllModifierKeysAreUp(pDev, pDev->key->modifierKeyMap,
|
|
||||||
pDev->key->maxKeysPerModifier,
|
|
||||||
inputMap, numKeyPerModifier) ||
|
|
||||||
!AllModifierKeysAreUp(pDev, inputMap, numKeyPerModifier,
|
|
||||||
pDev->key->modifierKeyMap,
|
|
||||||
pDev->key->maxKeysPerModifier)) {
|
|
||||||
rep->success = MappingBusy;
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
|
|
||||||
|
|
||||||
if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
|
|
||||||
bzero(pDev->key->modifierMap, MAP_LENGTH);
|
|
||||||
|
|
||||||
/* Annoyingly, we lack a modifierKeyMap size, so we have to just free
|
|
||||||
* and re-alloc it every time. */
|
|
||||||
if (pDev->key->modifierKeyMap)
|
|
||||||
xfree(pDev->key->modifierKeyMap);
|
|
||||||
|
|
||||||
if (inputMapLen) {
|
|
||||||
pDev->key->modifierKeyMap = (KeyCode *) xalloc(inputMapLen);
|
|
||||||
if (!pDev->key->modifierKeyMap)
|
|
||||||
return BadAlloc;
|
|
||||||
|
|
||||||
memcpy(pDev->key->modifierKeyMap, inputMap, inputMapLen);
|
|
||||||
pDev->key->maxKeysPerModifier = numKeyPerModifier;
|
|
||||||
|
|
||||||
for (i = 0; i < inputMapLen; i++) {
|
|
||||||
if (inputMap[i]) {
|
|
||||||
pDev->key->modifierMap[inputMap[i]] |=
|
|
||||||
(1 << (((unsigned int)i) / numKeyPerModifier));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pDev->key->modifierKeyMap = NULL;
|
|
||||||
pDev->key->maxKeysPerModifier = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rep->success = Success;
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ProcSetModifierMapping(ClientPtr client)
|
ProcSetModifierMapping(ClientPtr client)
|
||||||
{
|
{
|
||||||
xSetModifierMappingReply rep;
|
xSetModifierMappingReply rep;
|
||||||
DeviceIntPtr dev;
|
|
||||||
int rc;
|
int rc;
|
||||||
REQUEST(xSetModifierMappingReq);
|
REQUEST(xSetModifierMappingReq);
|
||||||
REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
|
REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
|
||||||
|
@ -1568,14 +1468,16 @@ ProcSetModifierMapping(ClientPtr client)
|
||||||
rep.length = 0;
|
rep.length = 0;
|
||||||
rep.sequenceNumber = client->sequence;
|
rep.sequenceNumber = client->sequence;
|
||||||
|
|
||||||
rc = DoSetModifierMapping(client, (KeyCode *)&stuff[1],
|
rc = change_modmap(client, PickKeyboard(client), (KeyCode *)&stuff[1],
|
||||||
stuff->numKeyPerModifier, &rep);
|
stuff->numKeyPerModifier);
|
||||||
if (rc != Success)
|
if (rc == MappingFailed || rc == -1)
|
||||||
|
rc = BadValue;
|
||||||
|
if (rc != Success && rc != MappingSuccess && rc != MappingFailed &&
|
||||||
|
rc != MappingBusy)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
for (dev = inputInfo.devices; dev; dev = dev->next)
|
rep.success = rc;
|
||||||
if (dev->key && dev->coreEvents)
|
|
||||||
SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev);
|
|
||||||
WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
|
WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
|
||||||
return client->noClientException;
|
return client->noClientException;
|
||||||
}
|
}
|
||||||
|
@ -1584,26 +1486,26 @@ int
|
||||||
ProcGetModifierMapping(ClientPtr client)
|
ProcGetModifierMapping(ClientPtr client)
|
||||||
{
|
{
|
||||||
xGetModifierMappingReply rep;
|
xGetModifierMappingReply rep;
|
||||||
DeviceIntPtr dev = PickKeyboard(client);
|
int ret, max_keys_per_mod = 0;
|
||||||
KeyClassPtr keyc = dev->key;
|
KeyCode *modkeymap = NULL;
|
||||||
int rc;
|
|
||||||
REQUEST_SIZE_MATCH(xReq);
|
REQUEST_SIZE_MATCH(xReq);
|
||||||
|
|
||||||
rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess);
|
ret = generate_modkeymap(client, PickKeyboard(client), &modkeymap,
|
||||||
if (rc != Success)
|
&max_keys_per_mod);
|
||||||
return rc;
|
if (ret != Success)
|
||||||
|
return ret;
|
||||||
|
|
||||||
rep.type = X_Reply;
|
rep.type = X_Reply;
|
||||||
rep.numKeyPerModifier = keyc->maxKeysPerModifier;
|
rep.numKeyPerModifier = max_keys_per_mod;
|
||||||
rep.sequenceNumber = client->sequence;
|
rep.sequenceNumber = client->sequence;
|
||||||
/* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
|
/* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
|
||||||
rep.length = keyc->maxKeysPerModifier << 1;
|
rep.length = max_keys_per_mod << 1;
|
||||||
|
|
||||||
WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep);
|
WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep);
|
||||||
|
(void)WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap);
|
||||||
|
|
||||||
|
xfree(modkeymap);
|
||||||
|
|
||||||
/* Use the (modified by DDX) map that SetModifierMapping passed in */
|
|
||||||
(void)WriteToClient(client, (int)(keyc->maxKeysPerModifier << 3),
|
|
||||||
(char *)keyc->modifierKeyMap);
|
|
||||||
return client->noClientException;
|
return client->noClientException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,22 +84,35 @@ GetMotionHistorySize(void)
|
||||||
return MOTION_HISTORY_SIZE;
|
return MOTION_HISTORY_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
set_key_down(DeviceIntPtr pDev, int key_code)
|
set_key_down(DeviceIntPtr pDev, int key_code, int type)
|
||||||
{
|
{
|
||||||
pDev->key->postdown[key_code >> 3] |= (1 << (key_code & 7));
|
if (type == KEY_PROCESSED)
|
||||||
|
pDev->key->down[key_code >> 3] |= (1 << (key_code & 7));
|
||||||
|
else
|
||||||
|
pDev->key->postdown[key_code >> 3] |= (1 << (key_code & 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
set_key_up(DeviceIntPtr pDev, int key_code)
|
set_key_up(DeviceIntPtr pDev, int key_code, int type)
|
||||||
{
|
{
|
||||||
pDev->key->postdown[key_code >> 3] &= ~(1 << (key_code & 7));
|
if (type == KEY_PROCESSED)
|
||||||
|
pDev->key->down[key_code >> 3] &= ~(1 << (key_code & 7));
|
||||||
|
else
|
||||||
|
pDev->key->postdown[key_code >> 3] &= ~(1 << (key_code & 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
Bool
|
||||||
key_is_down(DeviceIntPtr pDev, int key_code)
|
key_is_down(DeviceIntPtr pDev, int key_code, int type)
|
||||||
{
|
{
|
||||||
return !!(pDev->key->postdown[key_code >> 3] & (1 << (key_code & 7)));
|
int ret = 0;
|
||||||
|
|
||||||
|
if (type & KEY_PROCESSED)
|
||||||
|
ret |= !!(pDev->key->down[key_code >> 3] & (1 << (key_code & 7)));
|
||||||
|
else if (type & KEY_POSTED)
|
||||||
|
ret |= !!(pDev->key->postdown[key_code >> 3] & (1 << (key_code & 7)));
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
|
@ -787,8 +800,6 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
|
||||||
int num_valuators, int *valuators) {
|
int num_valuators, int *valuators) {
|
||||||
int numEvents = 0;
|
int numEvents = 0;
|
||||||
CARD32 ms = 0;
|
CARD32 ms = 0;
|
||||||
KeySym *map;
|
|
||||||
KeySym sym;
|
|
||||||
deviceKeyButtonPointer *kbp = NULL;
|
deviceKeyButtonPointer *kbp = NULL;
|
||||||
|
|
||||||
if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
|
if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
|
||||||
|
@ -798,16 +809,12 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
|
||||||
|
|
||||||
numEvents = 1;
|
numEvents = 1;
|
||||||
|
|
||||||
map = pDev->key->curKeySyms.map;
|
|
||||||
sym = map[(key_code - pDev->key->curKeySyms.minKeyCode)
|
|
||||||
* pDev->key->curKeySyms.mapWidth];
|
|
||||||
|
|
||||||
events = updateFromMaster(events, pDev, &numEvents);
|
events = updateFromMaster(events, pDev, &numEvents);
|
||||||
|
|
||||||
numEvents += countValuatorEvents(num_valuators);
|
numEvents += countValuatorEvents(num_valuators);
|
||||||
|
|
||||||
/* Handle core repeating, via press/release/press/release. */
|
/* Handle core repeating, via press/release/press/release. */
|
||||||
if (type == KeyPress && key_is_down(pDev, key_code)) {
|
if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) {
|
||||||
/* If autorepeating is disabled either globally or just for that key,
|
/* If autorepeating is disabled either globally or just for that key,
|
||||||
* or we have a modifier, don't generate a repeat event. */
|
* or we have a modifier, don't generate a repeat event. */
|
||||||
if (!pDev->kbdfeed->ctrl.autoRepeat ||
|
if (!pDev->kbdfeed->ctrl.autoRepeat ||
|
||||||
|
@ -824,11 +831,11 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
|
||||||
kbp->detail = key_code;
|
kbp->detail = key_code;
|
||||||
if (type == KeyPress) {
|
if (type == KeyPress) {
|
||||||
kbp->type = DeviceKeyPress;
|
kbp->type = DeviceKeyPress;
|
||||||
set_key_down(pDev, key_code);
|
set_key_down(pDev, key_code, KEY_POSTED);
|
||||||
}
|
}
|
||||||
else if (type == KeyRelease) {
|
else if (type == KeyRelease) {
|
||||||
kbp->type = DeviceKeyRelease;
|
kbp->type = DeviceKeyRelease;
|
||||||
set_key_up(pDev, key_code);
|
set_key_up(pDev, key_code, KEY_POSTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
events++;
|
events++;
|
||||||
|
|
|
@ -0,0 +1,239 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2008 Daniel Stone
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_DIX_CONFIG_H
|
||||||
|
#include "dix-config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "exevents.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "input.h"
|
||||||
|
#include "inputstr.h"
|
||||||
|
#include "xace.h"
|
||||||
|
|
||||||
|
/* Check if a modifier map change is okay with the device.
|
||||||
|
* Returns -1 for BadValue, as it collides with MappingBusy; this particular
|
||||||
|
* caveat can be removed with LegalModifier, as we have no other reason to
|
||||||
|
* set MappingFailed. Sigh. */
|
||||||
|
static int
|
||||||
|
check_modmap_change(ClientPtr client, DeviceIntPtr dev, KeyCode *modmap)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
KeySymsPtr syms;
|
||||||
|
|
||||||
|
ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
|
||||||
|
if (ret != Success)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (!dev->key)
|
||||||
|
return BadMatch;
|
||||||
|
syms = &dev->key->curKeySyms;
|
||||||
|
|
||||||
|
for (i = 0; i < MAP_LENGTH; i++) {
|
||||||
|
if (!modmap[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Check that all the new modifiers fall within the advertised
|
||||||
|
* keycode range. */
|
||||||
|
if (i < syms->minKeyCode || i > syms->maxKeyCode) {
|
||||||
|
client->errorValue = i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure the mapping is okay with the DDX. */
|
||||||
|
if (!LegalModifier(i, dev)) {
|
||||||
|
client->errorValue = i;
|
||||||
|
return MappingFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* None of the new modifiers may be down while we change the
|
||||||
|
* map. */
|
||||||
|
if (key_is_down(dev, i, KEY_POSTED | KEY_PROCESSED)) {
|
||||||
|
client->errorValue = i;
|
||||||
|
return MappingBusy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* None of the old modifiers may be down while we change the map,
|
||||||
|
* either. */
|
||||||
|
for (i = syms->minKeyCode; i < syms->maxKeyCode; i++) {
|
||||||
|
if (!dev->key->modifierMap[i])
|
||||||
|
continue;
|
||||||
|
if (key_is_down(dev, i, KEY_POSTED | KEY_PROCESSED)) {
|
||||||
|
client->errorValue = i;
|
||||||
|
return MappingBusy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_modmap_change_slave(ClientPtr client, DeviceIntPtr master,
|
||||||
|
DeviceIntPtr slave, CARD8 *modmap)
|
||||||
|
{
|
||||||
|
KeySymsPtr master_syms, slave_syms;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
if (!slave->key || !master->key)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
master_syms = &master->key->curKeySyms;
|
||||||
|
slave_syms = &slave->key->curKeySyms;
|
||||||
|
|
||||||
|
/* Ignore devices with a clearly different keymap. */
|
||||||
|
if (slave_syms->minKeyCode != master_syms->minKeyCode ||
|
||||||
|
slave_syms->maxKeyCode != master_syms->maxKeyCode)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < MAP_LENGTH; i++) {
|
||||||
|
if (!modmap[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* If we have different symbols for any modifier on an
|
||||||
|
* extended keyboard, ignore the whole remap request. */
|
||||||
|
for (j = 0; j < slave_syms->mapWidth && j < master_syms->mapWidth; j++)
|
||||||
|
if (slave_syms->map[modmap[i] * slave_syms->mapWidth + j] !=
|
||||||
|
master_syms->map[modmap[i] * master_syms->mapWidth + j])
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_modmap_change(client, slave, modmap) != Success)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Actually change the modifier map, and send notifications. Cannot fail. */
|
||||||
|
static void
|
||||||
|
do_modmap_change(ClientPtr client, DeviceIntPtr dev, CARD8 *modmap)
|
||||||
|
{
|
||||||
|
memcpy(dev->key->modifierMap, modmap, MAP_LENGTH);
|
||||||
|
SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rebuild modmap (key -> mod) from map (mod -> key). */
|
||||||
|
static int build_modmap_from_modkeymap(CARD8 *modmap, KeyCode *modkeymap,
|
||||||
|
int max_keys_per_mod)
|
||||||
|
{
|
||||||
|
int i, mod = 0, len = max_keys_per_mod * 8;
|
||||||
|
|
||||||
|
memset(modmap, 0, MAP_LENGTH);
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (!modkeymap[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (modmap[modkeymap[i]])
|
||||||
|
return BadValue;
|
||||||
|
|
||||||
|
if (!(i % max_keys_per_mod))
|
||||||
|
mod++;
|
||||||
|
modmap[modkeymap[i]] = mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *modkeymap,
|
||||||
|
int max_keys_per_mod)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
CARD8 modmap[MAP_LENGTH];
|
||||||
|
DeviceIntPtr slave;
|
||||||
|
|
||||||
|
ret = build_modmap_from_modkeymap(modmap, modkeymap, max_keys_per_mod);
|
||||||
|
if (ret != Success)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* If we can't perform the change on the requested device, bail out. */
|
||||||
|
ret = check_modmap_change(client, dev, modmap);
|
||||||
|
if (ret != Success)
|
||||||
|
return ret;
|
||||||
|
do_modmap_change(client, dev, modmap);
|
||||||
|
|
||||||
|
/* If we're acting on a master, change the slaves as well. */
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
int generate_modkeymap(ClientPtr client, DeviceIntPtr dev,
|
||||||
|
KeyCode **modkeymap_out, int *max_keys_per_mod_out)
|
||||||
|
{
|
||||||
|
CARD8 keys_per_mod[8];
|
||||||
|
int max_keys_per_mod;
|
||||||
|
KeyCode *modkeymap;
|
||||||
|
int i, j, ret;
|
||||||
|
|
||||||
|
ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess);
|
||||||
|
if (ret != Success)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (!dev->key)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
|
/* Count the number of keys per modifier to determine how wide we
|
||||||
|
* should make the map. */
|
||||||
|
max_keys_per_mod = 0;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
keys_per_mod[i] = 0;
|
||||||
|
for (i = 8; i < MAP_LENGTH; i++) {
|
||||||
|
for (j = 0; j < 8; j++) {
|
||||||
|
if (dev->key->modifierMap[i] & (1 << j)) {
|
||||||
|
if (++keys_per_mod[j] > max_keys_per_mod)
|
||||||
|
max_keys_per_mod = keys_per_mod[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modkeymap = xcalloc(max_keys_per_mod * 8, sizeof(KeyCode));
|
||||||
|
if (!modkeymap)
|
||||||
|
return BadAlloc;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
keys_per_mod[i] = 0;
|
||||||
|
|
||||||
|
for (i = 8; i < MAP_LENGTH; i++) {
|
||||||
|
for (j = 0; j < 8; j++) {
|
||||||
|
if (dev->key->modifierMap[i] & (1 << j)) {
|
||||||
|
modkeymap[(j * max_keys_per_mod) + keys_per_mod[j]] = i;
|
||||||
|
keys_per_mod[j]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*max_keys_per_mod_out = max_keys_per_mod;
|
||||||
|
*modkeymap_out = modkeymap;
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
|
@ -370,6 +370,10 @@ void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr pDev,
|
||||||
KeySymsRec keySyms;
|
KeySymsRec keySyms;
|
||||||
|
|
||||||
DEBUG_LOG("DarwinKeyboardReloadHandler\n");
|
DEBUG_LOG("DarwinKeyboardReloadHandler\n");
|
||||||
|
if (pDev->key) {
|
||||||
|
if (pDev->key->curKeySyms.map) xfree(pDev->key->curKeySyms.map);
|
||||||
|
xfree(pDev->key);
|
||||||
|
}
|
||||||
|
|
||||||
DarwinLoadKeyboardMapping(&keySyms);
|
DarwinLoadKeyboardMapping(&keySyms);
|
||||||
DarwinKeyboardSetDeviceKeyMap(&keySyms);
|
DarwinKeyboardSetDeviceKeyMap(&keySyms);
|
||||||
|
|
|
@ -31,6 +31,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#define EXEVENTS_H
|
#define EXEVENTS_H
|
||||||
|
|
||||||
#include <X11/extensions/XIproto.h>
|
#include <X11/extensions/XIproto.h>
|
||||||
|
#include "inputstr.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attached to the devPrivates of each client. Specifies the version number as
|
* Attached to the devPrivates of each client. Specifies the version number as
|
||||||
|
@ -136,15 +137,6 @@ extern _X_EXPORT int SetButtonMapping (
|
||||||
int /* nElts */,
|
int /* nElts */,
|
||||||
BYTE * /* map */);
|
BYTE * /* map */);
|
||||||
|
|
||||||
extern _X_EXPORT int SetModifierMapping(
|
|
||||||
ClientPtr /* client */,
|
|
||||||
DeviceIntPtr /* dev */,
|
|
||||||
int /* len */,
|
|
||||||
int /* rlen */,
|
|
||||||
int /* numKeyPerModifier */,
|
|
||||||
KeyCode * /* inputMap */,
|
|
||||||
KeyClassPtr * /* k */);
|
|
||||||
|
|
||||||
extern _X_EXPORT void SendDeviceMappingNotify(
|
extern _X_EXPORT void SendDeviceMappingNotify(
|
||||||
ClientPtr /* client, */,
|
ClientPtr /* client, */,
|
||||||
CARD8 /* request, */,
|
CARD8 /* request, */,
|
||||||
|
|
|
@ -222,6 +222,15 @@ typedef struct _InputOption {
|
||||||
struct _InputOption *next;
|
struct _InputOption *next;
|
||||||
} InputOption;
|
} InputOption;
|
||||||
|
|
||||||
|
/* Key has been run through all input processing and events sent to clients. */
|
||||||
|
#define KEY_PROCESSED 1
|
||||||
|
/* Key has not been fully processed, no events have been sent. */
|
||||||
|
#define KEY_POSTED 2
|
||||||
|
|
||||||
|
extern void set_key_down(DeviceIntPtr pDev, int key_code, int type);
|
||||||
|
extern void set_key_up(DeviceIntPtr pDev, int key_code, int type);
|
||||||
|
extern int key_is_down(DeviceIntPtr pDev, int key_code, int type);
|
||||||
|
|
||||||
extern _X_EXPORT void InitCoreDevices(void);
|
extern _X_EXPORT void InitCoreDevices(void);
|
||||||
|
|
||||||
extern _X_EXPORT DeviceIntPtr AddInputDevice(
|
extern _X_EXPORT DeviceIntPtr AddInputDevice(
|
||||||
|
@ -373,13 +382,6 @@ extern _X_EXPORT Bool BadDeviceMap(
|
||||||
unsigned /*high*/,
|
unsigned /*high*/,
|
||||||
XID* /*errval*/);
|
XID* /*errval*/);
|
||||||
|
|
||||||
extern _X_EXPORT Bool AllModifierKeysAreUp(
|
|
||||||
DeviceIntPtr /*device*/,
|
|
||||||
CARD8* /*map1*/,
|
|
||||||
int /*per1*/,
|
|
||||||
CARD8* /*map2*/,
|
|
||||||
int /*per2*/);
|
|
||||||
|
|
||||||
extern _X_EXPORT void NoteLedState(
|
extern _X_EXPORT void NoteLedState(
|
||||||
DeviceIntPtr /*keybd*/,
|
DeviceIntPtr /*keybd*/,
|
||||||
int /*led*/,
|
int /*led*/,
|
||||||
|
@ -498,6 +500,12 @@ extern _X_EXPORT int AllocMasterDevice(ClientPtr client,
|
||||||
extern _X_EXPORT void DeepCopyDeviceClasses(DeviceIntPtr from,
|
extern _X_EXPORT void DeepCopyDeviceClasses(DeviceIntPtr from,
|
||||||
DeviceIntPtr to);
|
DeviceIntPtr to);
|
||||||
|
|
||||||
|
/* Helper functions. */
|
||||||
|
extern int generate_modkeymap(ClientPtr client, DeviceIntPtr dev,
|
||||||
|
KeyCode **modkeymap, int *max_keys_per_mod);
|
||||||
|
extern int change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *map,
|
||||||
|
int max_keys_per_mod);
|
||||||
|
|
||||||
/* Implemented by the DDX. */
|
/* Implemented by the DDX. */
|
||||||
extern _X_EXPORT int NewInputDeviceRequest(
|
extern _X_EXPORT int NewInputDeviceRequest(
|
||||||
InputOption *options,
|
InputOption *options,
|
||||||
|
|
|
@ -137,11 +137,9 @@ typedef struct _GrabRec {
|
||||||
typedef struct _KeyClassRec {
|
typedef struct _KeyClassRec {
|
||||||
CARD8 down[DOWN_LENGTH];
|
CARD8 down[DOWN_LENGTH];
|
||||||
CARD8 postdown[DOWN_LENGTH];
|
CARD8 postdown[DOWN_LENGTH];
|
||||||
KeyCode *modifierKeyMap;
|
|
||||||
KeySymsRec curKeySyms;
|
KeySymsRec curKeySyms;
|
||||||
int modifierKeyCount[8];
|
int modifierKeyCount[8];
|
||||||
CARD8 modifierMap[MAP_LENGTH];
|
CARD8 modifierMap[MAP_LENGTH];
|
||||||
CARD8 maxKeysPerModifier;
|
|
||||||
struct _XkbSrvInfo *xkbInfo;
|
struct _XkbSrvInfo *xkbInfo;
|
||||||
} KeyClassRec, *KeyClassPtr;
|
} KeyClassRec, *KeyClassPtr;
|
||||||
|
|
||||||
|
|
|
@ -438,37 +438,8 @@ int maxNumberOfGroups;
|
||||||
if (nGroups > maxNumberOfGroups)
|
if (nGroups > maxNumberOfGroups)
|
||||||
maxNumberOfGroups = nGroups;
|
maxNumberOfGroups = nGroups;
|
||||||
}
|
}
|
||||||
if (_XkbCoreKeycodeInRange(keyc,key)) {
|
|
||||||
if (keyc->modifierMap[key]!=0) {
|
|
||||||
register unsigned bit,i,mask;
|
|
||||||
mask= keyc->modifierMap[key];
|
|
||||||
for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) {
|
|
||||||
if (mask&bit) {
|
|
||||||
keysPerMod[i]++;
|
|
||||||
if (keysPerMod[i]>maxKeysPerMod)
|
|
||||||
maxKeysPerMod= keysPerMod[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxKeysPerMod>0) {
|
|
||||||
tmp= maxKeysPerMod*XkbNumModifiers;
|
|
||||||
if (keyc->modifierKeyMap==NULL)
|
|
||||||
keyc->modifierKeyMap= (KeyCode *)_XkbCalloc(1, tmp);
|
|
||||||
else if (keyc->maxKeysPerModifier<maxKeysPerMod)
|
|
||||||
keyc->modifierKeyMap= (KeyCode *)_XkbRealloc(keyc->modifierKeyMap,tmp);
|
|
||||||
if (keyc->modifierKeyMap==NULL)
|
|
||||||
FatalError("Couldn't allocate modifierKeyMap in UpdateCore\n");
|
|
||||||
bzero(keyc->modifierKeyMap,tmp);
|
|
||||||
}
|
|
||||||
else if ((keyc->maxKeysPerModifier>0)&&(keyc->modifierKeyMap!=NULL)) {
|
|
||||||
_XkbFree(keyc->modifierKeyMap);
|
|
||||||
keyc->modifierKeyMap= NULL;
|
|
||||||
}
|
|
||||||
keyc->maxKeysPerModifier= maxKeysPerMod;
|
|
||||||
|
|
||||||
if (maxSymsPerKey>0) {
|
if (maxSymsPerKey>0) {
|
||||||
/* See Section 12.4 of the XKB Protocol spec. Because of the
|
/* See Section 12.4 of the XKB Protocol spec. Because of the
|
||||||
* single-group distribution for multi-group keyboards, we have to
|
* single-group distribution for multi-group keyboards, we have to
|
||||||
|
@ -489,7 +460,6 @@ int maxNumberOfGroups;
|
||||||
}
|
}
|
||||||
keyc->curKeySyms.mapWidth= maxSymsPerKey;
|
keyc->curKeySyms.mapWidth= maxSymsPerKey;
|
||||||
|
|
||||||
bzero(keysPerMod,sizeof(keysPerMod));
|
|
||||||
for (key=firstCommon;key<=lastCommon;key++) {
|
for (key=firstCommon;key<=lastCommon;key++) {
|
||||||
if (keyc->curKeySyms.map!=NULL) {
|
if (keyc->curKeySyms.map!=NULL) {
|
||||||
KeySym *pCore,*pXKB;
|
KeySym *pCore,*pXKB;
|
||||||
|
@ -568,17 +538,6 @@ int maxNumberOfGroups;
|
||||||
pXKB+= XkbKeyGroupsWidth(xkb,key);
|
pXKB+= XkbKeyGroupsWidth(xkb,key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (keyc->modifierMap[key]!=0) {
|
|
||||||
register unsigned bit,i,mask;
|
|
||||||
mask= keyc->modifierMap[key];
|
|
||||||
for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) {
|
|
||||||
if (mask&bit) {
|
|
||||||
tmp= i*maxKeysPerMod+keysPerMod[i];
|
|
||||||
keyc->modifierKeyMap[tmp]= key;
|
|
||||||
keysPerMod[i]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue