XKBAlloc.c revision 3233502e
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 _XkbFree(type->level_names); 220 type->level_names = NULL; 221 } 222 } 223 } 224 if (which & XkbKeyNamesMask) { 225 _XkbFree(names->keys); 226 names->keys = NULL; 227 names->num_keys = 0; 228 } 229 if (which & XkbKeyAliasesMask) { 230 _XkbFree(names->key_aliases); 231 names->key_aliases = NULL; 232 names->num_key_aliases = 0; 233 } 234 if (which & XkbRGNamesMask) { 235 _XkbFree(names->radio_groups); 236 names->radio_groups = NULL; 237 names->num_rg = 0; 238 } 239 if (freeMap) { 240 _XkbFree(names); 241 xkb->names = NULL; 242 } 243 return; 244} 245 246/***===================================================================***/ 247 248/*ARGSUSED*/ 249Status 250XkbAllocControls(XkbDescPtr xkb, unsigned which) 251{ 252 if (xkb == NULL) 253 return BadMatch; 254 255 if (xkb->ctrls == NULL) { 256 xkb->ctrls = _XkbTypedCalloc(1, XkbControlsRec); 257 if (!xkb->ctrls) 258 return BadAlloc; 259 } 260 return Success; 261} 262 263/*ARGSUSED*/ 264void 265XkbFreeControls(XkbDescPtr xkb, unsigned which, Bool freeMap) 266{ 267 if (freeMap && (xkb != NULL) && (xkb->ctrls != NULL)) { 268 _XkbFree(xkb->ctrls); 269 xkb->ctrls = NULL; 270 } 271 return; 272} 273 274/***===================================================================***/ 275 276Status 277XkbAllocIndicatorMaps(XkbDescPtr xkb) 278{ 279 if (xkb == NULL) 280 return BadMatch; 281 if (xkb->indicators == NULL) { 282 xkb->indicators = _XkbTypedCalloc(1, XkbIndicatorRec); 283 if (!xkb->indicators) 284 return BadAlloc; 285 } 286 return Success; 287} 288 289void 290XkbFreeIndicatorMaps(XkbDescPtr xkb) 291{ 292 if ((xkb != NULL) && (xkb->indicators != NULL)) { 293 _XkbFree(xkb->indicators); 294 xkb->indicators = NULL; 295 } 296 return; 297} 298 299/***====================================================================***/ 300 301XkbDescRec * 302XkbAllocKeyboard(void) 303{ 304 XkbDescRec *xkb; 305 306 xkb = _XkbTypedCalloc(1, XkbDescRec); 307 if (xkb) 308 xkb->device_spec = XkbUseCoreKbd; 309 return xkb; 310} 311 312void 313XkbFreeKeyboard(XkbDescPtr xkb, unsigned which, Bool freeAll) 314{ 315 if (xkb == NULL) 316 return; 317 if (freeAll) 318 which = XkbAllComponentsMask; 319 if (which & XkbClientMapMask) 320 XkbFreeClientMap(xkb, XkbAllClientInfoMask, True); 321 if (which & XkbServerMapMask) 322 XkbFreeServerMap(xkb, XkbAllServerInfoMask, True); 323 if (which & XkbCompatMapMask) 324 XkbFreeCompatMap(xkb, XkbAllCompatMask, True); 325 if (which & XkbIndicatorMapMask) 326 XkbFreeIndicatorMaps(xkb); 327 if (which & XkbNamesMask) 328 XkbFreeNames(xkb, XkbAllNamesMask, True); 329 if ((which & XkbGeometryMask) && (xkb->geom != NULL)) 330 XkbFreeGeometry(xkb->geom, XkbGeomAllMask, True); 331 if (which & XkbControlsMask) 332 XkbFreeControls(xkb, XkbAllControlsMask, True); 333 if (freeAll) 334 _XkbFree(xkb); 335 return; 336} 337 338/***====================================================================***/ 339 340XkbDeviceLedInfoPtr 341XkbAddDeviceLedInfo(XkbDeviceInfoPtr devi, unsigned ledClass, unsigned ledId) 342{ 343 XkbDeviceLedInfoPtr devli; 344 register int i; 345 346 if ((!devi) || (!XkbSingleXIClass(ledClass)) || (!XkbSingleXIId(ledId))) 347 return NULL; 348 for (i = 0, devli = devi->leds; i < devi->num_leds; i++, devli++) { 349 if ((devli->led_class == ledClass) && (devli->led_id == ledId)) 350 return devli; 351 } 352 if (devi->num_leds >= devi->sz_leds) { 353 XkbDeviceLedInfoRec *prev_leds = devi->leds; 354 355 if (devi->sz_leds > 0) 356 devi->sz_leds *= 2; 357 else 358 devi->sz_leds = 1; 359 devi->leds = _XkbTypedRealloc(devi->leds, devi->sz_leds, 360 XkbDeviceLedInfoRec); 361 if (!devi->leds) { 362 _XkbFree(prev_leds); 363 devi->sz_leds = devi->num_leds = 0; 364 return NULL; 365 } 366 i = devi->num_leds; 367 for (devli = &devi->leds[i]; i < devi->sz_leds; i++, devli++) { 368 bzero(devli, sizeof(XkbDeviceLedInfoRec)); 369 devli->led_class = XkbXINone; 370 devli->led_id = XkbXINone; 371 } 372 } 373 devli = &devi->leds[devi->num_leds++]; 374 bzero(devli, sizeof(XkbDeviceLedInfoRec)); 375 devli->led_class = ledClass; 376 devli->led_id = ledId; 377 return devli; 378} 379 380Status 381XkbResizeDeviceButtonActions(XkbDeviceInfoPtr devi, unsigned newTotal) 382{ 383 XkbAction *prev_btn_acts; 384 385 if ((!devi) || (newTotal > 255)) 386 return BadValue; 387 if ((devi->btn_acts != NULL) && (newTotal == devi->num_btns)) 388 return Success; 389 if (newTotal == 0) { 390 if (devi->btn_acts != NULL) { 391 _XkbFree(devi->btn_acts); 392 devi->btn_acts = NULL; 393 } 394 devi->num_btns = 0; 395 return Success; 396 } 397 prev_btn_acts = devi->btn_acts; 398 devi->btn_acts = _XkbTypedRealloc(devi->btn_acts, newTotal, XkbAction); 399 if (devi->btn_acts == NULL) { 400 _XkbFree(prev_btn_acts); 401 devi->num_btns = 0; 402 return BadAlloc; 403 } 404 if (newTotal > devi->num_btns) { 405 XkbAction *act; 406 407 act = &devi->btn_acts[devi->num_btns]; 408 bzero((char *) act, (newTotal - devi->num_btns) * sizeof(XkbAction)); 409 } 410 devi->num_btns = newTotal; 411 return Success; 412} 413 414/*ARGSUSED*/ 415XkbDeviceInfoPtr 416XkbAllocDeviceInfo(unsigned deviceSpec, unsigned nButtons, unsigned szLeds) 417{ 418 XkbDeviceInfoPtr devi; 419 420 devi = _XkbTypedCalloc(1, XkbDeviceInfoRec); 421 if (devi != NULL) { 422 devi->device_spec = deviceSpec; 423 devi->has_own_state = False; 424 devi->num_btns = 0; 425 devi->btn_acts = NULL; 426 if (nButtons > 0) { 427 devi->num_btns = nButtons; 428 devi->btn_acts = _XkbTypedCalloc(nButtons, XkbAction); 429 if (!devi->btn_acts) { 430 _XkbFree(devi); 431 return NULL; 432 } 433 } 434 devi->dflt_kbd_fb = XkbXINone; 435 devi->dflt_led_fb = XkbXINone; 436 devi->num_leds = 0; 437 devi->sz_leds = 0; 438 devi->leds = NULL; 439 if (szLeds > 0) { 440 devi->sz_leds = szLeds; 441 devi->leds = _XkbTypedCalloc(szLeds, XkbDeviceLedInfoRec); 442 if (!devi->leds) { 443 _XkbFree(devi->btn_acts); 444 _XkbFree(devi); 445 return NULL; 446 } 447 } 448 } 449 return devi; 450} 451 452 453void 454XkbFreeDeviceInfo(XkbDeviceInfoPtr devi, unsigned which, Bool freeDevI) 455{ 456 if (devi) { 457 if (freeDevI) { 458 which = XkbXI_AllDeviceFeaturesMask; 459 if (devi->name) { 460 _XkbFree(devi->name); 461 devi->name = NULL; 462 } 463 } 464 if ((which & XkbXI_ButtonActionsMask) && (devi->btn_acts)) { 465 _XkbFree(devi->btn_acts); 466 devi->num_btns = 0; 467 devi->btn_acts = NULL; 468 } 469 if ((which & XkbXI_IndicatorsMask) && (devi->leds)) { 470 register int i; 471 472 if ((which & XkbXI_IndicatorsMask) == XkbXI_IndicatorsMask) { 473 _XkbFree(devi->leds); 474 devi->sz_leds = devi->num_leds = 0; 475 devi->leds = NULL; 476 } 477 else { 478 XkbDeviceLedInfoPtr devli; 479 480 for (i = 0, devli = devi->leds; i < devi->num_leds; 481 i++, devli++) { 482 if (which & XkbXI_IndicatorMapsMask) 483 bzero((char *) &devli->maps[0], sizeof(devli->maps)); 484 else 485 bzero((char *) &devli->names[0], sizeof(devli->names)); 486 } 487 } 488 } 489 if (freeDevI) 490 _XkbFree(devi); 491 } 492 return; 493} 494