Stringify public name types
[profile/ivi/libxkbcommon.git] / src / alloc.c
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 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29 #include "xkballoc.h"
30 #include "xkbcommon/xkbcommon.h"
31 #include "XKBcommonint.h"
32 #include <X11/extensions/XKB.h>
33
34 int
35 XkbcAllocCompatMap(struct xkb_desc * xkb, unsigned which, unsigned nSI)
36 {
37     struct xkb_compat_map * compat;
38     struct xkb_sym_interpret *prev_interpret;
39
40     if (!xkb)
41         return BadMatch;
42
43     if (xkb->compat) {
44         if (xkb->compat->size_si >= nSI)
45             return Success;
46
47         compat = xkb->compat;
48         compat->size_si = nSI;
49         if (!compat->sym_interpret)
50             compat->num_si = 0;
51
52         prev_interpret = compat->sym_interpret;
53         compat->sym_interpret = _XkbTypedRealloc(compat->sym_interpret,
54                                                  nSI, struct xkb_sym_interpret);
55         if (!compat->sym_interpret) {
56             free(prev_interpret);
57             compat->size_si = compat->num_si = 0;
58             return BadAlloc;
59         }
60
61         if (compat->num_si != 0)
62             _XkbClearElems(compat->sym_interpret, compat->num_si,
63                            compat->size_si - 1, struct xkb_sym_interpret);
64
65         return Success;
66     }
67
68     compat = _XkbTypedCalloc(1, struct xkb_compat_map);
69     if (!compat)
70         return BadAlloc;
71
72     if (nSI > 0) {
73         compat->sym_interpret = _XkbTypedCalloc(nSI, struct xkb_sym_interpret);
74         if (!compat->sym_interpret) {
75             free(compat);
76             return BadAlloc;
77         }
78     }
79     compat->size_si = nSI;
80     compat->num_si = 0;
81     memset(&compat->groups[0], 0, XkbNumKbdGroups * sizeof(struct xkb_mods));
82     xkb->compat = compat;
83
84     return Success;
85 }
86
87
88 static void
89 XkbcFreeCompatMap(struct xkb_desc * xkb)
90 {
91     struct xkb_compat_map * compat;
92
93     if (!xkb || !xkb->compat)
94         return;
95
96     compat = xkb->compat;
97
98     free(compat->sym_interpret);
99     free(compat);
100     xkb->compat = NULL;
101 }
102
103 int
104 XkbcAllocNames(struct xkb_desc * xkb, unsigned which, int nTotalAliases)
105 {
106     struct xkb_names * names;
107
108     if (!xkb)
109         return BadMatch;
110
111     if (!xkb->names) {
112         xkb->names = _XkbTypedCalloc(1, struct xkb_names);
113         if (!xkb->names)
114             return BadAlloc;
115     }
116     names = xkb->names;
117
118     if ((which & XkbKTLevelNamesMask) && xkb->map && xkb->map->types) {
119         int i;
120         struct xkb_key_type * type;
121
122         type = xkb->map->types;
123         for (i = 0; i < xkb->map->num_types; i++, type++) {
124             if (!type->level_names) {
125                 type->level_names = _XkbTypedCalloc(type->num_levels, const char *);
126                 if (!type->level_names)
127                     return BadAlloc;
128             }
129         }
130     }
131
132     if ((which & XkbKeyNamesMask) && !names->keys) {
133         if (!xkb_keymap_keycode_range_is_legal(xkb))
134             return BadMatch;
135
136         names->keys = _XkbTypedCalloc(xkb->max_key_code + 1, struct xkb_key_name);
137         if (!names->keys)
138             return BadAlloc;
139     }
140
141     if ((which & XkbKeyAliasesMask) && (nTotalAliases > 0)) {
142         if (!names->key_aliases)
143             names->key_aliases = _XkbTypedCalloc(nTotalAliases,
144                                                  struct xkb_key_alias);
145         else if (nTotalAliases > names->num_key_aliases) {
146             struct xkb_key_alias *prev_aliases = names->key_aliases;
147
148             names->key_aliases = _XkbTypedRealloc(names->key_aliases,
149                                                   nTotalAliases,
150                                                   struct xkb_key_alias);
151             if (names->key_aliases)
152                 _XkbClearElems(names->key_aliases, names->num_key_aliases,
153                                nTotalAliases - 1, struct xkb_key_alias);
154             else
155                 free(prev_aliases);
156         }
157
158         if (!names->key_aliases) {
159             names->num_key_aliases = 0;
160             return BadAlloc;
161         }
162
163         names->num_key_aliases = nTotalAliases;
164     }
165
166     return Success;
167 }
168
169 static void
170 XkbcFreeNames(struct xkb_desc * xkb)
171 {
172     struct xkb_names * names;
173     struct xkb_client_map * map;
174     int i;
175
176     if (!xkb || !xkb->names)
177         return;
178
179     names = xkb->names;
180     map = xkb->map;
181
182     if (map && map->types) {
183         struct xkb_key_type * type = map->types;
184
185         for (i = 0; i < map->num_types; i++, type++) {
186             int j;
187             for (j = 0; j < type->num_levels; j++)
188                 free((char *) type->level_names[i]);
189             free(type->level_names);
190             type->level_names = NULL;
191         }
192     }
193
194     for (i = 0; i < XkbNumVirtualMods; i++)
195         free((char *) names->vmods[i]);
196     for (i = 0; i < XkbNumIndicators; i++)
197         free((char *) names->indicators[i]);
198     for (i = 0; i < XkbNumKbdGroups; i++)
199         free((char *) names->groups[i]);
200
201     free(names->keys);
202     free(names->key_aliases);
203     free(names);
204     xkb->names = NULL;
205 }
206
207 int
208 XkbcAllocControls(struct xkb_desc * xkb, unsigned which)
209 {
210     if (!xkb)
211         return BadMatch;
212
213     if (!xkb->ctrls) {
214         xkb->ctrls = _XkbTypedCalloc(1, struct xkb_controls);
215         if (!xkb->ctrls)
216             return BadAlloc;
217     }
218
219     if (!xkb->ctrls->per_key_repeat) {
220         xkb->ctrls->per_key_repeat = _XkbTypedCalloc(xkb->max_key_code << 3,
221                                                      unsigned char);
222         if (!xkb->ctrls->per_key_repeat)
223             return BadAlloc;
224     }
225
226     return Success;
227 }
228
229 static void
230 XkbcFreeControls(struct xkb_desc * xkb)
231 {
232     if (xkb && xkb->ctrls) {
233         free(xkb->ctrls->per_key_repeat);
234         free(xkb->ctrls);
235         xkb->ctrls = NULL;
236     }
237 }
238
239 int
240 XkbcAllocIndicatorMaps(struct xkb_desc * xkb)
241 {
242     if (!xkb)
243         return BadMatch;
244
245     if (!xkb->indicators) {
246         xkb->indicators = _XkbTypedCalloc(1, struct xkb_indicator);
247         if (!xkb->indicators)
248             return BadAlloc;
249     }
250
251     return Success;
252 }
253
254 static void
255 XkbcFreeIndicatorMaps(struct xkb_desc * xkb)
256 {
257     if (xkb) {
258         free(xkb->indicators);
259         xkb->indicators = NULL;
260     }
261 }
262
263 struct xkb_desc *
264 XkbcAllocKeyboard(void)
265 {
266     struct xkb_desc *xkb;
267
268     xkb = _XkbTypedCalloc(1, struct xkb_desc);
269     if (xkb)
270         xkb->device_spec = XkbUseCoreKbd;
271     return xkb;
272 }
273
274 void
275 XkbcFreeKeyboard(struct xkb_desc * xkb)
276 {
277     if (!xkb)
278         return;
279
280     XkbcFreeClientMap(xkb);
281     XkbcFreeServerMap(xkb);
282     XkbcFreeCompatMap(xkb);
283     XkbcFreeIndicatorMaps(xkb);
284     XkbcFreeNames(xkb);
285     XkbcFreeControls(xkb);
286     free(xkb);
287 }