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