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:
Daniel Stone 2008-04-16 19:15:30 +03:00
parent cf6a2fc2bd
commit f062e90a95
12 changed files with 335 additions and 319 deletions

View File

@ -201,21 +201,6 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
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.maxKeyCode = dk->curKeySyms.maxKeyCode;
SetKeySymsMap(&mk->curKeySyms, &dk->curKeySyms);
@ -498,7 +483,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
if (from->key)
{
KeyCode *oldModKeyMap;
KeySym *oldMap;
struct _XkbSrvInfo *oldXkbInfo;
if (!to->key)
@ -515,7 +499,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
classes->key = NULL;
}
oldModKeyMap = to->key->modifierKeyMap;
oldMap = to->key->curKeySyms.map;
oldXkbInfo = to->key->xkbInfo;
@ -528,7 +511,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
memcpy(oldMap, from->key->curKeySyms.map, bytes);
}
to->key->modifierKeyMap = oldModKeyMap;
to->key->curKeySyms.map = oldMap;
to->key->xkbInfo = oldXkbInfo;
@ -1664,86 +1646,6 @@ SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map)
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
SendDeviceMappingNotify(ClientPtr client, CARD8 request,
KeyCode firstKeyCode, CARD8 count, DeviceIntPtr dev)

View File

@ -87,36 +87,34 @@ SProcXGetDeviceModifierMapping(ClientPtr client)
int
ProcXGetDeviceModifierMapping(ClientPtr client)
{
CARD8 maxkeys;
DeviceIntPtr dev;
xGetDeviceModifierMappingReply rep;
KeyClassPtr kp;
int rc;
KeyCode *modkeymap = NULL;
int ret, max_keys_per_mod;
REQUEST(xGetDeviceModifierMappingReq);
REQUEST_SIZE_MATCH(xGetDeviceModifierMappingReq);
rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
if (rc != Success)
return rc;
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
if (ret != Success)
return ret;
kp = dev->key;
if (kp == NULL)
return BadMatch;
maxkeys = kp->maxKeysPerModifier;
ret = generate_modkeymap(client, dev, &modkeymap, &max_keys_per_mod);
if (ret != Success)
return ret;
rep.repType = X_Reply;
rep.RepType = X_GetDeviceModifierMapping;
rep.numKeyPerModifier = maxkeys;
rep.numKeyPerModifier = max_keys_per_mod;
rep.sequenceNumber = client->sequence;
/* 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);
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;
}

View File

@ -91,33 +91,39 @@ ProcXSetDeviceModifierMapping(ClientPtr client)
int ret;
xSetDeviceModifierMappingReply rep;
DeviceIntPtr dev;
KeyClassPtr kp;
REQUEST(xSetDeviceModifierMappingReq);
REQUEST_AT_LEAST_SIZE(xSetDeviceModifierMappingReq);
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
if (ret != Success)
return ret;
if (stuff->length != ((sizeof(xSetDeviceModifierMappingReq) >> 2) +
(stuff->numKeyPerModifier << 1)))
return BadLength;
rep.repType = X_Reply;
rep.RepType = X_SetDeviceModifierMapping;
rep.length = 0;
rep.sequenceNumber = client->sequence;
ret = SetModifierMapping(client, dev, stuff->length,
(sizeof(xSetDeviceModifierMappingReq) >> 2),
stuff->numKeyPerModifier, (BYTE *) & stuff[1],
&kp);
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess);
if (ret != Success)
return ret;
ret = change_modmap(client, dev, (KeyCode *) &stuff[1],
stuff->numKeyPerModifier);
if (ret == Success)
ret = MappingSuccess;
if (ret == MappingSuccess || ret == MappingBusy || ret == MappingFailed) {
rep.success = ret;
if (ret == MappingSuccess)
SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev);
WriteReplyToClient(client, sizeof(xSetDeviceModifierMappingReply),
&rep);
} else if (ret == -1)
return BadValue;
}
else if (ret == -1) {
return BadValue;
}
else {
return ret;
}
return Success;
}

View File

@ -25,6 +25,7 @@ libdix_la_SOURCES = \
glyphcurs.c \
grabs.c \
initatoms.c \
inpututils.c \
main.c \
pixmap.c \
privates.c \

View File

@ -620,7 +620,6 @@ FreeDeviceClass(int type, pointer *class)
(*k)->xkbInfo = NULL;
}
xfree((*k)->curKeySyms.map);
xfree((*k)->modifierKeyMap);
xfree((*k));
break;
}
@ -1453,109 +1452,10 @@ BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval)
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
ProcSetModifierMapping(ClientPtr client)
{
xSetModifierMappingReply rep;
DeviceIntPtr dev;
int rc;
REQUEST(xSetModifierMappingReq);
REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
@ -1568,14 +1468,16 @@ ProcSetModifierMapping(ClientPtr client)
rep.length = 0;
rep.sequenceNumber = client->sequence;
rc = DoSetModifierMapping(client, (KeyCode *)&stuff[1],
stuff->numKeyPerModifier, &rep);
if (rc != Success)
rc = change_modmap(client, PickKeyboard(client), (KeyCode *)&stuff[1],
stuff->numKeyPerModifier);
if (rc == MappingFailed || rc == -1)
rc = BadValue;
if (rc != Success && rc != MappingSuccess && rc != MappingFailed &&
rc != MappingBusy)
return rc;
for (dev = inputInfo.devices; dev; dev = dev->next)
if (dev->key && dev->coreEvents)
SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev);
rep.success = rc;
WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
return client->noClientException;
}
@ -1584,26 +1486,26 @@ int
ProcGetModifierMapping(ClientPtr client)
{
xGetModifierMappingReply rep;
DeviceIntPtr dev = PickKeyboard(client);
KeyClassPtr keyc = dev->key;
int rc;
int ret, max_keys_per_mod = 0;
KeyCode *modkeymap = NULL;
REQUEST_SIZE_MATCH(xReq);
rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess);
if (rc != Success)
return rc;
ret = generate_modkeymap(client, PickKeyboard(client), &modkeymap,
&max_keys_per_mod);
if (ret != Success)
return ret;
rep.type = X_Reply;
rep.numKeyPerModifier = keyc->maxKeysPerModifier;
rep.numKeyPerModifier = max_keys_per_mod;
rep.sequenceNumber = client->sequence;
/* 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);
(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;
}

View File

@ -84,22 +84,35 @@ GetMotionHistorySize(void)
return MOTION_HISTORY_SIZE;
}
static void
set_key_down(DeviceIntPtr pDev, int key_code)
void
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
set_key_up(DeviceIntPtr pDev, int key_code)
void
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
key_is_down(DeviceIntPtr pDev, int key_code)
Bool
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
@ -787,8 +800,6 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
int num_valuators, int *valuators) {
int numEvents = 0;
CARD32 ms = 0;
KeySym *map;
KeySym sym;
deviceKeyButtonPointer *kbp = NULL;
if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
@ -798,16 +809,12 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
numEvents = 1;
map = pDev->key->curKeySyms.map;
sym = map[(key_code - pDev->key->curKeySyms.minKeyCode)
* pDev->key->curKeySyms.mapWidth];
events = updateFromMaster(events, pDev, &numEvents);
numEvents += countValuatorEvents(num_valuators);
/* 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,
* or we have a modifier, don't generate a repeat event. */
if (!pDev->kbdfeed->ctrl.autoRepeat ||
@ -824,11 +831,11 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
kbp->detail = key_code;
if (type == KeyPress) {
kbp->type = DeviceKeyPress;
set_key_down(pDev, key_code);
set_key_down(pDev, key_code, KEY_POSTED);
}
else if (type == KeyRelease) {
kbp->type = DeviceKeyRelease;
set_key_up(pDev, key_code);
set_key_up(pDev, key_code, KEY_POSTED);
}
events++;

239
dix/inpututils.c Normal file
View File

@ -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;
}

View File

@ -370,6 +370,10 @@ void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr pDev,
KeySymsRec keySyms;
DEBUG_LOG("DarwinKeyboardReloadHandler\n");
if (pDev->key) {
if (pDev->key->curKeySyms.map) xfree(pDev->key->curKeySyms.map);
xfree(pDev->key);
}
DarwinLoadKeyboardMapping(&keySyms);
DarwinKeyboardSetDeviceKeyMap(&keySyms);

View File

@ -31,6 +31,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define EXEVENTS_H
#include <X11/extensions/XIproto.h>
#include "inputstr.h"
/**
* Attached to the devPrivates of each client. Specifies the version number as
@ -136,15 +137,6 @@ extern _X_EXPORT int SetButtonMapping (
int /* nElts */,
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(
ClientPtr /* client, */,
CARD8 /* request, */,

View File

@ -222,6 +222,15 @@ typedef struct _InputOption {
struct _InputOption *next;
} 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 DeviceIntPtr AddInputDevice(
@ -373,13 +382,6 @@ extern _X_EXPORT Bool BadDeviceMap(
unsigned /*high*/,
XID* /*errval*/);
extern _X_EXPORT Bool AllModifierKeysAreUp(
DeviceIntPtr /*device*/,
CARD8* /*map1*/,
int /*per1*/,
CARD8* /*map2*/,
int /*per2*/);
extern _X_EXPORT void NoteLedState(
DeviceIntPtr /*keybd*/,
int /*led*/,
@ -498,6 +500,12 @@ extern _X_EXPORT int AllocMasterDevice(ClientPtr client,
extern _X_EXPORT void DeepCopyDeviceClasses(DeviceIntPtr from,
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. */
extern _X_EXPORT int NewInputDeviceRequest(
InputOption *options,

View File

@ -137,11 +137,9 @@ typedef struct _GrabRec {
typedef struct _KeyClassRec {
CARD8 down[DOWN_LENGTH];
CARD8 postdown[DOWN_LENGTH];
KeyCode *modifierKeyMap;
KeySymsRec curKeySyms;
int modifierKeyCount[8];
CARD8 modifierMap[MAP_LENGTH];
CARD8 maxKeysPerModifier;
struct _XkbSrvInfo *xkbInfo;
} KeyClassRec, *KeyClassPtr;

View File

@ -438,37 +438,8 @@ int maxNumberOfGroups;
if (nGroups > maxNumberOfGroups)
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) {
/* See Section 12.4 of the XKB Protocol spec. Because of the
* single-group distribution for multi-group keyboards, we have to
@ -489,7 +460,6 @@ int maxNumberOfGroups;
}
keyc->curKeySyms.mapWidth= maxSymsPerKey;
bzero(keysPerMod,sizeof(keysPerMod));
for (key=firstCommon;key<=lastCommon;key++) {
if (keyc->curKeySyms.map!=NULL) {
KeySym *pCore,*pXKB;
@ -568,17 +538,6 @@ int maxNumberOfGroups;
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;
}