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)) { 66258a0ebeSmrg _XkbResizeArray(type->map, type->map_count, 67258a0ebeSmrg desc->nMapEntries, XkbKTMapEntryRec); 68818534a1Smrg if (type->map == NULL) { 69818534a1Smrg return BadAlloc; 70818534a1Smrg } 71818534a1Smrg } 72818534a1Smrg } 73818534a1Smrg else if (type->map != NULL) { 74818534a1Smrg Xfree(type->map); 75818534a1Smrg type->map_count = 0; 76818534a1Smrg type->map = NULL; 77818534a1Smrg } 78818534a1Smrg 79818534a1Smrg if (desc->preserve && (desc->nMapEntries > 0)) { 80818534a1Smrg if ((!type->preserve) || (desc->nMapEntries > lastMapCount)) { 81258a0ebeSmrg _XkbResizeArray(type->preserve, lastMapCount, 82258a0ebeSmrg desc->nMapEntries, XkbModsRec); 83818534a1Smrg if (type->preserve == NULL) { 84818534a1Smrg return BadAlloc; 85818534a1Smrg } 86818534a1Smrg } 87818534a1Smrg } 88818534a1Smrg else if (type->preserve != NULL) { 89818534a1Smrg Xfree(type->preserve); 90818534a1Smrg type->preserve = NULL; 91818534a1Smrg } 92818534a1Smrg 93818534a1Smrg type->mods.mask = desc->mask; 94818534a1Smrg type->mods.real_mods = desc->realMods; 95818534a1Smrg type->mods.vmods = desc->virtualMods; 96818534a1Smrg type->num_levels = desc->numLevels; 97818534a1Smrg type->map_count = desc->nMapEntries; 98818534a1Smrg if (desc->nMapEntries > 0) { 99818534a1Smrg register xkbKTMapEntryWireDesc *wire; 100818534a1Smrg register XkbKTMapEntryPtr entry; 101818534a1Smrg register int size; 102818534a1Smrg 103818534a1Smrg size = type->map_count * SIZEOF(xkbKTMapEntryWireDesc); 104818534a1Smrg wire = 105818534a1Smrg (xkbKTMapEntryWireDesc *) _XkbGetReadBufferPtr(buf, size); 106818534a1Smrg if (wire == NULL) 107818534a1Smrg return BadLength; 108818534a1Smrg entry = type->map; 109818534a1Smrg for (n = 0; n < type->map_count; n++, wire++, entry++) { 110818534a1Smrg entry->active = wire->active; 111818534a1Smrg entry->level = wire->level; 112818534a1Smrg entry->mods.mask = wire->mask; 113818534a1Smrg entry->mods.real_mods = wire->realMods; 114818534a1Smrg entry->mods.vmods = wire->virtualMods; 115818534a1Smrg } 116818534a1Smrg 117818534a1Smrg if (desc->preserve) { 118818534a1Smrg register xkbModsWireDesc *pwire; 119818534a1Smrg register XkbModsPtr preserve; 120818534a1Smrg register int sz; 121818534a1Smrg 122818534a1Smrg sz = desc->nMapEntries * SIZEOF(xkbModsWireDesc); 123818534a1Smrg pwire = (xkbModsWireDesc *) _XkbGetReadBufferPtr(buf, sz); 124818534a1Smrg if (pwire == NULL) 125818534a1Smrg return BadLength; 126818534a1Smrg preserve = type->preserve; 127818534a1Smrg for (n = 0; n < desc->nMapEntries; n++, pwire++, preserve++) { 128818534a1Smrg preserve->mask = pwire->mask; 129818534a1Smrg preserve->vmods = pwire->virtualMods; 130818534a1Smrg preserve->real_mods = pwire->realMods; 131818534a1Smrg } 132818534a1Smrg } 133818534a1Smrg } 134818534a1Smrg } 1351ab64890Smrg } 1361ab64890Smrg return Success; 1371ab64890Smrg} 1381ab64890Smrg 1391ab64890Smrgstatic Status 140818534a1Smrg_XkbReadKeySyms(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 1411ab64890Smrg{ 142818534a1Smrg register int i; 143818534a1Smrg XkbClientMapPtr map; 144818534a1Smrg int size = xkb->max_key_code + 1; 145818534a1Smrg 146818534a1Smrg if (((unsigned short) rep->firstKeySym + rep->nKeySyms) > size) 147818534a1Smrg return BadLength; 148818534a1Smrg 149818534a1Smrg map = xkb->map; 150818534a1Smrg if (map->key_sym_map == NULL) { 151818534a1Smrg register int offset; 152818534a1Smrg XkbSymMapPtr oldMap; 153818534a1Smrg xkbSymMapWireDesc *newMap; 154818534a1Smrg 155818534a1Smrg map->key_sym_map = _XkbTypedCalloc(size, XkbSymMapRec); 156818534a1Smrg if (map->key_sym_map == NULL) 157818534a1Smrg return BadAlloc; 158818534a1Smrg if (map->syms == NULL) { 159818534a1Smrg int sz; 160818534a1Smrg 161818534a1Smrg sz = (rep->totalSyms * 12) / 10; 162818534a1Smrg sz = ((sz + (unsigned) 128) / 128) * 128; 163818534a1Smrg map->syms = _XkbTypedCalloc(sz, KeySym); 164818534a1Smrg if (map->syms == NULL) 165818534a1Smrg return BadAlloc; 166818534a1Smrg map->size_syms = sz; 167818534a1Smrg } 168818534a1Smrg offset = 1; 169818534a1Smrg oldMap = &map->key_sym_map[rep->firstKeySym]; 170818534a1Smrg for (i = 0; i < (int) rep->nKeySyms; i++, oldMap++) { 171818534a1Smrg newMap = (xkbSymMapWireDesc *) 172818534a1Smrg _XkbGetReadBufferPtr(buf, SIZEOF(xkbSymMapWireDesc)); 173818534a1Smrg if (newMap == NULL) 174818534a1Smrg return BadLength; 175818534a1Smrg oldMap->kt_index[0] = newMap->ktIndex[0]; 176818534a1Smrg oldMap->kt_index[1] = newMap->ktIndex[1]; 177818534a1Smrg oldMap->kt_index[2] = newMap->ktIndex[2]; 178818534a1Smrg oldMap->kt_index[3] = newMap->ktIndex[3]; 179818534a1Smrg oldMap->group_info = newMap->groupInfo; 180818534a1Smrg oldMap->width = newMap->width; 181818534a1Smrg oldMap->offset = offset; 182818534a1Smrg if (offset + newMap->nSyms >= map->size_syms) { 183818534a1Smrg register int sz; 184818534a1Smrg 185cbfda780Smrg sz = offset + newMap->nSyms; 186cbfda780Smrg sz = ((sz + (unsigned) 128) / 128) * 128; 187258a0ebeSmrg _XkbResizeArray(map->syms, map->size_syms, sz, KeySym); 188818534a1Smrg if (map->syms == NULL) { 189818534a1Smrg map->size_syms = 0; 190818534a1Smrg return BadAlloc; 191818534a1Smrg } 192818534a1Smrg map->size_syms = sz; 193818534a1Smrg } 194818534a1Smrg if (newMap->nSyms > 0) { 195cbfda780Smrg if (_XkbReadBufferCopyKeySyms(buf, (KeySym *) &map->syms[offset], 196cbfda780Smrg newMap->nSyms) == 0) 197cbfda780Smrg return BadLength; 198818534a1Smrg offset += newMap->nSyms; 199818534a1Smrg } 200818534a1Smrg else { 201818534a1Smrg map->syms[offset] = 0; 202818534a1Smrg } 203818534a1Smrg } 204818534a1Smrg map->num_syms = offset; 2051ab64890Smrg } 2061ab64890Smrg else { 207818534a1Smrg XkbSymMapPtr oldMap = &map->key_sym_map[rep->firstKeySym]; 208818534a1Smrg 209818534a1Smrg for (i = 0; i < (int) rep->nKeySyms; i++, oldMap++) { 210818534a1Smrg xkbSymMapWireDesc *newMap; 211818534a1Smrg KeySym *newSyms; 212818534a1Smrg int tmp; 213818534a1Smrg 214818534a1Smrg newMap = (xkbSymMapWireDesc *) 215818534a1Smrg _XkbGetReadBufferPtr(buf, SIZEOF(xkbSymMapWireDesc)); 216818534a1Smrg if (newMap == NULL) 217818534a1Smrg return BadLength; 218818534a1Smrg 219818534a1Smrg if (newMap->nSyms > 0) 220818534a1Smrg tmp = newMap->nSyms; 221818534a1Smrg else 222818534a1Smrg tmp = 0; 223818534a1Smrg 224818534a1Smrg newSyms = XkbResizeKeySyms(xkb, i + rep->firstKeySym, tmp); 225818534a1Smrg if (newSyms == NULL) 226818534a1Smrg return BadAlloc; 227cbfda780Smrg if (newMap->nSyms > 0) { 228cbfda780Smrg if (_XkbReadBufferCopyKeySyms(buf, newSyms, newMap->nSyms) == 0) 229cbfda780Smrg return BadLength; 230cbfda780Smrg } 231818534a1Smrg else 232818534a1Smrg newSyms[0] = NoSymbol; 233818534a1Smrg oldMap->kt_index[0] = newMap->ktIndex[0]; 234818534a1Smrg oldMap->kt_index[1] = newMap->ktIndex[1]; 235818534a1Smrg oldMap->kt_index[2] = newMap->ktIndex[2]; 236818534a1Smrg oldMap->kt_index[3] = newMap->ktIndex[3]; 237818534a1Smrg oldMap->group_info = newMap->groupInfo; 238818534a1Smrg oldMap->width = newMap->width; 239818534a1Smrg } 2401ab64890Smrg } 2411ab64890Smrg return Success; 2421ab64890Smrg} 2431ab64890Smrg 2441ab64890Smrgstatic Status 245818534a1Smrg_XkbReadKeyActions(XkbReadBufferPtr buf, XkbDescPtr info, xkbGetMapReply *rep) 2461ab64890Smrg{ 247818534a1Smrg int i; 248818534a1Smrg CARD8 numDescBuf[248]; 249818534a1Smrg CARD8 *numDesc = NULL; 250818534a1Smrg register int nKeyActs; 251818534a1Smrg Status ret = Success; 252818534a1Smrg 253818534a1Smrg if ((nKeyActs = rep->nKeyActs) > 0) { 254818534a1Smrg XkbSymMapPtr symMap; 255818534a1Smrg 256818534a1Smrg if (nKeyActs < sizeof numDescBuf) 257818534a1Smrg numDesc = numDescBuf; 258818534a1Smrg else 259258a0ebeSmrg numDesc = Xmallocarray(nKeyActs, sizeof(CARD8)); 260818534a1Smrg 261818534a1Smrg if (!_XkbCopyFromReadBuffer(buf, (char *) numDesc, nKeyActs)) { 262818534a1Smrg ret = BadLength; 263818534a1Smrg goto done; 264818534a1Smrg } 265818534a1Smrg i = XkbPaddedSize(nKeyActs) - nKeyActs; 266818534a1Smrg if ((i > 0) && (!_XkbSkipReadBufferData(buf, i))) { 267818534a1Smrg ret = BadLength; 268818534a1Smrg goto done; 269818534a1Smrg } 270818534a1Smrg symMap = &info->map->key_sym_map[rep->firstKeyAct]; 271818534a1Smrg for (i = 0; i < (int) rep->nKeyActs; i++, symMap++) { 272818534a1Smrg if (numDesc[i] == 0) { 273818534a1Smrg if ((i + rep->firstKeyAct) > (info->max_key_code + 1)) { 274818534a1Smrg ret = BadLength; 275818534a1Smrg goto done; 276818534a1Smrg } 277818534a1Smrg info->server->key_acts[i + rep->firstKeyAct] = 0; 278818534a1Smrg } 279818534a1Smrg else { 280818534a1Smrg XkbAction *newActs; 281818534a1Smrg 282818534a1Smrg /* 8/16/93 (ef) -- XXX! Verify size here (numdesc must be */ 283818534a1Smrg /* either zero or XkbKeyNumSyms(info,key) */ 284818534a1Smrg newActs = XkbResizeKeyActions(info, i + rep->firstKeyAct, 285818534a1Smrg numDesc[i]); 286818534a1Smrg if (newActs == NULL) { 287818534a1Smrg ret = BadAlloc; 288818534a1Smrg goto done; 289818534a1Smrg } 290818534a1Smrg if (!_XkbCopyFromReadBuffer(buf, (char *) newActs, 291818534a1Smrg (int) (numDesc[i] * sizeof(XkbAction)))) { 292818534a1Smrg ret = BadLength; 293818534a1Smrg goto done; 294818534a1Smrg } 295818534a1Smrg } 296818534a1Smrg } 2971ab64890Smrg } 298818534a1Smrg done: 299818534a1Smrg if (numDesc != NULL && numDesc != numDescBuf) 300818534a1Smrg Xfree(numDesc); 3011ab64890Smrg return ret; 3021ab64890Smrg} 3031ab64890Smrg 3041ab64890Smrgstatic Status 305818534a1Smrg_XkbReadKeyBehaviors(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 3061ab64890Smrg{ 307818534a1Smrg register int i; 308818534a1Smrg 309818534a1Smrg if (rep->totalKeyBehaviors > 0) { 310818534a1Smrg int size = xkb->max_key_code + 1; 311818534a1Smrg 312818534a1Smrg if (((int) rep->firstKeyBehavior + rep->nKeyBehaviors) > size) 313818534a1Smrg return BadLength; 314818534a1Smrg if (xkb->server->behaviors == NULL) { 315818534a1Smrg xkb->server->behaviors = _XkbTypedCalloc(size, XkbBehavior); 316818534a1Smrg if (xkb->server->behaviors == NULL) 317818534a1Smrg return BadAlloc; 318818534a1Smrg } 319818534a1Smrg else { 320818534a1Smrg bzero(&xkb->server->behaviors[rep->firstKeyBehavior], 321818534a1Smrg (rep->nKeyBehaviors * sizeof(XkbBehavior))); 322818534a1Smrg } 323818534a1Smrg for (i = 0; i < rep->totalKeyBehaviors; i++) { 324818534a1Smrg xkbBehaviorWireDesc *wire; 325818534a1Smrg 326818534a1Smrg wire = (xkbBehaviorWireDesc *) _XkbGetReadBufferPtr(buf, 327818534a1Smrg SIZEOF(xkbBehaviorWireDesc)); 328818534a1Smrg if (wire == NULL || wire->key >= size) 329818534a1Smrg return BadLength; 330818534a1Smrg xkb->server->behaviors[wire->key].type = wire->type; 331818534a1Smrg xkb->server->behaviors[wire->key].data = wire->data; 332818534a1Smrg } 3331ab64890Smrg } 3341ab64890Smrg return Success; 3351ab64890Smrg} 3361ab64890Smrg 3371ab64890Smrgstatic Status 338818534a1Smrg_XkbReadVirtualMods(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 3391ab64890Smrg{ 340818534a1Smrg if (rep->virtualMods) { 341818534a1Smrg register int i, bit, nVMods; 342818534a1Smrg register char *data; 343818534a1Smrg 344818534a1Smrg for (i = nVMods = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 345818534a1Smrg if (rep->virtualMods & bit) 346818534a1Smrg nVMods++; 347818534a1Smrg } 348818534a1Smrg data = _XkbGetReadBufferPtr(buf, XkbPaddedSize(nVMods)); 349818534a1Smrg if (data == NULL) 350818534a1Smrg return BadLength; 351818534a1Smrg for (i = 0, bit = 1; (i < XkbNumVirtualMods) && (nVMods > 0); 352818534a1Smrg i++, bit <<= 1) { 353818534a1Smrg if (rep->virtualMods & bit) { 354818534a1Smrg xkb->server->vmods[i] = *data++; 355818534a1Smrg nVMods--; 356818534a1Smrg } 357818534a1Smrg } 3581ab64890Smrg } 3591ab64890Smrg return Success; 3601ab64890Smrg} 3611ab64890Smrg 3621ab64890Smrgstatic Status 363818534a1Smrg_XkbReadExplicitComponents(XkbReadBufferPtr buf, 364818534a1Smrg XkbDescPtr xkb, 365818534a1Smrg xkbGetMapReply *rep) 3661ab64890Smrg{ 367818534a1Smrg register int i; 368818534a1Smrg unsigned char *wire; 369818534a1Smrg 370818534a1Smrg if (rep->totalKeyExplicit > 0) { 371818534a1Smrg int size = xkb->max_key_code + 1; 372818534a1Smrg 373818534a1Smrg if (((int) rep->firstKeyExplicit + rep->nKeyExplicit) > size) 374818534a1Smrg return BadLength; 375818534a1Smrg if (xkb->server->explicit == NULL) { 376818534a1Smrg xkb->server->explicit = _XkbTypedCalloc(size, unsigned char); 377818534a1Smrg 378818534a1Smrg if (xkb->server->explicit == NULL) 379818534a1Smrg return BadAlloc; 380818534a1Smrg } 381818534a1Smrg else { 382818534a1Smrg bzero(&xkb->server->explicit[rep->firstKeyExplicit], 383818534a1Smrg rep->nKeyExplicit); 384818534a1Smrg } 385818534a1Smrg i = XkbPaddedSize(2 * rep->totalKeyExplicit); 386818534a1Smrg wire = (unsigned char *) _XkbGetReadBufferPtr(buf, i); 387818534a1Smrg if (!wire) 388818534a1Smrg return BadLength; 389818534a1Smrg for (i = 0; i < rep->totalKeyExplicit; i++, wire += 2) { 390818534a1Smrg if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code) 391818534a1Smrg return BadLength; 392818534a1Smrg xkb->server->explicit[wire[0]] = wire[1]; 393818534a1Smrg } 3941ab64890Smrg } 3951ab64890Smrg return Success; 3961ab64890Smrg} 3971ab64890Smrg 3981ab64890Smrgstatic Status 399818534a1Smrg_XkbReadModifierMap(XkbReadBufferPtr buf, XkbDescPtr xkb, xkbGetMapReply *rep) 4001ab64890Smrg{ 401818534a1Smrg register int i; 402818534a1Smrg unsigned char *wire; 403818534a1Smrg 404818534a1Smrg if (rep->totalModMapKeys > 0) { 405818534a1Smrg if (((int) rep->firstModMapKey + rep->nModMapKeys) > 406818534a1Smrg (xkb->max_key_code + 1)) 407818534a1Smrg return BadLength; 408818534a1Smrg if ((xkb->map->modmap == NULL) && 409818534a1Smrg (XkbAllocClientMap(xkb, XkbModifierMapMask, 0) != Success)) { 410818534a1Smrg return BadAlloc; 411818534a1Smrg } 412818534a1Smrg else { 413818534a1Smrg bzero(&xkb->map->modmap[rep->firstModMapKey], rep->nModMapKeys); 414818534a1Smrg } 415818534a1Smrg i = XkbPaddedSize(2 * rep->totalModMapKeys); 416818534a1Smrg wire = (unsigned char *) _XkbGetReadBufferPtr(buf, i); 417818534a1Smrg if (!wire) 418818534a1Smrg return BadLength; 419818534a1Smrg for (i = 0; i < rep->totalModMapKeys; i++, wire += 2) { 420818534a1Smrg if (wire[0] > xkb->max_key_code || wire[1] > xkb->max_key_code) 421818534a1Smrg return BadLength; 422818534a1Smrg xkb->map->modmap[wire[0]] = wire[1]; 423818534a1Smrg } 4241ab64890Smrg } 4251ab64890Smrg return Success; 4261ab64890Smrg} 4271ab64890Smrg 4281ab64890Smrgstatic Status 429818534a1Smrg_XkbReadVirtualModMap(XkbReadBufferPtr buf, 430818534a1Smrg XkbDescPtr xkb, 431818534a1Smrg xkbGetMapReply *rep) 4321ab64890Smrg{ 433818534a1Smrg register int i; 434818534a1Smrg xkbVModMapWireDesc *wire; 435818534a1Smrg XkbServerMapPtr srv; 436818534a1Smrg 437818534a1Smrg if (rep->totalVModMapKeys > 0) { 438818534a1Smrg if (((int) rep->firstVModMapKey + rep->nVModMapKeys) 439818534a1Smrg > xkb->max_key_code + 1) 440818534a1Smrg return BadLength; 441818534a1Smrg if (((xkb->server == NULL) || (xkb->server->vmodmap == NULL)) && 442818534a1Smrg (XkbAllocServerMap(xkb, XkbVirtualModMapMask, 0) != Success)) { 443818534a1Smrg return BadAlloc; 444818534a1Smrg } 445818534a1Smrg else { 446818534a1Smrg srv = xkb->server; 447818534a1Smrg if (rep->nVModMapKeys > rep->firstVModMapKey) 448818534a1Smrg bzero((char *) &srv->vmodmap[rep->firstVModMapKey], 449818534a1Smrg (rep->nVModMapKeys - rep->firstVModMapKey) * 450818534a1Smrg sizeof(unsigned short)); 451818534a1Smrg } 452818534a1Smrg srv = xkb->server; 453818534a1Smrg i = rep->totalVModMapKeys * SIZEOF(xkbVModMapWireDesc); 454818534a1Smrg wire = (xkbVModMapWireDesc *) _XkbGetReadBufferPtr(buf, i); 455818534a1Smrg if (!wire) 456818534a1Smrg return BadLength; 457818534a1Smrg for (i = 0; i < rep->totalVModMapKeys; i++, wire++) { 458818534a1Smrg if ((wire->key >= xkb->min_key_code) && 459818534a1Smrg (wire->key <= xkb->max_key_code)) 460818534a1Smrg srv->vmodmap[wire->key] = wire->vmods; 461818534a1Smrg } 4621ab64890Smrg } 4631ab64890Smrg return Success; 4641ab64890Smrg} 4651ab64890Smrg 4661ab64890Smrgstatic xkbGetMapReq * 467818534a1Smrg_XkbGetGetMapReq(Display *dpy, XkbDescPtr xkb) 4681ab64890Smrg{ 469818534a1Smrg xkbGetMapReq *req; 4701ab64890Smrg 4711ab64890Smrg GetReq(kbGetMap, req); 4721ab64890Smrg req->reqType = dpy->xkb_info->codes->major_opcode; 4731ab64890Smrg req->xkbReqType = X_kbGetMap; 4741ab64890Smrg req->deviceSpec = xkb->device_spec; 4751ab64890Smrg req->full = req->partial = 0; 4761ab64890Smrg req->firstType = req->nTypes = 0; 4771ab64890Smrg req->firstKeySym = req->nKeySyms = 0; 4781ab64890Smrg req->firstKeyAct = req->nKeyActs = 0; 4791ab64890Smrg req->firstKeyBehavior = req->nKeyBehaviors = 0; 4801ab64890Smrg req->virtualMods = 0; 4811ab64890Smrg req->firstKeyExplicit = req->nKeyExplicit = 0; 4821ab64890Smrg req->firstModMapKey = req->nModMapKeys = 0; 4831ab64890Smrg req->firstVModMapKey = req->nVModMapKeys = 0; 4841ab64890Smrg return req; 4851ab64890Smrg} 4861ab64890Smrg 4871ab64890SmrgStatus 488818534a1Smrg_XkbReadGetMapReply(Display *dpy, 489818534a1Smrg xkbGetMapReply *rep, 490818534a1Smrg XkbDescPtr xkb, 491818534a1Smrg int *nread_rtrn) 4921ab64890Smrg{ 493818534a1Smrg int extraData; 494818534a1Smrg unsigned mask; 4951ab64890Smrg 496818534a1Smrg if (xkb->device_spec == XkbUseCoreKbd) 497818534a1Smrg xkb->device_spec = rep->deviceID; 498818534a1Smrg if (rep->maxKeyCode < rep->minKeyCode) 499818534a1Smrg return BadImplementation; 5001ab64890Smrg xkb->min_key_code = rep->minKeyCode; 5011ab64890Smrg xkb->max_key_code = rep->maxKeyCode; 5021ab64890Smrg 5031ab64890Smrg if (!xkb->map) { 504818534a1Smrg mask = rep->present & XkbAllClientInfoMask; 505818534a1Smrg if (mask && (XkbAllocClientMap(xkb, mask, rep->nTypes) != Success)) 506818534a1Smrg return BadAlloc; 5071ab64890Smrg } 5081ab64890Smrg if (!xkb->server) { 509818534a1Smrg mask = rep->present & XkbAllServerInfoMask; 510818534a1Smrg if (mask && (XkbAllocServerMap(xkb, mask, rep->totalActs) != Success)) 511818534a1Smrg return BadAlloc; 5121ab64890Smrg } 513818534a1Smrg extraData = (int) (rep->length * 4); 514818534a1Smrg extraData -= (SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)); 5151ab64890Smrg if (rep->length) { 516818534a1Smrg XkbReadBufferRec buf; 517818534a1Smrg int left; 518818534a1Smrg 519818534a1Smrg if (_XkbInitReadBuffer(dpy, &buf, extraData)) { 520818534a1Smrg Status status = Success; 521818534a1Smrg 522818534a1Smrg if (nread_rtrn != NULL) 523818534a1Smrg *nread_rtrn = extraData; 524818534a1Smrg if (status == Success) 525818534a1Smrg status = _XkbReadKeyTypes(&buf, xkb, rep); 526818534a1Smrg if (status == Success) 527818534a1Smrg status = _XkbReadKeySyms(&buf, xkb, rep); 528818534a1Smrg if (status == Success) 529818534a1Smrg status = _XkbReadKeyActions(&buf, xkb, rep); 530818534a1Smrg if (status == Success) 531818534a1Smrg status = _XkbReadKeyBehaviors(&buf, xkb, rep); 532818534a1Smrg if (status == Success) 533818534a1Smrg status = _XkbReadVirtualMods(&buf, xkb, rep); 534818534a1Smrg if (status == Success) 535818534a1Smrg status = _XkbReadExplicitComponents(&buf, xkb, rep); 536818534a1Smrg if (status == Success) 537818534a1Smrg status = _XkbReadModifierMap(&buf, xkb, rep); 538818534a1Smrg if (status == Success) 539818534a1Smrg status = _XkbReadVirtualModMap(&buf, xkb, rep); 540818534a1Smrg left = _XkbFreeReadBuffer(&buf); 541818534a1Smrg if (status != Success) 542818534a1Smrg return status; 543818534a1Smrg else if (left || buf.error) 544818534a1Smrg return BadLength; 545818534a1Smrg } 546818534a1Smrg else 547818534a1Smrg return BadAlloc; 5481ab64890Smrg } 5491ab64890Smrg return Success; 5501ab64890Smrg} 5511ab64890Smrg 5521ab64890Smrgstatic Status 553818534a1Smrg_XkbHandleGetMapReply(Display *dpy, XkbDescPtr xkb) 5541ab64890Smrg{ 555818534a1Smrg xkbGetMapReply rep; 5561ab64890Smrg 557818534a1Smrg if (!_XReply(dpy, (xReply *) &rep, 558818534a1Smrg ((SIZEOF(xkbGetMapReply) - SIZEOF(xGenericReply)) >> 2), 559818534a1Smrg xFalse)) { 560818534a1Smrg return BadImplementation; 5611ab64890Smrg } 562818534a1Smrg return _XkbReadGetMapReply(dpy, &rep, xkb, NULL); 5631ab64890Smrg} 5641ab64890Smrg 5651ab64890SmrgStatus 566818534a1SmrgXkbGetUpdatedMap(Display *dpy, unsigned which, XkbDescPtr xkb) 5671ab64890Smrg{ 5681ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 569818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 570818534a1Smrg return BadAccess; 5711ab64890Smrg if (which) { 572818534a1Smrg register xkbGetMapReq *req; 573818534a1Smrg Status status; 5741ab64890Smrg 575818534a1Smrg LockDisplay(dpy); 5761ab64890Smrg 577818534a1Smrg req = _XkbGetGetMapReq(dpy, xkb); 578818534a1Smrg req->full = which; 579818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 5801ab64890Smrg 581818534a1Smrg UnlockDisplay(dpy); 582818534a1Smrg SyncHandle(); 583818534a1Smrg return status; 5841ab64890Smrg } 5851ab64890Smrg return Success; 5861ab64890Smrg} 5871ab64890Smrg 5881ab64890SmrgXkbDescPtr 589818534a1SmrgXkbGetMap(Display *dpy, unsigned which, unsigned deviceSpec) 5901ab64890Smrg{ 591818534a1Smrg XkbDescPtr xkb; 5921ab64890Smrg 593818534a1Smrg xkb = _XkbTypedCalloc(1, XkbDescRec); 5941ab64890Smrg if (xkb) { 595818534a1Smrg xkb->device_spec = deviceSpec; 596818534a1Smrg xkb->map = _XkbTypedCalloc(1, XkbClientMapRec); 597818534a1Smrg if ((xkb->map == NULL) || 598818534a1Smrg ((which) && (XkbGetUpdatedMap(dpy, which, xkb) != Success))) { 599818534a1Smrg if (xkb->map) { 600818534a1Smrg Xfree(xkb->map); 601818534a1Smrg xkb->map = NULL; 602818534a1Smrg } 603818534a1Smrg Xfree(xkb); 604818534a1Smrg return NULL; 605818534a1Smrg } 606818534a1Smrg xkb->dpy = dpy; 6071ab64890Smrg } 6081ab64890Smrg return xkb; 6091ab64890Smrg} 6101ab64890Smrg 6111ab64890SmrgStatus 612818534a1SmrgXkbGetKeyTypes(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 6131ab64890Smrg{ 6141ab64890Smrg register xkbGetMapReq *req; 6151ab64890Smrg Status status; 6161ab64890Smrg 6171ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 618818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 619818534a1Smrg return BadAccess; 620818534a1Smrg if ((num < 1) || (num > XkbMaxKeyTypes)) 621818534a1Smrg return BadValue; 6221ab64890Smrg 6231ab64890Smrg LockDisplay(dpy); 6241ab64890Smrg 6251ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 6261ab64890Smrg req->firstType = first; 6271ab64890Smrg req->nTypes = num; 628818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 6291ab64890Smrg 6301ab64890Smrg UnlockDisplay(dpy); 6311ab64890Smrg SyncHandle(); 6321ab64890Smrg return status; 6331ab64890Smrg} 6341ab64890Smrg 6351ab64890SmrgStatus 636818534a1SmrgXkbGetKeyActions(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 6371ab64890Smrg{ 6381ab64890Smrg register xkbGetMapReq *req; 6391ab64890Smrg Status status; 6401ab64890Smrg 6411ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 642818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 643818534a1Smrg return BadAccess; 6441ab64890Smrg 645818534a1Smrg if ((num < 1) || (num > XkbMaxKeyCount)) 646818534a1Smrg return BadValue; 6471ab64890Smrg 6481ab64890Smrg LockDisplay(dpy); 6491ab64890Smrg 6501ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 6511ab64890Smrg req->firstKeyAct = first; 6521ab64890Smrg req->nKeyActs = num; 653818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 6541ab64890Smrg 6551ab64890Smrg UnlockDisplay(dpy); 6561ab64890Smrg SyncHandle(); 6571ab64890Smrg return status; 6581ab64890Smrg} 6591ab64890Smrg 6601ab64890SmrgStatus 661818534a1SmrgXkbGetKeySyms(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 6621ab64890Smrg{ 6631ab64890Smrg register xkbGetMapReq *req; 6641ab64890Smrg Status status; 6651ab64890Smrg 6661ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 667818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 668818534a1Smrg return BadAccess; 6691ab64890Smrg 670818534a1Smrg if ((num < 1) || (num > XkbMaxKeyCount)) 671818534a1Smrg return BadValue; 6721ab64890Smrg 6731ab64890Smrg LockDisplay(dpy); 6741ab64890Smrg 6751ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 6761ab64890Smrg req->firstKeySym = first; 6771ab64890Smrg req->nKeySyms = num; 678818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 6791ab64890Smrg 6801ab64890Smrg UnlockDisplay(dpy); 6811ab64890Smrg SyncHandle(); 6821ab64890Smrg 6831ab64890Smrg return status; 6841ab64890Smrg} 6851ab64890Smrg 6861ab64890SmrgStatus 687818534a1SmrgXkbGetKeyBehaviors(Display *dpy, unsigned first, unsigned num, XkbDescPtr xkb) 6881ab64890Smrg{ 6891ab64890Smrg register xkbGetMapReq *req; 6901ab64890Smrg Status status; 6911ab64890Smrg 6921ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 693818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 694818534a1Smrg return BadAccess; 6951ab64890Smrg 696818534a1Smrg if ((num < 1) || (num > XkbMaxKeyCount)) 697818534a1Smrg return BadValue; 6981ab64890Smrg 6991ab64890Smrg LockDisplay(dpy); 7001ab64890Smrg 7011ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 7021ab64890Smrg req->firstKeyBehavior = first; 7031ab64890Smrg req->nKeyBehaviors = num; 704818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 7051ab64890Smrg 7061ab64890Smrg UnlockDisplay(dpy); 7071ab64890Smrg SyncHandle(); 7081ab64890Smrg return status; 7091ab64890Smrg} 7101ab64890Smrg 7111ab64890SmrgStatus 712818534a1SmrgXkbGetVirtualMods(Display *dpy, unsigned which, XkbDescPtr xkb) 7131ab64890Smrg{ 7141ab64890Smrg register xkbGetMapReq *req; 7151ab64890Smrg Status status; 7161ab64890Smrg 7171ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 718818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 719818534a1Smrg return BadAccess; 7201ab64890Smrg 7211ab64890Smrg LockDisplay(dpy); 7221ab64890Smrg 7231ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 7241ab64890Smrg req->virtualMods = which; 725818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 7261ab64890Smrg 7271ab64890Smrg UnlockDisplay(dpy); 7281ab64890Smrg SyncHandle(); 7291ab64890Smrg return status; 7301ab64890Smrg} 7311ab64890Smrg 7321ab64890SmrgStatus 733818534a1SmrgXkbGetKeyExplicitComponents(Display *dpy, 734818534a1Smrg unsigned first, 735818534a1Smrg unsigned num, 736818534a1Smrg XkbDescPtr xkb) 7371ab64890Smrg{ 7381ab64890Smrg register xkbGetMapReq *req; 7391ab64890Smrg Status status; 7401ab64890Smrg 7411ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 742818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 743818534a1Smrg return BadAccess; 7441ab64890Smrg 745818534a1Smrg if ((num < 1) || (num > XkbMaxKeyCount)) 746818534a1Smrg return BadValue; 7471ab64890Smrg 7481ab64890Smrg LockDisplay(dpy); 7491ab64890Smrg 7501ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 7511ab64890Smrg req->firstKeyExplicit = first; 7521ab64890Smrg req->nKeyExplicit = num; 753818534a1Smrg if ((xkb != NULL) && (xkb->server != NULL) && 754818534a1Smrg (xkb->server->explicit != NULL)) { 755818534a1Smrg if ((num > 0) && (first >= xkb->min_key_code) && 756818534a1Smrg (first + num <= xkb->max_key_code)) 757818534a1Smrg bzero(&xkb->server->explicit[first], num); 7581ab64890Smrg } 7591ab64890Smrg if (xkb) 760818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 7611ab64890Smrg else 7621ab64890Smrg status = BadMatch; 7631ab64890Smrg 7641ab64890Smrg UnlockDisplay(dpy); 7651ab64890Smrg SyncHandle(); 7661ab64890Smrg return status; 7671ab64890Smrg} 7681ab64890Smrg 7691ab64890SmrgStatus 770818534a1SmrgXkbGetKeyModifierMap(Display *dpy, 771818534a1Smrg unsigned first, 772818534a1Smrg unsigned num, 773818534a1Smrg XkbDescPtr xkb) 7741ab64890Smrg{ 7751ab64890Smrg register xkbGetMapReq *req; 7761ab64890Smrg Status status; 7771ab64890Smrg 7781ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 779818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 780818534a1Smrg return BadAccess; 7811ab64890Smrg 782818534a1Smrg if ((num < 1) || (num > XkbMaxKeyCount)) 783818534a1Smrg return BadValue; 7841ab64890Smrg 7851ab64890Smrg LockDisplay(dpy); 7861ab64890Smrg 7871ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 7881ab64890Smrg req->firstModMapKey = first; 7891ab64890Smrg req->nModMapKeys = num; 790818534a1Smrg if ((xkb != NULL) && (xkb->map != NULL) && (xkb->map->modmap != NULL)) { 791818534a1Smrg if ((num > 0) && (first >= xkb->min_key_code) && 792818534a1Smrg (first + num <= xkb->max_key_code)) 793818534a1Smrg bzero(&xkb->map->modmap[first], num); 7941ab64890Smrg } 7951ab64890Smrg if (xkb) 796818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 7971ab64890Smrg else 7981ab64890Smrg status = BadMatch; 7991ab64890Smrg 8001ab64890Smrg UnlockDisplay(dpy); 8011ab64890Smrg SyncHandle(); 8021ab64890Smrg return status; 8031ab64890Smrg} 8041ab64890Smrg 8051ab64890SmrgStatus 806818534a1SmrgXkbGetKeyVirtualModMap(Display *dpy, unsigned first, unsigned num, 807818534a1Smrg XkbDescPtr xkb) 8081ab64890Smrg{ 8091ab64890Smrg register xkbGetMapReq *req; 8101ab64890Smrg Status status; 8111ab64890Smrg 8121ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 813818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 814818534a1Smrg return BadAccess; 8151ab64890Smrg 816818534a1Smrg if ((num < 1) || (num > XkbMaxKeyCount)) 817818534a1Smrg return BadValue; 8181ab64890Smrg 8191ab64890Smrg LockDisplay(dpy); 8201ab64890Smrg 8211ab64890Smrg req = _XkbGetGetMapReq(dpy, xkb); 8221ab64890Smrg req->firstVModMapKey = first; 8231ab64890Smrg req->nVModMapKeys = num; 824818534a1Smrg if ((xkb != NULL) && (xkb->map != NULL) && (xkb->map->modmap != NULL)) { 825818534a1Smrg if ((num > 0) && (first >= xkb->min_key_code) && 826818534a1Smrg (first + num <= xkb->max_key_code)) 827818534a1Smrg bzero(&xkb->server->vmodmap[first], num * sizeof(unsigned short)); 8281ab64890Smrg } 8291ab64890Smrg 8301ab64890Smrg if (xkb) 831818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 8321ab64890Smrg else 8331ab64890Smrg status = BadMatch; 8341ab64890Smrg 8351ab64890Smrg UnlockDisplay(dpy); 8361ab64890Smrg SyncHandle(); 8371ab64890Smrg return status; 8381ab64890Smrg} 8391ab64890Smrg 8401ab64890SmrgStatus 841818534a1SmrgXkbGetMapChanges(Display *dpy, XkbDescPtr xkb, XkbMapChangesPtr changes) 8421ab64890Smrg{ 8431ab64890Smrg xkbGetMapReq *req; 8441ab64890Smrg 8451ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 846818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 847818534a1Smrg return BadAccess; 8481ab64890Smrg LockDisplay(dpy); 8491ab64890Smrg if (changes->changed) { 850818534a1Smrg Status status = Success; 851818534a1Smrg 852818534a1Smrg req = _XkbGetGetMapReq(dpy, xkb); 853818534a1Smrg req->full = 0; 854818534a1Smrg req->partial = changes->changed; 855818534a1Smrg req->firstType = changes->first_type; 856818534a1Smrg req->nTypes = changes->num_types; 857818534a1Smrg req->firstKeySym = changes->first_key_sym; 858818534a1Smrg req->nKeySyms = changes->num_key_syms; 859818534a1Smrg req->firstKeyAct = changes->first_key_act; 860818534a1Smrg req->nKeyActs = changes->num_key_acts; 861818534a1Smrg req->firstKeyBehavior = changes->first_key_behavior; 862818534a1Smrg req->nKeyBehaviors = changes->num_key_behaviors; 863818534a1Smrg req->virtualMods = changes->vmods; 864818534a1Smrg req->firstKeyExplicit = changes->first_key_explicit; 865818534a1Smrg req->nKeyExplicit = changes->num_key_explicit; 866818534a1Smrg req->firstModMapKey = changes->first_modmap_key; 867818534a1Smrg req->nModMapKeys = changes->num_modmap_keys; 868818534a1Smrg req->firstVModMapKey = changes->first_vmodmap_key; 869818534a1Smrg req->nVModMapKeys = changes->num_vmodmap_keys; 870818534a1Smrg status = _XkbHandleGetMapReply(dpy, xkb); 871818534a1Smrg UnlockDisplay(dpy); 872818534a1Smrg SyncHandle(); 873818534a1Smrg return status; 8741ab64890Smrg } 8751ab64890Smrg UnlockDisplay(dpy); 8761ab64890Smrg return Success; 8771ab64890Smrg} 878