Input: Remove modifierMap from core

We already have modmap (in the exact same format!) in XKB, so just use
that all the time, instead of duplicating the information.

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-17 12:42:01 -07:00
parent f062e90a95
commit 32db27a7f8
16 changed files with 30 additions and 136 deletions

View File

@ -199,8 +199,6 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
dk = device->key; dk = device->key;
mk = master->key; mk = master->key;
memcpy(mk->modifierMap, dk->modifierMap, MAP_LENGTH);
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);
@ -997,7 +995,7 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
if (xE->u.u.type == DeviceKeyPress) { if (xE->u.u.type == DeviceKeyPress) {
if (ret == IS_REPEAT) { /* allow ddx to generate multiple downs */ if (ret == IS_REPEAT) { /* allow ddx to generate multiple downs */
modifiers = k->modifierMap[key]; modifiers = k->xkbInfo->desc->map->modmap[key];
if (!modifiers) { if (!modifiers) {
xE->u.u.type = DeviceKeyRelease; xE->u.u.type = DeviceKeyRelease;
ProcessOtherEvent(xE, device, count); ProcessOtherEvent(xE, device, count);

View File

@ -819,7 +819,7 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
* 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 ||
!key_autorepeats(pDev, key_code) || !key_autorepeats(pDev, key_code) ||
pDev->key->modifierMap[key_code]) pDev->key->xkbInfo->desc->map->modmap[key_code])
return 0; return 0;
} }

View File

@ -32,6 +32,8 @@
#include "input.h" #include "input.h"
#include "inputstr.h" #include "inputstr.h"
#include "xace.h" #include "xace.h"
#include "xkbsrv.h"
#include "xkbstr.h"
/* Check if a modifier map change is okay with the device. /* Check if a modifier map change is okay with the device.
* Returns -1 for BadValue, as it collides with MappingBusy; this particular * Returns -1 for BadValue, as it collides with MappingBusy; this particular
@ -79,7 +81,7 @@ check_modmap_change(ClientPtr client, DeviceIntPtr dev, KeyCode *modmap)
/* None of the old modifiers may be down while we change the map, /* None of the old modifiers may be down while we change the map,
* either. */ * either. */
for (i = syms->minKeyCode; i < syms->maxKeyCode; i++) { for (i = syms->minKeyCode; i < syms->maxKeyCode; i++) {
if (!dev->key->modifierMap[i]) if (!dev->key->xkbInfo->desc->map->modmap[i])
continue; continue;
if (key_is_down(dev, i, KEY_POSTED | KEY_PROCESSED)) { if (key_is_down(dev, i, KEY_POSTED | KEY_PROCESSED)) {
client->errorValue = i; client->errorValue = i;
@ -130,7 +132,7 @@ check_modmap_change_slave(ClientPtr client, DeviceIntPtr master,
static void static void
do_modmap_change(ClientPtr client, DeviceIntPtr dev, CARD8 *modmap) do_modmap_change(ClientPtr client, DeviceIntPtr dev, CARD8 *modmap)
{ {
memcpy(dev->key->modifierMap, modmap, MAP_LENGTH); memcpy(dev->key->xkbInfo->desc->map->modmap, modmap, MAP_LENGTH);
SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev); SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev);
} }
@ -209,7 +211,7 @@ int generate_modkeymap(ClientPtr client, DeviceIntPtr dev,
keys_per_mod[i] = 0; keys_per_mod[i] = 0;
for (i = 8; i < MAP_LENGTH; i++) { for (i = 8; i < MAP_LENGTH; i++) {
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
if (dev->key->modifierMap[i] & (1 << j)) { if (dev->key->xkbInfo->desc->map->modmap[i] & (1 << j)) {
if (++keys_per_mod[j] > max_keys_per_mod) if (++keys_per_mod[j] > max_keys_per_mod)
max_keys_per_mod = keys_per_mod[j]; max_keys_per_mod = keys_per_mod[j];
} }
@ -225,7 +227,7 @@ int generate_modkeymap(ClientPtr client, DeviceIntPtr dev,
for (i = 8; i < MAP_LENGTH; i++) { for (i = 8; i < MAP_LENGTH; i++) {
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
if (dev->key->modifierMap[i] & (1 << j)) { if (dev->key->xkbInfo->desc->map->modmap[i] & (1 << j)) {
modkeymap[(j * max_keys_per_mod) + keys_per_mod[j]] = i; modkeymap[(j * max_keys_per_mod) + keys_per_mod[j]] = i;
keys_per_mod[j]++; keys_per_mod[j]++;
} }

View File

@ -427,7 +427,6 @@ static int dmxKeyboardOn(DeviceIntPtr pDevice, DMXLocalInitInfo *info)
XkbInitKeyboardDeviceStruct(pDevice, XkbInitKeyboardDeviceStruct(pDevice,
&info->names, &info->names,
&info->keySyms, &info->keySyms,
info->modMap,
dmxKeyboardBellProc, dmxKeyboardBellProc,
dmxKeyboardKbdCtrlProc); dmxKeyboardKbdCtrlProc);
@ -461,7 +460,6 @@ static int dmxDeviceOnOff(DeviceIntPtr pDevice, int what)
DevicePtr pDev = (DevicePtr) pDevice; DevicePtr pDev = (DevicePtr) pDevice;
InitKeyboardDeviceStruct(pDev, InitKeyboardDeviceStruct(pDev,
&info.keySyms, &info.keySyms,
info.modMap,
dmxBell, dmxKbdCtrl); dmxBell, dmxKbdCtrl);
} }
if (info.buttonClass) { if (info.buttonClass) {

View File

@ -697,7 +697,7 @@ static void kbdLinuxConvert(DevicePtr pDev,
/* No auto-repeat? */ /* No auto-repeat? */
if ((feed && !feed->ctrl.autoRepeat) if ((feed && !feed->ctrl.autoRepeat)
|| priv->pKeyboard->key->modifierMap[keyCode] || priv->pKeyboard->key->xkbInfo->desc->map->modmap[keyCode]
|| (feed || (feed
&& !(feed->ctrl.autoRepeats[keyCode >> 3] && !(feed->ctrl.autoRepeats[keyCode >> 3]
& (1 << (keyCode & 7))))) return; /* Ignore */ & (1 << (keyCode & 7))))) return; /* Ignore */

View File

@ -331,7 +331,7 @@ static void kbdUSBConvert(DevicePtr pDev,
/* No auto-repeat? */ /* No auto-repeat? */
if ((feed && !feed->ctrl.autoRepeat) if ((feed && !feed->ctrl.autoRepeat)
|| priv->pDevice->key->modifierMap[keyCode] || priv->pDevice->key->xkbInfo->desc->map->modmap[keyCode]
|| (feed || (feed
&& !(feed->ctrl.autoRepeats[keyCode >> 3] && !(feed->ctrl.autoRepeats[keyCode >> 3]
& (1 << (keyCode & 7))))) return; /* Ignore */ & (1 << (keyCode & 7))))) return; /* Ignore */

View File

@ -782,7 +782,7 @@ ephyrUpdateModifierState(unsigned int state)
int count = keyc->modifierKeyCount[i]; int count = keyc->modifierKeyCount[i];
for (key = 0; key < MAP_LENGTH; key++) for (key = 0; key < MAP_LENGTH; key++)
if (keyc->modifierMap[key] & mask) if (keyc->xkbInfo->desc->map->modmap[key] & mask)
{ {
int bit; int bit;
BYTE *kptr; BYTE *kptr;
@ -802,9 +802,9 @@ ephyrUpdateModifierState(unsigned int state)
/* Modifier shoud be down, but isn't */ /* Modifier shoud be down, but isn't */
if (!(keyc->state & mask) && (state & mask)) if (!(keyc->state & mask) && (state & mask))
for (key = 0; key < MAP_LENGTH; key++) for (key = 0; key < MAP_LENGTH; key++)
if (keyc->modifierMap[key] & mask) if (keyc->xkbInfo->desc->map->modmap[key] & mask)
{ {
if (keyc->modifierMap[key] & mask && ephyrKbd && if (keyc->xkbInfo->desc->map->modmap[key] & mask && ephyrKbd &&
((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */ KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */
break; break;

View File

@ -309,7 +309,6 @@ struct _KdKeyboardInfo {
CARD8 keyState[KD_KEY_COUNT/8]; CARD8 keyState[KD_KEY_COUNT/8];
int minScanCode; int minScanCode;
int maxScanCode; int maxScanCode;
CARD8 modmap[MAP_LENGTH];
KeySymsRec keySyms; KeySymsRec keySyms;
int leds; int leds;

View File

@ -660,85 +660,6 @@ KdKbdCtrl (DeviceIntPtr pDevice, KeybdCtrl *ctrl)
extern KeybdCtrl defaultKeyboardControl; extern KeybdCtrl defaultKeyboardControl;
static void
KdInitAutoRepeats (KdKeyboardInfo *ki)
{
int key_code;
unsigned char mask;
int i;
unsigned char *repeats;
repeats = defaultKeyboardControl.autoRepeats;
memset (repeats, '\0', 32);
for (key_code = KD_MIN_KEYCODE; key_code <= KD_MAX_KEYCODE; key_code++)
{
if (!ki->modmap[key_code])
{
i = key_code >> 3;
mask = 1 << (key_code & 7);
repeats[i] |= mask;
}
}
}
const KdKeySymModsRec kdKeySymMods[] = {
{ XK_Control_L, ControlMask },
{ XK_Control_R, ControlMask },
{ XK_Shift_L, ShiftMask },
{ XK_Shift_R, ShiftMask },
{ XK_Caps_Lock, LockMask },
{ XK_Shift_Lock, LockMask },
{ XK_Alt_L, Mod1Mask },
{ XK_Alt_R, Mod1Mask },
{ XK_Meta_L, Mod1Mask },
{ XK_Meta_R, Mod1Mask },
{ XK_Num_Lock, Mod2Mask },
{ XK_Super_L, Mod3Mask },
{ XK_Super_R, Mod3Mask },
{ XK_Hyper_L, Mod3Mask },
{ XK_Hyper_R, Mod3Mask },
{ XK_Mode_switch, Mod4Mask },
/* PDA specific hacks */
#ifdef XF86XK_Start
{ XF86XK_Start, ControlMask },
#endif
{ XK_Menu, ShiftMask },
{ XK_telephone, Mod1Mask },
#ifdef XF86XK_AudioRecord
{ XF86XK_AudioRecord, Mod2Mask },
#endif
#ifdef XF86XK_Calendar
{ XF86XK_Calendar, Mod3Mask }
#endif
};
#define NUM_SYM_MODS (sizeof(kdKeySymMods) / sizeof(kdKeySymMods[0]))
static void
KdInitModMap (KdKeyboardInfo *ki)
{
int key_code;
int row;
int width;
KeySym *syms;
int i;
width = ki->keySyms.mapWidth;
for (key_code = ki->keySyms.minKeyCode; key_code <= ki->keySyms.maxKeyCode; key_code++)
{
ki->modmap[key_code] = 0;
syms = ki->keySyms.map + (key_code - ki->keySyms.minKeyCode) * width;
for (row = 0; row < width; row++, syms++)
{
for (i = 0; i < NUM_SYM_MODS; i++)
{
if (*syms == kdKeySymMods[i].modsym)
ki->modmap[key_code] |= kdKeySymMods[i].modbit;
}
}
}
}
static int static int
KdKeyboardProc(DeviceIntPtr pDevice, int onoff) KdKeyboardProc(DeviceIntPtr pDevice, int onoff)
{ {
@ -792,9 +713,6 @@ KdKeyboardProc(DeviceIntPtr pDevice, int onoff)
return !Success; return !Success;
} }
KdInitModMap(ki);
KdInitAutoRepeats(ki);
memset(&rmlvo, 0, sizeof(rmlvo)); memset(&rmlvo, 0, sizeof(rmlvo));
rmlvo.rules = ki->xkbRules; rmlvo.rules = ki->xkbRules;
rmlvo.model = ki->xkbModel; rmlvo.model = ki->xkbModel;

View File

@ -119,7 +119,6 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
int mapWidth; int mapWidth;
int min_keycode, max_keycode; int min_keycode, max_keycode;
KeySymsRec keySyms; KeySymsRec keySyms;
CARD8 modmap[MAP_LENGTH];
int i, j; int i, j;
XKeyboardState values; XKeyboardState values;
XkbComponentNamesRec names; XkbComponentNamesRec names;
@ -130,7 +129,6 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
switch (onoff) switch (onoff)
{ {
case DEVICE_INIT: case DEVICE_INIT:
modifier_keymap = XGetModifierMapping(xnestDisplay);
XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode); XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
#ifdef _XSERVER64 #ifdef _XSERVER64
{ {
@ -153,18 +151,6 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
&mapWidth); &mapWidth);
#endif #endif
for (i = 0; i < MAP_LENGTH; i++)
modmap[i] = 0;
for (j = 0; j < 8; j++)
for(i = 0; i < modifier_keymap->max_keypermod; i++) {
CARD8 keycode;
if ((keycode =
modifier_keymap->
modifiermap[j * modifier_keymap->max_keypermod + i]))
modmap[keycode] |= 1<<j;
}
XFreeModifiermap(modifier_keymap);
keySyms.minKeyCode = min_keycode; keySyms.minKeyCode = min_keycode;
keySyms.maxKeyCode = max_keycode; keySyms.maxKeyCode = max_keycode;
keySyms.mapWidth = mapWidth; keySyms.mapWidth = mapWidth;
@ -189,8 +175,8 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
options = XKB_DFLT_OPTIONS; options = XKB_DFLT_OPTIONS;
XkbSetRulesDflts(rules, model, layout, variants, options); XkbSetRulesDflts(rules, model, layout, variants, options);
XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, modmap, XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms,
xnestBell, xnestChangeKeyboardControl); xnestBell, xnestChangeKeyboardControl);
XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls); XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
XkbFreeKeyboard(xkb, 0, False); XkbFreeKeyboard(xkb, 0, False);
xfree(keymap); xfree(keymap);
@ -250,7 +236,7 @@ xnestUpdateModifierState(unsigned int state)
int count = keyc->modifierKeyCount[i]; int count = keyc->modifierKeyCount[i];
for (key = 0; key < MAP_LENGTH; key++) for (key = 0; key < MAP_LENGTH; key++)
if (keyc->modifierMap[key] & mask) { if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
int bit; int bit;
BYTE *kptr; BYTE *kptr;
@ -269,7 +255,7 @@ xnestUpdateModifierState(unsigned int state)
*/ */
if (!(keyc->state & mask) && (state & mask)) if (!(keyc->state & mask) && (state & mask))
for (key = 0; key < MAP_LENGTH; key++) for (key = 0; key < MAP_LENGTH; key++)
if (keyc->modifierMap[key] & mask) { if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
xnestQueueKeyEvent(KeyPress, key); xnestQueueKeyEvent(KeyPress, key);
break; break;
} }

View File

@ -342,6 +342,16 @@ void DarwinKeyboardInit(DeviceIntPtr pDev) {
pthread_mutex_lock(&keyInfo_mutex); pthread_mutex_lock(&keyInfo_mutex);
assert(XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, keyInfo.modMap, assert(XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, keyInfo.modMap,
QuartzBell, DarwinChangeKeyboardControl)); QuartzBell, DarwinChangeKeyboardControl));
assert(pDev->key->xkbInfo->desc->map->modmap!=NULL);
memcpy(pDev->key->xkbInfo->desc->map->modmap, keyInfo.modMap, sizeof(keyInfo.modMap));
pthread_mutex_unlock(&keyInfo_mutex);
QuartzXkbUpdate(pDev);
#else
pthread_mutex_lock(&keyInfo_mutex);
assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms,
QuartzBell,
DarwinChangeKeyboardControl ));
pthread_mutex_unlock(&keyInfo_mutex); pthread_mutex_unlock(&keyInfo_mutex);
/* Get our key repeat settings from GlobalPreferences */ /* Get our key repeat settings from GlobalPreferences */

View File

@ -217,7 +217,6 @@ int
winKeybdProc (DeviceIntPtr pDeviceInt, int iState) winKeybdProc (DeviceIntPtr pDeviceInt, int iState)
{ {
KeySymsRec keySyms; KeySymsRec keySyms;
CARD8 modMap[MAP_LENGTH];
DevicePtr pDevice = (DevicePtr) pDeviceInt; DevicePtr pDevice = (DevicePtr) pDeviceInt;
XkbComponentNamesRec names; XkbComponentNamesRec names;
XkbSrvInfoPtr xkbi; XkbSrvInfoPtr xkbi;
@ -228,8 +227,6 @@ winKeybdProc (DeviceIntPtr pDeviceInt, int iState)
case DEVICE_INIT: case DEVICE_INIT:
winConfigKeyboard (pDeviceInt); winConfigKeyboard (pDeviceInt);
winGetKeyMappings (&keySyms, modMap);
/* FIXME: Maybe we should use winGetKbdLeds () here? */ /* FIXME: Maybe we should use winGetKbdLeds () here? */
defaultKeyboardControl.leds = g_winInfo.keyboard.leds; defaultKeyboardControl.leds = g_winInfo.keyboard.leds;
@ -237,7 +234,6 @@ winKeybdProc (DeviceIntPtr pDeviceInt, int iState)
{ {
InitKeyboardDeviceStruct (pDevice, InitKeyboardDeviceStruct (pDevice,
&keySyms, &keySyms,
modMap,
winKeybdBell, winKeybdBell,
winKeybdCtrl); winKeybdCtrl);
} }
@ -263,7 +259,7 @@ winKeybdProc (DeviceIntPtr pDeviceInt, int iState)
g_winInfo.xkb.layout, g_winInfo.xkb.variant, g_winInfo.xkb.layout, g_winInfo.xkb.variant,
g_winInfo.xkb.options); g_winInfo.xkb.options);
XkbInitKeyboardDeviceStruct (pDeviceInt, &names, &keySyms, XkbInitKeyboardDeviceStruct (pDeviceInt, &names, &keySyms,
modMap, winKeybdBell, winKeybdCtrl); winKeybdBell, winKeybdCtrl);
} }
if (!g_winInfo.xkb.disable) if (!g_winInfo.xkb.disable)

View File

@ -138,8 +138,7 @@ typedef struct _KeyClassRec {
CARD8 down[DOWN_LENGTH]; CARD8 down[DOWN_LENGTH];
CARD8 postdown[DOWN_LENGTH]; CARD8 postdown[DOWN_LENGTH];
KeySymsRec curKeySyms; KeySymsRec curKeySyms;
int modifierKeyCount[8]; int modifierKeyCount[8];
CARD8 modifierMap[MAP_LENGTH];
struct _XkbSrvInfo *xkbInfo; struct _XkbSrvInfo *xkbInfo;
} KeyClassRec, *KeyClassPtr; } KeyClassRec, *KeyClassPtr;

View File

@ -5836,9 +5836,6 @@ ProcXkbGetKbdByName(ClientPtr client)
if (tmpd == dev || if (tmpd == dev ||
(dev->id == inputInfo.keyboard->id && tmpd->key && (dev->id == inputInfo.keyboard->id && tmpd->key &&
tmpd->coreEvents)) { tmpd->coreEvents)) {
memcpy(tmpd->key->modifierMap, xkb->map->modmap,
xkb->max_key_code + 1);
if (tmpd != dev) if (tmpd != dev)
XkbCopyKeymap(dev->key->xkbInfo->desc, XkbCopyKeymap(dev->key->xkbInfo->desc,
tmpd->key->xkbInfo->desc, True); tmpd->key->xkbInfo->desc, True);

View File

@ -506,9 +506,6 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet *rmlvo,
XkbInitControls(dev, xkbi); XkbInitControls(dev, xkbi);
/* XXX: Doesn't XUCD make this redundant? */
memcpy(dev->key->modifierMap, xkb->map->modmap, xkb->max_key_code + 1);
XkbInitIndicatorMap(xkbi); XkbInitIndicatorMap(xkbi);
XkbDDXInitDevice(dev); XkbDDXInitDevice(dev);

View File

@ -363,17 +363,14 @@ int maxSymsPerKey,maxKeysPerMod, maxGroup1Width;
int first,last,firstCommon,lastCommon; int first,last,firstCommon,lastCommon;
XkbDescPtr xkb; XkbDescPtr xkb;
KeyClassPtr keyc; KeyClassPtr keyc;
CARD8 keysPerMod[XkbNumModifiers];
int maxNumberOfGroups; int maxNumberOfGroups;
if (!keybd || !keybd->key || !keybd->key->xkbInfo) if (!keybd || !keybd->key || !keybd->key->xkbInfo)
return; return;
xkb= keybd->key->xkbInfo->desc; xkb= keybd->key->xkbInfo->desc;
keyc= keybd->key; keyc= keybd->key;
maxSymsPerKey= maxKeysPerMod= maxGroup1Width= 0; maxSymsPerKey= maxGroup1Width= 0;
maxNumberOfGroups = 0; maxNumberOfGroups = 0;
bzero(keysPerMod,sizeof(keysPerMod));
memcpy(keyc->modifierMap,xkb->map->modmap,xkb->max_key_code+1);
if ((xkb->min_key_code==keyc->curKeySyms.minKeyCode)&& if ((xkb->min_key_code==keyc->curKeySyms.minKeyCode)&&
(xkb->max_key_code==keyc->curKeySyms.maxKeyCode)) { (xkb->max_key_code==keyc->curKeySyms.maxKeyCode)) {
first= firstCommon= xkb->min_key_code; first= firstCommon= xkb->min_key_code;
@ -590,10 +587,7 @@ unsigned check;
XkbDescPtr xkb= kbd->key->xkbInfo->desc; XkbDescPtr xkb= kbd->key->xkbInfo->desc;
XkbSetCauseCoreReq(&cause,X_SetModifierMapping,client); XkbSetCauseCoreReq(&cause,X_SetModifierMapping,client);
num = xkb->max_key_code-xkb->min_key_code+1; num = xkb->max_key_code-xkb->min_key_code+1;
memcpy(xkb->map->modmap,kbd->key->modifierMap,xkb->max_key_code+1);
changes.map.changed|= XkbModifierMapMask; changes.map.changed|= XkbModifierMapMask;
changes.map.first_modmap_key= xkb->min_key_code; changes.map.first_modmap_key= xkb->min_key_code;
changes.map.num_modmap_keys= num; changes.map.num_modmap_keys= num;