Fix all -Wsign-compare warnings
[platform/upstream/libxkbcommon.git] / src / malloc.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
27 #include "utils.h"
28 #include "xkballoc.h"
29 #include "xkbcommon/xkbcommon.h"
30 #include "XKBcommonint.h"
31
32 int
33 XkbcAllocClientMap(struct xkb_desc * xkb, unsigned which, unsigned nTotalTypes)
34 {
35     int i;
36     struct xkb_client_map * map;
37
38     if (!xkb || ((nTotalTypes > 0) && (nTotalTypes < XkbNumRequiredTypes)))
39         return BadValue;
40
41     if ((which & XkbKeySymsMask) && !xkb_keymap_keycode_range_is_legal(xkb)) {
42 #ifdef DEBUG
43         fprintf(stderr, "bad keycode (%d,%d) in XkbAllocClientMap\n",
44                 xkb->min_key_code, xkb->max_key_code);
45 #endif
46         return BadValue;
47     }
48
49     if (!xkb->map) {
50         map = uTypedCalloc(1, struct xkb_client_map);
51         if (!map)
52             return BadAlloc;
53         xkb->map = map;
54     }
55     else
56         map = xkb->map;
57
58     if ((which & XkbKeyTypesMask) && (nTotalTypes > 0)) {
59         if (!map->types) {
60             map->types = uTypedCalloc(nTotalTypes, struct xkb_key_type);
61             if (!map->types)
62                 return BadAlloc;
63
64             map->num_types = 0;
65             map->size_types = nTotalTypes;
66         }
67         else if (map->size_types < nTotalTypes) {
68             struct xkb_key_type *prev_types = map->types;
69
70             map->types = uTypedRealloc(map->types, nTotalTypes,
71                                           struct xkb_key_type);
72             if (!map->types) {
73                 free(prev_types);
74                 map->num_types = map->size_types = 0;
75                 return BadAlloc;
76             }
77
78             map->size_types = nTotalTypes;
79             memset(&map->types[map->num_types], 0,
80                    (map->size_types - map->num_types) * sizeof(struct xkb_key_type));
81         }
82     }
83
84     if (which & XkbKeySymsMask) {
85         int nKeys = XkbNumKeys(xkb);
86
87         if (!map->syms) {
88             map->size_syms = (nKeys * 15) / 10;
89             map->syms = uTypedCalloc(map->size_syms, xkb_keysym_t);
90             if (!map->syms) {
91                 map->size_syms = 0;
92                 return BadAlloc;
93             }
94             map->num_syms = 1;
95             map->syms[0] = NoSymbol;
96         }
97
98         if (!map->key_sym_map) {
99             i = xkb->max_key_code + 1;
100             map->key_sym_map = uTypedCalloc(i, struct xkb_sym_map);
101             if (!map->key_sym_map)
102                 return BadAlloc;
103         }
104     }
105
106     if (which & XkbModifierMapMask) {
107         if (!xkb_keymap_keycode_range_is_legal(xkb))
108             return BadMatch;
109
110         if (!map->modmap) {
111             i = xkb->max_key_code + 1;
112             map->modmap = uTypedCalloc(i, unsigned char);
113             if (!map->modmap)
114                 return BadAlloc;
115         }
116     }
117
118     return Success;
119 }
120
121 int
122 XkbcAllocServerMap(struct xkb_desc * xkb, unsigned which, unsigned nNewActions)
123 {
124     unsigned i;
125     struct xkb_server_map * map;
126
127     if (!xkb)
128         return BadMatch;
129
130     if (!xkb->server) {
131         map = uTypedCalloc(1, struct xkb_server_map);
132         if (!map)
133             return BadAlloc;
134
135         for (i = 0; i < XkbNumVirtualMods; i++)
136             map->vmods[i] = XkbNoModifierMask;
137
138         xkb->server = map;
139     }
140     else
141         map = xkb->server;
142
143     if (!which)
144         return Success;
145
146     if (!xkb_keymap_keycode_range_is_legal(xkb))
147         return BadMatch;
148
149     if (which & XkbExplicitComponentsMask) {
150         if (!map->explicit) {
151             i = xkb->max_key_code + 1;
152             map->explicit = uTypedCalloc(i, unsigned char);
153             if (!map->explicit)
154                 return BadAlloc;
155         }
156     }
157
158     if (which&XkbKeyActionsMask) {
159         if (nNewActions < 1)
160             nNewActions = 1;
161
162         if (!map->acts) {
163             map->acts = uTypedCalloc(nNewActions + 1, union xkb_action);
164             if (!map->acts)
165                 return BadAlloc;
166             map->num_acts = 1;
167             map->size_acts = nNewActions + 1;
168         }
169         else if ((map->size_acts - map->num_acts) < (int)nNewActions) {
170             unsigned need;
171             union xkb_action *prev_acts = map->acts;
172
173             need = map->num_acts + nNewActions;
174             map->acts = uTypedRealloc(map->acts, need, union xkb_action);
175             if (!map->acts) {
176                 free(prev_acts);
177                 map->num_acts = map->size_acts = 0;
178                 return BadAlloc;
179             }
180
181             map->size_acts = need;
182             memset(&map->acts[map->num_acts], 0,
183                    (map->size_acts - map->num_acts) * sizeof(union xkb_action));
184         }
185
186         if (!map->key_acts) {
187             i = xkb->max_key_code + 1;
188             map->key_acts = uTypedCalloc(i, unsigned short);
189             if (!map->key_acts)
190                 return BadAlloc;
191         }
192     }
193
194     if (which & XkbKeyBehaviorsMask) {
195         if (!map->behaviors) {
196             i = xkb->max_key_code + 1;
197             map->behaviors = uTypedCalloc(i, struct xkb_behavior);
198             if (!map->behaviors)
199                 return BadAlloc;
200         }
201     }
202
203     if (which & XkbVirtualModMapMask) {
204         if (!map->vmodmap) {
205             i = xkb->max_key_code + 1;
206             map->vmodmap = uTypedCalloc(i, uint32_t);
207             if (!map->vmodmap)
208                 return BadAlloc;
209         }
210     }
211
212     return Success;
213 }
214
215 int
216 XkbcCopyKeyType(struct xkb_key_type * from, struct xkb_key_type * into)
217 {
218     int i;
219
220     if (!from || !into)
221         return BadMatch;
222
223     free(into->map);
224     into->map = NULL;
225     free(into->preserve);
226     into->preserve= NULL;
227     for (i = 0; i < into->num_levels; i++)
228         free(UNCONSTIFY(into->level_names[i]));
229     free(into->level_names);
230     into->level_names = NULL;
231
232     *into = *from;
233
234     if (from->map && (into->map_count > 0)) {
235         into->map = uTypedCalloc(into->map_count, struct xkb_kt_map_entry);
236         if (!into->map)
237             return BadAlloc;
238         memcpy(into->map, from->map,
239                into->map_count * sizeof(struct xkb_kt_map_entry));
240     }
241
242     if (from->preserve && (into->map_count > 0)) {
243         into->preserve = uTypedCalloc(into->map_count, struct xkb_mods);
244         if (!into->preserve)
245             return BadAlloc;
246         memcpy(into->preserve, from->preserve,
247                into->map_count * sizeof(struct xkb_mods));
248     }
249
250     if (from->level_names && (into->num_levels > 0)) {
251         into->level_names = uTypedCalloc(into->num_levels, const char *);
252         if (!into->level_names)
253             return BadAlloc;
254         for (i = 0; i < into->num_levels; i++)
255             into->level_names[i] = strdup(from->level_names[i]);
256     }
257
258     return Success;
259 }
260
261 xkb_keysym_t *
262 XkbcResizeKeySyms(struct xkb_desc * xkb, xkb_keycode_t key,
263                   unsigned int needed)
264 {
265     uint32_t i, nSyms, nKeySyms;
266     uint32_t nOldSyms;
267     xkb_keysym_t *newSyms;
268
269     if (needed == 0) {
270         xkb->map->key_sym_map[key].offset = 0;
271         return xkb->map->syms;
272     }
273
274     nOldSyms = XkbKeyNumSyms(xkb, key);
275     if (nOldSyms >= needed)
276         return XkbKeySymsPtr(xkb, key);
277
278     if (xkb->map->size_syms - xkb->map->num_syms >= needed) {
279         if (nOldSyms > 0)
280             memcpy(&xkb->map->syms[xkb->map->num_syms],
281                    XkbKeySymsPtr(xkb, key), nOldSyms * sizeof(xkb_keysym_t));
282
283         if ((needed - nOldSyms) > 0)
284             memset(&xkb->map->syms[xkb->map->num_syms + XkbKeyNumSyms(xkb, key)],
285                    0, (needed - nOldSyms) * sizeof(xkb_keysym_t));
286
287         xkb->map->key_sym_map[key].offset = xkb->map->num_syms;
288         xkb->map->num_syms += needed;
289
290         return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
291     }
292
293     xkb->map->size_syms += (needed > 32 ? needed : 32);
294     newSyms = uTypedCalloc(xkb->map->size_syms, xkb_keysym_t);
295     if (!newSyms)
296         return NULL;
297
298     newSyms[0] = NoSymbol;
299     nSyms = 1;
300     for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) {
301         uint32_t nCopy;
302
303         nCopy = nKeySyms = XkbKeyNumSyms(xkb, i);
304         if ((nKeySyms == 0) && (i != key))
305             continue;
306
307         if (i == key)
308             nKeySyms = needed;
309         if (nCopy != 0)
310            memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i),
311                   nCopy * sizeof(xkb_keysym_t));
312         if (nKeySyms > nCopy)
313             memset(&newSyms[nSyms + nCopy], 0,
314                    (nKeySyms - nCopy) * sizeof(xkb_keysym_t));
315
316         xkb->map->key_sym_map[i].offset = nSyms;
317         nSyms += nKeySyms;
318     }
319
320     free(xkb->map->syms);
321     xkb->map->syms = newSyms;
322     xkb->map->num_syms = nSyms;
323
324     return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
325 }
326
327 union xkb_action *
328 XkbcResizeKeyActions(struct xkb_desc * xkb, xkb_keycode_t key, uint32_t needed)
329 {
330     xkb_keycode_t i, nActs;
331     union xkb_action *newActs;
332
333     if (needed == 0) {
334         xkb->server->key_acts[key] = 0;
335         return NULL;
336     }
337
338     if (XkbKeyHasActions(xkb, key) &&
339         (XkbKeyNumSyms(xkb, key) >= (int)needed))
340         return XkbKeyActionsPtr(xkb, key);
341
342     if (xkb->server->size_acts - xkb->server->num_acts >= (int)needed) {
343         xkb->server->key_acts[key] = xkb->server->num_acts;
344         xkb->server->num_acts += needed;
345
346         return &xkb->server->acts[xkb->server->key_acts[key]];
347     }
348
349     xkb->server->size_acts = xkb->server->num_acts + needed + 8;
350     newActs = uTypedCalloc(xkb->server->size_acts, union xkb_action);
351     if (!newActs)
352         return NULL;
353     newActs[0].type = XkbSA_NoAction;
354     nActs = 1;
355
356     for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) {
357         xkb_keycode_t nKeyActs, nCopy;
358
359         if ((xkb->server->key_acts[i] == 0) && (i != key))
360             continue;
361
362         nCopy = nKeyActs = XkbKeyNumActions(xkb, i);
363         if (i == key) {
364             nKeyActs= needed;
365             if (needed < nCopy)
366                 nCopy = needed;
367         }
368
369         if (nCopy > 0)
370             memcpy(&newActs[nActs], XkbKeyActionsPtr(xkb, i),
371                    nCopy * sizeof(union xkb_action));
372         if (nCopy < nKeyActs)
373             memset(&newActs[nActs + nCopy], 0,
374                    (nKeyActs - nCopy) * sizeof(union xkb_action));
375
376         xkb->server->key_acts[i] = nActs;
377         nActs += nKeyActs;
378     }
379
380     free(xkb->server->acts);
381     xkb->server->acts = newActs;
382     xkb->server->num_acts = nActs;
383
384     return &xkb->server->acts[xkb->server->key_acts[key]];
385 }
386
387 void
388 XkbcFreeClientMap(struct xkb_desc * xkb)
389 {
390     int i;
391     struct xkb_client_map * map;
392     struct xkb_key_type * type;
393
394     if (!xkb || !xkb->map)
395         return;
396
397     map = xkb->map;
398
399     for (i = 0, type = map->types; i < map->num_types && type; i++, type++) {
400         int j;
401         free(type->map);
402         free(type->preserve);
403         for (j = 0; j < type->num_levels; j++)
404             free(UNCONSTIFY(type->level_names[j]));
405         free(type->level_names);
406         free(UNCONSTIFY(type->name));
407     }
408     free(map->types);
409     free(map->key_sym_map);
410     free(map->syms);
411     free(map->modmap);
412     free(xkb->map);
413     xkb->map = NULL;
414 }
415
416 void
417 XkbcFreeServerMap(struct xkb_desc * xkb)
418 {
419     struct xkb_server_map * map;
420
421     if (!xkb || !xkb->server)
422         return;
423
424     map = xkb->server;
425
426     free(map->explicit);
427     free(map->key_acts);
428     free(map->acts);
429     free(map->behaviors);
430     free(map->vmodmap);
431     free(xkb->server);
432     xkb->server = NULL;
433 }