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