XKBAlloc.c revision 07fb9b8f
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 xkb->geom = NULL; 302 } 303 if (which & XkbControlsMask) 304 XkbFreeControls(xkb, XkbAllControlsMask, True); 305 if (freeAll) 306 _XkbFree(xkb); 307 return; 308} 309 310/***====================================================================***/ 311 312XkbDeviceLedInfoPtr 313XkbAddDeviceLedInfo(XkbDeviceInfoPtr devi, unsigned ledClass, unsigned ledId) 314{ 315 XkbDeviceLedInfoPtr devli; 316 register int i; 317 318 if ((!devi) || (!XkbSingleXIClass(ledClass)) || (!XkbSingleXIId(ledId))) 319 return NULL; 320 for (i = 0, devli = devi->leds; i < devi->num_leds; i++, devli++) { 321 if ((devli->led_class == ledClass) && (devli->led_id == ledId)) 322 return devli; 323 } 324 if (devi->num_leds >= devi->sz_leds) { 325 if (devi->sz_leds > 0) 326 devi->sz_leds *= 2; 327 else 328 devi->sz_leds = 1; 329 _XkbResizeArray(devi->leds, devi->num_leds, devi->sz_leds, 330 XkbDeviceLedInfoRec); 331 if (!devi->leds) { 332 devi->sz_leds = devi->num_leds = 0; 333 return NULL; 334 } 335 i = devi->num_leds; 336 for (devli = &devi->leds[i]; i < devi->sz_leds; i++, devli++) { 337 bzero(devli, sizeof(XkbDeviceLedInfoRec)); 338 devli->led_class = XkbXINone; 339 devli->led_id = XkbXINone; 340 } 341 } 342 devli = &devi->leds[devi->num_leds++]; 343 bzero(devli, sizeof(XkbDeviceLedInfoRec)); 344 devli->led_class = ledClass; 345 devli->led_id = ledId; 346 return devli; 347} 348 349Status 350XkbResizeDeviceButtonActions(XkbDeviceInfoPtr devi, unsigned newTotal) 351{ 352 if ((!devi) || (newTotal > 255)) 353 return BadValue; 354 if ((devi->btn_acts != NULL) && (newTotal == devi->num_btns)) 355 return Success; 356 if (newTotal == 0) { 357 if (devi->btn_acts != NULL) { 358 _XkbFree(devi->btn_acts); 359 devi->btn_acts = NULL; 360 } 361 devi->num_btns = 0; 362 return Success; 363 } 364 _XkbResizeArray(devi->btn_acts, devi->num_btns, newTotal, XkbAction); 365 if (devi->btn_acts == NULL) { 366 devi->num_btns = 0; 367 return BadAlloc; 368 } 369 if (newTotal > devi->num_btns) { 370 XkbAction *act; 371 372 act = &devi->btn_acts[devi->num_btns]; 373 bzero((char *) act, (newTotal - devi->num_btns) * sizeof(XkbAction)); 374 } 375 devi->num_btns = newTotal; 376 return Success; 377} 378 379/*ARGSUSED*/ 380XkbDeviceInfoPtr 381XkbAllocDeviceInfo(unsigned deviceSpec, unsigned nButtons, unsigned szLeds) 382{ 383 XkbDeviceInfoPtr devi; 384 385 devi = _XkbTypedCalloc(1, XkbDeviceInfoRec); 386 if (devi != NULL) { 387 devi->device_spec = deviceSpec; 388 devi->has_own_state = False; 389 devi->num_btns = 0; 390 devi->btn_acts = NULL; 391 if (nButtons > 0) { 392 devi->num_btns = nButtons; 393 devi->btn_acts = _XkbTypedCalloc(nButtons, XkbAction); 394 if (!devi->btn_acts) { 395 _XkbFree(devi); 396 return NULL; 397 } 398 } 399 devi->dflt_kbd_fb = XkbXINone; 400 devi->dflt_led_fb = XkbXINone; 401 devi->num_leds = 0; 402 devi->sz_leds = 0; 403 devi->leds = NULL; 404 if (szLeds > 0) { 405 devi->sz_leds = szLeds; 406 devi->leds = _XkbTypedCalloc(szLeds, XkbDeviceLedInfoRec); 407 if (!devi->leds) { 408 _XkbFree(devi->btn_acts); 409 _XkbFree(devi); 410 return NULL; 411 } 412 } 413 } 414 return devi; 415} 416 417 418void 419XkbFreeDeviceInfo(XkbDeviceInfoPtr devi, unsigned which, Bool freeDevI) 420{ 421 if (devi) { 422 if (freeDevI) { 423 which = XkbXI_AllDeviceFeaturesMask; 424 if (devi->name) { 425 _XkbFree(devi->name); 426 devi->name = NULL; 427 } 428 } 429 if ((which & XkbXI_ButtonActionsMask) && (devi->btn_acts)) { 430 _XkbFree(devi->btn_acts); 431 devi->num_btns = 0; 432 devi->btn_acts = NULL; 433 } 434 if ((which & XkbXI_IndicatorsMask) && (devi->leds)) { 435 register int i; 436 437 if ((which & XkbXI_IndicatorsMask) == XkbXI_IndicatorsMask) { 438 _XkbFree(devi->leds); 439 devi->sz_leds = devi->num_leds = 0; 440 devi->leds = NULL; 441 } 442 else { 443 XkbDeviceLedInfoPtr devli; 444 445 for (i = 0, devli = devi->leds; i < devi->num_leds; 446 i++, devli++) { 447 if (which & XkbXI_IndicatorMapsMask) 448 bzero((char *) &devli->maps[0], sizeof(devli->maps)); 449 else 450 bzero((char *) &devli->names[0], sizeof(devli->names)); 451 } 452 } 453 } 454 if (freeDevI) 455 _XkbFree(devi); 456 } 457 return; 458} 459