Imported Upstream version 1.15.1
[deb_xorg-server.git] / xkb / XKBAlloc.c
CommitLineData
a09e091a
JB
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 = realloc(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 = realloc(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 = realloc(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 return BadAlloc;
199 names->num_rg = nTotalRG;
200 }
201 return Success;
202}
203
204void
205XkbFreeNames(XkbDescPtr xkb, unsigned which, Bool freeMap)
206{
207 XkbNamesPtr names;
208
209 if ((xkb == NULL) || (xkb->names == NULL))
210 return;
211 names = xkb->names;
212 if (freeMap)
213 which = XkbAllNamesMask;
214 if (which & XkbKTLevelNamesMask) {
215 XkbClientMapPtr map = xkb->map;
216
217 if ((map != NULL) && (map->types != NULL)) {
218 register int i;
219 register XkbKeyTypePtr type;
220
221 type = map->types;
222 for (i = 0; i < map->num_types; i++, type++) {
223 free(type->level_names);
224 type->level_names = NULL;
225 }
226 }
227 }
228 if ((which & XkbKeyNamesMask) && (names->keys != NULL)) {
229 free(names->keys);
230 names->keys = NULL;
231 names->num_keys = 0;
232 }
233 if ((which & XkbKeyAliasesMask) && (names->key_aliases)) {
234 free(names->key_aliases);
235 names->key_aliases = NULL;
236 names->num_key_aliases = 0;
237 }
238 if ((which & XkbRGNamesMask) && (names->radio_groups)) {
239 free(names->radio_groups);
240 names->radio_groups = NULL;
241 names->num_rg = 0;
242 }
243 if (freeMap) {
244 free(names);
245 xkb->names = NULL;
246 }
247 return;
248}
249
250/***===================================================================***/
251
252 /*ARGSUSED*/ Status
253XkbAllocControls(XkbDescPtr xkb, unsigned which)
254{
255 if (xkb == NULL)
256 return BadMatch;
257
258 if (xkb->ctrls == NULL) {
259 xkb->ctrls = calloc(1, sizeof(XkbControlsRec));
260 if (!xkb->ctrls)
261 return BadAlloc;
262 }
263 return Success;
264}
265
266 /*ARGSUSED*/ static void
267XkbFreeControls(XkbDescPtr xkb, unsigned which, Bool freeMap)
268{
269 if (freeMap && (xkb != NULL) && (xkb->ctrls != NULL)) {
270 free(xkb->ctrls);
271 xkb->ctrls = NULL;
272 }
273 return;
274}
275
276/***===================================================================***/
277
278Status
279XkbAllocIndicatorMaps(XkbDescPtr xkb)
280{
281 if (xkb == NULL)
282 return BadMatch;
283 if (xkb->indicators == NULL) {
284 xkb->indicators = calloc(1, sizeof(XkbIndicatorRec));
285 if (!xkb->indicators)
286 return BadAlloc;
287 }
288 return Success;
289}
290
291static void
292XkbFreeIndicatorMaps(XkbDescPtr xkb)
293{
294 if ((xkb != NULL) && (xkb->indicators != NULL)) {
295 free(xkb->indicators);
296 xkb->indicators = NULL;
297 }
298 return;
299}
300
301/***====================================================================***/
302
303XkbDescRec *
304XkbAllocKeyboard(void)
305{
306 XkbDescRec *xkb;
307
308 xkb = calloc(1, sizeof(XkbDescRec));
309 if (xkb)
310 xkb->device_spec = XkbUseCoreKbd;
311 return xkb;
312}
313
314void
315XkbFreeKeyboard(XkbDescPtr xkb, unsigned which, Bool freeAll)
316{
317 if (xkb == NULL)
318 return;
319 if (freeAll)
320 which = XkbAllComponentsMask;
321 if (which & XkbClientMapMask)
322 XkbFreeClientMap(xkb, XkbAllClientInfoMask, TRUE);
323 if (which & XkbServerMapMask)
324 XkbFreeServerMap(xkb, XkbAllServerInfoMask, TRUE);
325 if (which & XkbCompatMapMask)
326 XkbFreeCompatMap(xkb, XkbAllCompatMask, TRUE);
327 if (which & XkbIndicatorMapMask)
328 XkbFreeIndicatorMaps(xkb);
329 if (which & XkbNamesMask)
330 XkbFreeNames(xkb, XkbAllNamesMask, TRUE);
331 if ((which & XkbGeometryMask) && (xkb->geom != NULL)) {
332 XkbFreeGeometry(xkb->geom, XkbGeomAllMask, TRUE);
333 /* PERHAPS BONGHITS etc */
334 xkb->geom = NULL;
335 }
336 if (which & XkbControlsMask)
337 XkbFreeControls(xkb, XkbAllControlsMask, TRUE);
338 if (freeAll)
339 free(xkb);
340 return;
341}
342
343/***====================================================================***/
344
345void
346XkbFreeComponentNames(XkbComponentNamesPtr names, Bool freeNames)
347{
348 if (names) {
349 free(names->keycodes);
350 free(names->types);
351 free(names->compat);
352 free(names->symbols);
353 free(names->geometry);
354 memset(names, 0, sizeof(XkbComponentNamesRec));
355 }
356 if (freeNames)
357 free(names);
358}