XKBAlloc.c revision 35c4bbdf
1/************************************************************ 2Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 3 4Permission to use, copy, modify, and distribute this 5software and its documentation for any purpose and without 6fee is hereby granted, provided that the above copyright 7notice appear in all copies and that both that copyright 8notice and this permission notice appear in supporting 9documentation, and that the name of Silicon Graphics not be 10used in advertising or publicity pertaining to distribution 11of the software without specific prior written permission. 12Silicon Graphics makes no representation about the suitability 13of this software for any purpose. It is provided "as is" 14without any express or implied warranty. 15 16SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 25********************************************************/ 26 27#ifdef HAVE_DIX_CONFIG_H 28#include <dix-config.h> 29#endif 30 31#include <stdio.h> 32#include <X11/X.h> 33#include <X11/Xproto.h> 34#include "misc.h" 35#include "inputstr.h" 36#include <xkbsrv.h> 37#include "xkbgeom.h" 38#include <os.h> 39#include <string.h> 40 41/***===================================================================***/ 42 43 /*ARGSUSED*/ Status 44XkbAllocCompatMap(XkbDescPtr xkb, unsigned which, unsigned nSI) 45{ 46 XkbCompatMapPtr compat; 47 XkbSymInterpretRec *prev_interpret; 48 49 if (!xkb) 50 return BadMatch; 51 if (xkb->compat) { 52 if (xkb->compat->size_si >= nSI) 53 return Success; 54 compat = xkb->compat; 55 compat->size_si = nSI; 56 if (compat->sym_interpret == NULL) 57 compat->num_si = 0; 58 prev_interpret = compat->sym_interpret; 59 compat->sym_interpret = reallocarray(compat->sym_interpret, 60 nSI, sizeof(XkbSymInterpretRec)); 61 if (compat->sym_interpret == NULL) { 62 free(prev_interpret); 63 compat->size_si = compat->num_si = 0; 64 return BadAlloc; 65 } 66 if (compat->num_si != 0) { 67 memset(&compat->sym_interpret[compat->num_si], 0, 68 (compat->size_si - 69 compat->num_si) * sizeof(XkbSymInterpretRec)); 70 } 71 return Success; 72 } 73 compat = calloc(1, sizeof(XkbCompatMapRec)); 74 if (compat == NULL) 75 return BadAlloc; 76 if (nSI > 0) { 77 compat->sym_interpret = calloc(nSI, sizeof(XkbSymInterpretRec)); 78 if (!compat->sym_interpret) { 79 free(compat); 80 return BadAlloc; 81 } 82 } 83 compat->size_si = nSI; 84 compat->num_si = 0; 85 memset((char *) &compat->groups[0], 0, 86 XkbNumKbdGroups * sizeof(XkbModsRec)); 87 xkb->compat = compat; 88 return Success; 89} 90 91void 92XkbFreeCompatMap(XkbDescPtr xkb, unsigned which, Bool freeMap) 93{ 94 register XkbCompatMapPtr compat; 95 96 if ((xkb == NULL) || (xkb->compat == NULL)) 97 return; 98 compat = xkb->compat; 99 if (freeMap) 100 which = XkbAllCompatMask; 101 if (which & XkbGroupCompatMask) 102 memset((char *) &compat->groups[0], 0, 103 XkbNumKbdGroups * sizeof(XkbModsRec)); 104 if (which & XkbSymInterpMask) { 105 if ((compat->sym_interpret) && (compat->size_si > 0)) 106 free(compat->sym_interpret); 107 compat->size_si = compat->num_si = 0; 108 compat->sym_interpret = NULL; 109 } 110 if (freeMap) { 111 free(compat); 112 xkb->compat = NULL; 113 } 114 return; 115} 116 117/***===================================================================***/ 118 119Status 120XkbAllocNames(XkbDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases) 121{ 122 XkbNamesPtr names; 123 124 if (xkb == NULL) 125 return BadMatch; 126 if (xkb->names == NULL) { 127 xkb->names = calloc(1, sizeof(XkbNamesRec)); 128 if (xkb->names == NULL) 129 return BadAlloc; 130 } 131 names = xkb->names; 132 if ((which & XkbKTLevelNamesMask) && (xkb->map != NULL) && 133 (xkb->map->types != NULL)) { 134 register int i; 135 XkbKeyTypePtr type; 136 137 type = xkb->map->types; 138 for (i = 0; i < xkb->map->num_types; i++, type++) { 139 if (type->level_names == NULL) { 140 type->level_names = calloc(type->num_levels, sizeof(Atom)); 141 if (type->level_names == NULL) 142 return BadAlloc; 143 } 144 } 145 } 146 if ((which & XkbKeyNamesMask) && (names->keys == NULL)) { 147 if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 148 (!XkbIsLegalKeycode(xkb->max_key_code)) || 149 (xkb->max_key_code < xkb->min_key_code)) 150 return BadValue; 151 names->keys = calloc((xkb->max_key_code + 1), sizeof(XkbKeyNameRec)); 152 if (names->keys == NULL) 153 return BadAlloc; 154 } 155 if ((which & XkbKeyAliasesMask) && (nTotalAliases > 0)) { 156 if (names->key_aliases == NULL) { 157 names->key_aliases = calloc(nTotalAliases, sizeof(XkbKeyAliasRec)); 158 } 159 else if (nTotalAliases > names->num_key_aliases) { 160 XkbKeyAliasRec *prev_aliases = names->key_aliases; 161 162 names->key_aliases = reallocarray(names->key_aliases, 163 nTotalAliases, 164 sizeof(XkbKeyAliasRec)); 165 if (names->key_aliases != NULL) { 166 memset(&names->key_aliases[names->num_key_aliases], 0, 167 (nTotalAliases - 168 names->num_key_aliases) * sizeof(XkbKeyAliasRec)); 169 } 170 else { 171 free(prev_aliases); 172 } 173 } 174 if (names->key_aliases == NULL) { 175 names->num_key_aliases = 0; 176 return BadAlloc; 177 } 178 names->num_key_aliases = nTotalAliases; 179 } 180 if ((which & XkbRGNamesMask) && (nTotalRG > 0)) { 181 if (names->radio_groups == NULL) { 182 names->radio_groups = calloc(nTotalRG, sizeof(Atom)); 183 } 184 else if (nTotalRG > names->num_rg) { 185 Atom *prev_radio_groups = names->radio_groups; 186 187 names->radio_groups = reallocarray(names->radio_groups, 188 nTotalRG, sizeof(Atom)); 189 if (names->radio_groups != NULL) { 190 memset(&names->radio_groups[names->num_rg], 0, 191 (nTotalRG - names->num_rg) * sizeof(Atom)); 192 } 193 else { 194 free(prev_radio_groups); 195 } 196 } 197 if (names->radio_groups == NULL) 198 return BadAlloc; 199 names->num_rg = nTotalRG; 200 } 201 return Success; 202} 203 204void 205XkbFreeNames(XkbDescPtr xkb, unsigned which, Bool freeMap) 206{ 207 XkbNamesPtr names; 208 209 if ((xkb == NULL) || (xkb->names == NULL)) 210 return; 211 names = xkb->names; 212 if (freeMap) 213 which = XkbAllNamesMask; 214 if (which & XkbKTLevelNamesMask) { 215 XkbClientMapPtr map = xkb->map; 216 217 if ((map != NULL) && (map->types != NULL)) { 218 register int i; 219 register XkbKeyTypePtr type; 220 221 type = map->types; 222 for (i = 0; i < map->num_types; i++, type++) { 223 free(type->level_names); 224 type->level_names = NULL; 225 } 226 } 227 } 228 if ((which & XkbKeyNamesMask) && (names->keys != NULL)) { 229 free(names->keys); 230 names->keys = NULL; 231 names->num_keys = 0; 232 } 233 if ((which & XkbKeyAliasesMask) && (names->key_aliases)) { 234 free(names->key_aliases); 235 names->key_aliases = NULL; 236 names->num_key_aliases = 0; 237 } 238 if ((which & XkbRGNamesMask) && (names->radio_groups)) { 239 free(names->radio_groups); 240 names->radio_groups = NULL; 241 names->num_rg = 0; 242 } 243 if (freeMap) { 244 free(names); 245 xkb->names = NULL; 246 } 247 return; 248} 249 250/***===================================================================***/ 251 252 /*ARGSUSED*/ Status 253XkbAllocControls(XkbDescPtr xkb, unsigned which) 254{ 255 if (xkb == NULL) 256 return BadMatch; 257 258 if (xkb->ctrls == NULL) { 259 xkb->ctrls = calloc(1, sizeof(XkbControlsRec)); 260 if (!xkb->ctrls) 261 return BadAlloc; 262 } 263 return Success; 264} 265 266 /*ARGSUSED*/ static void 267XkbFreeControls(XkbDescPtr xkb, unsigned which, Bool freeMap) 268{ 269 if (freeMap && (xkb != NULL) && (xkb->ctrls != NULL)) { 270 free(xkb->ctrls); 271 xkb->ctrls = NULL; 272 } 273 return; 274} 275 276/***===================================================================***/ 277 278Status 279XkbAllocIndicatorMaps(XkbDescPtr xkb) 280{ 281 if (xkb == NULL) 282 return BadMatch; 283 if (xkb->indicators == NULL) { 284 xkb->indicators = calloc(1, sizeof(XkbIndicatorRec)); 285 if (!xkb->indicators) 286 return BadAlloc; 287 } 288 return Success; 289} 290 291static void 292XkbFreeIndicatorMaps(XkbDescPtr xkb) 293{ 294 if ((xkb != NULL) && (xkb->indicators != NULL)) { 295 free(xkb->indicators); 296 xkb->indicators = NULL; 297 } 298 return; 299} 300 301/***====================================================================***/ 302 303XkbDescRec * 304XkbAllocKeyboard(void) 305{ 306 XkbDescRec *xkb; 307 308 xkb = calloc(1, sizeof(XkbDescRec)); 309 if (xkb) 310 xkb->device_spec = XkbUseCoreKbd; 311 return xkb; 312} 313 314void 315XkbFreeKeyboard(XkbDescPtr xkb, unsigned which, Bool freeAll) 316{ 317 if (xkb == NULL) 318 return; 319 if (freeAll) 320 which = XkbAllComponentsMask; 321 if (which & XkbClientMapMask) 322 XkbFreeClientMap(xkb, XkbAllClientInfoMask, TRUE); 323 if (which & XkbServerMapMask) 324 XkbFreeServerMap(xkb, XkbAllServerInfoMask, TRUE); 325 if (which & XkbCompatMapMask) 326 XkbFreeCompatMap(xkb, XkbAllCompatMask, TRUE); 327 if (which & XkbIndicatorMapMask) 328 XkbFreeIndicatorMaps(xkb); 329 if (which & XkbNamesMask) 330 XkbFreeNames(xkb, XkbAllNamesMask, TRUE); 331 if ((which & XkbGeometryMask) && (xkb->geom != NULL)) { 332 XkbFreeGeometry(xkb->geom, XkbGeomAllMask, TRUE); 333 /* PERHAPS BONGHITS etc */ 334 xkb->geom = NULL; 335 } 336 if (which & XkbControlsMask) 337 XkbFreeControls(xkb, XkbAllControlsMask, TRUE); 338 if (freeAll) 339 free(xkb); 340 return; 341} 342 343/***====================================================================***/ 344 345void 346XkbFreeComponentNames(XkbComponentNamesPtr names, Bool freeNames) 347{ 348 if (names) { 349 free(names->keycodes); 350 free(names->types); 351 free(names->compat); 352 free(names->symbols); 353 free(names->geometry); 354 memset(names, 0, sizeof(XkbComponentNamesRec)); 355 } 356 if (freeNames) 357 free(names); 358} 359