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