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