1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
15
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE 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
XkbAllocCompatMap(XkbDescPtr xkb,unsigned which,unsigned nSI)44 XkbAllocCompatMap(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
91 void
XkbFreeCompatMap(XkbDescPtr xkb,unsigned which,Bool freeMap)92 XkbFreeCompatMap(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
119 Status
XkbAllocNames(XkbDescPtr xkb,unsigned which,int nTotalRG,int nTotalAliases)120 XkbAllocNames(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 return BadAlloc;
199 names->num_rg = nTotalRG;
200 }
201 return Success;
202 }
203
204 void
XkbFreeNames(XkbDescPtr xkb,unsigned which,Bool freeMap)205 XkbFreeNames(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
XkbAllocControls(XkbDescPtr xkb,unsigned which)253 XkbAllocControls(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
XkbFreeControls(XkbDescPtr xkb,unsigned which,Bool freeMap)267 XkbFreeControls(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
278 Status
XkbAllocIndicatorMaps(XkbDescPtr xkb)279 XkbAllocIndicatorMaps(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
291 static void
XkbFreeIndicatorMaps(XkbDescPtr xkb)292 XkbFreeIndicatorMaps(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
303 XkbDescRec *
XkbAllocKeyboard(void)304 XkbAllocKeyboard(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
314 void
XkbFreeKeyboard(XkbDescPtr xkb,unsigned which,Bool freeAll)315 XkbFreeKeyboard(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
345 void
XkbFreeComponentNames(XkbComponentNamesPtr names,Bool freeNames)346 XkbFreeComponentNames(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 }
359