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 351ab64890Smrg 361ab64890Smrgstatic Status 37818534a1Smrg_XkbReadAtoms(XkbReadBufferPtr buf, 38818534a1Smrg Atom *atoms, 39818534a1Smrg int maxAtoms, 40818534a1Smrg CARD32 present) 411ab64890Smrg{ 42818534a1Smrg register int i, bit; 431ab64890Smrg 44818534a1Smrg for (i = 0, bit = 1; (i < maxAtoms) && (present); i++, bit <<= 1) { 45818534a1Smrg if (present & bit) { 46818534a1Smrg if (!_XkbReadBufferCopy32(buf, (long *) &atoms[i], 1)) 47818534a1Smrg return BadLength; 48818534a1Smrg present &= ~bit; 49818534a1Smrg } 501ab64890Smrg } 511ab64890Smrg return Success; 521ab64890Smrg} 531ab64890Smrg 541ab64890SmrgStatus 55818534a1Smrg_XkbReadGetNamesReply(Display *dpy, 56818534a1Smrg xkbGetNamesReply *rep, 57818534a1Smrg XkbDescPtr xkb, 58818534a1Smrg int *nread_rtrn) 591ab64890Smrg{ 60818534a1Smrg int i, len; 61818534a1Smrg XkbReadBufferRec buf; 62818534a1Smrg register XkbNamesPtr names; 631ab64890Smrg 64818534a1Smrg if (xkb->device_spec == XkbUseCoreKbd) 65818534a1Smrg xkb->device_spec = rep->deviceID; 661ab64890Smrg 67818534a1Smrg if ((xkb->names == NULL) && 68818534a1Smrg (XkbAllocNames(xkb, rep->which, 69818534a1Smrg rep->nRadioGroups, rep->nKeyAliases) != Success)) { 70818534a1Smrg return BadAlloc; 711ab64890Smrg } 72818534a1Smrg names = xkb->names; 73818534a1Smrg if (rep->length == 0) 74818534a1Smrg return Success; 751ab64890Smrg 76818534a1Smrg if (!_XkbInitReadBuffer(dpy, &buf, (int) rep->length * 4)) 77818534a1Smrg return BadAlloc; 781ab64890Smrg if (nread_rtrn) 79818534a1Smrg *nread_rtrn = (int) rep->length * 4; 80818534a1Smrg 81818534a1Smrg if ((rep->which & XkbKeycodesNameMask) && 82818534a1Smrg (!_XkbReadBufferCopy32(&buf, (long *) &names->keycodes, 1))) 83818534a1Smrg goto BAILOUT; 84818534a1Smrg if ((rep->which & XkbGeometryNameMask) && 85818534a1Smrg (!_XkbReadBufferCopy32(&buf, (long *) &names->geometry, 1))) 86818534a1Smrg goto BAILOUT; 87818534a1Smrg if ((rep->which & XkbSymbolsNameMask) && 88818534a1Smrg (!_XkbReadBufferCopy32(&buf, (long *) &names->symbols, 1))) 89818534a1Smrg goto BAILOUT; 90818534a1Smrg if ((rep->which & XkbPhysSymbolsNameMask) && 91818534a1Smrg (!_XkbReadBufferCopy32(&buf, (long *) &names->phys_symbols, 1))) 92818534a1Smrg goto BAILOUT; 93818534a1Smrg if ((rep->which & XkbTypesNameMask) && 94818534a1Smrg (!_XkbReadBufferCopy32(&buf, (long *) &names->types, 1))) 95818534a1Smrg goto BAILOUT; 96818534a1Smrg if ((rep->which & XkbCompatNameMask) && 97818534a1Smrg (!_XkbReadBufferCopy32(&buf, (long *) &names->compat, 1))) 98818534a1Smrg goto BAILOUT; 99818534a1Smrg 100818534a1Smrg if (rep->which & XkbKeyTypeNamesMask) { 101818534a1Smrg XkbClientMapPtr map = xkb->map; 102818534a1Smrg XkbKeyTypePtr type; 103818534a1Smrg 104818534a1Smrg len = rep->nTypes * 4; 105818534a1Smrg if (map != NULL) { 106818534a1Smrg type = map->types; 107818534a1Smrg for (i = 0; (i < map->num_types) && (i < rep->nTypes); i++, type++) { 108818534a1Smrg if (!_XkbReadBufferCopy32(&buf, (long *) &type->name, 1)) 109818534a1Smrg goto BAILOUT; 110818534a1Smrg len -= 4; 111818534a1Smrg } 112818534a1Smrg } 113818534a1Smrg if ((len > 0) && (!_XkbSkipReadBufferData(&buf, len))) 114818534a1Smrg goto BAILOUT; 115818534a1Smrg } 116818534a1Smrg if (rep->which & XkbKTLevelNamesMask) { 117818534a1Smrg CARD8 *nLevels; 118818534a1Smrg XkbClientMapPtr map = xkb->map; 119818534a1Smrg 120818534a1Smrg nLevels = 121818534a1Smrg (CARD8 *) _XkbGetReadBufferPtr(&buf, XkbPaddedSize(rep->nTypes)); 122818534a1Smrg if (nLevels == NULL) 123818534a1Smrg goto BAILOUT; 124818534a1Smrg if (map != NULL) { 125818534a1Smrg XkbKeyTypePtr type = map->types; 126818534a1Smrg 127818534a1Smrg for (i = 0; i < (int) rep->nTypes; i++, type++) { 128818534a1Smrg if (i >= map->num_types) { 129818534a1Smrg if (!_XkbSkipReadBufferData(&buf, nLevels[i] * 4)) 130818534a1Smrg goto BAILOUT; 131818534a1Smrg continue; 132818534a1Smrg } 133818534a1Smrg if ((nLevels[i] > 0) && (nLevels[i] != type->num_levels)) { 134818534a1Smrg goto BAILOUT; 135818534a1Smrg } 1360f8248bfSmrg 1370f8248bfSmrg Xfree(type->level_names); 138818534a1Smrg if (nLevels[i] == 0) { 139818534a1Smrg type->level_names = NULL; 140818534a1Smrg continue; 141818534a1Smrg } 142818534a1Smrg type->level_names = _XkbTypedCalloc(nLevels[i], Atom); 143818534a1Smrg if (type->level_names != NULL) { 144818534a1Smrg if (!_XkbReadBufferCopy32(&buf, (long *) type->level_names, 145818534a1Smrg nLevels[i])) 146818534a1Smrg goto BAILOUT; 147818534a1Smrg } 148818534a1Smrg else { 149818534a1Smrg _XkbSkipReadBufferData(&buf, nLevels[i] * 4); 150818534a1Smrg } 151818534a1Smrg } 152818534a1Smrg } 153818534a1Smrg else { 154818534a1Smrg for (i = 0; i < (int) rep->nTypes; i++) { 155818534a1Smrg _XkbSkipReadBufferData(&buf, nLevels[i] * 4); 156818534a1Smrg } 157818534a1Smrg } 1581ab64890Smrg } 1591ab64890Smrg if (rep->which & XkbIndicatorNamesMask) { 160818534a1Smrg if (_XkbReadAtoms(&buf, names->indicators, XkbNumIndicators, 161818534a1Smrg rep->indicators) != Success) 162818534a1Smrg goto BAILOUT; 163818534a1Smrg } 164818534a1Smrg if (rep->which & XkbVirtualModNamesMask) { 165818534a1Smrg if (_XkbReadAtoms(&buf, names->vmods, XkbNumVirtualMods, 166818534a1Smrg (CARD32) rep->virtualMods) != Success) 167818534a1Smrg goto BAILOUT; 168818534a1Smrg } 169818534a1Smrg if (rep->which & XkbGroupNamesMask) { 170818534a1Smrg if (_XkbReadAtoms(&buf, names->groups, XkbNumKbdGroups, 171818534a1Smrg (CARD32) rep->groupNames) != Success) 172818534a1Smrg goto BAILOUT; 173818534a1Smrg } 174818534a1Smrg if (rep->which & XkbKeyNamesMask) { 175818534a1Smrg if (names->keys == NULL) { 176818534a1Smrg int nKeys; 177818534a1Smrg 178818534a1Smrg if (xkb->max_key_code == 0) { 179818534a1Smrg xkb->min_key_code = rep->minKeyCode; 180818534a1Smrg xkb->max_key_code = rep->maxKeyCode; 181818534a1Smrg } 182818534a1Smrg nKeys = xkb->max_key_code + 1; 183818534a1Smrg names->keys = _XkbTypedCalloc(nKeys, XkbKeyNameRec); 184818534a1Smrg } 185818534a1Smrg if (((int) rep->firstKey + rep->nKeys) > xkb->max_key_code + 1) 186818534a1Smrg goto BAILOUT; 187818534a1Smrg if (names->keys != NULL) { 188818534a1Smrg if (!_XkbCopyFromReadBuffer(&buf, 189818534a1Smrg (char *) &names->keys[rep->firstKey], 190818534a1Smrg rep->nKeys * XkbKeyNameLength)) 191818534a1Smrg goto BAILOUT; 1925efbdfc3Smrg names->num_keys = rep->nKeys; 193818534a1Smrg } 194818534a1Smrg else 195818534a1Smrg _XkbSkipReadBufferData(&buf, rep->nKeys * XkbKeyNameLength); 196818534a1Smrg } 197818534a1Smrg if (rep->which & XkbKeyAliasesMask && (rep->nKeyAliases > 0)) { 198818534a1Smrg if (XkbAllocNames(xkb, XkbKeyAliasesMask, 0, rep->nKeyAliases) != 199818534a1Smrg Success) 200818534a1Smrg goto BAILOUT; 201818534a1Smrg if (!_XkbCopyFromReadBuffer(&buf, (char *) names->key_aliases, 202818534a1Smrg rep->nKeyAliases * XkbKeyNameLength * 2)) 203818534a1Smrg goto BAILOUT; 204818534a1Smrg } 205818534a1Smrg if (rep->which & XkbRGNamesMask) { 206818534a1Smrg if (rep->nRadioGroups > 0) { 207818534a1Smrg Atom *rgNames; 208818534a1Smrg 209258a0ebeSmrg if ((names->radio_groups == NULL) || 210258a0ebeSmrg (names->num_rg < rep->nRadioGroups)) { 211258a0ebeSmrg _XkbResizeArray(names->radio_groups, names->num_rg, 212258a0ebeSmrg rep->nRadioGroups, Atom); 213818534a1Smrg } 214818534a1Smrg rgNames = names->radio_groups; 215818534a1Smrg if (!rgNames) { 216258a0ebeSmrg names->num_rg = 0; 217818534a1Smrg goto BAILOUT; 218818534a1Smrg } 219818534a1Smrg if (!_XkbReadBufferCopy32 220818534a1Smrg (&buf, (long *) rgNames, rep->nRadioGroups)) 221818534a1Smrg goto BAILOUT; 222818534a1Smrg names->num_rg = rep->nRadioGroups; 223818534a1Smrg } 224818534a1Smrg else if (names->num_rg > 0) { 225818534a1Smrg names->num_rg = 0; 226818534a1Smrg Xfree(names->radio_groups); 227818534a1Smrg } 228818534a1Smrg } 229818534a1Smrg len = _XkbFreeReadBuffer(&buf); 230818534a1Smrg if (len != 0) 231818534a1Smrg return BadLength; 232818534a1Smrg else 233818534a1Smrg return Success; 234818534a1Smrg BAILOUT: 2351ab64890Smrg _XkbFreeReadBuffer(&buf); 2361ab64890Smrg return BadLength; 2371ab64890Smrg} 2381ab64890Smrg 2391ab64890SmrgStatus 240818534a1SmrgXkbGetNames(Display *dpy, unsigned which, XkbDescPtr xkb) 2411ab64890Smrg{ 2421ab64890Smrg register xkbGetNamesReq *req; 243818534a1Smrg xkbGetNamesReply rep; 244818534a1Smrg Status status; 2451ab64890Smrg XkbInfoPtr xkbi; 2461ab64890Smrg 2471ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 248818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 249818534a1Smrg return BadAccess; 2501ab64890Smrg LockDisplay(dpy); 2511ab64890Smrg xkbi = dpy->xkb_info; 2521ab64890Smrg if (!xkb->names) { 253818534a1Smrg xkb->names = _XkbTypedCalloc(1, XkbNamesRec); 254818534a1Smrg if (!xkb->names) { 255818534a1Smrg UnlockDisplay(dpy); 256818534a1Smrg SyncHandle(); 257818534a1Smrg return BadAlloc; 258818534a1Smrg } 2591ab64890Smrg } 2601ab64890Smrg GetReq(kbGetNames, req); 2611ab64890Smrg req->reqType = xkbi->codes->major_opcode; 2621ab64890Smrg req->xkbReqType = X_kbGetNames; 2631ab64890Smrg req->deviceSpec = xkb->device_spec; 2641ab64890Smrg req->which = which; 265818534a1Smrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 266818534a1Smrg UnlockDisplay(dpy); 267818534a1Smrg SyncHandle(); 268818534a1Smrg return BadImplementation; 2691ab64890Smrg } 2701ab64890Smrg 271818534a1Smrg status = _XkbReadGetNamesReply(dpy, &rep, xkb, NULL); 2721ab64890Smrg UnlockDisplay(dpy); 2731ab64890Smrg SyncHandle(); 2741ab64890Smrg return status; 2751ab64890Smrg} 2761ab64890Smrg 2771ab64890Smrg/***====================================================================***/ 2781ab64890Smrg 2791ab64890Smrgstatic int 280818534a1Smrg_XkbCountBits(int nBitsMax, unsigned long mask) 2811ab64890Smrg{ 282818534a1Smrg register unsigned long y, nBits; 2831ab64890Smrg 284818534a1Smrg y = (mask >> 1) & 033333333333; 285818534a1Smrg y = mask - y - ((y >> 1) & 033333333333); 2861ab64890Smrg nBits = ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077)); 2871ab64890Smrg 2881ab64890Smrg /* nBitsMax really means max+1 */ 2891ab64890Smrg return (nBits < nBitsMax) ? nBits : (nBitsMax - 1); 2901ab64890Smrg} 2911ab64890Smrg 2921ab64890Smrgstatic CARD32 293818534a1Smrg_XkbCountAtoms(Atom *atoms, int maxAtoms, int *count) 2941ab64890Smrg{ 295818534a1Smrg register unsigned int i, bit, nAtoms; 296818534a1Smrg register CARD32 atomsPresent; 2971ab64890Smrg 298818534a1Smrg for (i = nAtoms = atomsPresent = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) { 299818534a1Smrg if (atoms[i] != None) { 300818534a1Smrg atomsPresent |= bit; 3011ab64890Smrg nAtoms++; 3021ab64890Smrg } 3031ab64890Smrg } 3041ab64890Smrg if (count) 305818534a1Smrg *count = nAtoms; 3061ab64890Smrg return atomsPresent; 3071ab64890Smrg} 3081ab64890Smrg 3091ab64890Smrgstatic void 310818534a1Smrg_XkbCopyAtoms(Display *dpy, Atom *atoms, CARD32 mask, int maxAtoms) 3111ab64890Smrg{ 312818534a1Smrg register unsigned int i, bit; 3131ab64890Smrg 314818534a1Smrg for (i = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) { 315818534a1Smrg if (mask & bit) 316818534a1Smrg Data32(dpy, &atoms[i], 4); 3171ab64890Smrg } 3181ab64890Smrg return; 3191ab64890Smrg} 3201ab64890Smrg 3211ab64890SmrgBool 322818534a1SmrgXkbSetNames(Display *dpy, 323818534a1Smrg unsigned int which, 324818534a1Smrg unsigned int firstType, 325818534a1Smrg unsigned int nTypes, 326818534a1Smrg XkbDescPtr xkb) 3271ab64890Smrg{ 3281ab64890Smrg register xkbSetNamesReq *req; 329818534a1Smrg int nLvlNames = 0; 3301ab64890Smrg XkbInfoPtr xkbi; 3311ab64890Smrg XkbNamesPtr names; 332818534a1Smrg unsigned firstLvlType, nLvlTypes; 333818534a1Smrg int nVMods, nLEDs, nRG, nKA, nGroups; 334818534a1Smrg int nKeys = 0, firstKey = 0, nAtoms; 335818534a1Smrg CARD32 leds, vmods, groups; 3361ab64890Smrg 3371ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 338818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 339818534a1Smrg return False; 340818534a1Smrg if ((!xkb) || (!xkb->names)) 341818534a1Smrg return False; 342818534a1Smrg firstLvlType = firstType; 343818534a1Smrg nLvlTypes = nTypes; 344818534a1Smrg if (nTypes < 1) 345818534a1Smrg which &= ~(XkbKTLevelNamesMask | XkbKeyTypeNamesMask); 346818534a1Smrg else if (firstType <= XkbLastRequiredType) { 347818534a1Smrg int adjust; 348818534a1Smrg 349818534a1Smrg adjust = XkbLastRequiredType - firstType + 1; 350818534a1Smrg firstType += adjust; 351818534a1Smrg nTypes -= adjust; 352818534a1Smrg if (nTypes < 1) 353818534a1Smrg which &= ~XkbKeyTypeNamesMask; 354818534a1Smrg } 355818534a1Smrg names = xkb->names; 356818534a1Smrg if (which & (XkbKTLevelNamesMask | XkbKeyTypeNamesMask)) { 357818534a1Smrg register int i; 358818534a1Smrg XkbKeyTypePtr type; 359818534a1Smrg 360818534a1Smrg if ((xkb->map == NULL) || (xkb->map->types == NULL) || (nTypes == 0) || 361818534a1Smrg (firstType + nTypes > xkb->map->num_types) || 362818534a1Smrg (firstLvlType + nLvlTypes > xkb->map->num_types)) 363818534a1Smrg return False; 364818534a1Smrg if (which & XkbKTLevelNamesMask) { 365818534a1Smrg type = &xkb->map->types[firstLvlType]; 366818534a1Smrg for (i = nLvlNames = 0; i < nLvlTypes; i++, type++) { 367818534a1Smrg if (type->level_names != NULL) 368818534a1Smrg nLvlNames += type->num_levels; 369818534a1Smrg } 370818534a1Smrg } 371818534a1Smrg } 372818534a1Smrg 373818534a1Smrg nVMods = nLEDs = nRG = nKA = nAtoms = nGroups = 0; 3741ab64890Smrg LockDisplay(dpy); 3751ab64890Smrg xkbi = dpy->xkb_info; 3761ab64890Smrg GetReq(kbSetNames, req); 3771ab64890Smrg req->reqType = xkbi->codes->major_opcode; 3781ab64890Smrg req->xkbReqType = X_kbSetNames; 3791ab64890Smrg req->deviceSpec = xkb->device_spec; 3801ab64890Smrg req->firstType = firstType; 3811ab64890Smrg req->nTypes = nTypes; 3821ab64890Smrg req->firstKey = xkb->min_key_code; 383818534a1Smrg req->nKeys = xkb->max_key_code - xkb->min_key_code + 1; 384818534a1Smrg 385818534a1Smrg if (which & XkbKeycodesNameMask) 386818534a1Smrg nAtoms++; 387818534a1Smrg if (which & XkbGeometryNameMask) 388818534a1Smrg nAtoms++; 389818534a1Smrg if (which & XkbSymbolsNameMask) 390818534a1Smrg nAtoms++; 391818534a1Smrg if (which & XkbPhysSymbolsNameMask) 392818534a1Smrg nAtoms++; 393818534a1Smrg if (which & XkbTypesNameMask) 394818534a1Smrg nAtoms++; 395818534a1Smrg if (which & XkbCompatNameMask) 396818534a1Smrg nAtoms++; 397818534a1Smrg if (which & XkbKeyTypeNamesMask) 398818534a1Smrg nAtoms += nTypes; 399818534a1Smrg if (which & XkbKTLevelNamesMask) { 400818534a1Smrg req->firstKTLevel = firstLvlType; 401818534a1Smrg req->nKTLevels = nLvlTypes; 402818534a1Smrg req->length += XkbPaddedSize(nLvlTypes) / 4; /* room for group widths */ 403818534a1Smrg nAtoms += nLvlNames; 404818534a1Smrg } 405818534a1Smrg else 406818534a1Smrg req->firstKTLevel = req->nKTLevels = 0; 407818534a1Smrg 408818534a1Smrg if (which & XkbIndicatorNamesMask) { 409818534a1Smrg req->indicators = leds = 410818534a1Smrg _XkbCountAtoms(names->indicators, XkbNumIndicators, &nLEDs); 411818534a1Smrg if (nLEDs > 0) 412818534a1Smrg nAtoms += nLEDs; 413818534a1Smrg else 414818534a1Smrg which &= ~XkbIndicatorNamesMask; 415818534a1Smrg } 416818534a1Smrg else 417818534a1Smrg req->indicators = leds = 0; 418818534a1Smrg 419818534a1Smrg if (which & XkbVirtualModNamesMask) { 420818534a1Smrg vmods = req->virtualMods = (CARD16) 421818534a1Smrg _XkbCountAtoms(names->vmods, XkbNumVirtualMods, &nVMods); 422818534a1Smrg if (nVMods > 0) 423818534a1Smrg nAtoms += nVMods; 424818534a1Smrg else 425818534a1Smrg which &= ~XkbVirtualModNamesMask; 426818534a1Smrg } 427818534a1Smrg else 428818534a1Smrg vmods = req->virtualMods = 0; 429818534a1Smrg 430818534a1Smrg if (which & XkbGroupNamesMask) { 431818534a1Smrg groups = req->groupNames = (CARD8) 432818534a1Smrg _XkbCountAtoms(names->groups, XkbNumKbdGroups, &nGroups); 433818534a1Smrg if (nGroups > 0) 434818534a1Smrg nAtoms += nGroups; 435818534a1Smrg else 436818534a1Smrg which &= ~XkbGroupNamesMask; 437818534a1Smrg } 438818534a1Smrg else 439818534a1Smrg groups = req->groupNames = 0; 440818534a1Smrg 441818534a1Smrg if ((which & XkbKeyNamesMask) && (names->keys != NULL)) { 442818534a1Smrg firstKey = req->firstKey; 443818534a1Smrg nKeys = req->nKeys; 444818534a1Smrg nAtoms += nKeys; /* technically not atoms, but 4 bytes wide */ 445818534a1Smrg } 446818534a1Smrg else 447818534a1Smrg which &= ~XkbKeyNamesMask; 448818534a1Smrg 449818534a1Smrg if (which & XkbKeyAliasesMask) { 450818534a1Smrg nKA = ((names->key_aliases != NULL) ? names->num_key_aliases : 0); 451818534a1Smrg if (nKA > 0) { 452818534a1Smrg req->nKeyAliases = nKA; 453818534a1Smrg nAtoms += nKA * 2; /* not atoms, but 8 bytes on the wire */ 454818534a1Smrg } 455818534a1Smrg else { 456818534a1Smrg which &= ~XkbKeyAliasesMask; 457818534a1Smrg req->nKeyAliases = 0; 458818534a1Smrg } 459818534a1Smrg } 460818534a1Smrg else 461818534a1Smrg req->nKeyAliases = 0; 462818534a1Smrg 463818534a1Smrg if (which & XkbRGNamesMask) { 464818534a1Smrg nRG = names->num_rg; 465818534a1Smrg if (nRG > 0) 466818534a1Smrg nAtoms += nRG; 467818534a1Smrg else 468818534a1Smrg which &= ~XkbRGNamesMask; 469818534a1Smrg } 470818534a1Smrg 471818534a1Smrg req->which = which; 472818534a1Smrg req->nRadioGroups = nRG; 473818534a1Smrg req->length += (nAtoms * 4) / 4; 474818534a1Smrg 475818534a1Smrg if (which & XkbKeycodesNameMask) 476818534a1Smrg Data32(dpy, (long *) &names->keycodes, 4); 477818534a1Smrg if (which & XkbGeometryNameMask) 478818534a1Smrg Data32(dpy, (long *) &names->geometry, 4); 479818534a1Smrg if (which & XkbSymbolsNameMask) 480818534a1Smrg Data32(dpy, (long *) &names->symbols, 4); 481818534a1Smrg if (which & XkbPhysSymbolsNameMask) 482818534a1Smrg Data32(dpy, (long *) &names->phys_symbols, 4); 483818534a1Smrg if (which & XkbTypesNameMask) 484818534a1Smrg Data32(dpy, (long *) &names->types, 4); 485818534a1Smrg if (which & XkbCompatNameMask) 486818534a1Smrg Data32(dpy, (long *) &names->compat, 4); 487818534a1Smrg if (which & XkbKeyTypeNamesMask) { 488818534a1Smrg register int i; 489818534a1Smrg register XkbKeyTypePtr type; 490818534a1Smrg 491818534a1Smrg type = &xkb->map->types[firstType]; 492818534a1Smrg for (i = 0; i < nTypes; i++, type++) { 493818534a1Smrg Data32(dpy, (long *) &type->name, 4); 494818534a1Smrg } 495818534a1Smrg } 496818534a1Smrg if (which & XkbKTLevelNamesMask) { 497818534a1Smrg XkbKeyTypePtr type; 498818534a1Smrg int i; 499818534a1Smrg char *tmp; 500818534a1Smrg 501818534a1Smrg BufAlloc(char *, tmp, XkbPaddedSize(nLvlTypes)); 502818534a1Smrg type = &xkb->map->types[firstLvlType]; 503818534a1Smrg for (i = 0; i < nLvlTypes; i++, type++) { 504818534a1Smrg *tmp++ = type->num_levels; 505818534a1Smrg } 506818534a1Smrg type = &xkb->map->types[firstLvlType]; 507818534a1Smrg for (i = 0; i < nLvlTypes; i++, type++) { 508818534a1Smrg if (type->level_names != NULL) 509818534a1Smrg Data32(dpy, (long *) type->level_names, type->num_levels * 4); 510818534a1Smrg } 511818534a1Smrg } 512818534a1Smrg if (which & XkbIndicatorNamesMask) 513818534a1Smrg _XkbCopyAtoms(dpy, names->indicators, leds, XkbNumIndicators); 514818534a1Smrg if (which & XkbVirtualModNamesMask) 515818534a1Smrg _XkbCopyAtoms(dpy, names->vmods, vmods, XkbNumVirtualMods); 516818534a1Smrg if (which & XkbGroupNamesMask) 517818534a1Smrg _XkbCopyAtoms(dpy, names->groups, groups, XkbNumKbdGroups); 518818534a1Smrg if (which & XkbKeyNamesMask) { 519818534a1Smrg Data(dpy, (char *) &names->keys[firstKey], nKeys * XkbKeyNameLength); 520818534a1Smrg } 521818534a1Smrg if (which & XkbKeyAliasesMask) { 522818534a1Smrg Data(dpy, (char *) names->key_aliases, nKA * XkbKeyNameLength * 2); 523818534a1Smrg } 524818534a1Smrg if (which & XkbRGNamesMask) { 525818534a1Smrg Data32(dpy, (long *) names->radio_groups, nRG * 4); 5261ab64890Smrg } 5271ab64890Smrg UnlockDisplay(dpy); 5281ab64890Smrg SyncHandle(); 5291ab64890Smrg return True; 5301ab64890Smrg} 5311ab64890Smrg 5321ab64890SmrgBool 533818534a1SmrgXkbChangeNames(Display *dpy, XkbDescPtr xkb, XkbNameChangesPtr changes) 5341ab64890Smrg{ 5351ab64890Smrg register xkbSetNamesReq *req; 536818534a1Smrg int nLvlNames = 0; 5371ab64890Smrg XkbInfoPtr xkbi; 5381ab64890Smrg XkbNamesPtr names; 539818534a1Smrg unsigned which, firstType, nTypes; 540818534a1Smrg unsigned firstLvlType, nLvlTypes; 541818534a1Smrg int nVMods, nLEDs, nRG, nKA, nGroups; 542818534a1Smrg int nKeys = 0, firstKey = 0, nAtoms; 543818534a1Smrg CARD32 leds = 0, vmods = 0, groups = 0; 5441ab64890Smrg 5451ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 546818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 547818534a1Smrg return False; 548818534a1Smrg if ((!xkb) || (!xkb->names) || (!changes)) 549818534a1Smrg return False; 550818534a1Smrg which = changes->changed; 551818534a1Smrg firstType = changes->first_type; 552818534a1Smrg nTypes = changes->num_types; 5532d67cb4fSmrg firstLvlType = changes->first_lvl; 554818534a1Smrg nLvlTypes = changes->num_lvls; 555818534a1Smrg if (which & XkbKeyTypeNamesMask) { 556818534a1Smrg if (nTypes < 1) 557818534a1Smrg which &= ~XkbKeyTypeNamesMask; 558818534a1Smrg else if (firstType <= XkbLastRequiredType) { 559818534a1Smrg int adjust; 560818534a1Smrg 561818534a1Smrg adjust = XkbLastRequiredType - firstType + 1; 562818534a1Smrg firstType += adjust; 563818534a1Smrg nTypes -= adjust; 564818534a1Smrg if (nTypes < 1) 565818534a1Smrg which &= ~XkbKeyTypeNamesMask; 566818534a1Smrg } 567818534a1Smrg } 568818534a1Smrg else 569818534a1Smrg firstType = nTypes = 0; 570818534a1Smrg 571818534a1Smrg if (which & XkbKTLevelNamesMask) { 572818534a1Smrg if (nLvlTypes < 1) 573818534a1Smrg which &= ~XkbKTLevelNamesMask; 574818534a1Smrg } 575818534a1Smrg else 576818534a1Smrg firstLvlType = nLvlTypes = 0; 577818534a1Smrg 578818534a1Smrg names = xkb->names; 579818534a1Smrg if (which & (XkbKTLevelNamesMask | XkbKeyTypeNamesMask)) { 580818534a1Smrg register int i; 581818534a1Smrg 582818534a1Smrg if ((xkb->map == NULL) || (xkb->map->types == NULL) || (nTypes == 0) || 583818534a1Smrg (firstType + nTypes > xkb->map->num_types) || 584818534a1Smrg (firstLvlType + nLvlTypes > xkb->map->num_types)) 585818534a1Smrg return False; 586818534a1Smrg if (which & XkbKTLevelNamesMask) { 587818534a1Smrg XkbKeyTypePtr type = &xkb->map->types[firstLvlType]; 588818534a1Smrg 589818534a1Smrg for (i = nLvlNames = 0; i < nLvlTypes; i++, type++) { 590818534a1Smrg if (type->level_names != NULL) 591818534a1Smrg nLvlNames += type->num_levels; 592818534a1Smrg } 593818534a1Smrg } 594818534a1Smrg } 595818534a1Smrg 596818534a1Smrg if (changes->num_keys < 1) 597818534a1Smrg which &= ~XkbKeyNamesMask; 598818534a1Smrg if ((which & XkbKeyNamesMask) == 0) 599818534a1Smrg changes->first_key = changes->num_keys = 0; 600818534a1Smrg else if ((changes->first_key < xkb->min_key_code) || 601818534a1Smrg (changes->first_key + changes->num_keys > xkb->max_key_code)) { 602818534a1Smrg return False; 603818534a1Smrg } 604818534a1Smrg 605818534a1Smrg if ((which & XkbVirtualModNamesMask) == 0) 606818534a1Smrg changes->changed_vmods = 0; 607818534a1Smrg else if (changes->changed_vmods == 0) 608818534a1Smrg which &= ~XkbVirtualModNamesMask; 609818534a1Smrg 610818534a1Smrg if ((which & XkbIndicatorNamesMask) == 0) 611818534a1Smrg changes->changed_indicators = 0; 612818534a1Smrg else if (changes->changed_indicators == 0) 613818534a1Smrg which &= ~XkbIndicatorNamesMask; 614818534a1Smrg 615818534a1Smrg if ((which & XkbGroupNamesMask) == 0) 616818534a1Smrg changes->changed_groups = 0; 617818534a1Smrg else if (changes->changed_groups == 0) 618818534a1Smrg which &= ~XkbGroupNamesMask; 619818534a1Smrg 620818534a1Smrg nVMods = nLEDs = nRG = nKA = nAtoms = nGroups = 0; 6211ab64890Smrg LockDisplay(dpy); 6221ab64890Smrg xkbi = dpy->xkb_info; 6231ab64890Smrg GetReq(kbSetNames, req); 6241ab64890Smrg req->reqType = xkbi->codes->major_opcode; 6251ab64890Smrg req->xkbReqType = X_kbSetNames; 6261ab64890Smrg req->deviceSpec = xkb->device_spec; 6271ab64890Smrg req->firstType = firstType; 6281ab64890Smrg req->nTypes = nTypes; 6291ab64890Smrg req->firstKey = changes->first_key; 6301ab64890Smrg req->nKeys = changes->num_keys; 6311ab64890Smrg 632818534a1Smrg if (which & XkbKeycodesNameMask) 633818534a1Smrg nAtoms++; 634818534a1Smrg if (which & XkbGeometryNameMask) 635818534a1Smrg nAtoms++; 636818534a1Smrg if (which & XkbSymbolsNameMask) 637818534a1Smrg nAtoms++; 638818534a1Smrg if (which & XkbPhysSymbolsNameMask) 639818534a1Smrg nAtoms++; 640818534a1Smrg if (which & XkbTypesNameMask) 641818534a1Smrg nAtoms++; 642818534a1Smrg if (which & XkbCompatNameMask) 643818534a1Smrg nAtoms++; 644818534a1Smrg if (which & XkbKeyTypeNamesMask) 645818534a1Smrg nAtoms += nTypes; 646818534a1Smrg if (which & XkbKTLevelNamesMask) { 647818534a1Smrg req->firstKTLevel = firstLvlType; 648818534a1Smrg req->nKTLevels = nLvlTypes; 649818534a1Smrg req->length += XkbPaddedSize(nLvlTypes) / 4; /* room for group widths */ 650818534a1Smrg nAtoms += nLvlNames; 651818534a1Smrg } 652818534a1Smrg else 653818534a1Smrg req->firstKTLevel = req->nKTLevels = 0; 654818534a1Smrg 655818534a1Smrg if (which & XkbIndicatorNamesMask) { 656818534a1Smrg leds = req->indicators = (CARD32) changes->changed_indicators; 657818534a1Smrg nLEDs = _XkbCountBits(XkbNumIndicators, changes->changed_indicators); 658818534a1Smrg if (nLEDs > 0) 659818534a1Smrg nAtoms += nLEDs; 660818534a1Smrg else 661818534a1Smrg which &= ~XkbIndicatorNamesMask; 662818534a1Smrg } 663818534a1Smrg else 664818534a1Smrg req->indicators = 0; 665818534a1Smrg 666818534a1Smrg if (which & XkbVirtualModNamesMask) { 667818534a1Smrg vmods = req->virtualMods = changes->changed_vmods; 668818534a1Smrg nVMods = _XkbCountBits(XkbNumVirtualMods, 669818534a1Smrg (unsigned long) changes->changed_vmods); 670818534a1Smrg if (nVMods > 0) 671818534a1Smrg nAtoms += nVMods; 672818534a1Smrg else 673818534a1Smrg which &= ~XkbVirtualModNamesMask; 674818534a1Smrg } 675818534a1Smrg else 676818534a1Smrg req->virtualMods = 0; 677818534a1Smrg 678818534a1Smrg if (which & XkbGroupNamesMask) { 679818534a1Smrg groups = req->groupNames = changes->changed_groups; 680818534a1Smrg nGroups = _XkbCountBits(XkbNumKbdGroups, 681818534a1Smrg (unsigned long) changes->changed_groups); 682818534a1Smrg if (nGroups > 0) 683818534a1Smrg nAtoms += nGroups; 684818534a1Smrg else 685818534a1Smrg which &= ~XkbGroupNamesMask; 686818534a1Smrg } 687818534a1Smrg else 688818534a1Smrg req->groupNames = 0; 689818534a1Smrg 690818534a1Smrg if ((which & XkbKeyNamesMask) && (names->keys != NULL)) { 691818534a1Smrg firstKey = req->firstKey; 692818534a1Smrg nKeys = req->nKeys; 693818534a1Smrg nAtoms += nKeys; /* technically not atoms, but 4 bytes wide */ 694818534a1Smrg } 695818534a1Smrg else 696818534a1Smrg which &= ~XkbKeyNamesMask; 697818534a1Smrg 698818534a1Smrg if (which & XkbKeyAliasesMask) { 699818534a1Smrg nKA = ((names->key_aliases != NULL) ? names->num_key_aliases : 0); 700818534a1Smrg if (nKA > 0) 701818534a1Smrg nAtoms += nKA * 2; /* not atoms, but 8 bytes on the wire */ 702818534a1Smrg else 703818534a1Smrg which &= ~XkbKeyAliasesMask; 704818534a1Smrg } 705818534a1Smrg 706818534a1Smrg if (which & XkbRGNamesMask) { 707818534a1Smrg nRG = names->num_rg; 708818534a1Smrg if (nRG > 0) 709818534a1Smrg nAtoms += nRG; 710818534a1Smrg else 711818534a1Smrg which &= ~XkbRGNamesMask; 712818534a1Smrg } 713818534a1Smrg 714818534a1Smrg req->which = which; 715818534a1Smrg req->nRadioGroups = nRG; 716818534a1Smrg req->length += (nAtoms * 4) / 4; 717818534a1Smrg 718818534a1Smrg if (which & XkbKeycodesNameMask) 719818534a1Smrg Data32(dpy, (long *) &names->keycodes, 4); 720818534a1Smrg if (which & XkbGeometryNameMask) 721818534a1Smrg Data32(dpy, (long *) &names->geometry, 4); 722818534a1Smrg if (which & XkbSymbolsNameMask) 723818534a1Smrg Data32(dpy, (long *) &names->symbols, 4); 724818534a1Smrg if (which & XkbPhysSymbolsNameMask) 725818534a1Smrg Data32(dpy, (long *) &names->phys_symbols, 4); 726818534a1Smrg if (which & XkbTypesNameMask) 727818534a1Smrg Data32(dpy, (long *) &names->types, 4); 728818534a1Smrg if (which & XkbCompatNameMask) 729818534a1Smrg Data32(dpy, (long *) &names->compat, 4); 730818534a1Smrg if (which & XkbKeyTypeNamesMask) { 731818534a1Smrg register int i; 732818534a1Smrg register XkbKeyTypePtr type; 733818534a1Smrg 734818534a1Smrg type = &xkb->map->types[firstType]; 735818534a1Smrg for (i = 0; i < nTypes; i++, type++) { 736818534a1Smrg Data32(dpy, (long *) &type->name, 4); 737818534a1Smrg } 738818534a1Smrg } 739818534a1Smrg if (which & XkbKTLevelNamesMask) { 740818534a1Smrg XkbKeyTypePtr type; 741818534a1Smrg int i; 742818534a1Smrg char *tmp; 743818534a1Smrg 744818534a1Smrg BufAlloc(char *, tmp, XkbPaddedSize(nLvlTypes)); 745818534a1Smrg type = &xkb->map->types[firstLvlType]; 746818534a1Smrg for (i = 0; i < nLvlTypes; i++, type++) { 747818534a1Smrg *tmp++ = type->num_levels; 748818534a1Smrg } 749818534a1Smrg type = &xkb->map->types[firstLvlType]; 750818534a1Smrg for (i = 0; i < nLvlTypes; i++, type++) { 751818534a1Smrg if (type->level_names != NULL) 752818534a1Smrg Data32(dpy, (long *) type->level_names, type->num_levels * 4); 753818534a1Smrg } 754818534a1Smrg } 755818534a1Smrg if (which & XkbIndicatorNamesMask) 756818534a1Smrg _XkbCopyAtoms(dpy, names->indicators, leds, XkbNumIndicators); 757818534a1Smrg if (which & XkbVirtualModNamesMask) 758818534a1Smrg _XkbCopyAtoms(dpy, names->vmods, vmods, XkbNumVirtualMods); 759818534a1Smrg if (which & XkbGroupNamesMask) 760818534a1Smrg _XkbCopyAtoms(dpy, names->groups, groups, XkbNumKbdGroups); 761818534a1Smrg if (which & XkbKeyNamesMask) { 762818534a1Smrg Data(dpy, (char *) &names->keys[firstKey], nKeys * XkbKeyNameLength); 763818534a1Smrg } 764818534a1Smrg if (which & XkbKeyAliasesMask) { 765818534a1Smrg Data(dpy, (char *) names->key_aliases, nKA * XkbKeyNameLength * 2); 766818534a1Smrg } 767818534a1Smrg if (which & XkbRGNamesMask) { 768818534a1Smrg Data32(dpy, (long *) names->radio_groups, nRG * 4); 7691ab64890Smrg } 7701ab64890Smrg UnlockDisplay(dpy); 7711ab64890Smrg SyncHandle(); 7721ab64890Smrg return True; 7731ab64890Smrg} 7741ab64890Smrg 7751ab64890Smrgvoid 776818534a1SmrgXkbNoteNameChanges(XkbNameChangesPtr old, 777818534a1Smrg XkbNamesNotifyEvent *new, 778818534a1Smrg unsigned int wanted) 7791ab64890Smrg{ 780818534a1Smrg int first, last, old_last, new_last; 781818534a1Smrg 7820f8248bfSmrg if ((old == NULL) || (new == NULL)) 783818534a1Smrg return; 7840f8248bfSmrg 7850f8248bfSmrg wanted &= new->changed; 7860f8248bfSmrg 7870f8248bfSmrg if (wanted == 0) 7880f8248bfSmrg return; 7890f8248bfSmrg 790818534a1Smrg if (wanted & XkbKeyTypeNamesMask) { 791818534a1Smrg if (old->changed & XkbKeyTypeNamesMask) { 792818534a1Smrg new_last = (new->first_type + new->num_types - 1); 793818534a1Smrg old_last = (old->first_type + old->num_types - 1); 794818534a1Smrg 795818534a1Smrg if (new->first_type < old->first_type) 796818534a1Smrg first = new->first_type; 797818534a1Smrg else 798818534a1Smrg first = old->first_type; 799818534a1Smrg 800818534a1Smrg if (old_last > new_last) 801818534a1Smrg last = old_last; 802818534a1Smrg else 803818534a1Smrg last = new_last; 804818534a1Smrg 805818534a1Smrg old->first_type = first; 806818534a1Smrg old->num_types = (last - first) + 1; 807818534a1Smrg } 808818534a1Smrg else { 809818534a1Smrg old->first_type = new->first_type; 810818534a1Smrg old->num_types = new->num_types; 811818534a1Smrg } 812818534a1Smrg } 813818534a1Smrg if (wanted & XkbKTLevelNamesMask) { 814818534a1Smrg if (old->changed & XkbKTLevelNamesMask) { 815818534a1Smrg new_last = (new->first_lvl + new->num_lvls - 1); 816818534a1Smrg old_last = (old->first_lvl + old->num_lvls - 1); 817818534a1Smrg 818818534a1Smrg if (new->first_lvl < old->first_lvl) 819818534a1Smrg first = new->first_lvl; 820818534a1Smrg else 821818534a1Smrg first = old->first_lvl; 822818534a1Smrg 823818534a1Smrg if (old_last > new_last) 824818534a1Smrg last = old_last; 825818534a1Smrg else 826818534a1Smrg last = new_last; 827818534a1Smrg 828818534a1Smrg old->first_lvl = first; 829818534a1Smrg old->num_lvls = (last - first) + 1; 830818534a1Smrg } 831818534a1Smrg else { 832818534a1Smrg old->first_lvl = new->first_lvl; 833818534a1Smrg old->num_lvls = new->num_lvls; 834818534a1Smrg } 835818534a1Smrg } 836818534a1Smrg if (wanted & XkbIndicatorNamesMask) { 837818534a1Smrg if (old->changed & XkbIndicatorNamesMask) 838818534a1Smrg old->changed_indicators |= new->changed_indicators; 839818534a1Smrg else 840818534a1Smrg old->changed_indicators = new->changed_indicators; 841818534a1Smrg } 842818534a1Smrg if (wanted & XkbKeyNamesMask) { 843818534a1Smrg if (old->changed & XkbKeyNamesMask) { 844818534a1Smrg new_last = (new->first_key + new->num_keys - 1); 845818534a1Smrg old_last = (old->first_key + old->num_keys - 1); 846818534a1Smrg 847818534a1Smrg first = old->first_key; 848818534a1Smrg 849818534a1Smrg if (new->first_key < old->first_key) 850818534a1Smrg first = new->first_key; 851818534a1Smrg if (old_last > new_last) 852818534a1Smrg new_last = old_last; 853818534a1Smrg 854818534a1Smrg old->first_key = first; 855818534a1Smrg old->num_keys = (new_last - first) + 1; 856818534a1Smrg } 857818534a1Smrg else { 858818534a1Smrg old->first_key = new->first_key; 859818534a1Smrg old->num_keys = new->num_keys; 860818534a1Smrg } 861818534a1Smrg } 862818534a1Smrg if (wanted & XkbVirtualModNamesMask) { 863818534a1Smrg if (old->changed & XkbVirtualModNamesMask) 864818534a1Smrg old->changed_vmods |= new->changed_vmods; 865818534a1Smrg else 866818534a1Smrg old->changed_vmods = new->changed_vmods; 867818534a1Smrg } 868818534a1Smrg if (wanted & XkbGroupNamesMask) { 869818534a1Smrg if (old->changed & XkbGroupNamesMask) 870818534a1Smrg old->changed_groups |= new->changed_groups; 871818534a1Smrg else 872818534a1Smrg old->changed_groups = new->changed_groups; 873818534a1Smrg } 874818534a1Smrg if (wanted & XkbRGNamesMask) 875818534a1Smrg old->num_rg = new->num_radio_groups; 876818534a1Smrg if (wanted & XkbKeyAliasesMask) 877818534a1Smrg old->num_aliases = new->num_aliases; 878818534a1Smrg old->changed |= wanted; 8791ab64890Smrg return; 8801ab64890Smrg} 881