105b261ecSmrg/************************************************************ 205b261ecSmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 305b261ecSmrg 405b261ecSmrgPermission to use, copy, modify, and distribute this 505b261ecSmrgsoftware and its documentation for any purpose and without 605b261ecSmrgfee is hereby granted, provided that the above copyright 705b261ecSmrgnotice appear in all copies and that both that copyright 805b261ecSmrgnotice and this permission notice appear in supporting 935c4bbdfSmrgdocumentation, and that the name of Silicon Graphics not be 1035c4bbdfSmrgused in advertising or publicity pertaining to distribution 1105b261ecSmrgof the software without specific prior written permission. 1235c4bbdfSmrgSilicon Graphics makes no representation about the suitability 1305b261ecSmrgof this software for any purpose. It is provided "as is" 1405b261ecSmrgwithout any express or implied warranty. 1505b261ecSmrg 1635c4bbdfSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1735c4bbdfSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1805b261ecSmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 1935c4bbdfSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2035c4bbdfSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2135c4bbdfSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 2205b261ecSmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 2305b261ecSmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 2405b261ecSmrg 2505b261ecSmrg********************************************************/ 2605b261ecSmrg 2705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2805b261ecSmrg#include <dix-config.h> 2905b261ecSmrg#endif 3005b261ecSmrg 3105b261ecSmrg#include <stdio.h> 3205b261ecSmrg#include <X11/X.h> 3305b261ecSmrg#include <X11/Xproto.h> 3405b261ecSmrg#include "misc.h" 3505b261ecSmrg#include "inputstr.h" 3605b261ecSmrg#include <X11/keysym.h> 3705b261ecSmrg#define XKBSRV_NEED_FILE_FUNCS 3805b261ecSmrg#include <xkbsrv.h> 3905b261ecSmrg 4005b261ecSmrg/***====================================================================***/ 4105b261ecSmrg 4205b261ecSmrgStatus 4335c4bbdfSmrgXkbAllocClientMap(XkbDescPtr xkb, unsigned which, unsigned nTotalTypes) 4405b261ecSmrg{ 4535c4bbdfSmrg XkbClientMapPtr map; 4635c4bbdfSmrg 4735c4bbdfSmrg if ((xkb == NULL) || 4835c4bbdfSmrg ((nTotalTypes > 0) && (nTotalTypes < XkbNumRequiredTypes))) 4935c4bbdfSmrg return BadValue; 5035c4bbdfSmrg if ((which & XkbKeySymsMask) && 5135c4bbdfSmrg ((!XkbIsLegalKeycode(xkb->min_key_code)) || 5235c4bbdfSmrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 5335c4bbdfSmrg (xkb->max_key_code < xkb->min_key_code))) { 544642e01fSmrg DebugF("bad keycode (%d,%d) in XkbAllocClientMap\n", 5535c4bbdfSmrg xkb->min_key_code, xkb->max_key_code); 5635c4bbdfSmrg return BadValue; 5735c4bbdfSmrg } 5835c4bbdfSmrg 5935c4bbdfSmrg if (xkb->map == NULL) { 6035c4bbdfSmrg map = calloc(1, sizeof(XkbClientMapRec)); 6135c4bbdfSmrg if (map == NULL) 6235c4bbdfSmrg return BadAlloc; 6335c4bbdfSmrg xkb->map = map; 6435c4bbdfSmrg } 6535c4bbdfSmrg else 6635c4bbdfSmrg map = xkb->map; 6735c4bbdfSmrg 6835c4bbdfSmrg if ((which & XkbKeyTypesMask) && (nTotalTypes > 0)) { 6935c4bbdfSmrg if (map->types == NULL) { 7035c4bbdfSmrg map->types = calloc(nTotalTypes, sizeof(XkbKeyTypeRec)); 7135c4bbdfSmrg if (map->types == NULL) 7235c4bbdfSmrg return BadAlloc; 7335c4bbdfSmrg map->num_types = 0; 7435c4bbdfSmrg map->size_types = nTotalTypes; 7535c4bbdfSmrg } 7635c4bbdfSmrg else if (map->size_types < nTotalTypes) { 7735c4bbdfSmrg XkbKeyTypeRec *prev_types = map->types; 7835c4bbdfSmrg 7935c4bbdfSmrg map->types = 8035c4bbdfSmrg reallocarray(map->types, nTotalTypes, sizeof(XkbKeyTypeRec)); 8135c4bbdfSmrg if (map->types == NULL) { 8235c4bbdfSmrg free(prev_types); 8335c4bbdfSmrg map->num_types = map->size_types = 0; 8435c4bbdfSmrg return BadAlloc; 8535c4bbdfSmrg } 8635c4bbdfSmrg map->size_types = nTotalTypes; 8735c4bbdfSmrg memset(&map->types[map->num_types], 0, 8835c4bbdfSmrg ((map->size_types - 8935c4bbdfSmrg map->num_types) * sizeof(XkbKeyTypeRec))); 9035c4bbdfSmrg } 9135c4bbdfSmrg } 9235c4bbdfSmrg if (which & XkbKeySymsMask) { 9335c4bbdfSmrg int nKeys = XkbNumKeys(xkb); 9435c4bbdfSmrg 9535c4bbdfSmrg if (map->syms == NULL) { 9635c4bbdfSmrg map->size_syms = (nKeys * 15) / 10; 9735c4bbdfSmrg map->syms = calloc(map->size_syms, sizeof(KeySym)); 9835c4bbdfSmrg if (!map->syms) { 9935c4bbdfSmrg map->size_syms = 0; 10035c4bbdfSmrg return BadAlloc; 10135c4bbdfSmrg } 10235c4bbdfSmrg map->num_syms = 1; 10335c4bbdfSmrg map->syms[0] = NoSymbol; 10435c4bbdfSmrg } 10535c4bbdfSmrg if (map->key_sym_map == NULL) { 106f2346221Smrg map->key_sym_map = calloc(MAP_LENGTH, sizeof(XkbSymMapRec)); 10735c4bbdfSmrg if (map->key_sym_map == NULL) 10835c4bbdfSmrg return BadAlloc; 10935c4bbdfSmrg } 11035c4bbdfSmrg } 11135c4bbdfSmrg if (which & XkbModifierMapMask) { 11235c4bbdfSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 11335c4bbdfSmrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 11435c4bbdfSmrg (xkb->max_key_code < xkb->min_key_code)) 11535c4bbdfSmrg return BadMatch; 11635c4bbdfSmrg if (map->modmap == NULL) { 117f2346221Smrg map->modmap = calloc(MAP_LENGTH, sizeof(unsigned char)); 11835c4bbdfSmrg if (map->modmap == NULL) 11935c4bbdfSmrg return BadAlloc; 12035c4bbdfSmrg } 12105b261ecSmrg } 12205b261ecSmrg return Success; 12305b261ecSmrg} 12405b261ecSmrg 12505b261ecSmrgStatus 12635c4bbdfSmrgXkbAllocServerMap(XkbDescPtr xkb, unsigned which, unsigned nNewActions) 12705b261ecSmrg{ 12835c4bbdfSmrg register int i; 12935c4bbdfSmrg XkbServerMapPtr map; 13035c4bbdfSmrg 13135c4bbdfSmrg if (xkb == NULL) 13235c4bbdfSmrg return BadMatch; 13335c4bbdfSmrg if (xkb->server == NULL) { 13435c4bbdfSmrg map = calloc(1, sizeof(XkbServerMapRec)); 13535c4bbdfSmrg if (map == NULL) 13635c4bbdfSmrg return BadAlloc; 13735c4bbdfSmrg for (i = 0; i < XkbNumVirtualMods; i++) { 13835c4bbdfSmrg map->vmods[i] = XkbNoModifierMask; 13935c4bbdfSmrg } 14035c4bbdfSmrg xkb->server = map; 14135c4bbdfSmrg } 14235c4bbdfSmrg else 14335c4bbdfSmrg map = xkb->server; 14435c4bbdfSmrg if (which & XkbExplicitComponentsMask) { 14535c4bbdfSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 14635c4bbdfSmrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 14735c4bbdfSmrg (xkb->max_key_code < xkb->min_key_code)) 14835c4bbdfSmrg return BadMatch; 14935c4bbdfSmrg if (map->explicit == NULL) { 150f2346221Smrg map->explicit = calloc(MAP_LENGTH, sizeof(unsigned char)); 15135c4bbdfSmrg if (map->explicit == NULL) 15235c4bbdfSmrg return BadAlloc; 15335c4bbdfSmrg } 15435c4bbdfSmrg } 15535c4bbdfSmrg if (which & XkbKeyActionsMask) { 15635c4bbdfSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 15735c4bbdfSmrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 15835c4bbdfSmrg (xkb->max_key_code < xkb->min_key_code)) 15935c4bbdfSmrg return BadMatch; 16035c4bbdfSmrg if (nNewActions < 1) 16135c4bbdfSmrg nNewActions = 1; 16235c4bbdfSmrg if (map->acts == NULL) { 16335c4bbdfSmrg map->acts = calloc((nNewActions + 1), sizeof(XkbAction)); 16435c4bbdfSmrg if (map->acts == NULL) 16535c4bbdfSmrg return BadAlloc; 16635c4bbdfSmrg map->num_acts = 1; 16735c4bbdfSmrg map->size_acts = nNewActions + 1; 16835c4bbdfSmrg } 16935c4bbdfSmrg else if ((map->size_acts - map->num_acts) < nNewActions) { 17035c4bbdfSmrg unsigned need; 17135c4bbdfSmrg XkbAction *prev_acts = map->acts; 17235c4bbdfSmrg 17335c4bbdfSmrg need = map->num_acts + nNewActions; 17435c4bbdfSmrg map->acts = reallocarray(map->acts, need, sizeof(XkbAction)); 17535c4bbdfSmrg if (map->acts == NULL) { 17635c4bbdfSmrg free(prev_acts); 17735c4bbdfSmrg map->num_acts = map->size_acts = 0; 17835c4bbdfSmrg return BadAlloc; 17935c4bbdfSmrg } 18035c4bbdfSmrg map->size_acts = need; 18135c4bbdfSmrg memset(&map->acts[map->num_acts], 0, 18235c4bbdfSmrg ((map->size_acts - map->num_acts) * sizeof(XkbAction))); 18335c4bbdfSmrg } 18435c4bbdfSmrg if (map->key_acts == NULL) { 185f2346221Smrg map->key_acts = calloc(MAP_LENGTH, sizeof(unsigned short)); 18635c4bbdfSmrg if (map->key_acts == NULL) 18735c4bbdfSmrg return BadAlloc; 18835c4bbdfSmrg } 18935c4bbdfSmrg } 19035c4bbdfSmrg if (which & XkbKeyBehaviorsMask) { 19135c4bbdfSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 19235c4bbdfSmrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 19335c4bbdfSmrg (xkb->max_key_code < xkb->min_key_code)) 19435c4bbdfSmrg return BadMatch; 19535c4bbdfSmrg if (map->behaviors == NULL) { 196f2346221Smrg map->behaviors = calloc(MAP_LENGTH, sizeof(XkbBehavior)); 19735c4bbdfSmrg if (map->behaviors == NULL) 19835c4bbdfSmrg return BadAlloc; 19935c4bbdfSmrg } 20035c4bbdfSmrg } 20135c4bbdfSmrg if (which & XkbVirtualModMapMask) { 20235c4bbdfSmrg if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 20335c4bbdfSmrg (!XkbIsLegalKeycode(xkb->max_key_code)) || 20435c4bbdfSmrg (xkb->max_key_code < xkb->min_key_code)) 20535c4bbdfSmrg return BadMatch; 20635c4bbdfSmrg if (map->vmodmap == NULL) { 207f2346221Smrg map->vmodmap = calloc(MAP_LENGTH, sizeof(unsigned short)); 20835c4bbdfSmrg if (map->vmodmap == NULL) 20935c4bbdfSmrg return BadAlloc; 21035c4bbdfSmrg } 21105b261ecSmrg } 21205b261ecSmrg return Success; 21305b261ecSmrg} 21405b261ecSmrg 21505b261ecSmrg/***====================================================================***/ 21605b261ecSmrg 21705b261ecSmrgstatic Status 21835c4bbdfSmrgXkbCopyKeyType(XkbKeyTypePtr from, XkbKeyTypePtr into) 21905b261ecSmrg{ 22035c4bbdfSmrg if ((!from) || (!into)) 22135c4bbdfSmrg return BadMatch; 2226747b715Smrg free(into->map); 2236747b715Smrg into->map = NULL; 2246747b715Smrg free(into->preserve); 2256747b715Smrg into->preserve = NULL; 2266747b715Smrg free(into->level_names); 2276747b715Smrg into->level_names = NULL; 22835c4bbdfSmrg *into = *from; 22935c4bbdfSmrg if ((from->map) && (into->map_count > 0)) { 23035c4bbdfSmrg into->map = calloc(into->map_count, sizeof(XkbKTMapEntryRec)); 23135c4bbdfSmrg if (!into->map) 23235c4bbdfSmrg return BadAlloc; 23335c4bbdfSmrg memcpy(into->map, from->map, 23435c4bbdfSmrg into->map_count * sizeof(XkbKTMapEntryRec)); 23535c4bbdfSmrg } 23635c4bbdfSmrg if ((from->preserve) && (into->map_count > 0)) { 23735c4bbdfSmrg into->preserve = calloc(into->map_count, sizeof(XkbModsRec)); 23835c4bbdfSmrg if (!into->preserve) 23935c4bbdfSmrg return BadAlloc; 24035c4bbdfSmrg memcpy(into->preserve, from->preserve, 24135c4bbdfSmrg into->map_count * sizeof(XkbModsRec)); 24235c4bbdfSmrg } 24335c4bbdfSmrg if ((from->level_names) && (into->num_levels > 0)) { 24435c4bbdfSmrg into->level_names = calloc(into->num_levels, sizeof(Atom)); 24535c4bbdfSmrg if (!into->level_names) 24635c4bbdfSmrg return BadAlloc; 24735c4bbdfSmrg memcpy(into->level_names, from->level_names, 24835c4bbdfSmrg into->num_levels * sizeof(Atom)); 24905b261ecSmrg } 25005b261ecSmrg return Success; 25105b261ecSmrg} 25205b261ecSmrg 25305b261ecSmrgStatus 25435c4bbdfSmrgXkbCopyKeyTypes(XkbKeyTypePtr from, XkbKeyTypePtr into, int num_types) 25505b261ecSmrg{ 25635c4bbdfSmrg register int i, rtrn; 25705b261ecSmrg 25835c4bbdfSmrg if ((!from) || (!into) || (num_types < 0)) 25935c4bbdfSmrg return BadMatch; 26035c4bbdfSmrg for (i = 0; i < num_types; i++) { 26135c4bbdfSmrg if ((rtrn = XkbCopyKeyType(from++, into++)) != Success) 26235c4bbdfSmrg return rtrn; 26305b261ecSmrg } 26405b261ecSmrg return Success; 26505b261ecSmrg} 26605b261ecSmrg 26705b261ecSmrgStatus 26835c4bbdfSmrgXkbResizeKeyType(XkbDescPtr xkb, 26935c4bbdfSmrg int type_ndx, 27035c4bbdfSmrg int map_count, Bool want_preserve, int new_num_lvls) 27105b261ecSmrg{ 27235c4bbdfSmrg XkbKeyTypePtr type; 27335c4bbdfSmrg KeyCode matchingKeys[XkbMaxKeyCount], nMatchingKeys; 27405b261ecSmrg 27535c4bbdfSmrg if ((type_ndx < 0) || (type_ndx >= xkb->map->num_types) || (map_count < 0) 27635c4bbdfSmrg || (new_num_lvls < 1)) 27735c4bbdfSmrg return BadValue; 27805b261ecSmrg switch (type_ndx) { 27935c4bbdfSmrg case XkbOneLevelIndex: 28035c4bbdfSmrg if (new_num_lvls != 1) 28135c4bbdfSmrg return BadMatch; 28235c4bbdfSmrg break; 28335c4bbdfSmrg case XkbTwoLevelIndex: 28435c4bbdfSmrg case XkbAlphabeticIndex: 28535c4bbdfSmrg case XkbKeypadIndex: 28635c4bbdfSmrg if (new_num_lvls != 2) 28735c4bbdfSmrg return BadMatch; 28835c4bbdfSmrg break; 28935c4bbdfSmrg } 29035c4bbdfSmrg type = &xkb->map->types[type_ndx]; 29135c4bbdfSmrg if (map_count == 0) { 29235c4bbdfSmrg free(type->map); 29335c4bbdfSmrg type->map = NULL; 29435c4bbdfSmrg free(type->preserve); 29535c4bbdfSmrg type->preserve = NULL; 29635c4bbdfSmrg type->map_count = 0; 29705b261ecSmrg } 29805b261ecSmrg else { 29935c4bbdfSmrg XkbKTMapEntryRec *prev_map = type->map; 30035c4bbdfSmrg 30135c4bbdfSmrg if ((map_count > type->map_count) || (type->map == NULL)) 30235c4bbdfSmrg type->map = 30335c4bbdfSmrg reallocarray(type->map, map_count, sizeof(XkbKTMapEntryRec)); 30435c4bbdfSmrg if (!type->map) { 30535c4bbdfSmrg free(prev_map); 30635c4bbdfSmrg return BadAlloc; 30735c4bbdfSmrg } 30835c4bbdfSmrg if (want_preserve) { 30935c4bbdfSmrg XkbModsRec *prev_preserve = type->preserve; 31035c4bbdfSmrg 31135c4bbdfSmrg if ((map_count > type->map_count) || (type->preserve == NULL)) { 31235c4bbdfSmrg type->preserve = reallocarray(type->preserve, 31335c4bbdfSmrg map_count, sizeof(XkbModsRec)); 31435c4bbdfSmrg } 31535c4bbdfSmrg if (!type->preserve) { 31635c4bbdfSmrg free(prev_preserve); 31735c4bbdfSmrg return BadAlloc; 31835c4bbdfSmrg } 31935c4bbdfSmrg } 32035c4bbdfSmrg else { 32135c4bbdfSmrg free(type->preserve); 32235c4bbdfSmrg type->preserve = NULL; 32335c4bbdfSmrg } 32435c4bbdfSmrg type->map_count = map_count; 32535c4bbdfSmrg } 32635c4bbdfSmrg 32735c4bbdfSmrg if ((new_num_lvls > type->num_levels) || (type->level_names == NULL)) { 32835c4bbdfSmrg Atom *prev_level_names = type->level_names; 32935c4bbdfSmrg 33035c4bbdfSmrg type->level_names = reallocarray(type->level_names, 33135c4bbdfSmrg new_num_lvls, sizeof(Atom)); 33235c4bbdfSmrg if (!type->level_names) { 33335c4bbdfSmrg free(prev_level_names); 33435c4bbdfSmrg return BadAlloc; 33535c4bbdfSmrg } 33605b261ecSmrg } 33705b261ecSmrg /* 33805b261ecSmrg * Here's the theory: 33905b261ecSmrg * If the width of the type changed, we might have to resize the symbol 34005b261ecSmrg * maps for any keys that use the type for one or more groups. This is 34105b261ecSmrg * expensive, so we'll try to cull out any keys that are obviously okay: 34205b261ecSmrg * In any case: 34305b261ecSmrg * - keys that have a group width <= the old width are okay (because 34405b261ecSmrg * they could not possibly have been associated with the old type) 34505b261ecSmrg * If the key type increased in size: 34605b261ecSmrg * - keys that already have a group width >= to the new width are okay 34705b261ecSmrg * + keys that have a group width >= the old width but < the new width 34805b261ecSmrg * might have to be enlarged. 34905b261ecSmrg * If the key type decreased in size: 35005b261ecSmrg * - keys that have a group width > the old width don't have to be 35135c4bbdfSmrg * resized (because they must have some other wider type associated 35205b261ecSmrg * with some group). 35305b261ecSmrg * + keys that have a group width == the old width might have to be 35405b261ecSmrg * shrunk. 35505b261ecSmrg * The possibilities marked with '+' require us to examine the key types 35605b261ecSmrg * associated with each group for the key. 35705b261ecSmrg */ 35835c4bbdfSmrg memset(matchingKeys, 0, XkbMaxKeyCount * sizeof(KeyCode)); 35935c4bbdfSmrg nMatchingKeys = 0; 36035c4bbdfSmrg if (new_num_lvls > type->num_levels) { 36135c4bbdfSmrg int nTotal; 36235c4bbdfSmrg KeySym *newSyms; 36335c4bbdfSmrg int width, match, nResize; 36435c4bbdfSmrg register int i, g, nSyms; 36535c4bbdfSmrg 36635c4bbdfSmrg nResize = 0; 36735c4bbdfSmrg for (nTotal = 1, i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 36835c4bbdfSmrg width = XkbKeyGroupsWidth(xkb, i); 36935c4bbdfSmrg if (width < type->num_levels || width >= new_num_lvls) { 37035c4bbdfSmrg nTotal += XkbKeyNumSyms(xkb,i); 37135c4bbdfSmrg continue; 37235c4bbdfSmrg } 37335c4bbdfSmrg for (match = 0, g = XkbKeyNumGroups(xkb, i) - 1; 37435c4bbdfSmrg (g >= 0) && (!match); g--) { 37535c4bbdfSmrg if (XkbKeyKeyTypeIndex(xkb, i, g) == type_ndx) { 37635c4bbdfSmrg matchingKeys[nMatchingKeys++] = i; 37735c4bbdfSmrg match = 1; 37835c4bbdfSmrg } 37935c4bbdfSmrg } 38035c4bbdfSmrg if (!match) 38135c4bbdfSmrg nTotal += XkbKeyNumSyms(xkb, i); 38235c4bbdfSmrg else { 38335c4bbdfSmrg nTotal += XkbKeyNumGroups(xkb, i) * new_num_lvls; 38435c4bbdfSmrg nResize++; 38535c4bbdfSmrg } 38635c4bbdfSmrg } 38735c4bbdfSmrg if (nResize > 0) { 38835c4bbdfSmrg int nextMatch; 38935c4bbdfSmrg 39035c4bbdfSmrg xkb->map->size_syms = (nTotal * 15) / 10; 39135c4bbdfSmrg newSyms = calloc(xkb->map->size_syms, sizeof(KeySym)); 39235c4bbdfSmrg if (newSyms == NULL) 39335c4bbdfSmrg return BadAlloc; 39435c4bbdfSmrg nextMatch = 0; 39535c4bbdfSmrg nSyms = 1; 39635c4bbdfSmrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 39735c4bbdfSmrg if (matchingKeys[nextMatch] == i) { 39835c4bbdfSmrg KeySym *pOld; 39935c4bbdfSmrg 40035c4bbdfSmrg nextMatch++; 40135c4bbdfSmrg width = XkbKeyGroupsWidth(xkb, i); 40235c4bbdfSmrg pOld = XkbKeySymsPtr(xkb, i); 40335c4bbdfSmrg for (g = XkbKeyNumGroups(xkb, i) - 1; g >= 0; g--) { 40435c4bbdfSmrg memcpy(&newSyms[nSyms + (new_num_lvls * g)], 40535c4bbdfSmrg &pOld[width * g], width * sizeof(KeySym)); 40635c4bbdfSmrg } 40735c4bbdfSmrg xkb->map->key_sym_map[i].offset = nSyms; 40835c4bbdfSmrg nSyms += XkbKeyNumGroups(xkb, i) * new_num_lvls; 40935c4bbdfSmrg } 41035c4bbdfSmrg else { 41135c4bbdfSmrg memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i), 41235c4bbdfSmrg XkbKeyNumSyms(xkb, i) * sizeof(KeySym)); 41335c4bbdfSmrg xkb->map->key_sym_map[i].offset = nSyms; 41435c4bbdfSmrg nSyms += XkbKeyNumSyms(xkb, i); 41535c4bbdfSmrg } 41635c4bbdfSmrg } 41735c4bbdfSmrg type->num_levels = new_num_lvls; 41835c4bbdfSmrg free(xkb->map->syms); 41935c4bbdfSmrg xkb->map->syms = newSyms; 42035c4bbdfSmrg xkb->map->num_syms = nSyms; 42135c4bbdfSmrg return Success; 42235c4bbdfSmrg } 42335c4bbdfSmrg } 42435c4bbdfSmrg else if (new_num_lvls < type->num_levels) { 42535c4bbdfSmrg int width, match; 42635c4bbdfSmrg register int g, i; 42735c4bbdfSmrg 42835c4bbdfSmrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 42935c4bbdfSmrg width = XkbKeyGroupsWidth(xkb, i); 43035c4bbdfSmrg if (width < type->num_levels) 43135c4bbdfSmrg continue; 43235c4bbdfSmrg for (match = 0, g = XkbKeyNumGroups(xkb, i) - 1; 43335c4bbdfSmrg (g >= 0) && (!match); g--) { 43435c4bbdfSmrg if (XkbKeyKeyTypeIndex(xkb, i, g) == type_ndx) { 43535c4bbdfSmrg matchingKeys[nMatchingKeys++] = i; 43635c4bbdfSmrg match = 1; 43735c4bbdfSmrg } 43835c4bbdfSmrg } 43935c4bbdfSmrg } 44035c4bbdfSmrg } 44135c4bbdfSmrg if (nMatchingKeys > 0) { 44235c4bbdfSmrg int key, firstClear; 44335c4bbdfSmrg register int i, g; 44435c4bbdfSmrg 44535c4bbdfSmrg if (new_num_lvls > type->num_levels) 44635c4bbdfSmrg firstClear = type->num_levels; 44735c4bbdfSmrg else 44835c4bbdfSmrg firstClear = new_num_lvls; 44935c4bbdfSmrg for (i = 0; i < nMatchingKeys; i++) { 45035c4bbdfSmrg KeySym *pSyms; 45135c4bbdfSmrg int width, nClear; 45235c4bbdfSmrg 45335c4bbdfSmrg key = matchingKeys[i]; 45435c4bbdfSmrg width = XkbKeyGroupsWidth(xkb, key); 45535c4bbdfSmrg nClear = width - firstClear; 45635c4bbdfSmrg pSyms = XkbKeySymsPtr(xkb, key); 45735c4bbdfSmrg for (g = XkbKeyNumGroups(xkb, key) - 1; g >= 0; g--) { 45835c4bbdfSmrg if (XkbKeyKeyTypeIndex(xkb, key, g) == type_ndx) { 45935c4bbdfSmrg if (nClear > 0) 46035c4bbdfSmrg memset(&pSyms[g * width + firstClear], 0, 46135c4bbdfSmrg nClear * sizeof(KeySym)); 46235c4bbdfSmrg } 46335c4bbdfSmrg } 46435c4bbdfSmrg } 46535c4bbdfSmrg } 46635c4bbdfSmrg type->num_levels = new_num_lvls; 46705b261ecSmrg return Success; 46805b261ecSmrg} 46905b261ecSmrg 47005b261ecSmrgKeySym * 47135c4bbdfSmrgXkbResizeKeySyms(XkbDescPtr xkb, int key, int needed) 47205b261ecSmrg{ 47335c4bbdfSmrg register int i, nSyms, nKeySyms; 47435c4bbdfSmrg unsigned nOldSyms; 47535c4bbdfSmrg KeySym *newSyms; 47635c4bbdfSmrg 47735c4bbdfSmrg if (needed == 0) { 47835c4bbdfSmrg xkb->map->key_sym_map[key].offset = 0; 47935c4bbdfSmrg return xkb->map->syms; 48035c4bbdfSmrg } 48135c4bbdfSmrg nOldSyms = XkbKeyNumSyms(xkb, key); 48235c4bbdfSmrg if (nOldSyms >= (unsigned) needed) { 48335c4bbdfSmrg return XkbKeySymsPtr(xkb, key); 48435c4bbdfSmrg } 48535c4bbdfSmrg if (xkb->map->size_syms - xkb->map->num_syms >= (unsigned) needed) { 48635c4bbdfSmrg if (nOldSyms > 0) { 48735c4bbdfSmrg memcpy(&xkb->map->syms[xkb->map->num_syms], XkbKeySymsPtr(xkb, key), 48835c4bbdfSmrg nOldSyms * sizeof(KeySym)); 48935c4bbdfSmrg } 49035c4bbdfSmrg if ((needed - nOldSyms) > 0) { 49135c4bbdfSmrg memset(&xkb->map-> 49235c4bbdfSmrg syms[xkb->map->num_syms + XkbKeyNumSyms(xkb, key)], 0, 49335c4bbdfSmrg (needed - nOldSyms) * sizeof(KeySym)); 49435c4bbdfSmrg } 49535c4bbdfSmrg xkb->map->key_sym_map[key].offset = xkb->map->num_syms; 49635c4bbdfSmrg xkb->map->num_syms += needed; 49735c4bbdfSmrg return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 49835c4bbdfSmrg } 49935c4bbdfSmrg xkb->map->size_syms += (needed > 32 ? needed : 32); 5006747b715Smrg newSyms = calloc(xkb->map->size_syms, sizeof(KeySym)); 50135c4bbdfSmrg if (newSyms == NULL) 50235c4bbdfSmrg return NULL; 50335c4bbdfSmrg newSyms[0] = NoSymbol; 50405b261ecSmrg nSyms = 1; 50535c4bbdfSmrg for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { 50635c4bbdfSmrg int nCopy; 50735c4bbdfSmrg 50835c4bbdfSmrg nCopy = nKeySyms = XkbKeyNumSyms(xkb, i); 50935c4bbdfSmrg if ((nKeySyms == 0) && (i != key)) 51035c4bbdfSmrg continue; 51135c4bbdfSmrg if (i == key) 51235c4bbdfSmrg nKeySyms = needed; 51335c4bbdfSmrg if (nCopy != 0) 51435c4bbdfSmrg memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i), 51535c4bbdfSmrg nCopy * sizeof(KeySym)); 51635c4bbdfSmrg if (nKeySyms > nCopy) 51735c4bbdfSmrg memset(&newSyms[nSyms + nCopy], 0, 51835c4bbdfSmrg (nKeySyms - nCopy) * sizeof(KeySym)); 51935c4bbdfSmrg xkb->map->key_sym_map[i].offset = nSyms; 52035c4bbdfSmrg nSyms += nKeySyms; 52105b261ecSmrg } 5226747b715Smrg free(xkb->map->syms); 52305b261ecSmrg xkb->map->syms = newSyms; 52405b261ecSmrg xkb->map->num_syms = nSyms; 52505b261ecSmrg return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; 52605b261ecSmrg} 52705b261ecSmrg 52805b261ecSmrgstatic unsigned 52935c4bbdfSmrg_ExtendRange(unsigned int old_flags, 53035c4bbdfSmrg unsigned int flag, 53135c4bbdfSmrg KeyCode newKC, KeyCode *old_min, unsigned char *old_num) 53205b261ecSmrg{ 53335c4bbdfSmrg if ((old_flags & flag) == 0) { 53435c4bbdfSmrg old_flags |= flag; 53535c4bbdfSmrg *old_min = newKC; 53635c4bbdfSmrg *old_num = 1; 53705b261ecSmrg } 53805b261ecSmrg else { 53935c4bbdfSmrg int last = (*old_min) + (*old_num) - 1; 54035c4bbdfSmrg 54135c4bbdfSmrg if (newKC < *old_min) { 54235c4bbdfSmrg *old_min = newKC; 54335c4bbdfSmrg *old_num = (last - newKC) + 1; 54435c4bbdfSmrg } 54535c4bbdfSmrg else if (newKC > last) { 54635c4bbdfSmrg *old_num = (newKC - (*old_min)) + 1; 54735c4bbdfSmrg } 54805b261ecSmrg } 54905b261ecSmrg return old_flags; 55005b261ecSmrg} 55105b261ecSmrg 55205b261ecSmrgStatus 55335c4bbdfSmrgXkbChangeKeycodeRange(XkbDescPtr xkb, 55435c4bbdfSmrg int minKC, int maxKC, XkbChangesPtr changes) 55505b261ecSmrg{ 55635c4bbdfSmrg int tmp; 55735c4bbdfSmrg 55835c4bbdfSmrg if ((!xkb) || (minKC < XkbMinLegalKeyCode) || (maxKC > XkbMaxLegalKeyCode)) 55935c4bbdfSmrg return BadValue; 56035c4bbdfSmrg if (minKC > maxKC) 56135c4bbdfSmrg return BadMatch; 56235c4bbdfSmrg if (minKC < xkb->min_key_code) { 56335c4bbdfSmrg if (changes) 56435c4bbdfSmrg changes->map.min_key_code = minKC; 56535c4bbdfSmrg tmp = xkb->min_key_code - minKC; 56635c4bbdfSmrg if (xkb->map) { 56735c4bbdfSmrg if (xkb->map->key_sym_map) { 56835c4bbdfSmrg memset((char *) &xkb->map->key_sym_map[minKC], 0, 56935c4bbdfSmrg tmp * sizeof(XkbSymMapRec)); 57035c4bbdfSmrg if (changes) { 57135c4bbdfSmrg changes->map.changed = _ExtendRange(changes->map.changed, 57235c4bbdfSmrg XkbKeySymsMask, minKC, 57335c4bbdfSmrg &changes->map. 57435c4bbdfSmrg first_key_sym, 57535c4bbdfSmrg &changes->map. 57635c4bbdfSmrg num_key_syms); 57735c4bbdfSmrg } 57835c4bbdfSmrg } 57935c4bbdfSmrg if (xkb->map->modmap) { 58035c4bbdfSmrg memset((char *) &xkb->map->modmap[minKC], 0, tmp); 58135c4bbdfSmrg if (changes) { 58235c4bbdfSmrg changes->map.changed = _ExtendRange(changes->map.changed, 58335c4bbdfSmrg XkbModifierMapMask, 58435c4bbdfSmrg minKC, 58535c4bbdfSmrg &changes->map. 58635c4bbdfSmrg first_modmap_key, 58735c4bbdfSmrg &changes->map. 58835c4bbdfSmrg num_modmap_keys); 58935c4bbdfSmrg } 59035c4bbdfSmrg } 59135c4bbdfSmrg } 59235c4bbdfSmrg if (xkb->server) { 59335c4bbdfSmrg if (xkb->server->behaviors) { 59435c4bbdfSmrg memset((char *) &xkb->server->behaviors[minKC], 0, 59535c4bbdfSmrg tmp * sizeof(XkbBehavior)); 59635c4bbdfSmrg if (changes) { 59735c4bbdfSmrg changes->map.changed = _ExtendRange(changes->map.changed, 59835c4bbdfSmrg XkbKeyBehaviorsMask, 59935c4bbdfSmrg minKC, 60035c4bbdfSmrg &changes->map. 60135c4bbdfSmrg first_key_behavior, 60235c4bbdfSmrg &changes->map. 60335c4bbdfSmrg num_key_behaviors); 60435c4bbdfSmrg } 60535c4bbdfSmrg } 60635c4bbdfSmrg if (xkb->server->key_acts) { 60735c4bbdfSmrg memset((char *) &xkb->server->key_acts[minKC], 0, 60835c4bbdfSmrg tmp * sizeof(unsigned short)); 60935c4bbdfSmrg if (changes) { 61035c4bbdfSmrg changes->map.changed = _ExtendRange(changes->map.changed, 61135c4bbdfSmrg XkbKeyActionsMask, 61235c4bbdfSmrg minKC, 61335c4bbdfSmrg &changes->map. 61435c4bbdfSmrg first_key_act, 61535c4bbdfSmrg &changes->map. 61635c4bbdfSmrg num_key_acts); 61735c4bbdfSmrg } 61835c4bbdfSmrg } 61935c4bbdfSmrg if (xkb->server->vmodmap) { 62035c4bbdfSmrg memset((char *) &xkb->server->vmodmap[minKC], 0, 62135c4bbdfSmrg tmp * sizeof(unsigned short)); 62235c4bbdfSmrg if (changes) { 62335c4bbdfSmrg changes->map.changed = _ExtendRange(changes->map.changed, 62435c4bbdfSmrg XkbVirtualModMapMask, 62535c4bbdfSmrg minKC, 62635c4bbdfSmrg &changes->map. 62735c4bbdfSmrg first_modmap_key, 62835c4bbdfSmrg &changes->map. 62935c4bbdfSmrg num_vmodmap_keys); 63035c4bbdfSmrg } 63135c4bbdfSmrg } 63235c4bbdfSmrg } 63335c4bbdfSmrg if ((xkb->names) && (xkb->names->keys)) { 63435c4bbdfSmrg memset((char *) &xkb->names->keys[minKC], 0, 63535c4bbdfSmrg tmp * sizeof(XkbKeyNameRec)); 63635c4bbdfSmrg if (changes) { 63735c4bbdfSmrg changes->names.changed = _ExtendRange(changes->names.changed, 63835c4bbdfSmrg XkbKeyNamesMask, minKC, 63935c4bbdfSmrg &changes->names.first_key, 64035c4bbdfSmrg &changes->names.num_keys); 64135c4bbdfSmrg } 64235c4bbdfSmrg } 64335c4bbdfSmrg xkb->min_key_code = minKC; 64435c4bbdfSmrg } 64535c4bbdfSmrg if (maxKC > xkb->max_key_code) { 64635c4bbdfSmrg if (changes) 64735c4bbdfSmrg changes->map.max_key_code = maxKC; 648f2346221Smrg tmp = MAP_LENGTH - xkb->max_key_code; 64935c4bbdfSmrg if (xkb->map) { 65035c4bbdfSmrg if (xkb->map->key_sym_map) { 65135c4bbdfSmrg memset((char *) &xkb->map->key_sym_map[xkb->max_key_code], 0, 65235c4bbdfSmrg tmp * sizeof(XkbSymMapRec)); 65335c4bbdfSmrg if (changes) { 65435c4bbdfSmrg changes->map.changed = _ExtendRange(changes->map.changed, 65535c4bbdfSmrg XkbKeySymsMask, maxKC, 65635c4bbdfSmrg &changes->map. 65735c4bbdfSmrg first_key_sym, 65835c4bbdfSmrg &changes->map. 65935c4bbdfSmrg num_key_syms); 66035c4bbdfSmrg } 66135c4bbdfSmrg } 66235c4bbdfSmrg if (xkb->map->modmap) { 66335c4bbdfSmrg memset((char *) &xkb->map->modmap[xkb->max_key_code], 0, tmp); 66435c4bbdfSmrg if (changes) { 66535c4bbdfSmrg changes->map.changed = _ExtendRange(changes->map.changed, 66635c4bbdfSmrg XkbModifierMapMask, 66735c4bbdfSmrg maxKC, 66835c4bbdfSmrg &changes->map. 66935c4bbdfSmrg first_modmap_key, 67035c4bbdfSmrg &changes->map. 67135c4bbdfSmrg num_modmap_keys); 67235c4bbdfSmrg } 67335c4bbdfSmrg } 67435c4bbdfSmrg } 67535c4bbdfSmrg if (xkb->server) { 67635c4bbdfSmrg if (xkb->server->behaviors) { 67735c4bbdfSmrg memset((char *) &xkb->server->behaviors[xkb->max_key_code], 0, 67835c4bbdfSmrg tmp * sizeof(XkbBehavior)); 67935c4bbdfSmrg if (changes) { 68035c4bbdfSmrg changes->map.changed = _ExtendRange(changes->map.changed, 68135c4bbdfSmrg XkbKeyBehaviorsMask, 68235c4bbdfSmrg maxKC, 68335c4bbdfSmrg &changes->map. 68435c4bbdfSmrg first_key_behavior, 68535c4bbdfSmrg &changes->map. 68635c4bbdfSmrg num_key_behaviors); 68735c4bbdfSmrg } 68835c4bbdfSmrg } 68935c4bbdfSmrg if (xkb->server->key_acts) { 69035c4bbdfSmrg memset((char *) &xkb->server->key_acts[xkb->max_key_code], 0, 69135c4bbdfSmrg tmp * sizeof(unsigned short)); 69235c4bbdfSmrg if (changes) { 69335c4bbdfSmrg changes->map.changed = _ExtendRange(changes->map.changed, 69435c4bbdfSmrg XkbKeyActionsMask, 69535c4bbdfSmrg maxKC, 69635c4bbdfSmrg &changes->map. 69735c4bbdfSmrg first_key_act, 69835c4bbdfSmrg &changes->map. 69935c4bbdfSmrg num_key_acts); 70035c4bbdfSmrg } 70135c4bbdfSmrg } 70235c4bbdfSmrg if (xkb->server->vmodmap) { 70335c4bbdfSmrg memset((char *) &xkb->server->vmodmap[xkb->max_key_code], 0, 70435c4bbdfSmrg tmp * sizeof(unsigned short)); 70535c4bbdfSmrg if (changes) { 70635c4bbdfSmrg changes->map.changed = _ExtendRange(changes->map.changed, 70735c4bbdfSmrg XkbVirtualModMapMask, 70835c4bbdfSmrg maxKC, 70935c4bbdfSmrg &changes->map. 71035c4bbdfSmrg first_modmap_key, 71135c4bbdfSmrg &changes->map. 71235c4bbdfSmrg num_vmodmap_keys); 71335c4bbdfSmrg } 71435c4bbdfSmrg } 71535c4bbdfSmrg } 71635c4bbdfSmrg if ((xkb->names) && (xkb->names->keys)) { 71735c4bbdfSmrg memset((char *) &xkb->names->keys[xkb->max_key_code], 0, 71835c4bbdfSmrg tmp * sizeof(XkbKeyNameRec)); 71935c4bbdfSmrg if (changes) { 72035c4bbdfSmrg changes->names.changed = _ExtendRange(changes->names.changed, 72135c4bbdfSmrg XkbKeyNamesMask, maxKC, 72235c4bbdfSmrg &changes->names.first_key, 72335c4bbdfSmrg &changes->names.num_keys); 72435c4bbdfSmrg } 72535c4bbdfSmrg } 72635c4bbdfSmrg xkb->max_key_code = maxKC; 72705b261ecSmrg } 72805b261ecSmrg return Success; 72905b261ecSmrg} 73005b261ecSmrg 73105b261ecSmrgXkbAction * 73235c4bbdfSmrgXkbResizeKeyActions(XkbDescPtr xkb, int key, int needed) 73305b261ecSmrg{ 73435c4bbdfSmrg register int i, nActs; 73535c4bbdfSmrg XkbAction *newActs; 73635c4bbdfSmrg 73754b5899cSmrg if (needed <= 0) { 73835c4bbdfSmrg xkb->server->key_acts[key] = 0; 73935c4bbdfSmrg return NULL; 74035c4bbdfSmrg } 74135c4bbdfSmrg if (XkbKeyHasActions(xkb, key) && 74235c4bbdfSmrg (XkbKeyNumSyms(xkb, key) >= (unsigned) needed)) 74335c4bbdfSmrg return XkbKeyActionsPtr(xkb, key); 74435c4bbdfSmrg if (xkb->server->size_acts - xkb->server->num_acts >= (unsigned) needed) { 74535c4bbdfSmrg xkb->server->key_acts[key] = xkb->server->num_acts; 74635c4bbdfSmrg xkb->server->num_acts += needed; 74735c4bbdfSmrg return &xkb->server->acts[xkb->server->key_acts[key]]; 74835c4bbdfSmrg } 74935c4bbdfSmrg xkb->server->size_acts = xkb->server->num_acts + needed + 8; 7506747b715Smrg newActs = calloc(xkb->server->size_acts, sizeof(XkbAction)); 75135c4bbdfSmrg if (newActs == NULL) 75235c4bbdfSmrg return NULL; 75305b261ecSmrg newActs[0].type = XkbSA_NoAction; 75405b261ecSmrg nActs = 1; 75535c4bbdfSmrg for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { 75635c4bbdfSmrg int nKeyActs, nCopy; 75735c4bbdfSmrg 75835c4bbdfSmrg if ((xkb->server->key_acts[i] == 0) && (i != key)) 75935c4bbdfSmrg continue; 76035c4bbdfSmrg 76135c4bbdfSmrg nCopy = nKeyActs = XkbKeyNumActions(xkb, i); 76235c4bbdfSmrg if (i == key) { 76335c4bbdfSmrg nKeyActs = needed; 76435c4bbdfSmrg if (needed < nCopy) 76535c4bbdfSmrg nCopy = needed; 76635c4bbdfSmrg } 76735c4bbdfSmrg 76835c4bbdfSmrg if (nCopy > 0) 76935c4bbdfSmrg memcpy(&newActs[nActs], XkbKeyActionsPtr(xkb, i), 77035c4bbdfSmrg nCopy * sizeof(XkbAction)); 77135c4bbdfSmrg if (nCopy < nKeyActs) 77235c4bbdfSmrg memset(&newActs[nActs + nCopy], 0, 77335c4bbdfSmrg (nKeyActs - nCopy) * sizeof(XkbAction)); 77435c4bbdfSmrg xkb->server->key_acts[i] = nActs; 77535c4bbdfSmrg nActs += nKeyActs; 77605b261ecSmrg } 7776747b715Smrg free(xkb->server->acts); 77805b261ecSmrg xkb->server->acts = newActs; 77935c4bbdfSmrg xkb->server->num_acts = nActs; 78005b261ecSmrg return &xkb->server->acts[xkb->server->key_acts[key]]; 78105b261ecSmrg} 78205b261ecSmrg 78305b261ecSmrgvoid 78435c4bbdfSmrgXkbFreeClientMap(XkbDescPtr xkb, unsigned what, Bool freeMap) 78505b261ecSmrg{ 78635c4bbdfSmrg XkbClientMapPtr map; 78705b261ecSmrg 78835c4bbdfSmrg if ((xkb == NULL) || (xkb->map == NULL)) 78935c4bbdfSmrg return; 79005b261ecSmrg if (freeMap) 79135c4bbdfSmrg what = XkbAllClientInfoMask; 79235c4bbdfSmrg map = xkb->map; 79335c4bbdfSmrg if (what & XkbKeyTypesMask) { 79435c4bbdfSmrg if (map->types != NULL) { 79535c4bbdfSmrg if (map->num_types > 0) { 79635c4bbdfSmrg register int i; 79735c4bbdfSmrg XkbKeyTypePtr type; 79835c4bbdfSmrg 79935c4bbdfSmrg for (i = 0, type = map->types; i < map->num_types; i++, type++) { 80035c4bbdfSmrg free(type->map); 80135c4bbdfSmrg type->map = NULL; 80235c4bbdfSmrg free(type->preserve); 80335c4bbdfSmrg type->preserve = NULL; 80435c4bbdfSmrg type->map_count = 0; 80535c4bbdfSmrg free(type->level_names); 80635c4bbdfSmrg type->level_names = NULL; 80735c4bbdfSmrg } 80835c4bbdfSmrg } 80935c4bbdfSmrg free(map->types); 81035c4bbdfSmrg map->num_types = map->size_types = 0; 81135c4bbdfSmrg map->types = NULL; 81235c4bbdfSmrg } 81335c4bbdfSmrg } 81435c4bbdfSmrg if (what & XkbKeySymsMask) { 81535c4bbdfSmrg free(map->key_sym_map); 81635c4bbdfSmrg map->key_sym_map = NULL; 81735c4bbdfSmrg if (map->syms != NULL) { 81835c4bbdfSmrg free(map->syms); 81935c4bbdfSmrg map->size_syms = map->num_syms = 0; 82035c4bbdfSmrg map->syms = NULL; 82135c4bbdfSmrg } 82235c4bbdfSmrg } 82335c4bbdfSmrg if ((what & XkbModifierMapMask) && (map->modmap != NULL)) { 82435c4bbdfSmrg free(map->modmap); 82535c4bbdfSmrg map->modmap = NULL; 82605b261ecSmrg } 82705b261ecSmrg if (freeMap) { 82835c4bbdfSmrg free(xkb->map); 82935c4bbdfSmrg xkb->map = NULL; 83005b261ecSmrg } 83105b261ecSmrg return; 83205b261ecSmrg} 83305b261ecSmrg 83405b261ecSmrgvoid 83535c4bbdfSmrgXkbFreeServerMap(XkbDescPtr xkb, unsigned what, Bool freeMap) 83605b261ecSmrg{ 83735c4bbdfSmrg XkbServerMapPtr map; 83805b261ecSmrg 83935c4bbdfSmrg if ((xkb == NULL) || (xkb->server == NULL)) 84035c4bbdfSmrg return; 84105b261ecSmrg if (freeMap) 84235c4bbdfSmrg what = XkbAllServerInfoMask; 84335c4bbdfSmrg map = xkb->server; 84435c4bbdfSmrg if ((what & XkbExplicitComponentsMask) && (map->explicit != NULL)) { 84535c4bbdfSmrg free(map->explicit); 84635c4bbdfSmrg map->explicit = NULL; 84735c4bbdfSmrg } 84835c4bbdfSmrg if (what & XkbKeyActionsMask) { 84935c4bbdfSmrg free(map->key_acts); 85035c4bbdfSmrg map->key_acts = NULL; 85135c4bbdfSmrg if (map->acts != NULL) { 85235c4bbdfSmrg free(map->acts); 85335c4bbdfSmrg map->num_acts = map->size_acts = 0; 85435c4bbdfSmrg map->acts = NULL; 85535c4bbdfSmrg } 85635c4bbdfSmrg } 85735c4bbdfSmrg if ((what & XkbKeyBehaviorsMask) && (map->behaviors != NULL)) { 85835c4bbdfSmrg free(map->behaviors); 85935c4bbdfSmrg map->behaviors = NULL; 86035c4bbdfSmrg } 86135c4bbdfSmrg if ((what & XkbVirtualModMapMask) && (map->vmodmap != NULL)) { 86235c4bbdfSmrg free(map->vmodmap); 86335c4bbdfSmrg map->vmodmap = NULL; 86405b261ecSmrg } 86505b261ecSmrg 86605b261ecSmrg if (freeMap) { 86735c4bbdfSmrg free(xkb->server); 86835c4bbdfSmrg xkb->server = NULL; 86905b261ecSmrg } 87005b261ecSmrg return; 87105b261ecSmrg} 872