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