XKBAlloc.c revision 6747b715
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 if (type->level_names!=NULL) { 216 free(type->level_names); 217 type->level_names= NULL; 218 } 219 } 220 } 221 } 222 if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) { 223 free(names->keys); 224 names->keys= NULL; 225 names->num_keys= 0; 226 } 227 if ((which&XkbKeyAliasesMask)&&(names->key_aliases)){ 228 free(names->key_aliases); 229 names->key_aliases=NULL; 230 names->num_key_aliases=0; 231 } 232 if ((which&XkbRGNamesMask)&&(names->radio_groups)) { 233 free(names->radio_groups); 234 names->radio_groups= NULL; 235 names->num_rg= 0; 236 } 237 if (freeMap) { 238 free(names); 239 xkb->names= NULL; 240 } 241 return; 242} 243 244/***===================================================================***/ 245 246/*ARGSUSED*/ 247Status 248XkbAllocControls(XkbDescPtr xkb,unsigned which) 249{ 250 if (xkb==NULL) 251 return BadMatch; 252 253 if (xkb->ctrls==NULL) { 254 xkb->ctrls= calloc(1, sizeof(XkbControlsRec)); 255 if (!xkb->ctrls) 256 return BadAlloc; 257 } 258 return Success; 259} 260 261/*ARGSUSED*/ 262static void 263XkbFreeControls(XkbDescPtr xkb,unsigned which,Bool freeMap) 264{ 265 if (freeMap && (xkb!=NULL) && (xkb->ctrls!=NULL)) { 266 free(xkb->ctrls); 267 xkb->ctrls= NULL; 268 } 269 return; 270} 271 272/***===================================================================***/ 273 274Status 275XkbAllocIndicatorMaps(XkbDescPtr xkb) 276{ 277 if (xkb==NULL) 278 return BadMatch; 279 if (xkb->indicators==NULL) { 280 xkb->indicators= calloc(1, sizeof(XkbIndicatorRec)); 281 if (!xkb->indicators) 282 return BadAlloc; 283 } 284 return Success; 285} 286 287static void 288XkbFreeIndicatorMaps(XkbDescPtr xkb) 289{ 290 if ((xkb!=NULL)&&(xkb->indicators!=NULL)) { 291 free(xkb->indicators); 292 xkb->indicators= NULL; 293 } 294 return; 295} 296 297/***====================================================================***/ 298 299XkbDescRec * 300XkbAllocKeyboard(void) 301{ 302XkbDescRec *xkb; 303 304 xkb = calloc(1, sizeof(XkbDescRec)); 305 if (xkb) 306 xkb->device_spec= XkbUseCoreKbd; 307 return xkb; 308} 309 310void 311XkbFreeKeyboard(XkbDescPtr xkb,unsigned which,Bool freeAll) 312{ 313 if (xkb==NULL) 314 return; 315 if (freeAll) 316 which= XkbAllComponentsMask; 317 if (which&XkbClientMapMask) 318 XkbFreeClientMap(xkb,XkbAllClientInfoMask,TRUE); 319 if (which&XkbServerMapMask) 320 XkbFreeServerMap(xkb,XkbAllServerInfoMask,TRUE); 321 if (which&XkbCompatMapMask) 322 XkbFreeCompatMap(xkb,XkbAllCompatMask,TRUE); 323 if (which&XkbIndicatorMapMask) 324 XkbFreeIndicatorMaps(xkb); 325 if (which&XkbNamesMask) 326 XkbFreeNames(xkb,XkbAllNamesMask,TRUE); 327 if ((which&XkbGeometryMask) && (xkb->geom!=NULL)) { 328 XkbFreeGeometry(xkb->geom,XkbGeomAllMask,TRUE); 329 /* PERHAPS BONGHITS etc */ 330 xkb->geom = NULL; 331 } 332 if (which&XkbControlsMask) 333 XkbFreeControls(xkb,XkbAllControlsMask,TRUE); 334 if (freeAll) 335 free(xkb); 336 return; 337} 338