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