XKBNames.c revision 258a0ebe
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; 192818534a1Smrg } 193818534a1Smrg else 194818534a1Smrg _XkbSkipReadBufferData(&buf, rep->nKeys * XkbKeyNameLength); 195818534a1Smrg } 196818534a1Smrg if (rep->which & XkbKeyAliasesMask && (rep->nKeyAliases > 0)) { 197818534a1Smrg if (XkbAllocNames(xkb, XkbKeyAliasesMask, 0, rep->nKeyAliases) != 198818534a1Smrg Success) 199818534a1Smrg goto BAILOUT; 200818534a1Smrg if (!_XkbCopyFromReadBuffer(&buf, (char *) names->key_aliases, 201818534a1Smrg rep->nKeyAliases * XkbKeyNameLength * 2)) 202818534a1Smrg goto BAILOUT; 203818534a1Smrg } 204818534a1Smrg if (rep->which & XkbRGNamesMask) { 205818534a1Smrg if (rep->nRadioGroups > 0) { 206818534a1Smrg Atom *rgNames; 207818534a1Smrg 208258a0ebeSmrg if ((names->radio_groups == NULL) || 209258a0ebeSmrg (names->num_rg < rep->nRadioGroups)) { 210258a0ebeSmrg _XkbResizeArray(names->radio_groups, names->num_rg, 211258a0ebeSmrg rep->nRadioGroups, Atom); 212818534a1Smrg } 213818534a1Smrg rgNames = names->radio_groups; 214818534a1Smrg if (!rgNames) { 215258a0ebeSmrg names->num_rg = 0; 216818534a1Smrg goto BAILOUT; 217818534a1Smrg } 218818534a1Smrg if (!_XkbReadBufferCopy32 219818534a1Smrg (&buf, (long *) rgNames, rep->nRadioGroups)) 220818534a1Smrg goto BAILOUT; 221818534a1Smrg names->num_rg = rep->nRadioGroups; 222818534a1Smrg } 223818534a1Smrg else if (names->num_rg > 0) { 224818534a1Smrg names->num_rg = 0; 225818534a1Smrg Xfree(names->radio_groups); 226818534a1Smrg } 227818534a1Smrg } 228818534a1Smrg len = _XkbFreeReadBuffer(&buf); 229818534a1Smrg if (len != 0) 230818534a1Smrg return BadLength; 231818534a1Smrg else 232818534a1Smrg return Success; 233818534a1Smrg BAILOUT: 2341ab64890Smrg _XkbFreeReadBuffer(&buf); 2351ab64890Smrg return BadLength; 2361ab64890Smrg} 2371ab64890Smrg 2381ab64890SmrgStatus 239818534a1SmrgXkbGetNames(Display *dpy, unsigned which, XkbDescPtr xkb) 2401ab64890Smrg{ 2411ab64890Smrg register xkbGetNamesReq *req; 242818534a1Smrg xkbGetNamesReply rep; 243818534a1Smrg Status status; 2441ab64890Smrg XkbInfoPtr xkbi; 2451ab64890Smrg 2461ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 247818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 248818534a1Smrg return BadAccess; 2491ab64890Smrg LockDisplay(dpy); 2501ab64890Smrg xkbi = dpy->xkb_info; 2511ab64890Smrg if (!xkb->names) { 252818534a1Smrg xkb->names = _XkbTypedCalloc(1, XkbNamesRec); 253818534a1Smrg if (!xkb->names) { 254818534a1Smrg UnlockDisplay(dpy); 255818534a1Smrg SyncHandle(); 256818534a1Smrg return BadAlloc; 257818534a1Smrg } 2581ab64890Smrg } 2591ab64890Smrg GetReq(kbGetNames, req); 2601ab64890Smrg req->reqType = xkbi->codes->major_opcode; 2611ab64890Smrg req->xkbReqType = X_kbGetNames; 2621ab64890Smrg req->deviceSpec = xkb->device_spec; 2631ab64890Smrg req->which = which; 264818534a1Smrg if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { 265818534a1Smrg UnlockDisplay(dpy); 266818534a1Smrg SyncHandle(); 267818534a1Smrg return BadImplementation; 2681ab64890Smrg } 2691ab64890Smrg 270818534a1Smrg status = _XkbReadGetNamesReply(dpy, &rep, xkb, NULL); 2711ab64890Smrg UnlockDisplay(dpy); 2721ab64890Smrg SyncHandle(); 2731ab64890Smrg return status; 2741ab64890Smrg} 2751ab64890Smrg 2761ab64890Smrg/***====================================================================***/ 2771ab64890Smrg 2781ab64890Smrgstatic int 279818534a1Smrg_XkbCountBits(int nBitsMax, unsigned long mask) 2801ab64890Smrg{ 281818534a1Smrg register unsigned long y, nBits; 2821ab64890Smrg 283818534a1Smrg y = (mask >> 1) & 033333333333; 284818534a1Smrg y = mask - y - ((y >> 1) & 033333333333); 2851ab64890Smrg nBits = ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077)); 2861ab64890Smrg 2871ab64890Smrg /* nBitsMax really means max+1 */ 2881ab64890Smrg return (nBits < nBitsMax) ? nBits : (nBitsMax - 1); 2891ab64890Smrg} 2901ab64890Smrg 2911ab64890Smrgstatic CARD32 292818534a1Smrg_XkbCountAtoms(Atom *atoms, int maxAtoms, int *count) 2931ab64890Smrg{ 294818534a1Smrg register unsigned int i, bit, nAtoms; 295818534a1Smrg register CARD32 atomsPresent; 2961ab64890Smrg 297818534a1Smrg for (i = nAtoms = atomsPresent = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) { 298818534a1Smrg if (atoms[i] != None) { 299818534a1Smrg atomsPresent |= bit; 3001ab64890Smrg nAtoms++; 3011ab64890Smrg } 3021ab64890Smrg } 3031ab64890Smrg if (count) 304818534a1Smrg *count = nAtoms; 3051ab64890Smrg return atomsPresent; 3061ab64890Smrg} 3071ab64890Smrg 3081ab64890Smrgstatic void 309818534a1Smrg_XkbCopyAtoms(Display *dpy, Atom *atoms, CARD32 mask, int maxAtoms) 3101ab64890Smrg{ 311818534a1Smrg register unsigned int i, bit; 3121ab64890Smrg 313818534a1Smrg for (i = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) { 314818534a1Smrg if (mask & bit) 315818534a1Smrg Data32(dpy, &atoms[i], 4); 3161ab64890Smrg } 3171ab64890Smrg return; 3181ab64890Smrg} 3191ab64890Smrg 3201ab64890SmrgBool 321818534a1SmrgXkbSetNames(Display *dpy, 322818534a1Smrg unsigned int which, 323818534a1Smrg unsigned int firstType, 324818534a1Smrg unsigned int nTypes, 325818534a1Smrg XkbDescPtr xkb) 3261ab64890Smrg{ 3271ab64890Smrg register xkbSetNamesReq *req; 328818534a1Smrg int nLvlNames = 0; 3291ab64890Smrg XkbInfoPtr xkbi; 3301ab64890Smrg XkbNamesPtr names; 331818534a1Smrg unsigned firstLvlType, nLvlTypes; 332818534a1Smrg int nVMods, nLEDs, nRG, nKA, nGroups; 333818534a1Smrg int nKeys = 0, firstKey = 0, nAtoms; 334818534a1Smrg CARD32 leds, vmods, groups; 3351ab64890Smrg 3361ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 337818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 338818534a1Smrg return False; 339818534a1Smrg if ((!xkb) || (!xkb->names)) 340818534a1Smrg return False; 341818534a1Smrg firstLvlType = firstType; 342818534a1Smrg nLvlTypes = nTypes; 343818534a1Smrg if (nTypes < 1) 344818534a1Smrg which &= ~(XkbKTLevelNamesMask | XkbKeyTypeNamesMask); 345818534a1Smrg else if (firstType <= XkbLastRequiredType) { 346818534a1Smrg int adjust; 347818534a1Smrg 348818534a1Smrg adjust = XkbLastRequiredType - firstType + 1; 349818534a1Smrg firstType += adjust; 350818534a1Smrg nTypes -= adjust; 351818534a1Smrg if (nTypes < 1) 352818534a1Smrg which &= ~XkbKeyTypeNamesMask; 353818534a1Smrg } 354818534a1Smrg names = xkb->names; 355818534a1Smrg if (which & (XkbKTLevelNamesMask | XkbKeyTypeNamesMask)) { 356818534a1Smrg register int i; 357818534a1Smrg XkbKeyTypePtr type; 358818534a1Smrg 359818534a1Smrg if ((xkb->map == NULL) || (xkb->map->types == NULL) || (nTypes == 0) || 360818534a1Smrg (firstType + nTypes > xkb->map->num_types) || 361818534a1Smrg (firstLvlType + nLvlTypes > xkb->map->num_types)) 362818534a1Smrg return False; 363818534a1Smrg if (which & XkbKTLevelNamesMask) { 364818534a1Smrg type = &xkb->map->types[firstLvlType]; 365818534a1Smrg for (i = nLvlNames = 0; i < nLvlTypes; i++, type++) { 366818534a1Smrg if (type->level_names != NULL) 367818534a1Smrg nLvlNames += type->num_levels; 368818534a1Smrg } 369818534a1Smrg } 370818534a1Smrg } 371818534a1Smrg 372818534a1Smrg nVMods = nLEDs = nRG = nKA = nAtoms = nGroups = 0; 3731ab64890Smrg LockDisplay(dpy); 3741ab64890Smrg xkbi = dpy->xkb_info; 3751ab64890Smrg GetReq(kbSetNames, req); 3761ab64890Smrg req->reqType = xkbi->codes->major_opcode; 3771ab64890Smrg req->xkbReqType = X_kbSetNames; 3781ab64890Smrg req->deviceSpec = xkb->device_spec; 3791ab64890Smrg req->firstType = firstType; 3801ab64890Smrg req->nTypes = nTypes; 3811ab64890Smrg req->firstKey = xkb->min_key_code; 382818534a1Smrg req->nKeys = xkb->max_key_code - xkb->min_key_code + 1; 383818534a1Smrg 384818534a1Smrg if (which & XkbKeycodesNameMask) 385818534a1Smrg nAtoms++; 386818534a1Smrg if (which & XkbGeometryNameMask) 387818534a1Smrg nAtoms++; 388818534a1Smrg if (which & XkbSymbolsNameMask) 389818534a1Smrg nAtoms++; 390818534a1Smrg if (which & XkbPhysSymbolsNameMask) 391818534a1Smrg nAtoms++; 392818534a1Smrg if (which & XkbTypesNameMask) 393818534a1Smrg nAtoms++; 394818534a1Smrg if (which & XkbCompatNameMask) 395818534a1Smrg nAtoms++; 396818534a1Smrg if (which & XkbKeyTypeNamesMask) 397818534a1Smrg nAtoms += nTypes; 398818534a1Smrg if (which & XkbKTLevelNamesMask) { 399818534a1Smrg req->firstKTLevel = firstLvlType; 400818534a1Smrg req->nKTLevels = nLvlTypes; 401818534a1Smrg req->length += XkbPaddedSize(nLvlTypes) / 4; /* room for group widths */ 402818534a1Smrg nAtoms += nLvlNames; 403818534a1Smrg } 404818534a1Smrg else 405818534a1Smrg req->firstKTLevel = req->nKTLevels = 0; 406818534a1Smrg 407818534a1Smrg if (which & XkbIndicatorNamesMask) { 408818534a1Smrg req->indicators = leds = 409818534a1Smrg _XkbCountAtoms(names->indicators, XkbNumIndicators, &nLEDs); 410818534a1Smrg if (nLEDs > 0) 411818534a1Smrg nAtoms += nLEDs; 412818534a1Smrg else 413818534a1Smrg which &= ~XkbIndicatorNamesMask; 414818534a1Smrg } 415818534a1Smrg else 416818534a1Smrg req->indicators = leds = 0; 417818534a1Smrg 418818534a1Smrg if (which & XkbVirtualModNamesMask) { 419818534a1Smrg vmods = req->virtualMods = (CARD16) 420818534a1Smrg _XkbCountAtoms(names->vmods, XkbNumVirtualMods, &nVMods); 421818534a1Smrg if (nVMods > 0) 422818534a1Smrg nAtoms += nVMods; 423818534a1Smrg else 424818534a1Smrg which &= ~XkbVirtualModNamesMask; 425818534a1Smrg } 426818534a1Smrg else 427818534a1Smrg vmods = req->virtualMods = 0; 428818534a1Smrg 429818534a1Smrg if (which & XkbGroupNamesMask) { 430818534a1Smrg groups = req->groupNames = (CARD8) 431818534a1Smrg _XkbCountAtoms(names->groups, XkbNumKbdGroups, &nGroups); 432818534a1Smrg if (nGroups > 0) 433818534a1Smrg nAtoms += nGroups; 434818534a1Smrg else 435818534a1Smrg which &= ~XkbGroupNamesMask; 436818534a1Smrg } 437818534a1Smrg else 438818534a1Smrg groups = req->groupNames = 0; 439818534a1Smrg 440818534a1Smrg if ((which & XkbKeyNamesMask) && (names->keys != NULL)) { 441818534a1Smrg firstKey = req->firstKey; 442818534a1Smrg nKeys = req->nKeys; 443818534a1Smrg nAtoms += nKeys; /* technically not atoms, but 4 bytes wide */ 444818534a1Smrg } 445818534a1Smrg else 446818534a1Smrg which &= ~XkbKeyNamesMask; 447818534a1Smrg 448818534a1Smrg if (which & XkbKeyAliasesMask) { 449818534a1Smrg nKA = ((names->key_aliases != NULL) ? names->num_key_aliases : 0); 450818534a1Smrg if (nKA > 0) { 451818534a1Smrg req->nKeyAliases = nKA; 452818534a1Smrg nAtoms += nKA * 2; /* not atoms, but 8 bytes on the wire */ 453818534a1Smrg } 454818534a1Smrg else { 455818534a1Smrg which &= ~XkbKeyAliasesMask; 456818534a1Smrg req->nKeyAliases = 0; 457818534a1Smrg } 458818534a1Smrg } 459818534a1Smrg else 460818534a1Smrg req->nKeyAliases = 0; 461818534a1Smrg 462818534a1Smrg if (which & XkbRGNamesMask) { 463818534a1Smrg nRG = names->num_rg; 464818534a1Smrg if (nRG > 0) 465818534a1Smrg nAtoms += nRG; 466818534a1Smrg else 467818534a1Smrg which &= ~XkbRGNamesMask; 468818534a1Smrg } 469818534a1Smrg 470818534a1Smrg req->which = which; 471818534a1Smrg req->nRadioGroups = nRG; 472818534a1Smrg req->length += (nAtoms * 4) / 4; 473818534a1Smrg 474818534a1Smrg if (which & XkbKeycodesNameMask) 475818534a1Smrg Data32(dpy, (long *) &names->keycodes, 4); 476818534a1Smrg if (which & XkbGeometryNameMask) 477818534a1Smrg Data32(dpy, (long *) &names->geometry, 4); 478818534a1Smrg if (which & XkbSymbolsNameMask) 479818534a1Smrg Data32(dpy, (long *) &names->symbols, 4); 480818534a1Smrg if (which & XkbPhysSymbolsNameMask) 481818534a1Smrg Data32(dpy, (long *) &names->phys_symbols, 4); 482818534a1Smrg if (which & XkbTypesNameMask) 483818534a1Smrg Data32(dpy, (long *) &names->types, 4); 484818534a1Smrg if (which & XkbCompatNameMask) 485818534a1Smrg Data32(dpy, (long *) &names->compat, 4); 486818534a1Smrg if (which & XkbKeyTypeNamesMask) { 487818534a1Smrg register int i; 488818534a1Smrg register XkbKeyTypePtr type; 489818534a1Smrg 490818534a1Smrg type = &xkb->map->types[firstType]; 491818534a1Smrg for (i = 0; i < nTypes; i++, type++) { 492818534a1Smrg Data32(dpy, (long *) &type->name, 4); 493818534a1Smrg } 494818534a1Smrg } 495818534a1Smrg if (which & XkbKTLevelNamesMask) { 496818534a1Smrg XkbKeyTypePtr type; 497818534a1Smrg int i; 498818534a1Smrg char *tmp; 499818534a1Smrg 500818534a1Smrg BufAlloc(char *, tmp, XkbPaddedSize(nLvlTypes)); 501818534a1Smrg type = &xkb->map->types[firstLvlType]; 502818534a1Smrg for (i = 0; i < nLvlTypes; i++, type++) { 503818534a1Smrg *tmp++ = type->num_levels; 504818534a1Smrg } 505818534a1Smrg type = &xkb->map->types[firstLvlType]; 506818534a1Smrg for (i = 0; i < nLvlTypes; i++, type++) { 507818534a1Smrg if (type->level_names != NULL) 508818534a1Smrg Data32(dpy, (long *) type->level_names, type->num_levels * 4); 509818534a1Smrg } 510818534a1Smrg } 511818534a1Smrg if (which & XkbIndicatorNamesMask) 512818534a1Smrg _XkbCopyAtoms(dpy, names->indicators, leds, XkbNumIndicators); 513818534a1Smrg if (which & XkbVirtualModNamesMask) 514818534a1Smrg _XkbCopyAtoms(dpy, names->vmods, vmods, XkbNumVirtualMods); 515818534a1Smrg if (which & XkbGroupNamesMask) 516818534a1Smrg _XkbCopyAtoms(dpy, names->groups, groups, XkbNumKbdGroups); 517818534a1Smrg if (which & XkbKeyNamesMask) { 518818534a1Smrg Data(dpy, (char *) &names->keys[firstKey], nKeys * XkbKeyNameLength); 519818534a1Smrg } 520818534a1Smrg if (which & XkbKeyAliasesMask) { 521818534a1Smrg Data(dpy, (char *) names->key_aliases, nKA * XkbKeyNameLength * 2); 522818534a1Smrg } 523818534a1Smrg if (which & XkbRGNamesMask) { 524818534a1Smrg Data32(dpy, (long *) names->radio_groups, nRG * 4); 5251ab64890Smrg } 5261ab64890Smrg UnlockDisplay(dpy); 5271ab64890Smrg SyncHandle(); 5281ab64890Smrg return True; 5291ab64890Smrg} 5301ab64890Smrg 5311ab64890SmrgBool 532818534a1SmrgXkbChangeNames(Display *dpy, XkbDescPtr xkb, XkbNameChangesPtr changes) 5331ab64890Smrg{ 5341ab64890Smrg register xkbSetNamesReq *req; 535818534a1Smrg int nLvlNames = 0; 5361ab64890Smrg XkbInfoPtr xkbi; 5371ab64890Smrg XkbNamesPtr names; 538818534a1Smrg unsigned which, firstType, nTypes; 539818534a1Smrg unsigned firstLvlType, nLvlTypes; 540818534a1Smrg int nVMods, nLEDs, nRG, nKA, nGroups; 541818534a1Smrg int nKeys = 0, firstKey = 0, nAtoms; 542818534a1Smrg CARD32 leds = 0, vmods = 0, groups = 0; 5431ab64890Smrg 5441ab64890Smrg if ((dpy->flags & XlibDisplayNoXkb) || 545818534a1Smrg (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL))) 546818534a1Smrg return False; 547818534a1Smrg if ((!xkb) || (!xkb->names) || (!changes)) 548818534a1Smrg return False; 549818534a1Smrg which = changes->changed; 550818534a1Smrg firstType = changes->first_type; 551818534a1Smrg nTypes = changes->num_types; 5522d67cb4fSmrg firstLvlType = changes->first_lvl; 553818534a1Smrg nLvlTypes = changes->num_lvls; 554818534a1Smrg if (which & XkbKeyTypeNamesMask) { 555818534a1Smrg if (nTypes < 1) 556818534a1Smrg which &= ~XkbKeyTypeNamesMask; 557818534a1Smrg else if (firstType <= XkbLastRequiredType) { 558818534a1Smrg int adjust; 559818534a1Smrg 560818534a1Smrg adjust = XkbLastRequiredType - firstType + 1; 561818534a1Smrg firstType += adjust; 562818534a1Smrg nTypes -= adjust; 563818534a1Smrg if (nTypes < 1) 564818534a1Smrg which &= ~XkbKeyTypeNamesMask; 565818534a1Smrg } 566818534a1Smrg } 567818534a1Smrg else 568818534a1Smrg firstType = nTypes = 0; 569818534a1Smrg 570818534a1Smrg if (which & XkbKTLevelNamesMask) { 571818534a1Smrg if (nLvlTypes < 1) 572818534a1Smrg which &= ~XkbKTLevelNamesMask; 573818534a1Smrg } 574818534a1Smrg else 575818534a1Smrg firstLvlType = nLvlTypes = 0; 576818534a1Smrg 577818534a1Smrg names = xkb->names; 578818534a1Smrg if (which & (XkbKTLevelNamesMask | XkbKeyTypeNamesMask)) { 579818534a1Smrg register int i; 580818534a1Smrg 581818534a1Smrg if ((xkb->map == NULL) || (xkb->map->types == NULL) || (nTypes == 0) || 582818534a1Smrg (firstType + nTypes > xkb->map->num_types) || 583818534a1Smrg (firstLvlType + nLvlTypes > xkb->map->num_types)) 584818534a1Smrg return False; 585818534a1Smrg if (which & XkbKTLevelNamesMask) { 586818534a1Smrg XkbKeyTypePtr type = &xkb->map->types[firstLvlType]; 587818534a1Smrg 588818534a1Smrg for (i = nLvlNames = 0; i < nLvlTypes; i++, type++) { 589818534a1Smrg if (type->level_names != NULL) 590818534a1Smrg nLvlNames += type->num_levels; 591818534a1Smrg } 592818534a1Smrg } 593818534a1Smrg } 594818534a1Smrg 595818534a1Smrg if (changes->num_keys < 1) 596818534a1Smrg which &= ~XkbKeyNamesMask; 597818534a1Smrg if ((which & XkbKeyNamesMask) == 0) 598818534a1Smrg changes->first_key = changes->num_keys = 0; 599818534a1Smrg else if ((changes->first_key < xkb->min_key_code) || 600818534a1Smrg (changes->first_key + changes->num_keys > xkb->max_key_code)) { 601818534a1Smrg return False; 602818534a1Smrg } 603818534a1Smrg 604818534a1Smrg if ((which & XkbVirtualModNamesMask) == 0) 605818534a1Smrg changes->changed_vmods = 0; 606818534a1Smrg else if (changes->changed_vmods == 0) 607818534a1Smrg which &= ~XkbVirtualModNamesMask; 608818534a1Smrg 609818534a1Smrg if ((which & XkbIndicatorNamesMask) == 0) 610818534a1Smrg changes->changed_indicators = 0; 611818534a1Smrg else if (changes->changed_indicators == 0) 612818534a1Smrg which &= ~XkbIndicatorNamesMask; 613818534a1Smrg 614818534a1Smrg if ((which & XkbGroupNamesMask) == 0) 615818534a1Smrg changes->changed_groups = 0; 616818534a1Smrg else if (changes->changed_groups == 0) 617818534a1Smrg which &= ~XkbGroupNamesMask; 618818534a1Smrg 619818534a1Smrg nVMods = nLEDs = nRG = nKA = nAtoms = nGroups = 0; 6201ab64890Smrg LockDisplay(dpy); 6211ab64890Smrg xkbi = dpy->xkb_info; 6221ab64890Smrg GetReq(kbSetNames, req); 6231ab64890Smrg req->reqType = xkbi->codes->major_opcode; 6241ab64890Smrg req->xkbReqType = X_kbSetNames; 6251ab64890Smrg req->deviceSpec = xkb->device_spec; 6261ab64890Smrg req->firstType = firstType; 6271ab64890Smrg req->nTypes = nTypes; 6281ab64890Smrg req->firstKey = changes->first_key; 6291ab64890Smrg req->nKeys = changes->num_keys; 6301ab64890Smrg 631818534a1Smrg if (which & XkbKeycodesNameMask) 632818534a1Smrg nAtoms++; 633818534a1Smrg if (which & XkbGeometryNameMask) 634818534a1Smrg nAtoms++; 635818534a1Smrg if (which & XkbSymbolsNameMask) 636818534a1Smrg nAtoms++; 637818534a1Smrg if (which & XkbPhysSymbolsNameMask) 638818534a1Smrg nAtoms++; 639818534a1Smrg if (which & XkbTypesNameMask) 640818534a1Smrg nAtoms++; 641818534a1Smrg if (which & XkbCompatNameMask) 642818534a1Smrg nAtoms++; 643818534a1Smrg if (which & XkbKeyTypeNamesMask) 644818534a1Smrg nAtoms += nTypes; 645818534a1Smrg if (which & XkbKTLevelNamesMask) { 646818534a1Smrg req->firstKTLevel = firstLvlType; 647818534a1Smrg req->nKTLevels = nLvlTypes; 648818534a1Smrg req->length += XkbPaddedSize(nLvlTypes) / 4; /* room for group widths */ 649818534a1Smrg nAtoms += nLvlNames; 650818534a1Smrg } 651818534a1Smrg else 652818534a1Smrg req->firstKTLevel = req->nKTLevels = 0; 653818534a1Smrg 654818534a1Smrg if (which & XkbIndicatorNamesMask) { 655818534a1Smrg leds = req->indicators = (CARD32) changes->changed_indicators; 656818534a1Smrg nLEDs = _XkbCountBits(XkbNumIndicators, changes->changed_indicators); 657818534a1Smrg if (nLEDs > 0) 658818534a1Smrg nAtoms += nLEDs; 659818534a1Smrg else 660818534a1Smrg which &= ~XkbIndicatorNamesMask; 661818534a1Smrg } 662818534a1Smrg else 663818534a1Smrg req->indicators = 0; 664818534a1Smrg 665818534a1Smrg if (which & XkbVirtualModNamesMask) { 666818534a1Smrg vmods = req->virtualMods = changes->changed_vmods; 667818534a1Smrg nVMods = _XkbCountBits(XkbNumVirtualMods, 668818534a1Smrg (unsigned long) changes->changed_vmods); 669818534a1Smrg if (nVMods > 0) 670818534a1Smrg nAtoms += nVMods; 671818534a1Smrg else 672818534a1Smrg which &= ~XkbVirtualModNamesMask; 673818534a1Smrg } 674818534a1Smrg else 675818534a1Smrg req->virtualMods = 0; 676818534a1Smrg 677818534a1Smrg if (which & XkbGroupNamesMask) { 678818534a1Smrg groups = req->groupNames = changes->changed_groups; 679818534a1Smrg nGroups = _XkbCountBits(XkbNumKbdGroups, 680818534a1Smrg (unsigned long) changes->changed_groups); 681818534a1Smrg if (nGroups > 0) 682818534a1Smrg nAtoms += nGroups; 683818534a1Smrg else 684818534a1Smrg which &= ~XkbGroupNamesMask; 685818534a1Smrg } 686818534a1Smrg else 687818534a1Smrg req->groupNames = 0; 688818534a1Smrg 689818534a1Smrg if ((which & XkbKeyNamesMask) && (names->keys != NULL)) { 690818534a1Smrg firstKey = req->firstKey; 691818534a1Smrg nKeys = req->nKeys; 692818534a1Smrg nAtoms += nKeys; /* technically not atoms, but 4 bytes wide */ 693818534a1Smrg } 694818534a1Smrg else 695818534a1Smrg which &= ~XkbKeyNamesMask; 696818534a1Smrg 697818534a1Smrg if (which & XkbKeyAliasesMask) { 698818534a1Smrg nKA = ((names->key_aliases != NULL) ? names->num_key_aliases : 0); 699818534a1Smrg if (nKA > 0) 700818534a1Smrg nAtoms += nKA * 2; /* not atoms, but 8 bytes on the wire */ 701818534a1Smrg else 702818534a1Smrg which &= ~XkbKeyAliasesMask; 703818534a1Smrg } 704818534a1Smrg 705818534a1Smrg if (which & XkbRGNamesMask) { 706818534a1Smrg nRG = names->num_rg; 707818534a1Smrg if (nRG > 0) 708818534a1Smrg nAtoms += nRG; 709818534a1Smrg else 710818534a1Smrg which &= ~XkbRGNamesMask; 711818534a1Smrg } 712818534a1Smrg 713818534a1Smrg req->which = which; 714818534a1Smrg req->nRadioGroups = nRG; 715818534a1Smrg req->length += (nAtoms * 4) / 4; 716818534a1Smrg 717818534a1Smrg if (which & XkbKeycodesNameMask) 718818534a1Smrg Data32(dpy, (long *) &names->keycodes, 4); 719818534a1Smrg if (which & XkbGeometryNameMask) 720818534a1Smrg Data32(dpy, (long *) &names->geometry, 4); 721818534a1Smrg if (which & XkbSymbolsNameMask) 722818534a1Smrg Data32(dpy, (long *) &names->symbols, 4); 723818534a1Smrg if (which & XkbPhysSymbolsNameMask) 724818534a1Smrg Data32(dpy, (long *) &names->phys_symbols, 4); 725818534a1Smrg if (which & XkbTypesNameMask) 726818534a1Smrg Data32(dpy, (long *) &names->types, 4); 727818534a1Smrg if (which & XkbCompatNameMask) 728818534a1Smrg Data32(dpy, (long *) &names->compat, 4); 729818534a1Smrg if (which & XkbKeyTypeNamesMask) { 730818534a1Smrg register int i; 731818534a1Smrg register XkbKeyTypePtr type; 732818534a1Smrg 733818534a1Smrg type = &xkb->map->types[firstType]; 734818534a1Smrg for (i = 0; i < nTypes; i++, type++) { 735818534a1Smrg Data32(dpy, (long *) &type->name, 4); 736818534a1Smrg } 737818534a1Smrg } 738818534a1Smrg if (which & XkbKTLevelNamesMask) { 739818534a1Smrg XkbKeyTypePtr type; 740818534a1Smrg int i; 741818534a1Smrg char *tmp; 742818534a1Smrg 743818534a1Smrg BufAlloc(char *, tmp, XkbPaddedSize(nLvlTypes)); 744818534a1Smrg type = &xkb->map->types[firstLvlType]; 745818534a1Smrg for (i = 0; i < nLvlTypes; i++, type++) { 746818534a1Smrg *tmp++ = type->num_levels; 747818534a1Smrg } 748818534a1Smrg type = &xkb->map->types[firstLvlType]; 749818534a1Smrg for (i = 0; i < nLvlTypes; i++, type++) { 750818534a1Smrg if (type->level_names != NULL) 751818534a1Smrg Data32(dpy, (long *) type->level_names, type->num_levels * 4); 752818534a1Smrg } 753818534a1Smrg } 754818534a1Smrg if (which & XkbIndicatorNamesMask) 755818534a1Smrg _XkbCopyAtoms(dpy, names->indicators, leds, XkbNumIndicators); 756818534a1Smrg if (which & XkbVirtualModNamesMask) 757818534a1Smrg _XkbCopyAtoms(dpy, names->vmods, vmods, XkbNumVirtualMods); 758818534a1Smrg if (which & XkbGroupNamesMask) 759818534a1Smrg _XkbCopyAtoms(dpy, names->groups, groups, XkbNumKbdGroups); 760818534a1Smrg if (which & XkbKeyNamesMask) { 761818534a1Smrg Data(dpy, (char *) &names->keys[firstKey], nKeys * XkbKeyNameLength); 762818534a1Smrg } 763818534a1Smrg if (which & XkbKeyAliasesMask) { 764818534a1Smrg Data(dpy, (char *) names->key_aliases, nKA * XkbKeyNameLength * 2); 765818534a1Smrg } 766818534a1Smrg if (which & XkbRGNamesMask) { 767818534a1Smrg Data32(dpy, (long *) names->radio_groups, nRG * 4); 7681ab64890Smrg } 7691ab64890Smrg UnlockDisplay(dpy); 7701ab64890Smrg SyncHandle(); 7711ab64890Smrg return True; 7721ab64890Smrg} 7731ab64890Smrg 7741ab64890Smrgvoid 775818534a1SmrgXkbNoteNameChanges(XkbNameChangesPtr old, 776818534a1Smrg XkbNamesNotifyEvent *new, 777818534a1Smrg unsigned int wanted) 7781ab64890Smrg{ 779818534a1Smrg int first, last, old_last, new_last; 780818534a1Smrg 7810f8248bfSmrg if ((old == NULL) || (new == NULL)) 782818534a1Smrg return; 7830f8248bfSmrg 7840f8248bfSmrg wanted &= new->changed; 7850f8248bfSmrg 7860f8248bfSmrg if (wanted == 0) 7870f8248bfSmrg return; 7880f8248bfSmrg 789818534a1Smrg if (wanted & XkbKeyTypeNamesMask) { 790818534a1Smrg if (old->changed & XkbKeyTypeNamesMask) { 791818534a1Smrg new_last = (new->first_type + new->num_types - 1); 792818534a1Smrg old_last = (old->first_type + old->num_types - 1); 793818534a1Smrg 794818534a1Smrg if (new->first_type < old->first_type) 795818534a1Smrg first = new->first_type; 796818534a1Smrg else 797818534a1Smrg first = old->first_type; 798818534a1Smrg 799818534a1Smrg if (old_last > new_last) 800818534a1Smrg last = old_last; 801818534a1Smrg else 802818534a1Smrg last = new_last; 803818534a1Smrg 804818534a1Smrg old->first_type = first; 805818534a1Smrg old->num_types = (last - first) + 1; 806818534a1Smrg } 807818534a1Smrg else { 808818534a1Smrg old->first_type = new->first_type; 809818534a1Smrg old->num_types = new->num_types; 810818534a1Smrg } 811818534a1Smrg } 812818534a1Smrg if (wanted & XkbKTLevelNamesMask) { 813818534a1Smrg if (old->changed & XkbKTLevelNamesMask) { 814818534a1Smrg new_last = (new->first_lvl + new->num_lvls - 1); 815818534a1Smrg old_last = (old->first_lvl + old->num_lvls - 1); 816818534a1Smrg 817818534a1Smrg if (new->first_lvl < old->first_lvl) 818818534a1Smrg first = new->first_lvl; 819818534a1Smrg else 820818534a1Smrg first = old->first_lvl; 821818534a1Smrg 822818534a1Smrg if (old_last > new_last) 823818534a1Smrg last = old_last; 824818534a1Smrg else 825818534a1Smrg last = new_last; 826818534a1Smrg 827818534a1Smrg old->first_lvl = first; 828818534a1Smrg old->num_lvls = (last - first) + 1; 829818534a1Smrg } 830818534a1Smrg else { 831818534a1Smrg old->first_lvl = new->first_lvl; 832818534a1Smrg old->num_lvls = new->num_lvls; 833818534a1Smrg } 834818534a1Smrg } 835818534a1Smrg if (wanted & XkbIndicatorNamesMask) { 836818534a1Smrg if (old->changed & XkbIndicatorNamesMask) 837818534a1Smrg old->changed_indicators |= new->changed_indicators; 838818534a1Smrg else 839818534a1Smrg old->changed_indicators = new->changed_indicators; 840818534a1Smrg } 841818534a1Smrg if (wanted & XkbKeyNamesMask) { 842818534a1Smrg if (old->changed & XkbKeyNamesMask) { 843818534a1Smrg new_last = (new->first_key + new->num_keys - 1); 844818534a1Smrg old_last = (old->first_key + old->num_keys - 1); 845818534a1Smrg 846818534a1Smrg first = old->first_key; 847818534a1Smrg 848818534a1Smrg if (new->first_key < old->first_key) 849818534a1Smrg first = new->first_key; 850818534a1Smrg if (old_last > new_last) 851818534a1Smrg new_last = old_last; 852818534a1Smrg 853818534a1Smrg old->first_key = first; 854818534a1Smrg old->num_keys = (new_last - first) + 1; 855818534a1Smrg } 856818534a1Smrg else { 857818534a1Smrg old->first_key = new->first_key; 858818534a1Smrg old->num_keys = new->num_keys; 859818534a1Smrg } 860818534a1Smrg } 861818534a1Smrg if (wanted & XkbVirtualModNamesMask) { 862818534a1Smrg if (old->changed & XkbVirtualModNamesMask) 863818534a1Smrg old->changed_vmods |= new->changed_vmods; 864818534a1Smrg else 865818534a1Smrg old->changed_vmods = new->changed_vmods; 866818534a1Smrg } 867818534a1Smrg if (wanted & XkbGroupNamesMask) { 868818534a1Smrg if (old->changed & XkbGroupNamesMask) 869818534a1Smrg old->changed_groups |= new->changed_groups; 870818534a1Smrg else 871818534a1Smrg old->changed_groups = new->changed_groups; 872818534a1Smrg } 873818534a1Smrg if (wanted & XkbRGNamesMask) 874818534a1Smrg old->num_rg = new->num_radio_groups; 875818534a1Smrg if (wanted & XkbKeyAliasesMask) 876818534a1Smrg old->num_aliases = new->num_aliases; 877818534a1Smrg old->changed |= wanted; 8781ab64890Smrg return; 8791ab64890Smrg} 880