1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
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.
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.
25 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
29 #endif
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>
41 /***===================================================================***/
43 /*ARGSUSED*/
44 Status
45 XkbAllocCompatMap(XkbDescPtr xkb,unsigned which,unsigned nSI)
46 {
47 XkbCompatMapPtr compat;
48 XkbSymInterpretRec *prev_interpret;
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 }
91 void
92 XkbFreeCompatMap(XkbDescPtr xkb,unsigned which,Bool freeMap)
93 {
94 register XkbCompatMapPtr compat;
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 }
116 /***===================================================================***/
118 Status
119 XkbAllocNames(XkbDescPtr xkb,unsigned which,int nTotalRG,int nTotalAliases)
120 {
121 XkbNamesPtr names;
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;
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;
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;
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 }
198 void
199 XkbFreeNames(XkbDescPtr xkb,unsigned which,Bool freeMap)
200 {
201 XkbNamesPtr names;
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 free(type->level_names);
216 type->level_names = NULL;
217 }
218 }
219 }
220 if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) {
221 free(names->keys);
222 names->keys= NULL;
223 names->num_keys= 0;
224 }
225 if ((which&XkbKeyAliasesMask)&&(names->key_aliases)){
226 free(names->key_aliases);
227 names->key_aliases=NULL;
228 names->num_key_aliases=0;
229 }
230 if ((which&XkbRGNamesMask)&&(names->radio_groups)) {
231 free(names->radio_groups);
232 names->radio_groups= NULL;
233 names->num_rg= 0;
234 }
235 if (freeMap) {
236 free(names);
237 xkb->names= NULL;
238 }
239 return;
240 }
242 /***===================================================================***/
244 /*ARGSUSED*/
245 Status
246 XkbAllocControls(XkbDescPtr xkb,unsigned which)
247 {
248 if (xkb==NULL)
249 return BadMatch;
251 if (xkb->ctrls==NULL) {
252 xkb->ctrls= calloc(1, sizeof(XkbControlsRec));
253 if (!xkb->ctrls)
254 return BadAlloc;
255 }
256 return Success;
257 }
259 /*ARGSUSED*/
260 static void
261 XkbFreeControls(XkbDescPtr xkb,unsigned which,Bool freeMap)
262 {
263 if (freeMap && (xkb!=NULL) && (xkb->ctrls!=NULL)) {
264 free(xkb->ctrls);
265 xkb->ctrls= NULL;
266 }
267 return;
268 }
270 /***===================================================================***/
272 Status
273 XkbAllocIndicatorMaps(XkbDescPtr xkb)
274 {
275 if (xkb==NULL)
276 return BadMatch;
277 if (xkb->indicators==NULL) {
278 xkb->indicators= calloc(1, sizeof(XkbIndicatorRec));
279 if (!xkb->indicators)
280 return BadAlloc;
281 }
282 return Success;
283 }
285 static void
286 XkbFreeIndicatorMaps(XkbDescPtr xkb)
287 {
288 if ((xkb!=NULL)&&(xkb->indicators!=NULL)) {
289 free(xkb->indicators);
290 xkb->indicators= NULL;
291 }
292 return;
293 }
295 /***====================================================================***/
297 XkbDescRec *
298 XkbAllocKeyboard(void)
299 {
300 XkbDescRec *xkb;
302 xkb = calloc(1, sizeof(XkbDescRec));
303 if (xkb)
304 xkb->device_spec= XkbUseCoreKbd;
305 return xkb;
306 }
308 void
309 XkbFreeKeyboard(XkbDescPtr xkb,unsigned which,Bool freeAll)
310 {
311 if (xkb==NULL)
312 return;
313 if (freeAll)
314 which= XkbAllComponentsMask;
315 if (which&XkbClientMapMask)
316 XkbFreeClientMap(xkb,XkbAllClientInfoMask,TRUE);
317 if (which&XkbServerMapMask)
318 XkbFreeServerMap(xkb,XkbAllServerInfoMask,TRUE);
319 if (which&XkbCompatMapMask)
320 XkbFreeCompatMap(xkb,XkbAllCompatMask,TRUE);
321 if (which&XkbIndicatorMapMask)
322 XkbFreeIndicatorMaps(xkb);
323 if (which&XkbNamesMask)
324 XkbFreeNames(xkb,XkbAllNamesMask,TRUE);
325 if ((which&XkbGeometryMask) && (xkb->geom!=NULL)) {
326 XkbFreeGeometry(xkb->geom,XkbGeomAllMask,TRUE);
327 /* PERHAPS BONGHITS etc */
328 xkb->geom = NULL;
329 }
330 if (which&XkbControlsMask)
331 XkbFreeControls(xkb,XkbAllControlsMask,TRUE);
332 if (freeAll)
333 free(xkb);
334 return;
335 }
338 /***====================================================================***/
340 void
341 XkbFreeComponentNames(XkbComponentNamesPtr names, Bool freeNames)
342 {
343 if (names)
344 {
345 free(names->keycodes);
346 free(names->types);
347 free(names->compat);
348 free(names->symbols);
349 free(names->geometry);
350 memset(names, 0, sizeof(XkbComponentNamesRec));
351 }
352 if (freeNames)
353 free(names);
354 }