Home | History | Annotate | Line # | Download | only in xkb
      1 /************************************************************
      2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
      3 
      4 Permission to use, copy, modify, and distribute this
      5 software and its documentation for any purpose and without
      6 fee is hereby granted, provided that the above copyright
      7 notice appear in all copies and that both that copyright
      8 notice and this permission notice appear in supporting
      9 documentation, and that the name of Silicon Graphics not be
     10 used in advertising or publicity pertaining to distribution
     11 of the software without specific prior written permission.
     12 Silicon Graphics makes no representation about the suitability
     13 of this software for any purpose. It is provided "as is"
     14 without any express or implied warranty.
     15 
     16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
     17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
     18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
     19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
     20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
     22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
     23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
     24 
     25 ********************************************************/
     26 
     27 #define NEED_MAP_READERS
     28 #ifdef HAVE_CONFIG_H
     29 #include <config.h>
     30 #endif
     31 #include "Xlibint.h"
     32 #include <X11/extensions/XKBproto.h>
     33 #include "XKBlibint.h"
     34 
     35 
     36 static Status
     37 _XkbReadAtoms(XkbReadBufferPtr buf,
     38               Atom *atoms,
     39               int maxAtoms,
     40               CARD32 present)
     41 {
     42     register int i, bit;
     43 
     44     for (i = 0, bit = 1; (i < maxAtoms) && (present); i++, bit <<= 1) {
     45         if (present & bit) {
     46             if (!_XkbReadBufferCopy32(buf, (long *) &atoms[i], 1))
     47                 return BadLength;
     48             present &= ~bit;
     49         }
     50     }
     51     return Success;
     52 }
     53 
     54 Status
     55 _XkbReadGetNamesReply(Display *dpy,
     56                       xkbGetNamesReply *rep,
     57                       XkbDescPtr xkb,
     58                       int *nread_rtrn)
     59 {
     60     int i, len;
     61     XkbReadBufferRec buf;
     62     register XkbNamesPtr names;
     63 
     64     if (xkb->device_spec == XkbUseCoreKbd)
     65         xkb->device_spec = rep->deviceID;
     66 
     67     if ((xkb->names == NULL) &&
     68         (XkbAllocNames(xkb, rep->which,
     69                        rep->nRadioGroups, rep->nKeyAliases) != Success)) {
     70         return BadAlloc;
     71     }
     72     names = xkb->names;
     73     if (rep->length == 0)
     74         return Success;
     75 
     76     if (!_XkbInitReadBuffer(dpy, &buf, (int) rep->length * 4))
     77         return BadAlloc;
     78     if (nread_rtrn)
     79         *nread_rtrn = (int) rep->length * 4;
     80 
     81     if ((rep->which & XkbKeycodesNameMask) &&
     82         (!_XkbReadBufferCopy32(&buf, (long *) &names->keycodes, 1)))
     83         goto BAILOUT;
     84     if ((rep->which & XkbGeometryNameMask) &&
     85         (!_XkbReadBufferCopy32(&buf, (long *) &names->geometry, 1)))
     86         goto BAILOUT;
     87     if ((rep->which & XkbSymbolsNameMask) &&
     88         (!_XkbReadBufferCopy32(&buf, (long *) &names->symbols, 1)))
     89         goto BAILOUT;
     90     if ((rep->which & XkbPhysSymbolsNameMask) &&
     91         (!_XkbReadBufferCopy32(&buf, (long *) &names->phys_symbols, 1)))
     92         goto BAILOUT;
     93     if ((rep->which & XkbTypesNameMask) &&
     94         (!_XkbReadBufferCopy32(&buf, (long *) &names->types, 1)))
     95         goto BAILOUT;
     96     if ((rep->which & XkbCompatNameMask) &&
     97         (!_XkbReadBufferCopy32(&buf, (long *) &names->compat, 1)))
     98         goto BAILOUT;
     99 
    100     if (rep->which & XkbKeyTypeNamesMask) {
    101         XkbClientMapPtr map = xkb->map;
    102         XkbKeyTypePtr type;
    103 
    104         len = rep->nTypes * 4;
    105         if (map != NULL) {
    106             type = map->types;
    107             for (i = 0; (i < map->num_types) && (i < rep->nTypes); i++, type++) {
    108                 if (!_XkbReadBufferCopy32(&buf, (long *) &type->name, 1))
    109                     goto BAILOUT;
    110                 len -= 4;
    111             }
    112         }
    113         if ((len > 0) && (!_XkbSkipReadBufferData(&buf, len)))
    114             goto BAILOUT;
    115     }
    116     if (rep->which & XkbKTLevelNamesMask) {
    117         CARD8 *nLevels;
    118         XkbClientMapPtr map = xkb->map;
    119 
    120         nLevels =
    121             (CARD8 *) _XkbGetReadBufferPtr(&buf, XkbPaddedSize(rep->nTypes));
    122         if (nLevels == NULL)
    123             goto BAILOUT;
    124         if (map != NULL) {
    125             XkbKeyTypePtr type = map->types;
    126 
    127             for (i = 0; i < (int) rep->nTypes; i++, type++) {
    128                 if (i >= map->num_types) {
    129                     if (!_XkbSkipReadBufferData(&buf, nLevels[i] * 4))
    130                         goto BAILOUT;
    131                     continue;
    132                 }
    133                 if ((nLevels[i] > 0) && (nLevels[i] != type->num_levels)) {
    134                     goto BAILOUT;
    135                 }
    136 
    137                 Xfree(type->level_names);
    138                 if (nLevels[i] == 0) {
    139                     type->level_names = NULL;
    140                     continue;
    141                 }
    142                 type->level_names = _XkbTypedCalloc(nLevels[i], Atom);
    143                 if (type->level_names != NULL) {
    144                     if (!_XkbReadBufferCopy32(&buf, (long *) type->level_names,
    145                                               nLevels[i]))
    146                         goto BAILOUT;
    147                 }
    148                 else {
    149                     _XkbSkipReadBufferData(&buf, nLevels[i] * 4);
    150                 }
    151             }
    152         }
    153         else {
    154             for (i = 0; i < (int) rep->nTypes; i++) {
    155                 _XkbSkipReadBufferData(&buf, nLevels[i] * 4);
    156             }
    157         }
    158     }
    159     if (rep->which & XkbIndicatorNamesMask) {
    160         if (_XkbReadAtoms(&buf, names->indicators, XkbNumIndicators,
    161                           rep->indicators) != Success)
    162             goto BAILOUT;
    163     }
    164     if (rep->which & XkbVirtualModNamesMask) {
    165         if (_XkbReadAtoms(&buf, names->vmods, XkbNumVirtualMods,
    166                           (CARD32) rep->virtualMods) != Success)
    167             goto BAILOUT;
    168     }
    169     if (rep->which & XkbGroupNamesMask) {
    170         if (_XkbReadAtoms(&buf, names->groups, XkbNumKbdGroups,
    171                           (CARD32) rep->groupNames) != Success)
    172             goto BAILOUT;
    173     }
    174     if (rep->which & XkbKeyNamesMask) {
    175         if (names->keys == NULL) {
    176             int nKeys;
    177 
    178             if (xkb->max_key_code == 0) {
    179                 xkb->min_key_code = rep->minKeyCode;
    180                 xkb->max_key_code = rep->maxKeyCode;
    181             }
    182             nKeys = xkb->max_key_code + 1;
    183             names->keys = _XkbTypedCalloc(nKeys, XkbKeyNameRec);
    184         }
    185         if (((int) rep->firstKey + rep->nKeys) > xkb->max_key_code + 1)
    186             goto BAILOUT;
    187         if (names->keys != NULL) {
    188             if (!_XkbCopyFromReadBuffer(&buf,
    189                                         (char *) &names->keys[rep->firstKey],
    190                                         rep->nKeys * XkbKeyNameLength))
    191                 goto BAILOUT;
    192             names->num_keys = rep->nKeys;
    193         }
    194         else
    195             _XkbSkipReadBufferData(&buf, rep->nKeys * XkbKeyNameLength);
    196     }
    197     if (rep->which & XkbKeyAliasesMask && (rep->nKeyAliases > 0)) {
    198         if (XkbAllocNames(xkb, XkbKeyAliasesMask, 0, rep->nKeyAliases) !=
    199             Success)
    200             goto BAILOUT;
    201         if (!_XkbCopyFromReadBuffer(&buf, (char *) names->key_aliases,
    202                                     rep->nKeyAliases * XkbKeyNameLength * 2))
    203             goto BAILOUT;
    204     }
    205     if (rep->which & XkbRGNamesMask) {
    206         if (rep->nRadioGroups > 0) {
    207             Atom *rgNames;
    208 
    209             if ((names->radio_groups == NULL) ||
    210                 (names->num_rg < rep->nRadioGroups)) {
    211                 _XkbResizeArray(names->radio_groups, names->num_rg,
    212                                 rep->nRadioGroups, Atom);
    213             }
    214             rgNames = names->radio_groups;
    215             if (!rgNames) {
    216                 names->num_rg = 0;
    217                 goto BAILOUT;
    218             }
    219             if (!_XkbReadBufferCopy32
    220                 (&buf, (long *) rgNames, rep->nRadioGroups))
    221                 goto BAILOUT;
    222             names->num_rg = rep->nRadioGroups;
    223         }
    224         else if (names->num_rg > 0) {
    225             names->num_rg = 0;
    226             Xfree(names->radio_groups);
    227         }
    228     }
    229     len = _XkbFreeReadBuffer(&buf);
    230     if (len != 0)
    231         return BadLength;
    232     else
    233         return Success;
    234  BAILOUT:
    235     _XkbFreeReadBuffer(&buf);
    236     return BadLength;
    237 }
    238 
    239 Status
    240 XkbGetNames(Display *dpy, unsigned which, XkbDescPtr xkb)
    241 {
    242     register xkbGetNamesReq *req;
    243     xkbGetNamesReply rep;
    244     Status status;
    245     XkbInfoPtr xkbi;
    246 
    247     if ((dpy->flags & XlibDisplayNoXkb) ||
    248         (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
    249         return BadAccess;
    250     LockDisplay(dpy);
    251     xkbi = dpy->xkb_info;
    252     if (!xkb->names) {
    253         xkb->names = _XkbTypedCalloc(1, XkbNamesRec);
    254         if (!xkb->names) {
    255             UnlockDisplay(dpy);
    256             SyncHandle();
    257             return BadAlloc;
    258         }
    259     }
    260     GetReq(kbGetNames, req);
    261     req->reqType = xkbi->codes->major_opcode;
    262     req->xkbReqType = X_kbGetNames;
    263     req->deviceSpec = xkb->device_spec;
    264     req->which = which;
    265     if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
    266         UnlockDisplay(dpy);
    267         SyncHandle();
    268         return BadImplementation;
    269     }
    270 
    271     status = _XkbReadGetNamesReply(dpy, &rep, xkb, NULL);
    272     UnlockDisplay(dpy);
    273     SyncHandle();
    274     return status;
    275 }
    276 
    277 /***====================================================================***/
    278 
    279 static int
    280 _XkbCountBits(int nBitsMax, unsigned long mask)
    281 {
    282     register unsigned long y, nBits;
    283 
    284     y = (mask >> 1) & 033333333333;
    285     y = mask - y - ((y >> 1) & 033333333333);
    286     nBits = ((unsigned int) (((y + (y >> 3)) & 030707070707) % 077));
    287 
    288     /* nBitsMax really means max+1 */
    289     return (nBits < nBitsMax) ? nBits : (nBitsMax - 1);
    290 }
    291 
    292 static CARD32
    293 _XkbCountAtoms(Atom *atoms, int maxAtoms, int *count)
    294 {
    295     register unsigned int i, bit, nAtoms;
    296     register CARD32 atomsPresent;
    297 
    298     for (i = nAtoms = atomsPresent = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) {
    299         if (atoms[i] != None) {
    300             atomsPresent |= bit;
    301             nAtoms++;
    302         }
    303     }
    304     if (count)
    305         *count = nAtoms;
    306     return atomsPresent;
    307 }
    308 
    309 static void
    310 _XkbCopyAtoms(Display *dpy, Atom *atoms, CARD32 mask, int maxAtoms)
    311 {
    312     register unsigned int i, bit;
    313 
    314     for (i = 0, bit = 1; i < maxAtoms; i++, bit <<= 1) {
    315         if (mask & bit)
    316             Data32(dpy, &atoms[i], 4);
    317     }
    318     return;
    319 }
    320 
    321 Bool
    322 XkbSetNames(Display *dpy,
    323             unsigned int which,
    324             unsigned int firstType,
    325             unsigned int nTypes,
    326             XkbDescPtr xkb)
    327 {
    328     register xkbSetNamesReq *req;
    329     int nLvlNames = 0;
    330     XkbInfoPtr xkbi;
    331     XkbNamesPtr names;
    332     unsigned firstLvlType, nLvlTypes;
    333     int nVMods, nLEDs, nRG, nKA, nGroups;
    334     int nKeys = 0, firstKey = 0, nAtoms;
    335     CARD32 leds, vmods, groups;
    336 
    337     if ((dpy->flags & XlibDisplayNoXkb) ||
    338         (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
    339         return False;
    340     if ((!xkb) || (!xkb->names))
    341         return False;
    342     firstLvlType = firstType;
    343     nLvlTypes = nTypes;
    344     if (nTypes < 1)
    345         which &= ~(XkbKTLevelNamesMask | XkbKeyTypeNamesMask);
    346     else if (firstType <= XkbLastRequiredType) {
    347         int adjust;
    348 
    349         adjust = XkbLastRequiredType - firstType + 1;
    350         firstType += adjust;
    351         nTypes -= adjust;
    352         if (nTypes < 1)
    353             which &= ~XkbKeyTypeNamesMask;
    354     }
    355     names = xkb->names;
    356     if (which & (XkbKTLevelNamesMask | XkbKeyTypeNamesMask)) {
    357         register int i;
    358         XkbKeyTypePtr type;
    359 
    360         if ((xkb->map == NULL) || (xkb->map->types == NULL) || (nTypes == 0) ||
    361             (firstType + nTypes > xkb->map->num_types) ||
    362             (firstLvlType + nLvlTypes > xkb->map->num_types))
    363             return False;
    364         if (which & XkbKTLevelNamesMask) {
    365             type = &xkb->map->types[firstLvlType];
    366             for (i = nLvlNames = 0; i < nLvlTypes; i++, type++) {
    367                 if (type->level_names != NULL)
    368                     nLvlNames += type->num_levels;
    369             }
    370         }
    371     }
    372 
    373     nVMods = nLEDs = nRG = nKA = nAtoms = nGroups = 0;
    374     LockDisplay(dpy);
    375     xkbi = dpy->xkb_info;
    376     GetReq(kbSetNames, req);
    377     req->reqType = xkbi->codes->major_opcode;
    378     req->xkbReqType = X_kbSetNames;
    379     req->deviceSpec = xkb->device_spec;
    380     req->firstType = firstType;
    381     req->nTypes = nTypes;
    382     req->firstKey = xkb->min_key_code;
    383     req->nKeys = xkb->max_key_code - xkb->min_key_code + 1;
    384 
    385     if (which & XkbKeycodesNameMask)
    386         nAtoms++;
    387     if (which & XkbGeometryNameMask)
    388         nAtoms++;
    389     if (which & XkbSymbolsNameMask)
    390         nAtoms++;
    391     if (which & XkbPhysSymbolsNameMask)
    392         nAtoms++;
    393     if (which & XkbTypesNameMask)
    394         nAtoms++;
    395     if (which & XkbCompatNameMask)
    396         nAtoms++;
    397     if (which & XkbKeyTypeNamesMask)
    398         nAtoms += nTypes;
    399     if (which & XkbKTLevelNamesMask) {
    400         req->firstKTLevel = firstLvlType;
    401         req->nKTLevels = nLvlTypes;
    402         req->length += XkbPaddedSize(nLvlTypes) / 4;    /* room for group widths */
    403         nAtoms += nLvlNames;
    404     }
    405     else
    406         req->firstKTLevel = req->nKTLevels = 0;
    407 
    408     if (which & XkbIndicatorNamesMask) {
    409         req->indicators = leds =
    410             _XkbCountAtoms(names->indicators, XkbNumIndicators, &nLEDs);
    411         if (nLEDs > 0)
    412             nAtoms += nLEDs;
    413         else
    414             which &= ~XkbIndicatorNamesMask;
    415     }
    416     else
    417         req->indicators = leds = 0;
    418 
    419     if (which & XkbVirtualModNamesMask) {
    420         vmods = req->virtualMods = (CARD16)
    421             _XkbCountAtoms(names->vmods, XkbNumVirtualMods, &nVMods);
    422         if (nVMods > 0)
    423             nAtoms += nVMods;
    424         else
    425             which &= ~XkbVirtualModNamesMask;
    426     }
    427     else
    428         vmods = req->virtualMods = 0;
    429 
    430     if (which & XkbGroupNamesMask) {
    431         groups = req->groupNames = (CARD8)
    432             _XkbCountAtoms(names->groups, XkbNumKbdGroups, &nGroups);
    433         if (nGroups > 0)
    434             nAtoms += nGroups;
    435         else
    436             which &= ~XkbGroupNamesMask;
    437     }
    438     else
    439         groups = req->groupNames = 0;
    440 
    441     if ((which & XkbKeyNamesMask) && (names->keys != NULL)) {
    442         firstKey = req->firstKey;
    443         nKeys = req->nKeys;
    444         nAtoms += nKeys;        /* technically not atoms, but 4 bytes wide */
    445     }
    446     else
    447         which &= ~XkbKeyNamesMask;
    448 
    449     if (which & XkbKeyAliasesMask) {
    450         nKA = ((names->key_aliases != NULL) ? names->num_key_aliases : 0);
    451         if (nKA > 0) {
    452             req->nKeyAliases = nKA;
    453             nAtoms += nKA * 2;  /* not atoms, but 8 bytes on the wire */
    454         }
    455         else {
    456             which &= ~XkbKeyAliasesMask;
    457             req->nKeyAliases = 0;
    458         }
    459     }
    460     else
    461         req->nKeyAliases = 0;
    462 
    463     if (which & XkbRGNamesMask) {
    464         nRG = names->num_rg;
    465         if (nRG > 0)
    466             nAtoms += nRG;
    467         else
    468             which &= ~XkbRGNamesMask;
    469     }
    470 
    471     req->which = which;
    472     req->nRadioGroups = nRG;
    473     req->length += (nAtoms * 4) / 4;
    474 
    475     if (which & XkbKeycodesNameMask)
    476         Data32(dpy, (long *) &names->keycodes, 4);
    477     if (which & XkbGeometryNameMask)
    478         Data32(dpy, (long *) &names->geometry, 4);
    479     if (which & XkbSymbolsNameMask)
    480         Data32(dpy, (long *) &names->symbols, 4);
    481     if (which & XkbPhysSymbolsNameMask)
    482         Data32(dpy, (long *) &names->phys_symbols, 4);
    483     if (which & XkbTypesNameMask)
    484         Data32(dpy, (long *) &names->types, 4);
    485     if (which & XkbCompatNameMask)
    486         Data32(dpy, (long *) &names->compat, 4);
    487     if (which & XkbKeyTypeNamesMask) {
    488         register int i;
    489         register XkbKeyTypePtr type;
    490 
    491         type = &xkb->map->types[firstType];
    492         for (i = 0; i < nTypes; i++, type++) {
    493             Data32(dpy, (long *) &type->name, 4);
    494         }
    495     }
    496     if (which & XkbKTLevelNamesMask) {
    497         XkbKeyTypePtr type;
    498         int i;
    499         char *tmp;
    500 
    501         BufAlloc(char *, tmp, XkbPaddedSize(nLvlTypes));
    502         type = &xkb->map->types[firstLvlType];
    503         for (i = 0; i < nLvlTypes; i++, type++) {
    504             *tmp++ = (type->level_names == NULL) ? 0 : type->num_levels;
    505         }
    506         type = &xkb->map->types[firstLvlType];
    507         for (i = 0; i < nLvlTypes; i++, type++) {
    508             if (type->level_names != NULL)
    509                 Data32(dpy, (long *) type->level_names, type->num_levels * 4);
    510         }
    511     }
    512     if (which & XkbIndicatorNamesMask)
    513         _XkbCopyAtoms(dpy, names->indicators, leds, XkbNumIndicators);
    514     if (which & XkbVirtualModNamesMask)
    515         _XkbCopyAtoms(dpy, names->vmods, vmods, XkbNumVirtualMods);
    516     if (which & XkbGroupNamesMask)
    517         _XkbCopyAtoms(dpy, names->groups, groups, XkbNumKbdGroups);
    518     if (which & XkbKeyNamesMask) {
    519         Data(dpy, (char *) &names->keys[firstKey], nKeys * XkbKeyNameLength);
    520     }
    521     if (which & XkbKeyAliasesMask) {
    522         Data(dpy, (char *) names->key_aliases, nKA * XkbKeyNameLength * 2);
    523     }
    524     if (which & XkbRGNamesMask) {
    525         Data32(dpy, (long *) names->radio_groups, nRG * 4);
    526     }
    527     UnlockDisplay(dpy);
    528     SyncHandle();
    529     return True;
    530 }
    531 
    532 Bool
    533 XkbChangeNames(Display *dpy, XkbDescPtr xkb, XkbNameChangesPtr changes)
    534 {
    535     register xkbSetNamesReq *req;
    536     int nLvlNames = 0;
    537     XkbInfoPtr xkbi;
    538     XkbNamesPtr names;
    539     unsigned which, firstType, nTypes;
    540     unsigned firstLvlType, nLvlTypes;
    541     int nVMods, nLEDs, nRG, nKA, nGroups;
    542     int nKeys = 0, firstKey = 0, nAtoms;
    543     CARD32 leds = 0, vmods = 0, groups = 0;
    544 
    545     if ((dpy->flags & XlibDisplayNoXkb) ||
    546         (!dpy->xkb_info && !XkbUseExtension(dpy, NULL, NULL)))
    547         return False;
    548     if ((!xkb) || (!xkb->names) || (!changes))
    549         return False;
    550     which = changes->changed;
    551     firstType = changes->first_type;
    552     nTypes = changes->num_types;
    553     firstLvlType = changes->first_lvl;
    554     nLvlTypes = changes->num_lvls;
    555     if (which & XkbKeyTypeNamesMask) {
    556         if (nTypes < 1)
    557             which &= ~XkbKeyTypeNamesMask;
    558         else if (firstType <= XkbLastRequiredType) {
    559             int adjust;
    560 
    561             adjust = XkbLastRequiredType - firstType + 1;
    562             firstType += adjust;
    563             nTypes -= adjust;
    564             if (nTypes < 1)
    565                 which &= ~XkbKeyTypeNamesMask;
    566         }
    567     }
    568     else
    569         firstType = nTypes = 0;
    570 
    571     if (which & XkbKTLevelNamesMask) {
    572         if (nLvlTypes < 1)
    573             which &= ~XkbKTLevelNamesMask;
    574     }
    575     else
    576         firstLvlType = nLvlTypes = 0;
    577 
    578     names = xkb->names;
    579     if (which & (XkbKTLevelNamesMask | XkbKeyTypeNamesMask)) {
    580         register int i;
    581 
    582         if ((xkb->map == NULL) || (xkb->map->types == NULL) || (nTypes == 0) ||
    583             (firstType + nTypes > xkb->map->num_types) ||
    584             (firstLvlType + nLvlTypes > xkb->map->num_types))
    585             return False;
    586         if (which & XkbKTLevelNamesMask) {
    587             XkbKeyTypePtr type = &xkb->map->types[firstLvlType];
    588 
    589             for (i = nLvlNames = 0; i < nLvlTypes; i++, type++) {
    590                 if (type->level_names != NULL)
    591                     nLvlNames += type->num_levels;
    592             }
    593         }
    594     }
    595 
    596     if (changes->num_keys < 1)
    597         which &= ~XkbKeyNamesMask;
    598     if ((which & XkbKeyNamesMask) == 0)
    599         changes->first_key = changes->num_keys = 0;
    600     else if ((changes->first_key < xkb->min_key_code) ||
    601              (changes->first_key + changes->num_keys > xkb->max_key_code)) {
    602         return False;
    603     }
    604 
    605     if ((which & XkbVirtualModNamesMask) == 0)
    606         changes->changed_vmods = 0;
    607     else if (changes->changed_vmods == 0)
    608         which &= ~XkbVirtualModNamesMask;
    609 
    610     if ((which & XkbIndicatorNamesMask) == 0)
    611         changes->changed_indicators = 0;
    612     else if (changes->changed_indicators == 0)
    613         which &= ~XkbIndicatorNamesMask;
    614 
    615     if ((which & XkbGroupNamesMask) == 0)
    616         changes->changed_groups = 0;
    617     else if (changes->changed_groups == 0)
    618         which &= ~XkbGroupNamesMask;
    619 
    620     nVMods = nLEDs = nRG = nKA = nAtoms = nGroups = 0;
    621     LockDisplay(dpy);
    622     xkbi = dpy->xkb_info;
    623     GetReq(kbSetNames, req);
    624     req->reqType = xkbi->codes->major_opcode;
    625     req->xkbReqType = X_kbSetNames;
    626     req->deviceSpec = xkb->device_spec;
    627     req->firstType = firstType;
    628     req->nTypes = nTypes;
    629     req->firstKey = changes->first_key;
    630     req->nKeys = changes->num_keys;
    631 
    632     if (which & XkbKeycodesNameMask)
    633         nAtoms++;
    634     if (which & XkbGeometryNameMask)
    635         nAtoms++;
    636     if (which & XkbSymbolsNameMask)
    637         nAtoms++;
    638     if (which & XkbPhysSymbolsNameMask)
    639         nAtoms++;
    640     if (which & XkbTypesNameMask)
    641         nAtoms++;
    642     if (which & XkbCompatNameMask)
    643         nAtoms++;
    644     if (which & XkbKeyTypeNamesMask)
    645         nAtoms += nTypes;
    646     if (which & XkbKTLevelNamesMask) {
    647         req->firstKTLevel = firstLvlType;
    648         req->nKTLevels = nLvlTypes;
    649         req->length += XkbPaddedSize(nLvlTypes) / 4;    /* room for group widths */
    650         nAtoms += nLvlNames;
    651     }
    652     else
    653         req->firstKTLevel = req->nKTLevels = 0;
    654 
    655     if (which & XkbIndicatorNamesMask) {
    656         leds = req->indicators = (CARD32) changes->changed_indicators;
    657         nLEDs = _XkbCountBits(XkbNumIndicators, changes->changed_indicators);
    658         if (nLEDs > 0)
    659             nAtoms += nLEDs;
    660         else
    661             which &= ~XkbIndicatorNamesMask;
    662     }
    663     else
    664         req->indicators = 0;
    665 
    666     if (which & XkbVirtualModNamesMask) {
    667         vmods = req->virtualMods = changes->changed_vmods;
    668         nVMods = _XkbCountBits(XkbNumVirtualMods,
    669                                (unsigned long) changes->changed_vmods);
    670         if (nVMods > 0)
    671             nAtoms += nVMods;
    672         else
    673             which &= ~XkbVirtualModNamesMask;
    674     }
    675     else
    676         req->virtualMods = 0;
    677 
    678     if (which & XkbGroupNamesMask) {
    679         groups = req->groupNames = changes->changed_groups;
    680         nGroups = _XkbCountBits(XkbNumKbdGroups,
    681                                 (unsigned long) changes->changed_groups);
    682         if (nGroups > 0)
    683             nAtoms += nGroups;
    684         else
    685             which &= ~XkbGroupNamesMask;
    686     }
    687     else
    688         req->groupNames = 0;
    689 
    690     if ((which & XkbKeyNamesMask) && (names->keys != NULL)) {
    691         firstKey = req->firstKey;
    692         nKeys = req->nKeys;
    693         nAtoms += nKeys;        /* technically not atoms, but 4 bytes wide */
    694     }
    695     else
    696         which &= ~XkbKeyNamesMask;
    697 
    698     if (which & XkbKeyAliasesMask) {
    699         nKA = ((names->key_aliases != NULL) ? names->num_key_aliases : 0);
    700         if (nKA > 0)
    701             nAtoms += nKA * 2;  /* not atoms, but 8 bytes on the wire */
    702         else
    703             which &= ~XkbKeyAliasesMask;
    704     }
    705 
    706     if (which & XkbRGNamesMask) {
    707         nRG = names->num_rg;
    708         if (nRG > 0)
    709             nAtoms += nRG;
    710         else
    711             which &= ~XkbRGNamesMask;
    712     }
    713 
    714     req->which = which;
    715     req->nRadioGroups = nRG;
    716     req->length += (nAtoms * 4) / 4;
    717 
    718     if (which & XkbKeycodesNameMask)
    719         Data32(dpy, (long *) &names->keycodes, 4);
    720     if (which & XkbGeometryNameMask)
    721         Data32(dpy, (long *) &names->geometry, 4);
    722     if (which & XkbSymbolsNameMask)
    723         Data32(dpy, (long *) &names->symbols, 4);
    724     if (which & XkbPhysSymbolsNameMask)
    725         Data32(dpy, (long *) &names->phys_symbols, 4);
    726     if (which & XkbTypesNameMask)
    727         Data32(dpy, (long *) &names->types, 4);
    728     if (which & XkbCompatNameMask)
    729         Data32(dpy, (long *) &names->compat, 4);
    730     if (which & XkbKeyTypeNamesMask) {
    731         register int i;
    732         register XkbKeyTypePtr type;
    733 
    734         type = &xkb->map->types[firstType];
    735         for (i = 0; i < nTypes; i++, type++) {
    736             Data32(dpy, (long *) &type->name, 4);
    737         }
    738     }
    739     if (which & XkbKTLevelNamesMask) {
    740         XkbKeyTypePtr type;
    741         int i;
    742         char *tmp;
    743 
    744         BufAlloc(char *, tmp, XkbPaddedSize(nLvlTypes));
    745         type = &xkb->map->types[firstLvlType];
    746         for (i = 0; i < nLvlTypes; i++, type++) {
    747             *tmp++ = type->num_levels;
    748         }
    749         type = &xkb->map->types[firstLvlType];
    750         for (i = 0; i < nLvlTypes; i++, type++) {
    751             if (type->level_names != NULL)
    752                 Data32(dpy, (long *) type->level_names, type->num_levels * 4);
    753         }
    754     }
    755     if (which & XkbIndicatorNamesMask)
    756         _XkbCopyAtoms(dpy, names->indicators, leds, XkbNumIndicators);
    757     if (which & XkbVirtualModNamesMask)
    758         _XkbCopyAtoms(dpy, names->vmods, vmods, XkbNumVirtualMods);
    759     if (which & XkbGroupNamesMask)
    760         _XkbCopyAtoms(dpy, names->groups, groups, XkbNumKbdGroups);
    761     if (which & XkbKeyNamesMask) {
    762         Data(dpy, (char *) &names->keys[firstKey], nKeys * XkbKeyNameLength);
    763     }
    764     if (which & XkbKeyAliasesMask) {
    765         Data(dpy, (char *) names->key_aliases, nKA * XkbKeyNameLength * 2);
    766     }
    767     if (which & XkbRGNamesMask) {
    768         Data32(dpy, (long *) names->radio_groups, nRG * 4);
    769     }
    770     UnlockDisplay(dpy);
    771     SyncHandle();
    772     return True;
    773 }
    774 
    775 void
    776 XkbNoteNameChanges(XkbNameChangesPtr old,
    777                    XkbNamesNotifyEvent *new,
    778                    unsigned int wanted)
    779 {
    780     int first, last, old_last, new_last;
    781 
    782     if ((old == NULL) || (new == NULL))
    783         return;
    784 
    785     wanted &= new->changed;
    786 
    787     if (wanted == 0)
    788 	return;
    789 
    790     if (wanted & XkbKeyTypeNamesMask) {
    791         if (old->changed & XkbKeyTypeNamesMask) {
    792             new_last = (new->first_type + new->num_types - 1);
    793             old_last = (old->first_type + old->num_types - 1);
    794 
    795             if (new->first_type < old->first_type)
    796                 first = new->first_type;
    797             else
    798                 first = old->first_type;
    799 
    800             if (old_last > new_last)
    801                 last = old_last;
    802             else
    803                 last = new_last;
    804 
    805             old->first_type = first;
    806             old->num_types = (last - first) + 1;
    807         }
    808         else {
    809             old->first_type = new->first_type;
    810             old->num_types = new->num_types;
    811         }
    812     }
    813     if (wanted & XkbKTLevelNamesMask) {
    814         if (old->changed & XkbKTLevelNamesMask) {
    815             new_last = (new->first_lvl + new->num_lvls - 1);
    816             old_last = (old->first_lvl + old->num_lvls - 1);
    817 
    818             if (new->first_lvl < old->first_lvl)
    819                 first = new->first_lvl;
    820             else
    821                 first = old->first_lvl;
    822 
    823             if (old_last > new_last)
    824                 last = old_last;
    825             else
    826                 last = new_last;
    827 
    828             old->first_lvl = first;
    829             old->num_lvls = (last - first) + 1;
    830         }
    831         else {
    832             old->first_lvl = new->first_lvl;
    833             old->num_lvls = new->num_lvls;
    834         }
    835     }
    836     if (wanted & XkbIndicatorNamesMask) {
    837         if (old->changed & XkbIndicatorNamesMask)
    838             old->changed_indicators |= new->changed_indicators;
    839         else
    840             old->changed_indicators = new->changed_indicators;
    841     }
    842     if (wanted & XkbKeyNamesMask) {
    843         if (old->changed & XkbKeyNamesMask) {
    844             new_last = (new->first_key + new->num_keys - 1);
    845             old_last = (old->first_key + old->num_keys - 1);
    846 
    847             first = old->first_key;
    848 
    849             if (new->first_key < old->first_key)
    850                 first = new->first_key;
    851             if (old_last > new_last)
    852                 new_last = old_last;
    853 
    854             old->first_key = first;
    855             old->num_keys = (new_last - first) + 1;
    856         }
    857         else {
    858             old->first_key = new->first_key;
    859             old->num_keys = new->num_keys;
    860         }
    861     }
    862     if (wanted & XkbVirtualModNamesMask) {
    863         if (old->changed & XkbVirtualModNamesMask)
    864             old->changed_vmods |= new->changed_vmods;
    865         else
    866             old->changed_vmods = new->changed_vmods;
    867     }
    868     if (wanted & XkbGroupNamesMask) {
    869         if (old->changed & XkbGroupNamesMask)
    870             old->changed_groups |= new->changed_groups;
    871         else
    872             old->changed_groups = new->changed_groups;
    873     }
    874     if (wanted & XkbRGNamesMask)
    875         old->num_rg = new->num_radio_groups;
    876     if (wanted & XkbKeyAliasesMask)
    877         old->num_aliases = new->num_aliases;
    878     old->changed |= wanted;
    879     return;
    880 }
    881