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