XKBAlloc.c revision 0f8248bf
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_CONFIG_H 28#include <config.h> 29#endif 30 31 32#include <stdio.h> 33#include "Xlibint.h" 34#include "XKBlibint.h" 35#include <X11/extensions/XKBgeom.h> 36#include <X11/extensions/XKBproto.h> 37#include "XKBlibint.h" 38 39 40/***===================================================================***/ 41 42/*ARGSUSED*/ 43Status 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 = _XkbTypedRealloc(compat->sym_interpret, 60 nSI, XkbSymInterpretRec); 61 if (compat->sym_interpret == NULL) { 62 _XkbFree(prev_interpret); 63 compat->size_si = compat->num_si = 0; 64 return BadAlloc; 65 } 66 if (compat->num_si != 0) { 67 _XkbClearElems(compat->sym_interpret, compat->num_si, 68 compat->size_si - 1, XkbSymInterpretRec); 69 } 70 return Success; 71 } 72 compat = _XkbTypedCalloc(1, XkbCompatMapRec); 73 if (compat == NULL) 74 return BadAlloc; 75 if (nSI > 0) { 76 compat->sym_interpret = _XkbTypedCalloc(nSI, XkbSymInterpretRec); 77 if (!compat->sym_interpret) { 78 _XkbFree(compat); 79 return BadAlloc; 80 } 81 } 82 compat->size_si = nSI; 83 compat->num_si = 0; 84 bzero((char *) &compat->groups[0], XkbNumKbdGroups * sizeof(XkbModsRec)); 85 xkb->compat = compat; 86 return Success; 87} 88 89 90void 91XkbFreeCompatMap(XkbDescPtr xkb, unsigned which, Bool freeMap) 92{ 93 register XkbCompatMapPtr compat; 94 95 if ((xkb == NULL) || (xkb->compat == NULL)) 96 return; 97 compat = xkb->compat; 98 if (freeMap) 99 which = XkbAllCompatMask; 100 if (which & XkbGroupCompatMask) 101 bzero(&compat->groups[0], XkbNumKbdGroups * sizeof(XkbModsRec)); 102 if (which & XkbSymInterpMask) { 103 if ((compat->sym_interpret) && (compat->size_si > 0)) 104 _XkbFree(compat->sym_interpret); 105 compat->size_si = compat->num_si = 0; 106 compat->sym_interpret = NULL; 107 } 108 if (freeMap) { 109 _XkbFree(compat); 110 xkb->compat = NULL; 111 } 112 return; 113} 114 115/***===================================================================***/ 116 117Status 118XkbAllocNames(XkbDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases) 119{ 120 XkbNamesPtr names; 121 122 if (xkb == NULL) 123 return BadMatch; 124 if (xkb->names == NULL) { 125 xkb->names = _XkbTypedCalloc(1, XkbNamesRec); 126 if (xkb->names == NULL) 127 return BadAlloc; 128 } 129 names = xkb->names; 130 if ((which & XkbKTLevelNamesMask) && (xkb->map != NULL) && 131 (xkb->map->types != NULL)) { 132 register int i; 133 XkbKeyTypePtr type = xkb->map->types; 134 135 for (i = 0; i < xkb->map->num_types; i++, type++) { 136 if (type->level_names == NULL) { 137 type->level_names = _XkbTypedCalloc(type->num_levels, Atom); 138 if (type->level_names == NULL) 139 return BadAlloc; 140 } 141 } 142 } 143 if ((which & XkbKeyNamesMask) && (names->keys == NULL)) { 144 if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 145 (!XkbIsLegalKeycode(xkb->max_key_code)) || 146 (xkb->max_key_code < xkb->min_key_code)) 147 return BadValue; 148 names->keys = _XkbTypedCalloc((xkb->max_key_code + 1), XkbKeyNameRec); 149 if (names->keys == NULL) 150 return BadAlloc; 151 } 152 if ((which & XkbKeyAliasesMask) && (nTotalAliases > 0)) { 153 if (names->key_aliases == NULL) { 154 names->key_aliases = _XkbTypedCalloc(nTotalAliases, XkbKeyAliasRec); 155 } 156 else if (nTotalAliases > names->num_key_aliases) { 157 XkbKeyAliasRec *prev_aliases = names->key_aliases; 158 159 names->key_aliases = _XkbTypedRealloc(names->key_aliases, 160 nTotalAliases, 161 XkbKeyAliasRec); 162 if (names->key_aliases != NULL) { 163 _XkbClearElems(names->key_aliases, names->num_key_aliases, 164 nTotalAliases - 1, XkbKeyAliasRec); 165 } 166 else { 167 _XkbFree(prev_aliases); 168 } 169 } 170 if (names->key_aliases == NULL) { 171 names->num_key_aliases = 0; 172 return BadAlloc; 173 } 174 names->num_key_aliases = nTotalAliases; 175 } 176 if ((which & XkbRGNamesMask) && (nTotalRG > 0)) { 177 if (names->radio_groups == NULL) { 178 names->radio_groups = _XkbTypedCalloc(nTotalRG, Atom); 179 } 180 else if (nTotalRG > names->num_rg) { 181 Atom *prev_radio_groups = names->radio_groups; 182 183 names->radio_groups = 184 _XkbTypedRealloc(names->radio_groups, nTotalRG, Atom); 185 if (names->radio_groups != NULL) { 186 _XkbClearElems(names->radio_groups, names->num_rg, nTotalRG - 1, 187 Atom); 188 } 189 else { 190 _XkbFree(prev_radio_groups); 191 } 192 } 193 if (names->radio_groups == NULL) 194 return BadAlloc; 195 names->num_rg = nTotalRG; 196 } 197 return Success; 198} 199 200void 201XkbFreeNames(XkbDescPtr xkb, unsigned which, Bool freeMap) 202{ 203 XkbNamesPtr names; 204 205 if ((xkb == NULL) || (xkb->names == NULL)) 206 return; 207 names = xkb->names; 208 if (freeMap) 209 which = XkbAllNamesMask; 210 if (which & XkbKTLevelNamesMask) { 211 XkbClientMapPtr map = xkb->map; 212 213 if ((map != NULL) && (map->types != NULL)) { 214 register int i; 215 register XkbKeyTypePtr type; 216 217 type = map->types; 218 for (i = 0; i < map->num_types; i++, type++) { 219 if (type->level_names != NULL) { 220 _XkbFree(type->level_names); 221 type->level_names = NULL; 222 } 223 } 224 } 225 } 226 if ((which & XkbKeyNamesMask) && (names->keys != NULL)) { 227 _XkbFree(names->keys); 228 names->keys = NULL; 229 names->num_keys = 0; 230 } 231 if ((which & XkbKeyAliasesMask) && (names->key_aliases)) { 232 _XkbFree(names->key_aliases); 233 names->key_aliases = NULL; 234 names->num_key_aliases = 0; 235 } 236 if ((which & XkbRGNamesMask) && (names->radio_groups)) { 237 _XkbFree(names->radio_groups); 238 names->radio_groups = NULL; 239 names->num_rg = 0; 240 } 241 if (freeMap) { 242 _XkbFree(names); 243 xkb->names = NULL; 244 } 245 return; 246} 247 248/***===================================================================***/ 249 250/*ARGSUSED*/ 251Status 252XkbAllocControls(XkbDescPtr xkb, unsigned which) 253{ 254 if (xkb == NULL) 255 return BadMatch; 256 257 if (xkb->ctrls == NULL) { 258 xkb->ctrls = _XkbTypedCalloc(1, XkbControlsRec); 259 if (!xkb->ctrls) 260 return BadAlloc; 261 } 262 return Success; 263} 264 265/*ARGSUSED*/ 266void 267XkbFreeControls(XkbDescPtr xkb, unsigned which, Bool freeMap) 268{ 269 if (freeMap && (xkb != NULL) && (xkb->ctrls != NULL)) { 270 _XkbFree(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 = _XkbTypedCalloc(1, XkbIndicatorRec); 285 if (!xkb->indicators) 286 return BadAlloc; 287 } 288 return Success; 289} 290 291void 292XkbFreeIndicatorMaps(XkbDescPtr xkb) 293{ 294 if ((xkb != NULL) && (xkb->indicators != NULL)) { 295 _XkbFree(xkb->indicators); 296 xkb->indicators = NULL; 297 } 298 return; 299} 300 301/***====================================================================***/ 302 303XkbDescRec * 304XkbAllocKeyboard(void) 305{ 306 XkbDescRec *xkb; 307 308 xkb = _XkbTypedCalloc(1, 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 if (which & XkbControlsMask) 334 XkbFreeControls(xkb, XkbAllControlsMask, True); 335 if (freeAll) 336 _XkbFree(xkb); 337 return; 338} 339 340/***====================================================================***/ 341 342XkbDeviceLedInfoPtr 343XkbAddDeviceLedInfo(XkbDeviceInfoPtr devi, unsigned ledClass, unsigned ledId) 344{ 345 XkbDeviceLedInfoPtr devli; 346 register int i; 347 348 if ((!devi) || (!XkbSingleXIClass(ledClass)) || (!XkbSingleXIId(ledId))) 349 return NULL; 350 for (i = 0, devli = devi->leds; i < devi->num_leds; i++, devli++) { 351 if ((devli->led_class == ledClass) && (devli->led_id == ledId)) 352 return devli; 353 } 354 if (devi->num_leds >= devi->sz_leds) { 355 XkbDeviceLedInfoRec *prev_leds = devi->leds; 356 357 if (devi->sz_leds > 0) 358 devi->sz_leds *= 2; 359 else 360 devi->sz_leds = 1; 361 devi->leds = _XkbTypedRealloc(devi->leds, devi->sz_leds, 362 XkbDeviceLedInfoRec); 363 if (!devi->leds) { 364 _XkbFree(prev_leds); 365 devi->sz_leds = devi->num_leds = 0; 366 return NULL; 367 } 368 i = devi->num_leds; 369 for (devli = &devi->leds[i]; i < devi->sz_leds; i++, devli++) { 370 bzero(devli, sizeof(XkbDeviceLedInfoRec)); 371 devli->led_class = XkbXINone; 372 devli->led_id = XkbXINone; 373 } 374 } 375 devli = &devi->leds[devi->num_leds++]; 376 bzero(devli, sizeof(XkbDeviceLedInfoRec)); 377 devli->led_class = ledClass; 378 devli->led_id = ledId; 379 return devli; 380} 381 382Status 383XkbResizeDeviceButtonActions(XkbDeviceInfoPtr devi, unsigned newTotal) 384{ 385 XkbAction *prev_btn_acts; 386 387 if ((!devi) || (newTotal > 255)) 388 return BadValue; 389 if ((devi->btn_acts != NULL) && (newTotal == devi->num_btns)) 390 return Success; 391 if (newTotal == 0) { 392 if (devi->btn_acts != NULL) { 393 _XkbFree(devi->btn_acts); 394 devi->btn_acts = NULL; 395 } 396 devi->num_btns = 0; 397 return Success; 398 } 399 prev_btn_acts = devi->btn_acts; 400 devi->btn_acts = _XkbTypedRealloc(devi->btn_acts, newTotal, XkbAction); 401 if (devi->btn_acts == NULL) { 402 _XkbFree(prev_btn_acts); 403 devi->num_btns = 0; 404 return BadAlloc; 405 } 406 if (newTotal > devi->num_btns) { 407 XkbAction *act; 408 409 act = &devi->btn_acts[devi->num_btns]; 410 bzero((char *) act, (newTotal - devi->num_btns) * sizeof(XkbAction)); 411 } 412 devi->num_btns = newTotal; 413 return Success; 414} 415 416/*ARGSUSED*/ 417XkbDeviceInfoPtr 418XkbAllocDeviceInfo(unsigned deviceSpec, unsigned nButtons, unsigned szLeds) 419{ 420 XkbDeviceInfoPtr devi; 421 422 devi = _XkbTypedCalloc(1, XkbDeviceInfoRec); 423 if (devi != NULL) { 424 devi->device_spec = deviceSpec; 425 devi->has_own_state = False; 426 devi->num_btns = 0; 427 devi->btn_acts = NULL; 428 if (nButtons > 0) { 429 devi->num_btns = nButtons; 430 devi->btn_acts = _XkbTypedCalloc(nButtons, XkbAction); 431 if (!devi->btn_acts) { 432 _XkbFree(devi); 433 return NULL; 434 } 435 } 436 devi->dflt_kbd_fb = XkbXINone; 437 devi->dflt_led_fb = XkbXINone; 438 devi->num_leds = 0; 439 devi->sz_leds = 0; 440 devi->leds = NULL; 441 if (szLeds > 0) { 442 devi->sz_leds = szLeds; 443 devi->leds = _XkbTypedCalloc(szLeds, XkbDeviceLedInfoRec); 444 if (!devi->leds) { 445 _XkbFree(devi->btn_acts); 446 _XkbFree(devi); 447 return NULL; 448 } 449 } 450 } 451 return devi; 452} 453 454 455void 456XkbFreeDeviceInfo(XkbDeviceInfoPtr devi, unsigned which, Bool freeDevI) 457{ 458 if (devi) { 459 if (freeDevI) { 460 which = XkbXI_AllDeviceFeaturesMask; 461 if (devi->name) { 462 _XkbFree(devi->name); 463 devi->name = NULL; 464 } 465 } 466 if ((which & XkbXI_ButtonActionsMask) && (devi->btn_acts)) { 467 _XkbFree(devi->btn_acts); 468 devi->num_btns = 0; 469 devi->btn_acts = NULL; 470 } 471 if ((which & XkbXI_IndicatorsMask) && (devi->leds)) { 472 register int i; 473 474 if ((which & XkbXI_IndicatorsMask) == XkbXI_IndicatorsMask) { 475 _XkbFree(devi->leds); 476 devi->sz_leds = devi->num_leds = 0; 477 devi->leds = NULL; 478 } 479 else { 480 XkbDeviceLedInfoPtr devli; 481 482 for (i = 0, devli = devi->leds; i < devi->num_leds; 483 i++, devli++) { 484 if (which & XkbXI_IndicatorMapsMask) 485 bzero((char *) &devli->maps[0], sizeof(devli->maps)); 486 else 487 bzero((char *) &devli->names[0], sizeof(devli->names)); 488 } 489 } 490 } 491 if (freeDevI) 492 _XkbFree(devi); 493 } 494 return; 495} 496