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#endif 30 31#include <stdio.h> 32#include <X11/X.h> 33#include <X11/Xproto.h> 34#include "misc.h" 35#include "inputstr.h" 36#include <xkbsrv.h> 37#include "xkbgeom.h" 38#include <os.h> 39#include <string.h> 40 41/***===================================================================***/ 42 43/*ARGSUSED*/ 44Status 45XkbAllocCompatMap(XkbDescPtr xkb,unsigned which,unsigned nSI) 46{ 47XkbCompatMapPtr compat; 48XkbSymInterpretRec *prev_interpret; 49 50 if (!xkb) 51 return BadMatch; 52 if (xkb->compat) { 53 if (xkb->compat->size_si>=nSI) 54 return Success; 55 compat= xkb->compat; 56 compat->size_si= nSI; 57 if (compat->sym_interpret==NULL) 58 compat->num_si= 0; 59 prev_interpret = compat->sym_interpret; 60 compat->sym_interpret= realloc(compat->sym_interpret, 61 nSI * sizeof(XkbSymInterpretRec)); 62 if (compat->sym_interpret==NULL) { 63 free(prev_interpret); 64 compat->size_si= compat->num_si= 0; 65 return BadAlloc; 66 } 67 if (compat->num_si!=0) { 68 memset(&compat->sym_interpret[compat->num_si], 0, 69 (compat->size_si - compat->num_si) * sizeof(XkbSymInterpretRec)); 70 } 71 return Success; 72 } 73 compat= calloc(1, sizeof(XkbCompatMapRec)); 74 if (compat==NULL) 75 return BadAlloc; 76 if (nSI>0) { 77 compat->sym_interpret= calloc(nSI, sizeof(XkbSymInterpretRec)); 78 if (!compat->sym_interpret) { 79 free(compat); 80 return BadAlloc; 81 } 82 } 83 compat->size_si= nSI; 84 compat->num_si= 0; 85 memset((char *)&compat->groups[0], 0, XkbNumKbdGroups*sizeof(XkbModsRec)); 86 xkb->compat= compat; 87 return Success; 88} 89 90 91void 92XkbFreeCompatMap(XkbDescPtr xkb,unsigned which,Bool freeMap) 93{ 94register XkbCompatMapPtr compat; 95 96 if ((xkb==NULL)||(xkb->compat==NULL)) 97 return; 98 compat= xkb->compat; 99 if (freeMap) 100 which= XkbAllCompatMask; 101 if (which&XkbGroupCompatMask) 102 memset((char *)&compat->groups[0], 0, XkbNumKbdGroups*sizeof(XkbModsRec)); 103 if (which&XkbSymInterpMask) { 104 if ((compat->sym_interpret)&&(compat->size_si>0)) 105 free(compat->sym_interpret); 106 compat->size_si= compat->num_si= 0; 107 compat->sym_interpret= NULL; 108 } 109 if (freeMap) { 110 free(compat); 111 xkb->compat= NULL; 112 } 113 return; 114} 115 116/***===================================================================***/ 117 118Status 119XkbAllocNames(XkbDescPtr xkb,unsigned which,int nTotalRG,int nTotalAliases) 120{ 121XkbNamesPtr names; 122 123 if (xkb==NULL) 124 return BadMatch; 125 if (xkb->names==NULL) { 126 xkb->names = calloc(1, sizeof(XkbNamesRec)); 127 if (xkb->names==NULL) 128 return BadAlloc; 129 } 130 names= xkb->names; 131 if ((which&XkbKTLevelNamesMask)&&(xkb->map!=NULL)&&(xkb->map->types!=NULL)){ 132 register int i; 133 XkbKeyTypePtr type; 134 135 type= xkb->map->types; 136 for (i=0;i<xkb->map->num_types;i++,type++) { 137 if (type->level_names==NULL) { 138 type->level_names= calloc(type->num_levels, sizeof(Atom)); 139 if (type->level_names==NULL) 140 return BadAlloc; 141 } 142 } 143 } 144 if ((which&XkbKeyNamesMask)&&(names->keys==NULL)) { 145 if ((!XkbIsLegalKeycode(xkb->min_key_code))|| 146 (!XkbIsLegalKeycode(xkb->max_key_code))|| 147 (xkb->max_key_code<xkb->min_key_code)) 148 return BadValue; 149 names->keys= calloc((xkb->max_key_code+1), sizeof(XkbKeyNameRec)); 150 if (names->keys==NULL) 151 return BadAlloc; 152 } 153 if ((which&XkbKeyAliasesMask)&&(nTotalAliases>0)) { 154 if (names->key_aliases==NULL) { 155 names->key_aliases= calloc(nTotalAliases, sizeof(XkbKeyAliasRec)); 156 } 157 else if (nTotalAliases>names->num_key_aliases) { 158 XkbKeyAliasRec *prev_aliases = names->key_aliases; 159 160 names->key_aliases= realloc(names->key_aliases, 161 nTotalAliases * sizeof(XkbKeyAliasRec)); 162 if (names->key_aliases!=NULL) { 163 memset(&names->key_aliases[names->num_key_aliases], 0, 164 (nTotalAliases - names->num_key_aliases) * sizeof(XkbKeyAliasRec)); 165 } else { 166 free(prev_aliases); 167 } 168 } 169 if (names->key_aliases==NULL) { 170 names->num_key_aliases= 0; 171 return BadAlloc; 172 } 173 names->num_key_aliases= nTotalAliases; 174 } 175 if ((which&XkbRGNamesMask)&&(nTotalRG>0)) { 176 if (names->radio_groups==NULL) { 177 names->radio_groups= calloc(nTotalRG, sizeof(Atom)); 178 } 179 else if (nTotalRG>names->num_rg) { 180 Atom *prev_radio_groups = names->radio_groups; 181 182 names->radio_groups= realloc(names->radio_groups, 183 nTotalRG * sizeof(Atom)); 184 if (names->radio_groups!=NULL) { 185 memset(&names->radio_groups[names->num_rg], 0, 186 (nTotalRG - names->num_rg) * sizeof(Atom)); 187 } else { 188 free(prev_radio_groups); 189 } 190 } 191 if (names->radio_groups==NULL) 192 return BadAlloc; 193 names->num_rg= nTotalRG; 194 } 195 return Success; 196} 197 198void 199XkbFreeNames(XkbDescPtr xkb,unsigned which,Bool freeMap) 200{ 201XkbNamesPtr names; 202 203 if ((xkb==NULL)||(xkb->names==NULL)) 204 return; 205 names= xkb->names; 206 if (freeMap) 207 which= XkbAllNamesMask; 208 if (which&XkbKTLevelNamesMask) { 209 XkbClientMapPtr map= xkb->map; 210 if ((map!=NULL)&&(map->types!=NULL)) { 211 register int i; 212 register XkbKeyTypePtr type; 213 type= map->types; 214 for (i=0;i<map->num_types;i++,type++) { 215 free(type->level_names); 216 type->level_names = NULL; 217 } 218 } 219 } 220 if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) { 221 free(names->keys); 222 names->keys= NULL; 223 names->num_keys= 0; 224 } 225 if ((which&XkbKeyAliasesMask)&&(names->key_aliases)){ 226 free(names->key_aliases); 227 names->key_aliases=NULL; 228 names->num_key_aliases=0; 229 } 230 if ((which&XkbRGNamesMask)&&(names->radio_groups)) { 231 free(names->radio_groups); 232 names->radio_groups= NULL; 233 names->num_rg= 0; 234 } 235 if (freeMap) { 236 free(names); 237 xkb->names= NULL; 238 } 239 return; 240} 241 242/***===================================================================***/ 243 244/*ARGSUSED*/ 245Status 246XkbAllocControls(XkbDescPtr xkb,unsigned which) 247{ 248 if (xkb==NULL) 249 return BadMatch; 250 251 if (xkb->ctrls==NULL) { 252 xkb->ctrls= calloc(1, sizeof(XkbControlsRec)); 253 if (!xkb->ctrls) 254 return BadAlloc; 255 } 256 return Success; 257} 258 259/*ARGSUSED*/ 260static void 261XkbFreeControls(XkbDescPtr xkb,unsigned which,Bool freeMap) 262{ 263 if (freeMap && (xkb!=NULL) && (xkb->ctrls!=NULL)) { 264 free(xkb->ctrls); 265 xkb->ctrls= NULL; 266 } 267 return; 268} 269 270/***===================================================================***/ 271 272Status 273XkbAllocIndicatorMaps(XkbDescPtr xkb) 274{ 275 if (xkb==NULL) 276 return BadMatch; 277 if (xkb->indicators==NULL) { 278 xkb->indicators= calloc(1, sizeof(XkbIndicatorRec)); 279 if (!xkb->indicators) 280 return BadAlloc; 281 } 282 return Success; 283} 284 285static void 286XkbFreeIndicatorMaps(XkbDescPtr xkb) 287{ 288 if ((xkb!=NULL)&&(xkb->indicators!=NULL)) { 289 free(xkb->indicators); 290 xkb->indicators= NULL; 291 } 292 return; 293} 294 295/***====================================================================***/ 296 297XkbDescRec * 298XkbAllocKeyboard(void) 299{ 300XkbDescRec *xkb; 301 302 xkb = calloc(1, sizeof(XkbDescRec)); 303 if (xkb) 304 xkb->device_spec= XkbUseCoreKbd; 305 return xkb; 306} 307 308void 309XkbFreeKeyboard(XkbDescPtr xkb,unsigned which,Bool freeAll) 310{ 311 if (xkb==NULL) 312 return; 313 if (freeAll) 314 which= XkbAllComponentsMask; 315 if (which&XkbClientMapMask) 316 XkbFreeClientMap(xkb,XkbAllClientInfoMask,TRUE); 317 if (which&XkbServerMapMask) 318 XkbFreeServerMap(xkb,XkbAllServerInfoMask,TRUE); 319 if (which&XkbCompatMapMask) 320 XkbFreeCompatMap(xkb,XkbAllCompatMask,TRUE); 321 if (which&XkbIndicatorMapMask) 322 XkbFreeIndicatorMaps(xkb); 323 if (which&XkbNamesMask) 324 XkbFreeNames(xkb,XkbAllNamesMask,TRUE); 325 if ((which&XkbGeometryMask) && (xkb->geom!=NULL)) { 326 XkbFreeGeometry(xkb->geom,XkbGeomAllMask,TRUE); 327 /* PERHAPS BONGHITS etc */ 328 xkb->geom = NULL; 329 } 330 if (which&XkbControlsMask) 331 XkbFreeControls(xkb,XkbAllControlsMask,TRUE); 332 if (freeAll) 333 free(xkb); 334 return; 335} 336 337 338/***====================================================================***/ 339 340void 341XkbFreeComponentNames(XkbComponentNamesPtr names, Bool freeNames) 342{ 343 if (names) 344 { 345 free(names->keycodes); 346 free(names->types); 347 free(names->compat); 348 free(names->symbols); 349 free(names->geometry); 350 memset(names, 0, sizeof(XkbComponentNamesRec)); 351 } 352 if (freeNames) 353 free(names); 354} 355