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