XKBAlloc.c revision 61b2299d
1/* $Xorg: XKBAlloc.c,v 1.4 2000/08/17 19:44:59 cpqbld Exp $ */ 2/************************************************************ 3Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 4 5Permission to use, copy, modify, and distribute this 6software and its documentation for any purpose and without 7fee is hereby granted, provided that the above copyright 8notice appear in all copies and that both that copyright 9notice and this permission notice appear in supporting 10documentation, and that the name of Silicon Graphics not be 11used in advertising or publicity pertaining to distribution 12of the software without specific prior written permission. 13Silicon Graphics makes no representation about the suitability 14of this software for any purpose. It is provided "as is" 15without any express or implied warranty. 16 17SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 18SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 20GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 21DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 22DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 23OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 24THE USE OR PERFORMANCE OF THIS SOFTWARE. 25 26********************************************************/ 27/* $XFree86: xc/lib/X11/XKBAlloc.c,v 3.5 2001/01/17 19:41:48 dawes Exp $ */ 28 29#ifdef HAVE_DIX_CONFIG_H 30#include <dix-config.h> 31#elif defined(HAVE_CONFIG_H) 32#include <config.h> 33#endif 34 35#ifndef XKB_IN_SERVER 36 37#include <stdio.h> 38#define NEED_REPLIES 39#define NEED_EVENTS 40#include "Xlibint.h" 41#include "XKBlibint.h" 42#include <X11/extensions/XKBgeom.h> 43#include <X11/extensions/XKBproto.h> 44#include "XKBlibint.h" 45 46#else 47 48#include <stdio.h> 49#include <X11/X.h> 50#define NEED_EVENTS 51#define NEED_REPLIES 52#include <X11/Xproto.h> 53#include "misc.h" 54#include "inputstr.h" 55#include <X11/extensions/XKBsrv.h> 56#include <X11/extensions/XKBgeom.h> 57 58#endif /* XKB_IN_SERVER */ 59 60/***===================================================================***/ 61 62/*ARGSUSED*/ 63Status 64XkbAllocCompatMap(XkbDescPtr xkb,unsigned which,unsigned nSI) 65{ 66XkbCompatMapPtr compat; 67XkbSymInterpretRec *prev_interpret; 68 69 if (!xkb) 70 return BadMatch; 71 if (xkb->compat) { 72 if (xkb->compat->size_si>=nSI) 73 return Success; 74 compat= xkb->compat; 75 compat->size_si= nSI; 76 if (compat->sym_interpret==NULL) 77 compat->num_si= 0; 78 prev_interpret = compat->sym_interpret; 79 compat->sym_interpret= _XkbTypedRealloc(compat->sym_interpret, 80 nSI,XkbSymInterpretRec); 81 if (compat->sym_interpret==NULL) { 82 _XkbFree(prev_interpret); 83 compat->size_si= compat->num_si= 0; 84 return BadAlloc; 85 } 86 if (compat->num_si!=0) { 87 _XkbClearElems(compat->sym_interpret,compat->num_si, 88 compat->size_si-1,XkbSymInterpretRec); 89 } 90 return Success; 91 } 92 compat= _XkbTypedCalloc(1,XkbCompatMapRec); 93 if (compat==NULL) 94 return BadAlloc; 95 if (nSI>0) { 96 compat->sym_interpret= _XkbTypedCalloc(nSI,XkbSymInterpretRec); 97 if (!compat->sym_interpret) { 98 _XkbFree(compat); 99 return BadAlloc; 100 } 101 } 102 compat->size_si= nSI; 103 compat->num_si= 0; 104 bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec)); 105 xkb->compat= compat; 106 return Success; 107} 108 109 110void 111XkbFreeCompatMap(XkbDescPtr xkb,unsigned which,Bool freeMap) 112{ 113register XkbCompatMapPtr compat; 114 115 if ((xkb==NULL)||(xkb->compat==NULL)) 116 return; 117 compat= xkb->compat; 118 if (freeMap) 119 which= XkbAllCompatMask; 120 if (which&XkbGroupCompatMask) 121 bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec)); 122 if (which&XkbSymInterpMask) { 123 if ((compat->sym_interpret)&&(compat->size_si>0)) 124 _XkbFree(compat->sym_interpret); 125 compat->size_si= compat->num_si= 0; 126 compat->sym_interpret= NULL; 127 } 128 if (freeMap) { 129 _XkbFree(compat); 130 xkb->compat= NULL; 131 } 132 return; 133} 134 135/***===================================================================***/ 136 137Status 138XkbAllocNames(XkbDescPtr xkb,unsigned which,int nTotalRG,int nTotalAliases) 139{ 140XkbNamesPtr names; 141 142 if (xkb==NULL) 143 return BadMatch; 144 if (xkb->names==NULL) { 145 xkb->names = _XkbTypedCalloc(1,XkbNamesRec); 146 if (xkb->names==NULL) 147 return BadAlloc; 148 } 149 names= xkb->names; 150 if ((which&XkbKTLevelNamesMask)&&(xkb->map!=NULL)&&(xkb->map->types!=NULL)){ 151 register int i; 152 XkbKeyTypePtr type; 153 154 type= xkb->map->types; 155 for (i=0;i<xkb->map->num_types;i++,type++) { 156 if (type->level_names==NULL) { 157 type->level_names= _XkbTypedCalloc(type->num_levels,Atom); 158 if (type->level_names==NULL) 159 return BadAlloc; 160 } 161 } 162 } 163 if ((which&XkbKeyNamesMask)&&(names->keys==NULL)) { 164 if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 165 (!XkbIsLegalKeycode(xkb->max_key_code))|| 166 (xkb->max_key_code<xkb->min_key_code)) 167 return BadValue; 168 names->keys= _XkbTypedCalloc((xkb->max_key_code+1),XkbKeyNameRec); 169 if (names->keys==NULL) 170 return BadAlloc; 171 } 172 if ((which&XkbKeyAliasesMask)&&(nTotalAliases>0)) { 173 if (names->key_aliases==NULL) { 174 names->key_aliases= _XkbTypedCalloc(nTotalAliases,XkbKeyAliasRec); 175 } 176 else if (nTotalAliases>names->num_key_aliases) { 177 XkbKeyAliasRec *prev_aliases = names->key_aliases; 178 179 names->key_aliases= _XkbTypedRealloc(names->key_aliases, 180 nTotalAliases,XkbKeyAliasRec); 181 if (names->key_aliases!=NULL) { 182 _XkbClearElems(names->key_aliases,names->num_key_aliases, 183 nTotalAliases-1,XkbKeyAliasRec); 184 } else { 185 _XkbFree(prev_aliases); 186 } 187 } 188 if (names->key_aliases==NULL) { 189 names->num_key_aliases= 0; 190 return BadAlloc; 191 } 192 names->num_key_aliases= nTotalAliases; 193 } 194 if ((which&XkbRGNamesMask)&&(nTotalRG>0)) { 195 if (names->radio_groups==NULL) { 196 names->radio_groups= _XkbTypedCalloc(nTotalRG,Atom); 197 } 198 else if (nTotalRG>names->num_rg) { 199 Atom *prev_radio_groups = names->radio_groups; 200 201 names->radio_groups= _XkbTypedRealloc(names->radio_groups,nTotalRG, 202 Atom); 203 if (names->radio_groups!=NULL) { 204 _XkbClearElems(names->radio_groups,names->num_rg,nTotalRG-1, 205 Atom); 206 } else { 207 _XkbFree(prev_radio_groups); 208 } 209 } 210 if (names->radio_groups==NULL) 211 return BadAlloc; 212 names->num_rg= nTotalRG; 213 } 214 return Success; 215} 216 217void 218XkbFreeNames(XkbDescPtr xkb,unsigned which,Bool freeMap) 219{ 220XkbNamesPtr names; 221 222 if ((xkb==NULL)||(xkb->names==NULL)) 223 return; 224 names= xkb->names; 225 if (freeMap) 226 which= XkbAllNamesMask; 227 if (which&XkbKTLevelNamesMask) { 228 XkbClientMapPtr map= xkb->map; 229 if ((map!=NULL)&&(map->types!=NULL)) { 230 register int i; 231 register XkbKeyTypePtr type; 232 type= map->types; 233 for (i=0;i<map->num_types;i++,type++) { 234 if (type->level_names!=NULL) { 235 _XkbFree(type->level_names); 236 type->level_names= NULL; 237 } 238 } 239 } 240 } 241 if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) { 242 _XkbFree(names->keys); 243 names->keys= NULL; 244 names->num_keys= 0; 245 } 246 if ((which&XkbKeyAliasesMask)&&(names->key_aliases)){ 247 _XkbFree(names->key_aliases); 248 names->key_aliases=NULL; 249 names->num_key_aliases=0; 250 } 251 if ((which&XkbRGNamesMask)&&(names->radio_groups)) { 252 _XkbFree(names->radio_groups); 253 names->radio_groups= NULL; 254 names->num_rg= 0; 255 } 256 if (freeMap) { 257 _XkbFree(names); 258 xkb->names= NULL; 259 } 260 return; 261} 262 263/***===================================================================***/ 264 265/*ARGSUSED*/ 266Status 267XkbAllocControls(XkbDescPtr xkb,unsigned which) 268{ 269 if (xkb==NULL) 270 return BadMatch; 271 272 if (xkb->ctrls==NULL) { 273 xkb->ctrls= _XkbTypedCalloc(1,XkbControlsRec); 274 if (!xkb->ctrls) 275 return BadAlloc; 276 } 277 return Success; 278} 279 280/*ARGSUSED*/ 281void 282XkbFreeControls(XkbDescPtr xkb,unsigned which,Bool freeMap) 283{ 284 if (freeMap && (xkb!=NULL) && (xkb->ctrls!=NULL)) { 285 _XkbFree(xkb->ctrls); 286 xkb->ctrls= NULL; 287 } 288 return; 289} 290 291/***===================================================================***/ 292 293Status 294XkbAllocIndicatorMaps(XkbDescPtr xkb) 295{ 296 if (xkb==NULL) 297 return BadMatch; 298 if (xkb->indicators==NULL) { 299 xkb->indicators= _XkbTypedCalloc(1,XkbIndicatorRec); 300 if (!xkb->indicators) 301 return BadAlloc; 302 } 303 return Success; 304} 305 306void 307XkbFreeIndicatorMaps(XkbDescPtr xkb) 308{ 309 if ((xkb!=NULL)&&(xkb->indicators!=NULL)) { 310 _XkbFree(xkb->indicators); 311 xkb->indicators= NULL; 312 } 313 return; 314} 315 316/***====================================================================***/ 317 318XkbDescRec * 319XkbAllocKeyboard(void) 320{ 321XkbDescRec *xkb; 322 323 xkb = _XkbTypedCalloc(1,XkbDescRec); 324 if (xkb) 325 xkb->device_spec= XkbUseCoreKbd; 326 return xkb; 327} 328 329void 330XkbFreeKeyboard(XkbDescPtr xkb,unsigned which,Bool freeAll) 331{ 332 if (xkb==NULL) 333 return; 334 if (freeAll) 335 which= XkbAllComponentsMask; 336 if (which&XkbClientMapMask) 337 XkbFreeClientMap(xkb,XkbAllClientInfoMask,True); 338 if (which&XkbServerMapMask) 339 XkbFreeServerMap(xkb,XkbAllServerInfoMask,True); 340 if (which&XkbCompatMapMask) 341 XkbFreeCompatMap(xkb,XkbAllCompatMask,True); 342 if (which&XkbIndicatorMapMask) 343 XkbFreeIndicatorMaps(xkb); 344 if (which&XkbNamesMask) 345 XkbFreeNames(xkb,XkbAllNamesMask,True); 346 if ((which&XkbGeometryMask) && (xkb->geom!=NULL)) 347 XkbFreeGeometry(xkb->geom,XkbGeomAllMask,True); 348 if (which&XkbControlsMask) 349 XkbFreeControls(xkb,XkbAllControlsMask,True); 350 if (freeAll) 351 _XkbFree(xkb); 352 return; 353} 354 355/***====================================================================***/ 356 357XkbDeviceLedInfoPtr 358XkbAddDeviceLedInfo(XkbDeviceInfoPtr devi,unsigned ledClass,unsigned ledId) 359{ 360XkbDeviceLedInfoPtr devli; 361register int i; 362 363 if ((!devi)||(!XkbSingleXIClass(ledClass))||(!XkbSingleXIId(ledId))) 364 return NULL; 365 for (i=0,devli=devi->leds;i<devi->num_leds;i++,devli++) { 366 if ((devli->led_class==ledClass)&&(devli->led_id==ledId)) 367 return devli; 368 } 369 if (devi->num_leds>=devi->sz_leds) { 370 XkbDeviceLedInfoRec *prev_leds = devi->leds; 371 372 if (devi->sz_leds>0) devi->sz_leds*= 2; 373 else devi->sz_leds= 1; 374 devi->leds= _XkbTypedRealloc(devi->leds,devi->sz_leds, 375 XkbDeviceLedInfoRec); 376 if (!devi->leds) { 377 _XkbFree(prev_leds); 378 devi->sz_leds= devi->num_leds= 0; 379 return NULL; 380 } 381 i= devi->num_leds; 382 for (devli=&devi->leds[i];i<devi->sz_leds;i++,devli++) { 383 bzero(devli,sizeof(XkbDeviceLedInfoRec)); 384 devli->led_class= XkbXINone; 385 devli->led_id= XkbXINone; 386 } 387 } 388 devli= &devi->leds[devi->num_leds++]; 389 bzero(devli,sizeof(XkbDeviceLedInfoRec)); 390 devli->led_class= ledClass; 391 devli->led_id= ledId; 392 return devli; 393} 394 395Status 396XkbResizeDeviceButtonActions(XkbDeviceInfoPtr devi,unsigned newTotal) 397{ 398 XkbAction *prev_btn_acts; 399 400 if ((!devi)||(newTotal>255)) 401 return BadValue; 402 if ((devi->btn_acts!=NULL)&&(newTotal==devi->num_btns)) 403 return Success; 404 if (newTotal==0) { 405 if (devi->btn_acts!=NULL) { 406 _XkbFree(devi->btn_acts); 407 devi->btn_acts= NULL; 408 } 409 devi->num_btns= 0; 410 return Success; 411 } 412 prev_btn_acts = devi->btn_acts; 413 devi->btn_acts= _XkbTypedRealloc(devi->btn_acts,newTotal,XkbAction); 414 if (devi->btn_acts==NULL) { 415 _XkbFree(prev_btn_acts); 416 devi->num_btns= 0; 417 return BadAlloc; 418 } 419 if (newTotal>devi->num_btns) { 420 XkbAction *act; 421 act= &devi->btn_acts[devi->num_btns]; 422 bzero((char *)act,(newTotal-devi->num_btns)*sizeof(XkbAction)); 423 } 424 devi->num_btns= newTotal; 425 return Success; 426} 427 428/*ARGSUSED*/ 429XkbDeviceInfoPtr 430XkbAllocDeviceInfo(unsigned deviceSpec,unsigned nButtons,unsigned szLeds) 431{ 432XkbDeviceInfoPtr devi; 433 434 devi= _XkbTypedCalloc(1,XkbDeviceInfoRec); 435 if (devi!=NULL) { 436 devi->device_spec= deviceSpec; 437 devi->has_own_state= False; 438 devi->num_btns= 0; 439 devi->btn_acts= NULL; 440 if (nButtons>0) { 441 devi->num_btns= nButtons; 442 devi->btn_acts= _XkbTypedCalloc(nButtons,XkbAction); 443 if (!devi->btn_acts) { 444 _XkbFree(devi); 445 return NULL; 446 } 447 } 448 devi->dflt_kbd_fb= XkbXINone; 449 devi->dflt_led_fb= XkbXINone; 450 devi->num_leds= 0; 451 devi->sz_leds= 0; 452 devi->leds= NULL; 453 if (szLeds>0) { 454 devi->sz_leds= szLeds; 455 devi->leds= _XkbTypedCalloc(szLeds,XkbDeviceLedInfoRec); 456 if (!devi->leds) { 457 if (devi->btn_acts) 458 _XkbFree(devi->btn_acts); 459 _XkbFree(devi); 460 return NULL; 461 } 462 } 463 } 464 return devi; 465} 466 467 468void 469XkbFreeDeviceInfo(XkbDeviceInfoPtr devi,unsigned which,Bool freeDevI) 470{ 471 if (devi) { 472 if (freeDevI) { 473 which= XkbXI_AllDeviceFeaturesMask; 474 if (devi->name) { 475 _XkbFree(devi->name); 476 devi->name= NULL; 477 } 478 } 479 if ((which&XkbXI_ButtonActionsMask)&&(devi->btn_acts)) { 480 _XkbFree(devi->btn_acts); 481 devi->num_btns= 0; 482 devi->btn_acts= NULL; 483 } 484 if ((which&XkbXI_IndicatorsMask)&&(devi->leds)) { 485 register int i; 486 if ((which&XkbXI_IndicatorsMask)==XkbXI_IndicatorsMask) { 487 _XkbFree(devi->leds); 488 devi->sz_leds= devi->num_leds= 0; 489 devi->leds= NULL; 490 } 491 else { 492 XkbDeviceLedInfoPtr devli; 493 for (i=0,devli=devi->leds;i<devi->num_leds;i++,devli++) { 494 if (which&XkbXI_IndicatorMapsMask) 495 bzero((char *)&devli->maps[0],sizeof(devli->maps)); 496 else bzero((char *)&devli->names[0],sizeof(devli->names)); 497 } 498 } 499 } 500 if (freeDevI) 501 _XkbFree(devi); 502 } 503 return; 504} 505