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