XKBAlloc.c revision 5afda2e6
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 48 if (!xkb) 49 return BadMatch; 50 if (xkb->compat) { 51 if (xkb->compat->size_si >= nSI) 52 return Success; 53 compat = xkb->compat; 54 compat->size_si = nSI; 55 if (compat->sym_interpret == NULL) 56 compat->num_si = 0; 57 _XkbResizeArray(compat->sym_interpret, compat->num_si, 58 nSI, XkbSymInterpretRec); 59 if (compat->sym_interpret == NULL) { 60 compat->size_si = compat->num_si = 0; 61 return BadAlloc; 62 } 63 return Success; 64 } 65 compat = _XkbTypedCalloc(1, XkbCompatMapRec); 66 if (compat == NULL) 67 return BadAlloc; 68 if (nSI > 0) { 69 compat->sym_interpret = _XkbTypedCalloc(nSI, XkbSymInterpretRec); 70 if (!compat->sym_interpret) { 71 _XkbFree(compat); 72 return BadAlloc; 73 } 74 } 75 compat->size_si = nSI; 76 compat->num_si = 0; 77 bzero((char *) &compat->groups[0], XkbNumKbdGroups * sizeof(XkbModsRec)); 78 xkb->compat = compat; 79 return Success; 80} 81 82 83void 84XkbFreeCompatMap(XkbDescPtr xkb, unsigned which, Bool freeMap) 85{ 86 register XkbCompatMapPtr compat; 87 88 if ((xkb == NULL) || (xkb->compat == NULL)) 89 return; 90 compat = xkb->compat; 91 if (freeMap) 92 which = XkbAllCompatMask; 93 if (which & XkbGroupCompatMask) 94 bzero(&compat->groups[0], XkbNumKbdGroups * sizeof(XkbModsRec)); 95 if (which & XkbSymInterpMask) { 96 if ((compat->sym_interpret) && (compat->size_si > 0)) 97 _XkbFree(compat->sym_interpret); 98 compat->size_si = compat->num_si = 0; 99 compat->sym_interpret = NULL; 100 } 101 if (freeMap) { 102 _XkbFree(compat); 103 xkb->compat = NULL; 104 } 105 return; 106} 107 108/***===================================================================***/ 109 110Status 111XkbAllocNames(XkbDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases) 112{ 113 XkbNamesPtr names; 114 115 if (xkb == NULL) 116 return BadMatch; 117 if (xkb->names == NULL) { 118 xkb->names = _XkbTypedCalloc(1, XkbNamesRec); 119 if (xkb->names == NULL) 120 return BadAlloc; 121 } 122 names = xkb->names; 123 if ((which & XkbKTLevelNamesMask) && (xkb->map != NULL) && 124 (xkb->map->types != NULL)) { 125 register int i; 126 XkbKeyTypePtr type = xkb->map->types; 127 128 for (i = 0; i < xkb->map->num_types; i++, type++) { 129 if (type->level_names == NULL) { 130 type->level_names = _XkbTypedCalloc(type->num_levels, Atom); 131 if (type->level_names == NULL) 132 return BadAlloc; 133 } 134 } 135 } 136 if ((which & XkbKeyNamesMask) && (names->keys == NULL)) { 137 if ((!XkbIsLegalKeycode(xkb->min_key_code)) || 138 (!XkbIsLegalKeycode(xkb->max_key_code)) || 139 (xkb->max_key_code < xkb->min_key_code)) 140 return BadValue; 141 names->keys = _XkbTypedCalloc((xkb->max_key_code + 1), XkbKeyNameRec); 142 if (names->keys == NULL) 143 return BadAlloc; 144 } 145 if ((which & XkbKeyAliasesMask) && (nTotalAliases > 0)) { 146 if ((names->key_aliases == NULL) || 147 (nTotalAliases > names->num_key_aliases)) { 148 _XkbResizeArray(names->key_aliases, names->num_key_aliases, 149 nTotalAliases, XkbKeyAliasRec); 150 } 151 if (names->key_aliases == NULL) { 152 names->num_key_aliases = 0; 153 return BadAlloc; 154 } 155 names->num_key_aliases = nTotalAliases; 156 } 157 if ((which & XkbRGNamesMask) && (nTotalRG > 0)) { 158 if ((names->radio_groups == NULL) || (nTotalRG > names->num_rg)) { 159 _XkbResizeArray(names->radio_groups, names->num_rg, nTotalRG, Atom); 160 } 161 if (names->radio_groups == NULL) { 162 names->num_rg = 0; 163 return BadAlloc; 164 } 165 names->num_rg = nTotalRG; 166 } 167 return Success; 168} 169 170void 171XkbFreeNames(XkbDescPtr xkb, unsigned which, Bool freeMap) 172{ 173 XkbNamesPtr names; 174 175 if ((xkb == NULL) || (xkb->names == NULL)) 176 return; 177 names = xkb->names; 178 if (freeMap) 179 which = XkbAllNamesMask; 180 if (which & XkbKTLevelNamesMask) { 181 XkbClientMapPtr map = xkb->map; 182 183 if ((map != NULL) && (map->types != NULL)) { 184 register int i; 185 register XkbKeyTypePtr type; 186 187 type = map->types; 188 for (i = 0; i < map->num_types; i++, type++) { 189 _XkbFree(type->level_names); 190 type->level_names = NULL; 191 } 192 } 193 } 194 if (which & XkbKeyNamesMask) { 195 _XkbFree(names->keys); 196 names->keys = NULL; 197 names->num_keys = 0; 198 } 199 if (which & XkbKeyAliasesMask) { 200 _XkbFree(names->key_aliases); 201 names->key_aliases = NULL; 202 names->num_key_aliases = 0; 203 } 204 if (which & XkbRGNamesMask) { 205 _XkbFree(names->radio_groups); 206 names->radio_groups = NULL; 207 names->num_rg = 0; 208 } 209 if (freeMap) { 210 _XkbFree(names); 211 xkb->names = NULL; 212 } 213 return; 214} 215 216/***===================================================================***/ 217 218/*ARGSUSED*/ 219Status 220XkbAllocControls(XkbDescPtr xkb, unsigned which) 221{ 222 if (xkb == NULL) 223 return BadMatch; 224 225 if (xkb->ctrls == NULL) { 226 xkb->ctrls = _XkbTypedCalloc(1, XkbControlsRec); 227 if (!xkb->ctrls) 228 return BadAlloc; 229 } 230 return Success; 231} 232 233/*ARGSUSED*/ 234void 235XkbFreeControls(XkbDescPtr xkb, unsigned which, Bool freeMap) 236{ 237 if (freeMap && (xkb != NULL) && (xkb->ctrls != NULL)) { 238 _XkbFree(xkb->ctrls); 239 xkb->ctrls = NULL; 240 } 241 return; 242} 243 244/***===================================================================***/ 245 246Status 247XkbAllocIndicatorMaps(XkbDescPtr xkb) 248{ 249 if (xkb == NULL) 250 return BadMatch; 251 if (xkb->indicators == NULL) { 252 xkb->indicators = _XkbTypedCalloc(1, XkbIndicatorRec); 253 if (!xkb->indicators) 254 return BadAlloc; 255 } 256 return Success; 257} 258 259void 260XkbFreeIndicatorMaps(XkbDescPtr xkb) 261{ 262 if ((xkb != NULL) && (xkb->indicators != NULL)) { 263 _XkbFree(xkb->indicators); 264 xkb->indicators = NULL; 265 } 266 return; 267} 268 269/***====================================================================***/ 270 271XkbDescRec * 272XkbAllocKeyboard(void) 273{ 274 XkbDescRec *xkb; 275 276 xkb = _XkbTypedCalloc(1, XkbDescRec); 277 if (xkb) 278 xkb->device_spec = XkbUseCoreKbd; 279 return xkb; 280} 281 282void 283XkbFreeKeyboard(XkbDescPtr xkb, unsigned which, Bool freeAll) 284{ 285 if (xkb == NULL) 286 return; 287 if (freeAll) 288 which = XkbAllComponentsMask; 289 if (which & XkbClientMapMask) 290 XkbFreeClientMap(xkb, XkbAllClientInfoMask, True); 291 if (which & XkbServerMapMask) 292 XkbFreeServerMap(xkb, XkbAllServerInfoMask, True); 293 if (which & XkbCompatMapMask) 294 XkbFreeCompatMap(xkb, XkbAllCompatMask, True); 295 if (which & XkbIndicatorMapMask) 296 XkbFreeIndicatorMaps(xkb); 297 if (which & XkbNamesMask) 298 XkbFreeNames(xkb, XkbAllNamesMask, True); 299 if ((which & XkbGeometryMask) && (xkb->geom != NULL)) 300 XkbFreeGeometry(xkb->geom, XkbGeomAllMask, True); 301 if (which & XkbControlsMask) 302 XkbFreeControls(xkb, XkbAllControlsMask, True); 303 if (freeAll) 304 _XkbFree(xkb); 305 return; 306} 307 308/***====================================================================***/ 309 310XkbDeviceLedInfoPtr 311XkbAddDeviceLedInfo(XkbDeviceInfoPtr devi, unsigned ledClass, unsigned ledId) 312{ 313 XkbDeviceLedInfoPtr devli; 314 register int i; 315 316 if ((!devi) || (!XkbSingleXIClass(ledClass)) || (!XkbSingleXIId(ledId))) 317 return NULL; 318 for (i = 0, devli = devi->leds; i < devi->num_leds; i++, devli++) { 319 if ((devli->led_class == ledClass) && (devli->led_id == ledId)) 320 return devli; 321 } 322 if (devi->num_leds >= devi->sz_leds) { 323 if (devi->sz_leds > 0) 324 devi->sz_leds *= 2; 325 else 326 devi->sz_leds = 1; 327 _XkbResizeArray(devi->leds, devi->num_leds, devi->sz_leds, 328 XkbDeviceLedInfoRec); 329 if (!devi->leds) { 330 devi->sz_leds = devi->num_leds = 0; 331 return NULL; 332 } 333 i = devi->num_leds; 334 for (devli = &devi->leds[i]; i < devi->sz_leds; i++, devli++) { 335 bzero(devli, sizeof(XkbDeviceLedInfoRec)); 336 devli->led_class = XkbXINone; 337 devli->led_id = XkbXINone; 338 } 339 } 340 devli = &devi->leds[devi->num_leds++]; 341 bzero(devli, sizeof(XkbDeviceLedInfoRec)); 342 devli->led_class = ledClass; 343 devli->led_id = ledId; 344 return devli; 345} 346 347Status 348XkbResizeDeviceButtonActions(XkbDeviceInfoPtr devi, unsigned newTotal) 349{ 350 if ((!devi) || (newTotal > 255)) 351 return BadValue; 352 if ((devi->btn_acts != NULL) && (newTotal == devi->num_btns)) 353 return Success; 354 if (newTotal == 0) { 355 if (devi->btn_acts != NULL) { 356 _XkbFree(devi->btn_acts); 357 devi->btn_acts = NULL; 358 } 359 devi->num_btns = 0; 360 return Success; 361 } 362 _XkbResizeArray(devi->btn_acts, devi->num_btns, newTotal, XkbAction); 363 if (devi->btn_acts == NULL) { 364 devi->num_btns = 0; 365 return BadAlloc; 366 } 367 if (newTotal > devi->num_btns) { 368 XkbAction *act; 369 370 act = &devi->btn_acts[devi->num_btns]; 371 bzero((char *) act, (newTotal - devi->num_btns) * sizeof(XkbAction)); 372 } 373 devi->num_btns = newTotal; 374 return Success; 375} 376 377/*ARGSUSED*/ 378XkbDeviceInfoPtr 379XkbAllocDeviceInfo(unsigned deviceSpec, unsigned nButtons, unsigned szLeds) 380{ 381 XkbDeviceInfoPtr devi; 382 383 devi = _XkbTypedCalloc(1, XkbDeviceInfoRec); 384 if (devi != NULL) { 385 devi->device_spec = deviceSpec; 386 devi->has_own_state = False; 387 devi->num_btns = 0; 388 devi->btn_acts = NULL; 389 if (nButtons > 0) { 390 devi->num_btns = nButtons; 391 devi->btn_acts = _XkbTypedCalloc(nButtons, XkbAction); 392 if (!devi->btn_acts) { 393 _XkbFree(devi); 394 return NULL; 395 } 396 } 397 devi->dflt_kbd_fb = XkbXINone; 398 devi->dflt_led_fb = XkbXINone; 399 devi->num_leds = 0; 400 devi->sz_leds = 0; 401 devi->leds = NULL; 402 if (szLeds > 0) { 403 devi->sz_leds = szLeds; 404 devi->leds = _XkbTypedCalloc(szLeds, XkbDeviceLedInfoRec); 405 if (!devi->leds) { 406 _XkbFree(devi->btn_acts); 407 _XkbFree(devi); 408 return NULL; 409 } 410 } 411 } 412 return devi; 413} 414 415 416void 417XkbFreeDeviceInfo(XkbDeviceInfoPtr devi, unsigned which, Bool freeDevI) 418{ 419 if (devi) { 420 if (freeDevI) { 421 which = XkbXI_AllDeviceFeaturesMask; 422 if (devi->name) { 423 _XkbFree(devi->name); 424 devi->name = NULL; 425 } 426 } 427 if ((which & XkbXI_ButtonActionsMask) && (devi->btn_acts)) { 428 _XkbFree(devi->btn_acts); 429 devi->num_btns = 0; 430 devi->btn_acts = NULL; 431 } 432 if ((which & XkbXI_IndicatorsMask) && (devi->leds)) { 433 register int i; 434 435 if ((which & XkbXI_IndicatorsMask) == XkbXI_IndicatorsMask) { 436 _XkbFree(devi->leds); 437 devi->sz_leds = devi->num_leds = 0; 438 devi->leds = NULL; 439 } 440 else { 441 XkbDeviceLedInfoPtr devli; 442 443 for (i = 0, devli = devi->leds; i < devi->num_leds; 444 i++, devli++) { 445 if (which & XkbXI_IndicatorMapsMask) 446 bzero((char *) &devli->maps[0], sizeof(devli->maps)); 447 else 448 bzero((char *) &devli->names[0], sizeof(devli->names)); 449 } 450 } 451 } 452 if (freeDevI) 453 _XkbFree(devi); 454 } 455 return; 456} 457