XKBGetMap.c revision 818534a1
11ab64890Smrg/************************************************************ 21ab64890SmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 31ab64890Smrg 41ab64890SmrgPermission to use, copy, modify, and distribute this 51ab64890Smrgsoftware and its documentation for any purpose and without 61ab64890Smrgfee is hereby granted, provided that the above copyright 71ab64890Smrgnotice appear in all copies and that both that copyright 81ab64890Smrgnotice and this permission notice appear in supporting 961b2299dSmrgdocumentation, and that the name of Silicon Graphics not be 1061b2299dSmrgused in advertising or publicity pertaining to distribution 111ab64890Smrgof the software without specific prior written permission. 1261b2299dSmrgSilicon Graphics makes no representation about the suitability 131ab64890Smrgof this software for any purpose. It is provided "as is" 141ab64890Smrgwithout any express or implied warranty. 151ab64890Smrg 1661b2299dSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1761b2299dSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 181ab64890SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 1961b2299dSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2061b2299dSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2161b2299dSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 221ab64890SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 231ab64890SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 241ab64890Smrg 251ab64890Smrg********************************************************/ 261ab64890Smrg 271ab64890Smrg#define NEED_MAP_READERS 281ab64890Smrg#ifdef HAVE_CONFIG_H 291ab64890Smrg#include <config.h> 301ab64890Smrg#endif 311ab64890Smrg#include "Xlibint.h" 321ab64890Smrg#include <X11/extensions/XKBproto.h> 331ab64890Smrg#include "XKBlibint.h" 341ab64890Smrg 351ab64890Smrgstatic Status 36818534a1Smrg_XkbReadKeyTypes(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 371ab64890Smrg{ 38818534a1Smrg int i, n, lastMapCount; 39818534a1Smrg XkbKeyTypePtr type; 40818534a1Smrg 41818534a1Smrg if (rep->nTypes > 0) { 42818534a1Smrg n = rep->firstType + rep->nTypes; 43818534a1Smrg if (xkb->map->num_types >= n) 44818534a1Smrg n = xkb->map->num_types; 45818534a1Smrg else if (XkbAllocClientMap(xkb, XkbKeyTypesMask, n) != Success) 46818534a1Smrg return BadAlloc; 47818534a1Smrg 48818534a1Smrg type = &xkb->map->types[rep->firstType]; 49818534a1Smrg for (i = 0; i < (int) rep->nTypes; i++, type++) { 50818534a1Smrg xkbKeyTypeWireDesc *desc; 51818534a1Smrg register int ndx; 52818534a1Smrg 53818534a1Smrg ndx = i + rep->firstType; 54818534a1Smrg if (ndx >= xkb->map->num_types) 55818534a1Smrg xkb->map->num_types = ndx + 1; 56818534a1Smrg 57818534a1Smrg desc = (xkbKeyTypeWireDesc *) 58818534a1Smrg _XkbGetReadBufferPtr(buf, SIZEOF(xkbKeyTypeWireDesc)); 59818534a1Smrg if (desc == NULL) 60818534a1Smrg return BadLength; 61818534a1Smrg 62818534a1Smrg lastMapCount = type->map_count; 63818534a1Smrg if (desc->nMapEntries > 0) { 64818534a1Smrg if ((type->map == NULL) || 65818534a1Smrg (desc->nMapEntries > type->map_count)) { 66818534a1Smrg XkbKTMapEntryRec *prev_map = type->map; 67818534a1Smrg 68818534a1Smrg type->map = _XkbTypedRealloc(type->map, desc->nMapEntries, 69818534a1Smrg XkbKTMapEntryRec); 70818534a1Smrg if (type->map == NULL) { 71818534a1Smrg _XkbFree(prev_map); 72818534a1Smrg return BadAlloc; 73818534a1Smrg } 74818534a1Smrg } 75818534a1Smrg } 76818534a1Smrg else if (type->map != NULL) { 77818534a1Smrg Xfree(type->map); 78818534a1Smrg type->map_count = 0; 79818534a1Smrg type->map = NULL; 80818534a1Smrg } 81818534a1Smrg 82818534a1Smrg if (desc->preserve && (desc->nMapEntries > 0)) { 83818534a1Smrg if ((!type->preserve) || (desc->nMapEntries > lastMapCount)) { 84818534a1Smrg XkbModsRec *prev_preserve = type->preserve; 85818534a1Smrg 86818534a1Smrg type->preserve = _XkbTypedRealloc(type->preserve, 87818534a1Smrg desc->nMapEntries, 88818534a1Smrg XkbModsRec); 89818534a1Smrg if (type->preserve == NULL) { 90818534a1Smrg _XkbFree(prev_preserve); 91818534a1Smrg return BadAlloc; 92818534a1Smrg } 93818534a1Smrg } 94818534a1Smrg } 95818534a1Smrg else if (type->preserve != NULL) { 96818534a1Smrg Xfree(type->preserve); 97818534a1Smrg type->preserve = NULL; 98818534a1Smrg } 99818534a1Smrg 100818534a1Smrg type->mods.mask = desc->mask; 101818534a1Smrg type->mods.real_mods = desc->realMods; 102818534a1Smrg type->mods.vmods = desc->virtualMods; 103818534a1Smrg type->num_levels = desc->numLevels; 104818534a1Smrg type->map_count = desc->nMapEntries; 105818534a1Smrg if (desc->nMapEntries > 0) { 106818534a1Smrg register xkbKTMapEntryWireDesc *wire; 107818534a1Smrg register XkbKTMapEntryPtr entry; 108818534a1Smrg register int size; 109818534a1Smrg 110818534a1Smrg size = type->map_count * SIZEOF(xkbKTMapEntryWireDesc); 111818534a1Smrg wire = 112818534a1Smrg (xkbKTMapEntryWireDesc *) _XkbGetReadBufferPtr(buf, size); 113818534a1Smrg if (wire == NULL) 114818534a1Smrg return BadLength; 115818534a1Smrg entry = type->map; 116818534a1Smrg for (n = 0; n < type->map_count; n++, wire++, entry++) { 117818534a1Smrg entry->active = wire->active; 118818534a1Smrg entry->level = wire->level; 119818534a1Smrg entry->mods.mask = wire->mask; 120818534a1Smrg entry->mods.real_mods = wire->realMods; 121818534a1Smrg entry->mods.vmods = wire->virtualMods; 122818534a1Smrg } 123818534a1Smrg 124818534a1Smrg if (desc->preserve) { 125818534a1Smrg register xkbModsWireDesc *pwire; 126818534a1Smrg register XkbModsPtr preserve; 127818534a1Smrg register int sz; 128818534a1Smrg 129818534a1Smrg sz = desc->nMapEntries * SIZEOF(xkbModsWireDesc); 130818534a1Smrg pwire = (xkbModsWireDesc *) _XkbGetReadBufferPtr(buf, sz); 131818534a1Smrg if (pwire == NULL) 132818534a1Smrg return BadLength; 133818534a1Smrg preserve = type->preserve; 134818534a1Smrg for (n = 0; n < desc->nMapEntries; n++, pwire++, preserve++) { 135818534a1Smrg preserve->mask = pwire->mask; 136818534a1Smrg preserve->vmods = pwire->virtualMods; 137818534a1Smrg preserve->real_mods = pwire->realMods; 138818534a1Smrg } 139818534a1Smrg } 140818534a1Smrg } 141818534a1Smrg } 1421ab64890Smrg } 1431ab64890Smrg return Success; 1441ab64890Smrg} 1451ab64890Smrg 1461ab64890Smrgstatic Status 147818534a1Smrg_XkbReadKeySyms(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 1481ab64890Smrg{ 149818534a1Smrg register int i; 150818534a1Smrg XkbClientMapPtr map; 151818534a1Smrg int size = xkb->max_key_code + 1; 152818534a1Smrg 153818534a1Smrg if (((unsigned short) rep->firstKeySym + rep->nKeySyms) > size) 154818534a1Smrg return BadLength; 155818534a1Smrg 156818534a1Smrg map = xkb->map; 157818534a1Smrg if (map->key_sym_map == NULL) { 158818534a1Smrg register int offset; 159818534a1Smrg XkbSymMapPtr oldMap; 160818534a1Smrg xkbSymMapWireDesc *newMap; 161818534a1Smrg 162818534a1Smrg map->key_sym_map = _XkbTypedCalloc(size, XkbSymMapRec); 163818534a1Smrg if (map->key_sym_map == NULL) 164818534a1Smrg return BadAlloc; 165818534a1Smrg if (map->syms == NULL) { 166818534a1Smrg int sz; 167818534a1Smrg 168818534a1Smrg sz = (rep->totalSyms * 12) / 10; 169818534a1Smrg sz = ((sz + (unsigned) 128) / 128) * 128; 170818534a1Smrg map->syms = _XkbTypedCalloc(sz, KeySym); 171818534a1Smrg if (map->syms == NULL) 172818534a1Smrg return BadAlloc; 173818534a1Smrg map->size_syms = sz; 174818534a1Smrg } 175818534a1Smrg offset = 1; 176818534a1Smrg oldMap = &map->key_sym_map[rep->firstKeySym]; 177818534a1Smrg for (i = 0; i < (int) rep->nKeySyms; i++, oldMap++) { 178818534a1Smrg newMap = (xkbSymMapWireDesc *) 179818534a1Smrg _XkbGetReadBufferPtr(buf, SIZEOF(xkbSymMapWireDesc)); 180818534a1Smrg if (newMap == NULL) 181818534a1Smrg return BadLength; 182818534a1Smrg oldMap->kt_index[0] = newMap->ktIndex[0]; 183818534a1Smrg oldMap->kt_index[1] = newMap->ktIndex[1]; 184818534a1Smrg oldMap->kt_index[2] = newMap->ktIndex[2]; 185818534a1Smrg oldMap->kt_index[3] = newMap->ktIndex[3]; 186818534a1Smrg oldMap->group_info = newMap->groupInfo; 187818534a1Smrg oldMap->width = newMap->width; 188818534a1Smrg oldMap->offset = offset; 189818534a1Smrg if (offset + newMap->nSyms >= map->size_syms) { 190818534a1Smrg register int sz; 191818534a1Smrg KeySym *prev_syms = map->syms; 192818534a1Smrg 193818534a1Smrg sz = map->size_syms + 128; 194818534a1Smrg map->syms = _XkbTypedRealloc(map->syms, sz, KeySym); 195818534a1Smrg if (map->syms == NULL) { 196818534a1Smrg _XkbFree(prev_syms); 197818534a1Smrg map->size_syms = 0; 198818534a1Smrg return BadAlloc; 199818534a1Smrg } 200818534a1Smrg map->size_syms = sz; 201818534a1Smrg } 202818534a1Smrg if (newMap->nSyms > 0) { 203818534a1Smrg _XkbReadBufferCopyKeySyms(buf, (KeySym *) &map->syms[offset], 204818534a1Smrg newMap->nSyms); 205818534a1Smrg offset += newMap->nSyms; 206818534a1Smrg } 207818534a1Smrg else { 208818534a1Smrg map->syms[offset] = 0; 209818534a1Smrg } 210818534a1Smrg } 211818534a1Smrg map->num_syms = offset; 2121ab64890Smrg } 2131ab64890Smrg else { 214818534a1Smrg XkbSymMapPtr oldMap = &map->key_sym_map[rep->firstKeySym]; 215818534a1Smrg 216818534a1Smrg for (i = 0; i < (int) rep->nKeySyms; i++, oldMap++) { 217818534a1Smrg xkbSymMapWireDesc *newMap; 218818534a1Smrg KeySym *newSyms; 219818534a1Smrg int tmp; 220818534a1Smrg 221818534a1Smrg newMap = (xkbSymMapWireDesc *) 222818534a1Smrg _XkbGetReadBufferPtr(buf, SIZEOF(xkbSymMapWireDesc)); 223818534a1Smrg if (newMap == NULL) 224818534a1Smrg return BadLength; 225818534a1Smrg 226818534a1Smrg if (newMap->nSyms > 0) 227818534a1Smrg tmp = newMap->nSyms; 228818534a1Smrg else 229818534a1Smrg tmp = 0; 230818534a1Smrg 231818534a1Smrg newSyms = XkbResizeKeySyms(xkb, i + rep->firstKeySym, tmp); 232818534a1Smrg if (newSyms == NULL) 233818534a1Smrg return BadAlloc; 234818534a1Smrg if (newMap->nSyms > 0) 235818534a1Smrg _XkbReadBufferCopyKeySyms(buf, newSyms, newMap->nSyms); 236818534a1Smrg else 237818534a1Smrg newSyms[0] = NoSymbol; 238818534a1Smrg oldMap->kt_index[0] = newMap->ktIndex[0]; 239818534a1Smrg oldMap->kt_index[1] = newMap->ktIndex[1]; 240818534a1Smrg oldMap->kt_index[2] = newMap->ktIndex[2]; 241818534a1Smrg oldMap->kt_index[3] = newMap->ktIndex[3]; 242818534a1Smrg oldMap->group_info = newMap->groupInfo; 243818534a1Smrg oldMap->width = newMap->width; 244818534a1Smrg } 2451ab64890Smrg } 2461ab64890Smrg return Success; 2471ab64890Smrg} 2481ab64890Smrg 2491ab64890Smrgstatic Status 250818534a1Smrg_XkbReadKeyActions(XkbReadBufferPtr buf, XkbDescPtr info, xkbGetMapReply *rep) 2511ab64890Smrg{ 252818534a1Smrg int i; 253818534a1Smrg CARD8 numDescBuf[248]; 254818534a1Smrg CARD8 *numDesc = NULL; 255818534a1Smrg register int nKeyActs; 256818534a1Smrg Status ret = Success; 257818534a1Smrg 258818534a1Smrg if ((nKeyActs = rep->nKeyActs) > 0) { 259818534a1Smrg XkbSymMapPtr symMap; 260818534a1Smrg 261818534a1Smrg if (nKeyActs < sizeof numDescBuf) 262818534a1Smrg numDesc = numDescBuf; 263818534a1Smrg else 264818534a1Smrg numDesc = Xmalloc(nKeyActs * sizeof(CARD8)); 265818534a1Smrg 266818534a1Smrg if (!_XkbCopyFromReadBuffer(buf, (char *) numDesc, nKeyActs)) { 267818534a1Smrg ret = BadLength; 268818534a1Smrg goto done; 269818534a1Smrg } 270818534a1Smrg i = XkbPaddedSize(nKeyActs) - nKeyActs; 271818534a1Smrg if ((i > 0) && (!_XkbSkipReadBufferData(buf, i))) { 272818534a1Smrg ret = BadLength; 273818534a1Smrg goto done; 274818534a1Smrg } 275818534a1Smrg symMap = &info->map->key_sym_map[rep->firstKeyAct]; 276818534a1Smrg for (i = 0; i < (int) rep->nKeyActs; i++, symMap++) { 277818534a1Smrg if (numDesc[i] == 0) { 278818534a1Smrg if ((i + rep->firstKeyAct) > (info->max_key_code + 1)) { 279818534a1Smrg ret = BadLength; 280818534a1Smrg goto done; 281818534a1Smrg } 282818534a1Smrg info->server->key_acts[i + rep->firstKeyAct] = 0; 283818534a1Smrg } 284818534a1Smrg else { 285818534a1Smrg XkbAction *newActs; 286818534a1Smrg 287818534a1Smrg /* 8/16/93 (ef) -- XXX! Verify size here (numdesc must be */ 288818534a1Smrg /* either zero or XkbKeyNumSyms(info,key) */ 289818534a1Smrg newActs = XkbResizeKeyActions(info, i + rep->firstKeyAct, 290818534a1Smrg numDesc[i]); 291818534a1Smrg if (newActs == NULL) { 292818534a1Smrg ret = BadAlloc; 293818534a1Smrg goto done; 294818534a1Smrg } 295818534a1Smrg if (!_XkbCopyFromReadBuffer(buf, (char *) newActs, 296818534a1Smrg (int) (numDesc[i] * sizeof(XkbAction)))) { 297818534a1Smrg ret = BadLength; 298818534a1Smrg goto done; 299818534a1Smrg } 300818534a1Smrg } 301818534a1Smrg } 3021ab64890Smrg } 303818534a1Smrg done: 304818534a1Smrg if (numDesc != NULL && numDesc != numDescBuf) 305818534a1Smrg Xfree(numDesc); 3061ab64890Smrg return ret; 3071ab64890Smrg} 3081ab64890Smrg 3091ab64890Smrgstatic Status 310818534a1Smrg_XkbReadKeyBehaviors(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 3111ab64890Smrg{ 312818534a1Smrg register int i; 313818534a1Smrg 314818534a1Smrg if (rep->totalKeyBehaviors > 0) { 315818534a1Smrg int size = xkb->max_key_code + 1; 316818534a1Smrg 317818534a1Smrg if (((int) rep->firstKeyBehavior + rep->nKeyBehaviors) > size) 318818534a1Smrg return BadLength; 319818534a1Smrg if (xkb->server->behaviors == NULL) { 320818534a1Smrg xkb->server->behaviors = _XkbTypedCalloc(size, XkbBehavior); 321818534a1Smrg if (xkb->server->behaviors == NULL) 322818534a1Smrg return BadAlloc; 323818534a1Smrg } 324818534a1Smrg else { 325818534a1Smrg bzero(&xkb->server->behaviors[rep->firstKeyBehavior], 326818534a1Smrg (rep->nKeyBehaviors * sizeof(XkbBehavior))); 327818534a1Smrg } 328818534a1Smrg for (i = 0; i < rep->totalKeyBehaviors; i++) { 329818534a1Smrg xkbBehaviorWireDesc *wire; 330818534a1Smrg 331818534a1Smrg wire = (xkbBehaviorWireDesc *) _XkbGetReadBufferPtr(buf, 332818534a1Smrg SIZEOF(xkbBehaviorWireDesc)); 333818534a1Smrg if (wire == NULL || wire->key >= size) 334818534a1Smrg return BadLength; 335818534a1Smrg xkb->server->behaviors[wire->key].type = wire->type; 336818534a1Smrg xkb->server->behaviors[wire->key].data = wire->data; 337818534a1Smrg } 3381ab64890Smrg } 3391ab64890Smrg return Success; 3401ab64890Smrg} 3411ab64890Smrg 3421ab64890Smrgstatic Status 343818534a1Smrg_XkbReadVirtualMods(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 3441ab64890Smrg{ 345818534a1Smrg if (rep->virtualMods) { 346818534a1Smrg register int i, bit, nVMods; 347818534a1Smrg register char *data; 348818534a1Smrg 349818534a1Smrg for (i = nVMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 350818534a1Smrg if (rep->virtualMods & bit) 351818534a1Smrg nVMods++; 352818534a1Smrg } 353818534a1Smrg data = _XkbGetReadBufferPtr(buf, XkbPaddedSize(nVMods)); 354818534a1Smrg if (data == NULL) 355818534a1Smrg return BadLength; 356818534a1Smrg for (i = 0, bit = 1; (i < XkbNumVirtualMods) && (nVMods > 0); 357818534a1Smrg i++, bit <<= 1) { 358818534a1Smrg if (rep->virtualMods & bit) { 359818534a1Smrg xkb->server->vmods[i] = *data++; 360818534a1Smrg nVMods--; 361818534a1Smrg } 362818534a1Smrg } 3631ab64890Smrg } 3641ab64890Smrg return Success; 3651ab64890Smrg} 3661ab64890Smrg 3671ab64890Smrgstatic Status 368818534a1Smrg_XkbReadExplicitComponents(XkbReadBufferPtr buf, 369818534a1Smrg XkbDescPtr xkb, 370818534a1Smrg xkbGetMapReply *rep) 3711ab64890Smrg{ 372818534a1Smrg register int i; 373818534a1Smrg unsigned char *wire; 374818534a1Smrg 375818534a1Smrg if (rep->totalKeyExplicit > 0) { 376818534a1Smrg int size = xkb->max_key_code + 1; 377818534a1Smrg 378818534a1Smrg if (((int) rep->firstKeyExplicit + rep->nKeyExplicit) > size) 379818534a1Smrg return BadLength; 380818534a1Smrg if (xkb->server->explicit == NULL) { 381818534a1Smrg xkb->server->explicit = _XkbTypedCalloc(size, unsigned char); 382818534a1Smrg 383818534a1Smrg if (xkb->server->explicit == NULL) 384818534a1Smrg return BadAlloc; 385818534a1Smrg } 386818534a1Smrg else { 387818534a1Smrg bzero(&xkb->server->explicit[rep->firstKeyExplicit], 388818534a1Smrg rep->nKeyExplicit); 389818534a1Smrg } 390818534a1Smrg i = XkbPaddedSize(2 * rep->totalKeyExplicit); 391818534a1Smrg wire = (unsigned char *) _XkbGetReadBufferPtr(buf, i); 392818534a1Smrg if (!wire) 393818534a1Smrg return BadLength; 394818534a1Smrg for (i = 0; i < rep->totalKeyExplicit; i++, wire += 2) { 395818534a1Smrg if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code) 396818534a1Smrg return BadLength; 397818534a1Smrg xkb->server->explicit[wire[0]] = wire[1]; 398818534a1Smrg } 3991ab64890Smrg } 4001ab64890Smrg return Success; 4011ab64890Smrg} 4021ab64890Smrg 4031ab64890Smrgstatic Status 404818534a1Smrg_XkbReadModifierMap(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 4051ab64890Smrg{ 406818534a1Smrg register int i; 407818534a1Smrg unsigned char *wire; 408818534a1Smrg 409818534a1Smrg if (rep->totalModMapKeys > 0) { 410818534a1Smrg if (((int) rep->firstModMapKey + rep->nModMapKeys) > 411818534a1Smrg (xkb->max_key_code + 1)) 412818534a1Smrg return BadLength; 413818534a1Smrg if ((xkb->map->modmap == NULL) && 414818534a1Smrg (XkbAllocClientMap(xkb, XkbModifierMapMask, 0) != Success)) { 415818534a1Smrg return BadAlloc; 416818534a1Smrg } 417818534a1Smrg else { 418818534a1Smrg bzero(&xkb->map->modmap[rep->firstModMapKey], rep->nModMapKeys); 419818534a1Smrg } 420818534a1Smrg i = XkbPaddedSize(2 * rep->totalModMapKeys); 421818534a1Smrg wire = (unsigned char *) _XkbGetReadBufferPtr(buf, i); 422818534a1Smrg if (!wire) 423818534a1Smrg return BadLength; 424818534a1Smrg for (i = 0; i < rep->totalModMapKeys; i++, wire += 2) { 425818534a1Smrg if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code) 426818534a1Smrg return BadLength; 427818534a1Smrg xkb->map->modmap[wire[0]] = wire[1]; 428818534a1Smrg } 4291ab64890Smrg } 4301ab64890Smrg return Success; 4311ab64890Smrg} 4321ab64890Smrg 4331ab64890Smrgstatic Status 434818534a1Smrg_XkbReadVirtualModMap(XkbReadBufferPtr buf, 435818534a1Smrg XkbDescPtr xkb, 436818534a1Smrg xkbGetMapReply *rep) 4371ab64890Smrg{ 438818534a1Smrg register int i; 439818534a1Smrg xkbVModMapWireDesc *wire; 440818534a1Smrg XkbServerMapPtr srv; 441818534a1Smrg 442818534a1Smrg if (rep->totalVModMapKeys > 0) { 443818534a1Smrg if (((int) rep->firstVModMapKey + rep->nVModMapKeys) 444818534a1Smrg > xkb->max_key_code + 1) 445818534a1Smrg return BadLength; 446818534a1Smrg if (((xkb->server == NULL) || (xkb->server->vmodmap == NULL)) && 447818534a1Smrg (XkbAllocServerMap(xkb, XkbVirtualModMapMask, 0) != Success)) { 448818534a1Smrg return BadAlloc; 449818534a1Smrg } 450818534a1Smrg else { 451818534a1Smrg srv = xkb->server; 452818534a1Smrg if (rep->nVModMapKeys > rep->firstVModMapKey) 453818534a1Smrg bzero((char *) &srv->vmodmap[rep->firstVModMapKey], 454818534a1Smrg (rep->nVModMapKeys - rep->firstVModMapKey) * 455818534a1Smrg sizeof(unsigned short)); 456818534a1Smrg } 457818534a1Smrg srv = xkb->server; 458818534a1Smrg i = rep->totalVModMapKeys * SIZEOF(xkbVModMapWireDesc); 459818534a1Smrg wire = (xkbVModMapWireDesc *) _XkbGetReadBufferPtr(buf, i); 460818534a1Smrg if (!wire) 461818534a1Smrg return BadLength; 462818534a1Smrg for (i = 0; i < rep->totalVModMapKeys; i++, wire++) { 463818534a1Smrg if ((wire->key >= xkb->min_key_code) && 464818534a1Smrg (wire->key <= xkb->max_key_code)) 465818534a1Smrg srv->vmodmap[wire->key] = wire->vmods; 466818534a1Smrg } 4671ab64890Smrg } 4681ab64890Smrg return Success; 4691ab64890Smrg} 4701ab64890Smrg 4711ab64890Smrgstatic xkbGetMapReq * 472818534a1Smrg_XkbGetGetMapReq(Display *dpy, XkbDescPtr xkb) 4731ab64890Smrg{ 474818534a1Smrg xkbGetMapReq *req; 4751ab64890Smrg 4761ab64890Smrg GetReq(kbGetMap, req); 4771ab64890Smrg req->reqType = dpy->xkb_info->codes->major_opcode; 4781ab64890Smrg req->xkbReqType = X_kbGetMap; 4791ab64890Smrg req->deviceSpec = xkb->device_spec; 4801ab64890Smrg req->full = req->partial = 0; 4811ab64890Smrg req->firstType = req->nTypes = 0; 4821ab64890Smrg req->firstKeySym = req->nKeySyms = 0; 4831ab64890Smrg req->firstKeyAct = req->nKeyActs = 0; 4841ab64890Smrg req->firstKeyBehavior = req->nKeyBehaviors = 0; 4851ab64890Smrg req->virtualMods = 0; 4861ab64890Smrg req->firstKeyExplicit = req->nKeyExplicit = 0; 4871ab64890Smrg req->firstModMapKey = req->nModMapKeys = 0; 4881ab64890Smrg req->firstVModMapKey = req->nVModMapKeys = 0; 4891ab64890Smrg return req; 4901ab64890Smrg} 4911ab64890Smrg 4921ab64890SmrgStatus 493818534a1Smrg_XkbReadGetMapReply(Display *dpy, 494818534a1Smrg xkbGetMapReply *rep, 495818534a1Smrg XkbDescPtr xkb, 496818534a1Smrg int *nread_rtrn) 4971ab64890Smrg{ 498818534a1Smrg int extraData; 499818534a1Smrg unsigned mask; 5001ab64890Smrg 501818534a1Smrg if (xkb->device_spec == XkbUseCoreKbd) 502818534a1Smrg xkb->device_spec = rep->deviceID; 503818534a1Smrg if (rep->maxKeyCode < rep->minKeyCode) 504818534a1Smrg return BadImplementation; 5051ab64890Smrg xkb->min_key_code = rep->minKeyCode; 5061ab64890Smrg xkb->max_key_code = rep->maxKeyCode; 5071ab64890Smrg 5081ab64890Smrg if (!xkb->map) { 509818534a1Smrg mask = rep->present & XkbAllClientInfoMask; 510818534a1Smrg if (mask && (XkbAllocClientMap(xkb, mask, rep->nTypes) != Success)) 511818534a1Smrg return BadAlloc; 5121ab64890Smrg } 5131ab64890Smrg if (!xkb->server) { 514818534a1Smrg mask = rep->present & XkbAllServerInfoMask; 515818534a1Smrg if (mask && (XkbAllocServerMap(xkb, mask, rep->totalActs) != Success)) 516818534a1Smrg return BadAlloc; 5171ab64890Smrg } 518818534a1Smrg extraData = (int) (rep->length * 4); 519818534a1Smrg extraData -= (SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)); 5201ab64890Smrg if (rep->length) { 521818534a1Smrg XkbReadBufferRec buf; 522818534a1Smrg int left; 523818534a1Smrg 524818534a1Smrg if (_XkbInitReadBuffer(dpy, &buf, extraData)) { 525818534a1Smrg Status status = Success; 526818534a1Smrg 527818534a1Smrg if (nread_rtrn != NULL) 528818534a1Smrg *nread_rtrn = extraData; 529818534a1Smrg if (status == Success) 530818534a1Smrg status = _XkbReadKeyTypes(&buf, xkb, rep); 531818534a1Smrg if (status == Success) 532818534a1Smrg status = _XkbReadKeySyms(&buf, xkb, rep); 533818534a1Smrg if (status == Success) 534818534a1Smrg status = _XkbReadKeyActions(&buf, xkb, rep); 535818534a1Smrg if (status == Success) 536818534a1Smrg status = _XkbReadKeyBehaviors(&buf, xkb, rep); 537818534a1Smrg if (status == Success) 538818534a1Smrg status = _XkbReadVirtualMods(&buf, xkb, rep); 539818534a1Smrg if (status == Success) 540818534a1Smrg status = _XkbReadExplicitComponents(&buf, xkb, rep); 541818534a1Smrg if (status == Success) 542818534a1Smrg status = _XkbReadModifierMap(&buf, xkb, rep); 543818534a1Smrg if (status == Success) 544818534a1Smrg status = _XkbReadVirtualModMap(&buf, xkb, rep); 545818534a1Smrg left = _XkbFreeReadBuffer(&buf); 546818534a1Smrg if (status != Success) 547818534a1Smrg return status; 548818534a1Smrg else if (left || buf.error) 549818534a1Smrg return BadLength; 550818534a1Smrg } 551818534a1Smrg else 552818534a1Smrg return BadAlloc; 5531ab64890Smrg } 5541ab64890Smrg return Success; 5551ab64890Smrg} 5561ab64890Smrg 5571ab64890Smrgstatic Status 558818534a1Smrg_XkbHandleGetMapReply(Display *dpy, XkbDescPtr xkb) 5591ab64890Smrg{ 560818534a1Smrg xkbGetMapReply rep; 5611ab64890Smrg 562818534a1Smrg if (!_XReply(dpy, (xReply *) &rep, 563818534a1Smrg ((SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)) >> 2), 564818534a1Smrg xFalse)) { 565818534a1Smrg return BadImplementation; 5661ab64890Smrg } 567818534a1Smrg return _XkbReadGetMapReply(dpy, &rep, xkb, NULL); 5681ab64890Smrg} 5691ab64890Smrg 5701ab64890SmrgStatus 571818534a1SmrgXkbGetUpdatedMap(Display *dpy, unsigned which, XkbDescPtr xkb) 5721ab64890Smrg{ 5731ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 574818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 575818534a1Smrg return BadAccess; 5761ab64890Smrg if (which) { 577818534a1Smrg register xkbGetMapReq *req; 578818534a1Smrg Status status; 5791ab64890Smrg 580818534a1Smrg LockDisplay(dpy); 5811ab64890Smrg 582818534a1Smrg req = _XkbGetGetMapReq(dpy, xkb); 583818534a1Smrg req->full = which; 584818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 5851ab64890Smrg 586818534a1Smrg UnlockDisplay(dpy); 587818534a1Smrg SyncHandle(); 588818534a1Smrg return status; 5891ab64890Smrg } 5901ab64890Smrg return Success; 5911ab64890Smrg} 5921ab64890Smrg 5931ab64890SmrgXkbDescPtr 594818534a1SmrgXkbGetMap(Display *dpy, unsigned which, unsigned deviceSpec) 5951ab64890Smrg{ 596818534a1Smrg XkbDescPtr xkb; 5971ab64890Smrg 598818534a1Smrg xkb = _XkbTypedCalloc(1, XkbDescRec); 5991ab64890Smrg if (xkb) { 600818534a1Smrg xkb->device_spec = deviceSpec; 601818534a1Smrg xkb->map = _XkbTypedCalloc(1, XkbClientMapRec); 602818534a1Smrg if ((xkb->map == NULL) || 603818534a1Smrg ((which) && (XkbGetUpdatedMap(dpy, which, xkb) != Success))) { 604818534a1Smrg if (xkb->map) { 605818534a1Smrg Xfree(xkb->map); 606818534a1Smrg xkb->map = NULL; 607818534a1Smrg } 608818534a1Smrg Xfree(xkb); 609818534a1Smrg return NULL; 610818534a1Smrg } 611818534a1Smrg xkb->dpy = dpy; 6121ab64890Smrg } 6131ab64890Smrg return xkb; 6141ab64890Smrg} 6151ab64890Smrg 6161ab64890SmrgStatus 617818534a1SmrgXkbGetKeyTypes(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 6181ab64890Smrg{ 6191ab64890Smrg register xkbGetMapReq *req; 6201ab64890Smrg Status status; 6211ab64890Smrg 6221ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 623818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 624818534a1Smrg return BadAccess; 625818534a1Smrg if ((num < 1) || (num > XkbMaxKeyTypes)) 626818534a1Smrg return BadValue; 6271ab64890Smrg 6281ab64890Smrg LockDisplay(dpy); 6291ab64890Smrg 6301ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 6311ab64890Smrg req->firstType = first; 6321ab64890Smrg req->nTypes = num; 633818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 6341ab64890Smrg 6351ab64890Smrg UnlockDisplay(dpy); 6361ab64890Smrg SyncHandle(); 6371ab64890Smrg return status; 6381ab64890Smrg} 6391ab64890Smrg 6401ab64890SmrgStatus 641818534a1SmrgXkbGetKeyActions(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 6421ab64890Smrg{ 6431ab64890Smrg register xkbGetMapReq *req; 6441ab64890Smrg Status status; 6451ab64890Smrg 6461ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 647818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 648818534a1Smrg return BadAccess; 6491ab64890Smrg 650818534a1Smrg if ((num < 1) || (num > XkbMaxKeyCount)) 651818534a1Smrg return BadValue; 6521ab64890Smrg 6531ab64890Smrg LockDisplay(dpy); 6541ab64890Smrg 6551ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 6561ab64890Smrg req->firstKeyAct = first; 6571ab64890Smrg req->nKeyActs = num; 658818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 6591ab64890Smrg 6601ab64890Smrg UnlockDisplay(dpy); 6611ab64890Smrg SyncHandle(); 6621ab64890Smrg return status; 6631ab64890Smrg} 6641ab64890Smrg 6651ab64890SmrgStatus 666818534a1SmrgXkbGetKeySyms(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 6671ab64890Smrg{ 6681ab64890Smrg register xkbGetMapReq *req; 6691ab64890Smrg Status status; 6701ab64890Smrg 6711ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 672818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 673818534a1Smrg return BadAccess; 6741ab64890Smrg 675818534a1Smrg if ((num < 1) || (num > XkbMaxKeyCount)) 676818534a1Smrg return BadValue; 6771ab64890Smrg 6781ab64890Smrg LockDisplay(dpy); 6791ab64890Smrg 6801ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 6811ab64890Smrg req->firstKeySym = first; 6821ab64890Smrg req->nKeySyms = num; 683818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 6841ab64890Smrg 6851ab64890Smrg UnlockDisplay(dpy); 6861ab64890Smrg SyncHandle(); 6871ab64890Smrg 6881ab64890Smrg return status; 6891ab64890Smrg} 6901ab64890Smrg 6911ab64890SmrgStatus 692818534a1SmrgXkbGetKeyBehaviors(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 6931ab64890Smrg{ 6941ab64890Smrg register xkbGetMapReq *req; 6951ab64890Smrg Status status; 6961ab64890Smrg 6971ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 698818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 699818534a1Smrg return BadAccess; 7001ab64890Smrg 701818534a1Smrg if ((num < 1) || (num > XkbMaxKeyCount)) 702818534a1Smrg return BadValue; 7031ab64890Smrg 7041ab64890Smrg LockDisplay(dpy); 7051ab64890Smrg 7061ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 7071ab64890Smrg req->firstKeyBehavior = first; 7081ab64890Smrg req->nKeyBehaviors = num; 709818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 7101ab64890Smrg 7111ab64890Smrg UnlockDisplay(dpy); 7121ab64890Smrg SyncHandle(); 7131ab64890Smrg return status; 7141ab64890Smrg} 7151ab64890Smrg 7161ab64890SmrgStatus 717818534a1SmrgXkbGetVirtualMods(Display *dpy, unsigned which, XkbDescPtr xkb) 7181ab64890Smrg{ 7191ab64890Smrg register xkbGetMapReq *req; 7201ab64890Smrg Status status; 7211ab64890Smrg 7221ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 723818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 724818534a1Smrg return BadAccess; 7251ab64890Smrg 7261ab64890Smrg LockDisplay(dpy); 7271ab64890Smrg 7281ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 7291ab64890Smrg req->virtualMods = which; 730818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 7311ab64890Smrg 7321ab64890Smrg UnlockDisplay(dpy); 7331ab64890Smrg SyncHandle(); 7341ab64890Smrg return status; 7351ab64890Smrg} 7361ab64890Smrg 7371ab64890SmrgStatus 738818534a1SmrgXkbGetKeyExplicitComponents(Display *dpy, 739818534a1Smrg unsigned first, 740818534a1Smrg unsigned num, 741818534a1Smrg XkbDescPtr xkb) 7421ab64890Smrg{ 7431ab64890Smrg register xkbGetMapReq *req; 7441ab64890Smrg Status status; 7451ab64890Smrg 7461ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 747818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 748818534a1Smrg return BadAccess; 7491ab64890Smrg 750818534a1Smrg if ((num < 1) || (num > XkbMaxKeyCount)) 751818534a1Smrg return BadValue; 7521ab64890Smrg 7531ab64890Smrg LockDisplay(dpy); 7541ab64890Smrg 7551ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 7561ab64890Smrg req->firstKeyExplicit = first; 7571ab64890Smrg req->nKeyExplicit = num; 758818534a1Smrg if ((xkb != NULL) && (xkb->server != NULL) && 759818534a1Smrg (xkb->server->explicit != NULL)) { 760818534a1Smrg if ((num > 0) && (first >= xkb->min_key_code) && 761818534a1Smrg (first + num <= xkb->max_key_code)) 762818534a1Smrg bzero(&xkb->server->explicit[first], num); 7631ab64890Smrg } 7641ab64890Smrg if (xkb) 765818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 7661ab64890Smrg else 7671ab64890Smrg status = BadMatch; 7681ab64890Smrg 7691ab64890Smrg UnlockDisplay(dpy); 7701ab64890Smrg SyncHandle(); 7711ab64890Smrg return status; 7721ab64890Smrg} 7731ab64890Smrg 7741ab64890SmrgStatus 775818534a1SmrgXkbGetKeyModifierMap(Display *dpy, 776818534a1Smrg unsigned first, 777818534a1Smrg unsigned num, 778818534a1Smrg XkbDescPtr xkb) 7791ab64890Smrg{ 7801ab64890Smrg register xkbGetMapReq *req; 7811ab64890Smrg Status status; 7821ab64890Smrg 7831ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 784818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 785818534a1Smrg return BadAccess; 7861ab64890Smrg 787818534a1Smrg if ((num < 1) || (num > XkbMaxKeyCount)) 788818534a1Smrg return BadValue; 7891ab64890Smrg 7901ab64890Smrg LockDisplay(dpy); 7911ab64890Smrg 7921ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 7931ab64890Smrg req->firstModMapKey = first; 7941ab64890Smrg req->nModMapKeys = num; 795818534a1Smrg if ((xkb != NULL) && (xkb->map != NULL) && (xkb->map->modmap != NULL)) { 796818534a1Smrg if ((num > 0) && (first >= xkb->min_key_code) && 797818534a1Smrg (first + num <= xkb->max_key_code)) 798818534a1Smrg bzero(&xkb->map->modmap[first], num); 7991ab64890Smrg } 8001ab64890Smrg if (xkb) 801818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 8021ab64890Smrg else 8031ab64890Smrg status = BadMatch; 8041ab64890Smrg 8051ab64890Smrg UnlockDisplay(dpy); 8061ab64890Smrg SyncHandle(); 8071ab64890Smrg return status; 8081ab64890Smrg} 8091ab64890Smrg 8101ab64890SmrgStatus 811818534a1SmrgXkbGetKeyVirtualModMap(Display *dpy, unsigned first, unsigned num, 812818534a1Smrg XkbDescPtr xkb) 8131ab64890Smrg{ 8141ab64890Smrg register xkbGetMapReq *req; 8151ab64890Smrg Status status; 8161ab64890Smrg 8171ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 818818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 819818534a1Smrg return BadAccess; 8201ab64890Smrg 821818534a1Smrg if ((num < 1) || (num > XkbMaxKeyCount)) 822818534a1Smrg return BadValue; 8231ab64890Smrg 8241ab64890Smrg LockDisplay(dpy); 8251ab64890Smrg 8261ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 8271ab64890Smrg req->firstVModMapKey = first; 8281ab64890Smrg req->nVModMapKeys = num; 829818534a1Smrg if ((xkb != NULL) && (xkb->map != NULL) && (xkb->map->modmap != NULL)) { 830818534a1Smrg if ((num > 0) && (first >= xkb->min_key_code) && 831818534a1Smrg (first + num <= xkb->max_key_code)) 832818534a1Smrg bzero(&xkb->server->vmodmap[first], num * sizeof(unsigned short)); 8331ab64890Smrg } 8341ab64890Smrg 8351ab64890Smrg if (xkb) 836818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 8371ab64890Smrg else 8381ab64890Smrg status = BadMatch; 8391ab64890Smrg 8401ab64890Smrg UnlockDisplay(dpy); 8411ab64890Smrg SyncHandle(); 8421ab64890Smrg return status; 8431ab64890Smrg} 8441ab64890Smrg 8451ab64890SmrgStatus 846818534a1SmrgXkbGetMapChanges(Display *dpy, XkbDescPtr xkb, XkbMapChangesPtr changes) 8471ab64890Smrg{ 8481ab64890Smrg xkbGetMapReq *req; 8491ab64890Smrg 8501ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 851818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 852818534a1Smrg return BadAccess; 8531ab64890Smrg LockDisplay(dpy); 8541ab64890Smrg if (changes->changed) { 855818534a1Smrg Status status = Success; 856818534a1Smrg 857818534a1Smrg req = _XkbGetGetMapReq(dpy, xkb); 858818534a1Smrg req->full = 0; 859818534a1Smrg req->partial = changes->changed; 860818534a1Smrg req->firstType = changes->first_type; 861818534a1Smrg req->nTypes = changes->num_types; 862818534a1Smrg req->firstKeySym = changes->first_key_sym; 863818534a1Smrg req->nKeySyms = changes->num_key_syms; 864818534a1Smrg req->firstKeyAct = changes->first_key_act; 865818534a1Smrg req->nKeyActs = changes->num_key_acts; 866818534a1Smrg req->firstKeyBehavior = changes->first_key_behavior; 867818534a1Smrg req->nKeyBehaviors = changes->num_key_behaviors; 868818534a1Smrg req->virtualMods = changes->vmods; 869818534a1Smrg req->firstKeyExplicit = changes->first_key_explicit; 870818534a1Smrg req->nKeyExplicit = changes->num_key_explicit; 871818534a1Smrg req->firstModMapKey = changes->first_modmap_key; 872818534a1Smrg req->nModMapKeys = changes->num_modmap_keys; 873818534a1Smrg req->firstVModMapKey = changes->first_vmodmap_key; 874818534a1Smrg req->nVModMapKeys = changes->num_vmodmap_keys; 875818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 876818534a1Smrg UnlockDisplay(dpy); 877818534a1Smrg SyncHandle(); 878818534a1Smrg return status; 8791ab64890Smrg } 8801ab64890Smrg UnlockDisplay(dpy); 8811ab64890Smrg return Success; 8821ab64890Smrg} 883