1*4882a593Smuzhiyun /************************************************************
2*4882a593Smuzhiyun Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun Permission to use, copy, modify, and distribute this
5*4882a593Smuzhiyun software and its documentation for any purpose and without
6*4882a593Smuzhiyun fee is hereby granted, provided that the above copyright
7*4882a593Smuzhiyun notice appear in all copies and that both that copyright
8*4882a593Smuzhiyun notice and this permission notice appear in supporting
9*4882a593Smuzhiyun documentation, and that the name of Silicon Graphics not be
10*4882a593Smuzhiyun used in advertising or publicity pertaining to distribution
11*4882a593Smuzhiyun of the software without specific prior written permission.
12*4882a593Smuzhiyun Silicon Graphics makes no representation about the suitability
13*4882a593Smuzhiyun of this software for any purpose. It is provided "as is"
14*4882a593Smuzhiyun without any express or implied warranty.
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17*4882a593Smuzhiyun SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18*4882a593Smuzhiyun AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19*4882a593Smuzhiyun GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20*4882a593Smuzhiyun DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21*4882a593Smuzhiyun DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22*4882a593Smuzhiyun OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23*4882a593Smuzhiyun THE USE OR PERFORMANCE OF THIS SOFTWARE.
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun ********************************************************/
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
28*4882a593Smuzhiyun #include <dix-config.h>
29*4882a593Smuzhiyun #endif
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #include <stdio.h>
32*4882a593Smuzhiyun #include <X11/X.h>
33*4882a593Smuzhiyun #include <X11/Xproto.h>
34*4882a593Smuzhiyun #include "misc.h"
35*4882a593Smuzhiyun #include "inputstr.h"
36*4882a593Smuzhiyun #include <xkbsrv.h>
37*4882a593Smuzhiyun #include "xkbgeom.h"
38*4882a593Smuzhiyun #include <os.h>
39*4882a593Smuzhiyun #include <string.h>
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun /***===================================================================***/
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun /*ARGSUSED*/ Status
XkbAllocCompatMap(XkbDescPtr xkb,unsigned which,unsigned nSI)44*4882a593Smuzhiyun XkbAllocCompatMap(XkbDescPtr xkb, unsigned which, unsigned nSI)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun XkbCompatMapPtr compat;
47*4882a593Smuzhiyun XkbSymInterpretRec *prev_interpret;
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun if (!xkb)
50*4882a593Smuzhiyun return BadMatch;
51*4882a593Smuzhiyun if (xkb->compat) {
52*4882a593Smuzhiyun if (xkb->compat->size_si >= nSI)
53*4882a593Smuzhiyun return Success;
54*4882a593Smuzhiyun compat = xkb->compat;
55*4882a593Smuzhiyun compat->size_si = nSI;
56*4882a593Smuzhiyun if (compat->sym_interpret == NULL)
57*4882a593Smuzhiyun compat->num_si = 0;
58*4882a593Smuzhiyun prev_interpret = compat->sym_interpret;
59*4882a593Smuzhiyun compat->sym_interpret = reallocarray(compat->sym_interpret,
60*4882a593Smuzhiyun nSI, sizeof(XkbSymInterpretRec));
61*4882a593Smuzhiyun if (compat->sym_interpret == NULL) {
62*4882a593Smuzhiyun free(prev_interpret);
63*4882a593Smuzhiyun compat->size_si = compat->num_si = 0;
64*4882a593Smuzhiyun return BadAlloc;
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun if (compat->num_si != 0) {
67*4882a593Smuzhiyun memset(&compat->sym_interpret[compat->num_si], 0,
68*4882a593Smuzhiyun (compat->size_si -
69*4882a593Smuzhiyun compat->num_si) * sizeof(XkbSymInterpretRec));
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun return Success;
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun compat = calloc(1, sizeof(XkbCompatMapRec));
74*4882a593Smuzhiyun if (compat == NULL)
75*4882a593Smuzhiyun return BadAlloc;
76*4882a593Smuzhiyun if (nSI > 0) {
77*4882a593Smuzhiyun compat->sym_interpret = calloc(nSI, sizeof(XkbSymInterpretRec));
78*4882a593Smuzhiyun if (!compat->sym_interpret) {
79*4882a593Smuzhiyun free(compat);
80*4882a593Smuzhiyun return BadAlloc;
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun compat->size_si = nSI;
84*4882a593Smuzhiyun compat->num_si = 0;
85*4882a593Smuzhiyun memset((char *) &compat->groups[0], 0,
86*4882a593Smuzhiyun XkbNumKbdGroups * sizeof(XkbModsRec));
87*4882a593Smuzhiyun xkb->compat = compat;
88*4882a593Smuzhiyun return Success;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun void
XkbFreeCompatMap(XkbDescPtr xkb,unsigned which,Bool freeMap)92*4882a593Smuzhiyun XkbFreeCompatMap(XkbDescPtr xkb, unsigned which, Bool freeMap)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun register XkbCompatMapPtr compat;
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun if ((xkb == NULL) || (xkb->compat == NULL))
97*4882a593Smuzhiyun return;
98*4882a593Smuzhiyun compat = xkb->compat;
99*4882a593Smuzhiyun if (freeMap)
100*4882a593Smuzhiyun which = XkbAllCompatMask;
101*4882a593Smuzhiyun if (which & XkbGroupCompatMask)
102*4882a593Smuzhiyun memset((char *) &compat->groups[0], 0,
103*4882a593Smuzhiyun XkbNumKbdGroups * sizeof(XkbModsRec));
104*4882a593Smuzhiyun if (which & XkbSymInterpMask) {
105*4882a593Smuzhiyun if ((compat->sym_interpret) && (compat->size_si > 0))
106*4882a593Smuzhiyun free(compat->sym_interpret);
107*4882a593Smuzhiyun compat->size_si = compat->num_si = 0;
108*4882a593Smuzhiyun compat->sym_interpret = NULL;
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun if (freeMap) {
111*4882a593Smuzhiyun free(compat);
112*4882a593Smuzhiyun xkb->compat = NULL;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun return;
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun /***===================================================================***/
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun Status
XkbAllocNames(XkbDescPtr xkb,unsigned which,int nTotalRG,int nTotalAliases)120*4882a593Smuzhiyun XkbAllocNames(XkbDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun XkbNamesPtr names;
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun if (xkb == NULL)
125*4882a593Smuzhiyun return BadMatch;
126*4882a593Smuzhiyun if (xkb->names == NULL) {
127*4882a593Smuzhiyun xkb->names = calloc(1, sizeof(XkbNamesRec));
128*4882a593Smuzhiyun if (xkb->names == NULL)
129*4882a593Smuzhiyun return BadAlloc;
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun names = xkb->names;
132*4882a593Smuzhiyun if ((which & XkbKTLevelNamesMask) && (xkb->map != NULL) &&
133*4882a593Smuzhiyun (xkb->map->types != NULL)) {
134*4882a593Smuzhiyun register int i;
135*4882a593Smuzhiyun XkbKeyTypePtr type;
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun type = xkb->map->types;
138*4882a593Smuzhiyun for (i = 0; i < xkb->map->num_types; i++, type++) {
139*4882a593Smuzhiyun if (type->level_names == NULL) {
140*4882a593Smuzhiyun type->level_names = calloc(type->num_levels, sizeof(Atom));
141*4882a593Smuzhiyun if (type->level_names == NULL)
142*4882a593Smuzhiyun return BadAlloc;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun if ((which & XkbKeyNamesMask) && (names->keys == NULL)) {
147*4882a593Smuzhiyun if ((!XkbIsLegalKeycode(xkb->min_key_code)) ||
148*4882a593Smuzhiyun (!XkbIsLegalKeycode(xkb->max_key_code)) ||
149*4882a593Smuzhiyun (xkb->max_key_code < xkb->min_key_code))
150*4882a593Smuzhiyun return BadValue;
151*4882a593Smuzhiyun names->keys = calloc((xkb->max_key_code + 1), sizeof(XkbKeyNameRec));
152*4882a593Smuzhiyun if (names->keys == NULL)
153*4882a593Smuzhiyun return BadAlloc;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun if ((which & XkbKeyAliasesMask) && (nTotalAliases > 0)) {
156*4882a593Smuzhiyun if (names->key_aliases == NULL) {
157*4882a593Smuzhiyun names->key_aliases = calloc(nTotalAliases, sizeof(XkbKeyAliasRec));
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun else if (nTotalAliases > names->num_key_aliases) {
160*4882a593Smuzhiyun XkbKeyAliasRec *prev_aliases = names->key_aliases;
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun names->key_aliases = reallocarray(names->key_aliases,
163*4882a593Smuzhiyun nTotalAliases,
164*4882a593Smuzhiyun sizeof(XkbKeyAliasRec));
165*4882a593Smuzhiyun if (names->key_aliases != NULL) {
166*4882a593Smuzhiyun memset(&names->key_aliases[names->num_key_aliases], 0,
167*4882a593Smuzhiyun (nTotalAliases -
168*4882a593Smuzhiyun names->num_key_aliases) * sizeof(XkbKeyAliasRec));
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun else {
171*4882a593Smuzhiyun free(prev_aliases);
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun if (names->key_aliases == NULL) {
175*4882a593Smuzhiyun names->num_key_aliases = 0;
176*4882a593Smuzhiyun return BadAlloc;
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun names->num_key_aliases = nTotalAliases;
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun if ((which & XkbRGNamesMask) && (nTotalRG > 0)) {
181*4882a593Smuzhiyun if (names->radio_groups == NULL) {
182*4882a593Smuzhiyun names->radio_groups = calloc(nTotalRG, sizeof(Atom));
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun else if (nTotalRG > names->num_rg) {
185*4882a593Smuzhiyun Atom *prev_radio_groups = names->radio_groups;
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun names->radio_groups = reallocarray(names->radio_groups,
188*4882a593Smuzhiyun nTotalRG, sizeof(Atom));
189*4882a593Smuzhiyun if (names->radio_groups != NULL) {
190*4882a593Smuzhiyun memset(&names->radio_groups[names->num_rg], 0,
191*4882a593Smuzhiyun (nTotalRG - names->num_rg) * sizeof(Atom));
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun else {
194*4882a593Smuzhiyun free(prev_radio_groups);
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun if (names->radio_groups == NULL)
198*4882a593Smuzhiyun return BadAlloc;
199*4882a593Smuzhiyun names->num_rg = nTotalRG;
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun return Success;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun void
XkbFreeNames(XkbDescPtr xkb,unsigned which,Bool freeMap)205*4882a593Smuzhiyun XkbFreeNames(XkbDescPtr xkb, unsigned which, Bool freeMap)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun XkbNamesPtr names;
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun if ((xkb == NULL) || (xkb->names == NULL))
210*4882a593Smuzhiyun return;
211*4882a593Smuzhiyun names = xkb->names;
212*4882a593Smuzhiyun if (freeMap)
213*4882a593Smuzhiyun which = XkbAllNamesMask;
214*4882a593Smuzhiyun if (which & XkbKTLevelNamesMask) {
215*4882a593Smuzhiyun XkbClientMapPtr map = xkb->map;
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun if ((map != NULL) && (map->types != NULL)) {
218*4882a593Smuzhiyun register int i;
219*4882a593Smuzhiyun register XkbKeyTypePtr type;
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun type = map->types;
222*4882a593Smuzhiyun for (i = 0; i < map->num_types; i++, type++) {
223*4882a593Smuzhiyun free(type->level_names);
224*4882a593Smuzhiyun type->level_names = NULL;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun if ((which & XkbKeyNamesMask) && (names->keys != NULL)) {
229*4882a593Smuzhiyun free(names->keys);
230*4882a593Smuzhiyun names->keys = NULL;
231*4882a593Smuzhiyun names->num_keys = 0;
232*4882a593Smuzhiyun }
233*4882a593Smuzhiyun if ((which & XkbKeyAliasesMask) && (names->key_aliases)) {
234*4882a593Smuzhiyun free(names->key_aliases);
235*4882a593Smuzhiyun names->key_aliases = NULL;
236*4882a593Smuzhiyun names->num_key_aliases = 0;
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun if ((which & XkbRGNamesMask) && (names->radio_groups)) {
239*4882a593Smuzhiyun free(names->radio_groups);
240*4882a593Smuzhiyun names->radio_groups = NULL;
241*4882a593Smuzhiyun names->num_rg = 0;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun if (freeMap) {
244*4882a593Smuzhiyun free(names);
245*4882a593Smuzhiyun xkb->names = NULL;
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun return;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun /***===================================================================***/
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun /*ARGSUSED*/ Status
XkbAllocControls(XkbDescPtr xkb,unsigned which)253*4882a593Smuzhiyun XkbAllocControls(XkbDescPtr xkb, unsigned which)
254*4882a593Smuzhiyun {
255*4882a593Smuzhiyun if (xkb == NULL)
256*4882a593Smuzhiyun return BadMatch;
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun if (xkb->ctrls == NULL) {
259*4882a593Smuzhiyun xkb->ctrls = calloc(1, sizeof(XkbControlsRec));
260*4882a593Smuzhiyun if (!xkb->ctrls)
261*4882a593Smuzhiyun return BadAlloc;
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun return Success;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun /*ARGSUSED*/ static void
XkbFreeControls(XkbDescPtr xkb,unsigned which,Bool freeMap)267*4882a593Smuzhiyun XkbFreeControls(XkbDescPtr xkb, unsigned which, Bool freeMap)
268*4882a593Smuzhiyun {
269*4882a593Smuzhiyun if (freeMap && (xkb != NULL) && (xkb->ctrls != NULL)) {
270*4882a593Smuzhiyun free(xkb->ctrls);
271*4882a593Smuzhiyun xkb->ctrls = NULL;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun return;
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun /***===================================================================***/
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun Status
XkbAllocIndicatorMaps(XkbDescPtr xkb)279*4882a593Smuzhiyun XkbAllocIndicatorMaps(XkbDescPtr xkb)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun if (xkb == NULL)
282*4882a593Smuzhiyun return BadMatch;
283*4882a593Smuzhiyun if (xkb->indicators == NULL) {
284*4882a593Smuzhiyun xkb->indicators = calloc(1, sizeof(XkbIndicatorRec));
285*4882a593Smuzhiyun if (!xkb->indicators)
286*4882a593Smuzhiyun return BadAlloc;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun return Success;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun static void
XkbFreeIndicatorMaps(XkbDescPtr xkb)292*4882a593Smuzhiyun XkbFreeIndicatorMaps(XkbDescPtr xkb)
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun if ((xkb != NULL) && (xkb->indicators != NULL)) {
295*4882a593Smuzhiyun free(xkb->indicators);
296*4882a593Smuzhiyun xkb->indicators = NULL;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun return;
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun /***====================================================================***/
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun XkbDescRec *
XkbAllocKeyboard(void)304*4882a593Smuzhiyun XkbAllocKeyboard(void)
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun XkbDescRec *xkb;
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun xkb = calloc(1, sizeof(XkbDescRec));
309*4882a593Smuzhiyun if (xkb)
310*4882a593Smuzhiyun xkb->device_spec = XkbUseCoreKbd;
311*4882a593Smuzhiyun return xkb;
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun void
XkbFreeKeyboard(XkbDescPtr xkb,unsigned which,Bool freeAll)315*4882a593Smuzhiyun XkbFreeKeyboard(XkbDescPtr xkb, unsigned which, Bool freeAll)
316*4882a593Smuzhiyun {
317*4882a593Smuzhiyun if (xkb == NULL)
318*4882a593Smuzhiyun return;
319*4882a593Smuzhiyun if (freeAll)
320*4882a593Smuzhiyun which = XkbAllComponentsMask;
321*4882a593Smuzhiyun if (which & XkbClientMapMask)
322*4882a593Smuzhiyun XkbFreeClientMap(xkb, XkbAllClientInfoMask, TRUE);
323*4882a593Smuzhiyun if (which & XkbServerMapMask)
324*4882a593Smuzhiyun XkbFreeServerMap(xkb, XkbAllServerInfoMask, TRUE);
325*4882a593Smuzhiyun if (which & XkbCompatMapMask)
326*4882a593Smuzhiyun XkbFreeCompatMap(xkb, XkbAllCompatMask, TRUE);
327*4882a593Smuzhiyun if (which & XkbIndicatorMapMask)
328*4882a593Smuzhiyun XkbFreeIndicatorMaps(xkb);
329*4882a593Smuzhiyun if (which & XkbNamesMask)
330*4882a593Smuzhiyun XkbFreeNames(xkb, XkbAllNamesMask, TRUE);
331*4882a593Smuzhiyun if ((which & XkbGeometryMask) && (xkb->geom != NULL)) {
332*4882a593Smuzhiyun XkbFreeGeometry(xkb->geom, XkbGeomAllMask, TRUE);
333*4882a593Smuzhiyun /* PERHAPS BONGHITS etc */
334*4882a593Smuzhiyun xkb->geom = NULL;
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun if (which & XkbControlsMask)
337*4882a593Smuzhiyun XkbFreeControls(xkb, XkbAllControlsMask, TRUE);
338*4882a593Smuzhiyun if (freeAll)
339*4882a593Smuzhiyun free(xkb);
340*4882a593Smuzhiyun return;
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun /***====================================================================***/
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun void
XkbFreeComponentNames(XkbComponentNamesPtr names,Bool freeNames)346*4882a593Smuzhiyun XkbFreeComponentNames(XkbComponentNamesPtr names, Bool freeNames)
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun if (names) {
349*4882a593Smuzhiyun free(names->keycodes);
350*4882a593Smuzhiyun free(names->types);
351*4882a593Smuzhiyun free(names->compat);
352*4882a593Smuzhiyun free(names->symbols);
353*4882a593Smuzhiyun free(names->geometry);
354*4882a593Smuzhiyun memset(names, 0, sizeof(XkbComponentNamesRec));
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun if (freeNames)
357*4882a593Smuzhiyun free(names);
358*4882a593Smuzhiyun }
359