XKBSetMap.c revision 1ab64890
1/* $Xorg: XKBSetMap.c,v 1.4 2000/08/17 19:45:03 cpqbld Exp $ */ 2/************************************************************ 3Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 4 5Permission to use, copy, modify, and distribute this 6software and its documentation for any purpose and without 7fee is hereby granted, provided that the above copyright 8notice appear in all copies and that both that copyright 9notice and this permission notice appear in supporting 10documentation, and that the name of Silicon Graphics not be 11used in advertising or publicity pertaining to distribution 12of the software without specific prior written permission. 13Silicon Graphics makes no representation about the suitability 14of this software for any purpose. It is provided "as is" 15without any express or implied warranty. 16 17SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 18SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 20GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 21DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 22DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 23OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 24THE USE OR PERFORMANCE OF THIS SOFTWARE. 25 26********************************************************/ 27/* $XFree86: xc/lib/X11/XKBSetMap.c,v 3.2 2001/01/17 19:41:49 dawes Exp $ */ 28 29#ifdef HAVE_CONFIG_H 30#include <config.h> 31#endif 32#include <stdio.h> 33#define NEED_REPLIES 34#define NEED_EVENTS 35#include "Xlibint.h" 36#include <X11/extensions/XKBproto.h> 37#include "XKBlibint.h" 38 39static int 40_XkbSizeKeyTypes(XkbDescPtr xkb,xkbSetMapReq *req) 41{ 42 XkbKeyTypePtr map; 43 int i,len; 44 45 if (((req->present&XkbKeyTypesMask)==0)||(req->nTypes==0)) { 46 req->present&= ~XkbKeyTypesMask; 47 req->firstType= req->nTypes= 0; 48 return 0; 49 } 50 len= 0; 51 map= &xkb->map->types[req->firstType]; 52 for (i=0;i<req->nTypes;i++,map++){ 53 len+= SIZEOF(xkbKeyTypeWireDesc); 54 len+= map->map_count*SIZEOF(xkbKTSetMapEntryWireDesc); 55 if (map->preserve) 56 len+= map->map_count*SIZEOF(xkbModsWireDesc); 57 } 58 return len; 59} 60 61static void 62_XkbWriteKeyTypes(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) 63{ 64 char * buf; 65 XkbKeyTypePtr type; 66 int i,n,sz; 67 xkbKeyTypeWireDesc *desc; 68 69 if ((req->present&XkbKeyTypesMask)==0) 70 return; 71 type= &xkb->map->types[req->firstType]; 72 for (i=0;i<req->nTypes;i++,type++) { 73 sz= SIZEOF(xkbKeyTypeWireDesc); 74 sz+= type->map_count*SIZEOF(xkbKTSetMapEntryWireDesc); 75 if (type->preserve) 76 sz+= type->map_count*SIZEOF(xkbModsWireDesc); 77 BufAlloc(xkbKeyTypeWireDesc *,desc,sz); 78 desc->mask = type->mods.mask; 79 desc->realMods = type->mods.real_mods; 80 desc->virtualMods = type->mods.vmods; 81 desc->numLevels = type->num_levels; 82 desc->nMapEntries = type->map_count; 83 desc->preserve = (type->preserve!=NULL); 84 buf= (char *)&desc[1]; 85 if (desc->nMapEntries>0) { 86 xkbKTSetMapEntryWireDesc *wire; 87 wire= (xkbKTSetMapEntryWireDesc *)buf; 88 for (n=0;n<type->map_count;n++,wire++) { 89 wire->level= type->map[n].level; 90 wire->realMods= type->map[n].mods.real_mods; 91 wire->virtualMods= type->map[n].mods.vmods; 92 } 93 buf= (char *)wire; 94 if (type->preserve) { 95 xkbModsWireDesc *pwire; 96 pwire= (xkbModsWireDesc *)buf; 97 for (n=0;n<type->map_count;n++,pwire++) { 98 pwire->realMods= type->preserve[n].real_mods; 99 pwire->virtualMods= type->preserve[n].vmods; 100 } 101 } 102 } 103 } 104 return; 105} 106 107static int 108_XkbSizeKeySyms(XkbDescPtr xkb,xkbSetMapReq *req) 109{ 110 int i,len; 111 unsigned nSyms; 112 113 if (((req->present&XkbKeySymsMask)==0)||(req->nKeySyms==0)) { 114 req->present&= ~XkbKeySymsMask; 115 req->firstKeySym= req->nKeySyms= 0; 116 req->totalSyms= 0; 117 return 0; 118 } 119 len= (int)(req->nKeySyms*sizeof(XkbSymMapRec)); 120 for (i=nSyms=0;i<req->nKeySyms;i++) { 121 nSyms+= XkbKeyNumSyms(xkb,i+req->firstKeySym); 122 } 123 len+= nSyms*sizeof(CARD32); 124 req->totalSyms= nSyms; 125 return len; 126} 127 128static void 129_XkbWriteKeySyms(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) 130{ 131register KeySym * pSym; 132CARD32 * outSym; 133XkbSymMapPtr symMap; 134xkbSymMapWireDesc *desc; 135register int i; 136 137 if ((req->present&XkbKeySymsMask)==0) 138 return; 139 symMap = &xkb->map->key_sym_map[req->firstKeySym]; 140 for (i=0;i<req->nKeySyms;i++,symMap++) { 141 BufAlloc(xkbSymMapWireDesc *,desc, 142 SIZEOF(xkbSymMapWireDesc)+ 143 (XkbKeyNumSyms(xkb,i+req->firstKeySym)*sizeof(CARD32))); 144 desc->ktIndex[0] = symMap->kt_index[0]; 145 desc->ktIndex[1] = symMap->kt_index[1]; 146 desc->ktIndex[2] = symMap->kt_index[2]; 147 desc->ktIndex[3] = symMap->kt_index[3]; 148 desc->groupInfo = symMap->group_info; 149 desc->width = symMap->width; 150 desc->nSyms = XkbKeyNumSyms(xkb,i+req->firstKeySym); 151 outSym = (CARD32 *)&desc[1]; 152 if (desc->nSyms>0) { 153 pSym = XkbKeySymsPtr(xkb,i+req->firstKeySym); 154 _XkbWriteCopyKeySyms(pSym,outSym,desc->nSyms); 155 } 156 } 157 return; 158} 159 160static int 161_XkbSizeKeyActions(XkbDescPtr xkb,xkbSetMapReq *req) 162{ 163 int i,len,nActs; 164 165 if (((req->present&XkbKeyActionsMask)==0)||(req->nKeyActs==0)) { 166 req->present&= ~XkbKeyActionsMask; 167 req->firstKeyAct= req->nKeyActs= 0; 168 req->totalActs= 0; 169 return 0; 170 } 171 for (nActs=i=0;i<req->nKeyActs;i++) { 172 if (xkb->server->key_acts[i+req->firstKeyAct]!=0) 173 nActs+= XkbKeyNumActions(xkb,i+req->firstKeyAct); 174 } 175 len= XkbPaddedSize(req->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc)); 176 req->totalActs= nActs; 177 return len; 178} 179 180static void 181_XkbWriteKeyActions(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) 182{ 183 register int i; 184 int n; 185 CARD8 *numDesc; 186 XkbAction *actDesc; 187 188 if ((req->present&XkbKeyActionsMask)==0) 189 return; 190 n = XkbPaddedSize(req->nKeyActs); 191 n+= (req->totalActs*SIZEOF(xkbActionWireDesc)); 192 193 BufAlloc(CARD8 *,numDesc,n); 194 for (i=0;i<req->nKeyActs;i++) { 195 if (xkb->server->key_acts[i+req->firstKeyAct]==0) 196 numDesc[i] = 0; 197 else numDesc[i] = XkbKeyNumActions(xkb,(i+req->firstKeyAct)); 198 } 199 actDesc = (XkbAction *)&numDesc[XkbPaddedSize(req->nKeyActs)]; 200 for (i=0;i<req->nKeyActs;i++) { 201 if (xkb->server->key_acts[i+req->firstKeyAct]!=0) { 202 n = XkbKeyNumActions(xkb,(i+req->firstKeyAct)); 203 memcpy(actDesc,XkbKeyActionsPtr(xkb,(i+req->firstKeyAct)), 204 n*SIZEOF(xkbActionWireDesc)); 205 actDesc+= n; 206 } 207 } 208 return; 209} 210 211static int 212_XkbSizeKeyBehaviors(XkbDescPtr xkb,xkbSetMapReq *req) 213{ 214register int i,first,last,nFound; 215 216 if (((req->present&XkbKeyBehaviorsMask)==0)||(req->nKeyBehaviors<1)) { 217 req->present&= ~XkbKeyBehaviorsMask; 218 req->firstKeyBehavior= req->nKeyBehaviors= 0; 219 req->totalKeyBehaviors= 0; 220 return 0; 221 } 222 first= req->firstKeyBehavior; 223 last= first+req->nKeyBehaviors-1; 224 for (i=first,nFound=0;i<=last;i++) { 225 if (xkb->server->behaviors[i].type!=XkbKB_Default) 226 nFound++; 227 } 228 req->totalKeyBehaviors= nFound; 229 return (nFound*SIZEOF(xkbBehaviorWireDesc)); 230} 231 232static void 233_XkbWriteKeyBehaviors(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) 234{ 235register int i,first,last; 236xkbBehaviorWireDesc * wire; 237char * buf; 238 239 if ((req->present&XkbKeyBehaviorsMask)==0) 240 return; 241 first= req->firstKeyBehavior; 242 last= first+req->nKeyBehaviors-1; 243 244 i= req->totalKeyBehaviors*SIZEOF(xkbBehaviorWireDesc); 245 BufAlloc(char *,buf,i); 246 wire= (xkbBehaviorWireDesc *)buf; 247 for (i=first;i<=last;i++) { 248 if (xkb->server->behaviors[i].type!=XkbKB_Default) { 249 wire->key= i; 250 wire->type= xkb->server->behaviors[i].type; 251 wire->data= xkb->server->behaviors[i].data; 252 buf+= SIZEOF(xkbBehaviorWireDesc); 253 wire= (xkbBehaviorWireDesc *)buf; 254 } 255 } 256 return; 257} 258 259static unsigned 260_XkbSizeVirtualMods(xkbSetMapReq *req) 261{ 262register int i,bit,nMods; 263 264 if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0)) { 265 req->present&= ~XkbVirtualModsMask; 266 req->virtualMods= 0; 267 return 0; 268 } 269 for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 270 if (req->virtualMods&bit) 271 nMods++; 272 } 273 return XkbPaddedSize(nMods); 274} 275 276static void 277_XkbWriteVirtualMods( Display * dpy, 278 XkbDescPtr xkb, 279 xkbSetMapReq * req, 280 unsigned size) 281{ 282 register int i,bit; 283 CARD8 *vmods; 284 285 /* This was req->present&XkbVirtualModsMask==0, and '==' beats '&' */ 286 if (((req->present & XkbVirtualModsMask) == 0) || (size < 1)) 287 return; 288 BufAlloc(CARD8 *,vmods,size); 289 for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 290 if (req->virtualMods&bit) 291 *vmods++= xkb->server->vmods[i]; 292 } 293 return; 294} 295 296static int 297_XkbSizeKeyExplicit(XkbDescPtr xkb,xkbSetMapReq *req) 298{ 299register int i,first,last,nFound; 300 301 if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit==0)) { 302 req->present&= ~XkbExplicitComponentsMask; 303 req->firstKeyExplicit= req->nKeyExplicit= 0; 304 req->totalKeyExplicit= 0; 305 return 0; 306 } 307 first= req->firstKeyExplicit; 308 last= first+req->nKeyExplicit-1; 309 310 for (i=first,nFound=0;i<=last;i++) { 311 if (xkb->server->explicit[i]!=0) 312 nFound++; 313 } 314 req->totalKeyExplicit= nFound; 315 return XkbPaddedSize((nFound*2)); 316} 317 318static void 319_XkbWriteKeyExplicit(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) 320{ 321register int i,first,last; 322CARD8 * wire; 323 324 if ((req->present&XkbExplicitComponentsMask)==0) 325 return; 326 first= req->firstKeyExplicit; 327 last= first+req->nKeyExplicit; 328 i= XkbPaddedSize((req->totalKeyExplicit*2)); 329 BufAlloc(CARD8 *,wire,i); 330 for (i=first;i<=last;i++) { 331 if (xkb->server->explicit[i]!=0) { 332 wire[0]= i; 333 wire[1]= xkb->server->explicit[i]; 334 wire+= 2; 335 } 336 } 337 return; 338} 339 340static int 341_XkbSizeModifierMap(XkbDescPtr xkb,xkbSetMapReq *req) 342{ 343register int i,first,last,nFound; 344 345 if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys==0)) { 346 req->present&= ~XkbModifierMapMask; 347 req->firstModMapKey= req->nModMapKeys= 0; 348 req->totalModMapKeys= 0; 349 return 0; 350 } 351 first= req->firstModMapKey; 352 last= first+req->nModMapKeys-1; 353 354 for (i=first,nFound=0;i<=last;i++) { 355 if (xkb->map->modmap[i]!=0) 356 nFound++; 357 } 358 req->totalModMapKeys= nFound; 359 return XkbPaddedSize((nFound*2)); 360} 361 362static void 363_XkbWriteModifierMap(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) 364{ 365register int i,first,last; 366CARD8 * wire; 367 368 if ((req->present&XkbModifierMapMask)==0) 369 return; 370 first= req->firstModMapKey; 371 last= first+req->nModMapKeys-1; 372 if (req->totalModMapKeys>0) { 373 i= XkbPaddedSize((req->totalModMapKeys*2)); 374 BufAlloc(CARD8 *,wire,i); 375 for (i=first;i<=last;i++) { 376 if (xkb->map->modmap[i]!=0) { 377 wire[0]= i; 378 wire[1]= xkb->map->modmap[i]; 379 wire+= 2; 380 } 381 } 382 } 383 return; 384} 385 386static int 387_XkbSizeVirtualModMap(XkbDescPtr xkb,xkbSetMapReq *req) 388{ 389register int i,first,last,nFound; 390 391 if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys==0)) { 392 req->present&= ~XkbVirtualModMapMask; 393 req->firstVModMapKey= req->nVModMapKeys= 0; 394 req->totalVModMapKeys= 0; 395 return 0; 396 } 397 first= req->firstVModMapKey; 398 last= first+req->nVModMapKeys-1; 399 400 for (i=first,nFound=0;i<=last;i++) { 401 if (xkb->server->vmodmap[i]!=0) 402 nFound++; 403 } 404 req->totalVModMapKeys= nFound; 405 return nFound*SIZEOF(xkbVModMapWireDesc); 406} 407 408static void 409_XkbWriteVirtualModMap(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) 410{ 411register int i,first,last; 412xkbVModMapWireDesc * wire; 413 414 if ((req->present&XkbVirtualModMapMask)==0) 415 return; 416 first= req->firstVModMapKey; 417 last= first+req->nVModMapKeys-1; 418 if (req->totalVModMapKeys>0) { 419 i= req->totalVModMapKeys*SIZEOF(xkbVModMapWireDesc); 420 BufAlloc(xkbVModMapWireDesc *,wire,i); 421 for (i=first;i<=last;i++) { 422 if (xkb->server->vmodmap[i]!=0) { 423 wire->key= i; 424 wire->vmods= xkb->server->vmodmap[i]; 425 wire++; 426 } 427 } 428 } 429 return; 430} 431 432static void 433SendSetMap(Display *dpy,XkbDescPtr xkb,xkbSetMapReq *req) 434{ 435xkbSetMapReq tmp; 436unsigned szMods; 437 438 req->length+= _XkbSizeKeyTypes(xkb,req)/4; 439 req->length+= _XkbSizeKeySyms(xkb,req)/4; 440 req->length+= _XkbSizeKeyActions(xkb,req)/4; 441 req->length+= _XkbSizeKeyBehaviors(xkb,req)/4; 442 szMods= _XkbSizeVirtualMods(req); 443 req->length+= szMods/4; 444 req->length+= _XkbSizeKeyExplicit(xkb,req)/4; 445 req->length+= _XkbSizeModifierMap(xkb,req)/4; 446 req->length+= _XkbSizeVirtualModMap(xkb,req)/4; 447 448 tmp= *req; 449 if ( tmp.nTypes>0 ) 450 _XkbWriteKeyTypes(dpy,xkb,&tmp); 451 if ( tmp.nKeySyms>0 ) 452 _XkbWriteKeySyms(dpy,xkb,&tmp); 453 if ( tmp.nKeyActs ) 454 _XkbWriteKeyActions(dpy,xkb,&tmp); 455 if ( tmp.totalKeyBehaviors>0 ) 456 _XkbWriteKeyBehaviors(dpy,xkb,&tmp); 457 if ( tmp.virtualMods ) 458 _XkbWriteVirtualMods(dpy,xkb,&tmp,szMods); 459 if ( tmp.totalKeyExplicit>0) 460 _XkbWriteKeyExplicit(dpy,xkb,&tmp); 461 if ( tmp.totalModMapKeys>0) 462 _XkbWriteModifierMap(dpy,xkb,&tmp); 463 if ( tmp.totalVModMapKeys>0) 464 _XkbWriteVirtualModMap(dpy,xkb,&tmp); 465 return; 466} 467 468Bool 469XkbSetMap(Display *dpy,unsigned which,XkbDescPtr xkb) 470{ 471register xkbSetMapReq * req; 472XkbInfoPtr xkbi; 473XkbServerMapPtr srv; 474XkbClientMapPtr map; 475 476 if ((dpy->flags & XlibDisplayNoXkb) || 477 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))|| 478 (!xkb)) 479 return False; 480 map= xkb->map; 481 srv= xkb->server; 482 483 if (((which&XkbKeyTypesMask)&&((!map)||(!map->types)))|| 484 ((which&XkbKeySymsMask)&&((!map)||(!map->syms)||(!map->key_sym_map)))|| 485 ((which&XkbKeyActionsMask)&&((!srv)||(!srv->key_acts)))|| 486 ((which&XkbKeyBehaviorsMask)&&((!srv)||(!srv->behaviors)))|| 487 ((which&XkbVirtualModsMask)&&(!srv))|| 488 ((which&XkbExplicitComponentsMask)&&((!srv)||(!srv->explicit)))|| 489 ((which&XkbModifierMapMask)&&((!map)||(!map->modmap)))|| 490 ((which&XkbVirtualModMapMask)&&((!srv)||(!srv->vmodmap)))) 491 return False; 492 493 LockDisplay(dpy); 494 xkbi = dpy->xkb_info; 495 GetReq(kbSetMap, req); 496 req->reqType = xkbi->codes->major_opcode; 497 req->xkbReqType = X_kbSetMap; 498 req->deviceSpec = xkb->device_spec; 499 req->present = which; 500 req->flags = XkbSetMapAllFlags; 501 req->minKeyCode= xkb->min_key_code; 502 req->maxKeyCode= xkb->max_key_code; 503 req->firstType = 0; 504 if (which&XkbKeyTypesMask) req->nTypes = map->num_types; 505 else req->nTypes = 0; 506 if (which&XkbKeySymsMask) { 507 req->firstKeySym = xkb->min_key_code; 508 req->nKeySyms = XkbNumKeys(xkb); 509 } 510 if (which&XkbKeyActionsMask) { 511 req->firstKeyAct = xkb->min_key_code; 512 req->nKeyActs = XkbNumKeys(xkb); 513 } 514 if (which&XkbKeyBehaviorsMask) { 515 req->firstKeyBehavior = xkb->min_key_code; 516 req->nKeyBehaviors = XkbNumKeys(xkb); 517 } 518 if (which&XkbVirtualModsMask) 519 req->virtualMods= ~0; 520 if (which&XkbExplicitComponentsMask) { 521 req->firstKeyExplicit= xkb->min_key_code; 522 req->nKeyExplicit = XkbNumKeys(xkb); 523 } 524 if (which&XkbModifierMapMask) { 525 req->firstModMapKey= xkb->min_key_code; 526 req->nModMapKeys = XkbNumKeys(xkb); 527 } 528 if (which&XkbVirtualModMapMask) { 529 req->firstVModMapKey= xkb->min_key_code; 530 req->nVModMapKeys = XkbNumKeys(xkb); 531 } 532 SendSetMap(dpy,xkb,req); 533 UnlockDisplay(dpy); 534 SyncHandle(); 535 return True; 536} 537 538Bool 539XkbChangeMap(Display *dpy,XkbDescPtr xkb,XkbMapChangesPtr changes) 540{ 541register xkbSetMapReq * req; 542XkbInfoPtr xkbi; 543XkbServerMapPtr srv; 544XkbClientMapPtr map; 545 546 if ((dpy->flags & XlibDisplayNoXkb) || 547 (!dpy->xkb_info && !XkbUseExtension(dpy,NULL,NULL))|| 548 (!xkb)||(!changes)) 549 return False; 550 srv= xkb->server; 551 map= xkb->map; 552 553 if (((changes->changed&XkbKeyTypesMask)&&((!map)||(!map->types)))|| 554 ((changes->changed&XkbKeySymsMask)&&((!map)||(!map->syms)|| 555 (!map->key_sym_map)))|| 556 ((changes->changed&XkbKeyActionsMask)&&((!srv)||(!srv->key_acts)))|| 557 ((changes->changed&XkbKeyBehaviorsMask)&&((!srv)||(!srv->behaviors)))|| 558 ((changes->changed&XkbVirtualModsMask)&&(!srv))|| 559 ((changes->changed&XkbExplicitComponentsMask)&& 560 ((!srv)||(!srv->explicit)))|| 561 ((changes->changed&XkbModifierMapMask)&&((!map)||(!map->modmap)))|| 562 ((changes->changed&XkbVirtualModMapMask)&&((!srv)||(!srv->vmodmap)))) 563 return False; 564 565 LockDisplay(dpy); 566 xkbi = dpy->xkb_info; 567 GetReq(kbSetMap, req); 568 req->reqType = xkbi->codes->major_opcode; 569 req->xkbReqType = X_kbSetMap; 570 req->deviceSpec = xkb->device_spec; 571 req->present = changes->changed; 572 req->flags = XkbSetMapRecomputeActions; 573 req->minKeyCode= xkb->min_key_code; 574 req->maxKeyCode= xkb->max_key_code; 575 req->firstType = changes->first_type; 576 req->nTypes = changes->num_types; 577 req->firstKeySym = changes->first_key_sym; 578 req->nKeySyms = changes->num_key_syms; 579 req->firstKeyAct = changes->first_key_act; 580 req->nKeyActs = changes->num_key_acts; 581 req->firstKeyBehavior = changes->first_key_behavior; 582 req->nKeyBehaviors = changes->num_key_behaviors; 583 req->virtualMods = changes->vmods; 584 req->firstKeyExplicit = changes->first_key_explicit; 585 req->nKeyExplicit = changes->num_key_explicit; 586 req->firstModMapKey = changes->first_modmap_key; 587 req->nModMapKeys = changes->num_modmap_keys; 588 req->firstVModMapKey = changes->first_vmodmap_key; 589 req->nVModMapKeys = changes->num_vmodmap_keys; 590 SendSetMap(dpy,xkb,req); 591 UnlockDisplay(dpy); 592 SyncHandle(); 593 return True; 594} 595 596