Use memset instead of bzero
[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 "xkballoc.h"
30 #include "xkbgeom.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 = _XkbTypedRealloc(compat->sym_interpret,
55                                                  nSI, struct xkb_sym_interpret);
56         if (!compat->sym_interpret) {
57             free(prev_interpret);
58             compat->size_si = compat->num_si = 0;
59             return BadAlloc;
60         }
61
62         if (compat->num_si != 0)
63             _XkbClearElems(compat->sym_interpret, compat->num_si,
64                            compat->size_si - 1, struct xkb_sym_interpret);
65
66         return Success;
67     }
68
69     compat = _XkbTypedCalloc(1, struct xkb_compat_map);
70     if (!compat)
71         return BadAlloc;
72
73     if (nSI > 0) {
74         compat->sym_interpret = _XkbTypedCalloc(nSI, struct xkb_sym_interpret);
75         if (!compat->sym_interpret) {
76             free(compat);
77             return BadAlloc;
78         }
79     }
80     compat->size_si = nSI;
81     compat->num_si = 0;
82     memset(&compat->groups[0], 0, XkbNumKbdGroups * sizeof(struct xkb_mods));
83     xkb->compat = compat;
84
85     return Success;
86 }
87
88
89 static void
90 XkbcFreeCompatMap(struct xkb_desc * xkb, unsigned which, Bool freeMap)
91 {
92     struct xkb_compat_map * compat;
93
94     if (!xkb || !xkb->compat)
95         return;
96
97     compat = xkb->compat;
98     if (freeMap)
99         which = XkbAllCompatMask;
100
101     if (which & XkbGroupCompatMask)
102         memset(&compat->groups[0], 0,
103                XkbNumKbdGroups * sizeof(struct xkb_mods));
104
105     if (which & XkbSymInterpMask) {
106         free(compat->sym_interpret);
107         compat->size_si = compat->num_si = 0;
108         compat->sym_interpret = NULL;
109     }
110
111     if (freeMap) {
112         free(compat);
113         xkb->compat = NULL;
114     }
115 }
116
117 int
118 XkbcAllocNames(struct xkb_desc * xkb, unsigned which, int nTotalRG, int nTotalAliases)
119 {
120     struct xkb_names * names;
121
122     if (!xkb)
123         return BadMatch;
124
125     if (!xkb->names) {
126         xkb->names = _XkbTypedCalloc(1, struct xkb_names);
127         if (!xkb->names)
128             return BadAlloc;
129     }
130     names = xkb->names;
131
132     if ((which & XkbKTLevelNamesMask) && xkb->map && xkb->map->types) {
133         int i;
134         struct xkb_key_type * type;
135
136         type = xkb->map->types;
137         for (i = 0; i < xkb->map->num_types; i++, type++) {
138             if (!type->level_names) {
139                 type->level_names = _XkbTypedCalloc(type->num_levels, uint32_t);
140                 if (!type->level_names)
141                     return BadAlloc;
142             }
143         }
144     }
145
146     if ((which & XkbKeyNamesMask) && !names->keys) {
147         if (!xkb_keymap_keycode_range_is_legal(xkb))
148             return BadMatch;
149
150         names->keys = _XkbTypedCalloc(xkb->max_key_code + 1, struct xkb_key_name);
151         if (!names->keys)
152             return BadAlloc;
153     }
154
155     if ((which & XkbKeyAliasesMask) && (nTotalAliases > 0)) {
156         if (!names->key_aliases)
157             names->key_aliases = _XkbTypedCalloc(nTotalAliases,
158                                                  struct xkb_key_alias);
159         else if (nTotalAliases > names->num_key_aliases) {
160             struct xkb_key_alias *prev_aliases = names->key_aliases;
161
162             names->key_aliases = _XkbTypedRealloc(names->key_aliases,
163                                                   nTotalAliases,
164                                                   struct xkb_key_alias);
165             if (names->key_aliases)
166                 _XkbClearElems(names->key_aliases, names->num_key_aliases,
167                                nTotalAliases - 1, struct xkb_key_alias);
168             else
169                 free(prev_aliases);
170         }
171
172         if (!names->key_aliases) {
173             names->num_key_aliases = 0;
174             return BadAlloc;
175         }
176
177         names->num_key_aliases = nTotalAliases;
178     }
179
180     if ((which & XkbRGNamesMask) && (nTotalRG > 0)) {
181         if (!names->radio_groups)
182             names->radio_groups = _XkbTypedCalloc(nTotalRG, uint32_t);
183         else if (nTotalRG > names->num_rg) {
184             uint32_t *prev_radio_groups = names->radio_groups;
185
186             names->radio_groups = _XkbTypedRealloc(names->radio_groups,
187                                                    nTotalRG, uint32_t);
188             if (names->radio_groups)
189                 _XkbClearElems(names->radio_groups, names->num_rg,
190                                nTotalRG - 1, uint32_t);
191             else
192                 free(prev_radio_groups);
193         }
194
195         if (!names->radio_groups)
196             return BadAlloc;
197
198         names->num_rg = nTotalRG;
199     }
200
201     return Success;
202 }
203
204 static void
205 XkbcFreeNames(struct xkb_desc * xkb, unsigned which, Bool freeMap)
206 {
207     struct xkb_names * names;
208
209     if (!xkb || !xkb->names)
210         return;
211
212     names = xkb->names;
213     if (freeMap)
214         which = XkbAllNamesMask;
215
216     if (which & XkbKTLevelNamesMask) {
217         struct xkb_client_map * map = xkb->map;
218
219         if (map && map->types) {
220             int i;
221             struct xkb_key_type * type = map->types;
222
223             for (i = 0; i < map->num_types; i++, type++) {
224                 free(type->level_names);
225                 type->level_names = NULL;
226             }
227         }
228     }
229
230     if (which & XkbKeyNamesMask) {
231         free(names->keys);
232         names->keys = NULL;
233         names->num_keys = 0;
234     }
235
236     if (which & XkbKeyAliasesMask) {
237         free(names->key_aliases);
238         names->key_aliases = NULL;
239         names->num_key_aliases = 0;
240     }
241
242     if (which & XkbRGNamesMask) {
243         free(names->radio_groups);
244         names->radio_groups = NULL;
245         names->num_rg = 0;
246     }
247
248     if (freeMap) {
249         free(names);
250         xkb->names = NULL;
251     }
252 }
253
254 int
255 XkbcAllocControls(struct xkb_desc * xkb, unsigned which)
256 {
257     if (!xkb)
258         return BadMatch;
259
260     if (!xkb->ctrls) {
261         xkb->ctrls = _XkbTypedCalloc(1, struct xkb_controls);
262         if (!xkb->ctrls)
263             return BadAlloc;
264     }
265
266     if (!xkb->ctrls->per_key_repeat) {
267         xkb->ctrls->per_key_repeat = _XkbTypedCalloc(xkb->max_key_code << 3,
268                                                      unsigned char);
269         if (!xkb->ctrls->per_key_repeat)
270             return BadAlloc;
271     }
272
273     return Success;
274 }
275
276 static void
277 XkbcFreeControls(struct xkb_desc * xkb, unsigned which, Bool freeMap)
278 {
279     if (freeMap && xkb && xkb->ctrls) {
280         free(xkb->ctrls->per_key_repeat);
281         free(xkb->ctrls);
282         xkb->ctrls = NULL;
283     }
284 }
285
286 int
287 XkbcAllocIndicatorMaps(struct xkb_desc * xkb)
288 {
289     if (!xkb)
290         return BadMatch;
291
292     if (!xkb->indicators) {
293         xkb->indicators = _XkbTypedCalloc(1, struct xkb_indicator);
294         if (!xkb->indicators)
295             return BadAlloc;
296     }
297
298     return Success;
299 }
300
301 static void
302 XkbcFreeIndicatorMaps(struct xkb_desc * xkb)
303 {
304     if (xkb) {
305         free(xkb->indicators);
306         xkb->indicators = NULL;
307     }
308 }
309
310 struct xkb_desc *
311 XkbcAllocKeyboard(void)
312 {
313     struct xkb_desc *xkb;
314
315     xkb = _XkbTypedCalloc(1, struct xkb_desc);
316     if (xkb)
317         xkb->device_spec = XkbUseCoreKbd;
318     return xkb;
319 }
320
321 void
322 XkbcFreeKeyboard(struct xkb_desc * xkb, unsigned which, Bool freeAll)
323 {
324     if (!xkb)
325         return;
326
327     if (freeAll)
328         which = XkbAllComponentsMask;
329
330     if (which & XkbClientMapMask)
331         XkbcFreeClientMap(xkb, XkbAllClientInfoMask, True);
332     if (which & XkbServerMapMask)
333         XkbcFreeServerMap(xkb, XkbAllServerInfoMask, True);
334     if (which & XkbCompatMapMask)
335         XkbcFreeCompatMap(xkb, XkbAllCompatMask, True);
336     if (which & XkbIndicatorMapMask)
337         XkbcFreeIndicatorMaps(xkb);
338     if (which & XkbNamesMask)
339         XkbcFreeNames(xkb, XkbAllNamesMask, True);
340     if ((which & XkbGeometryMask) && xkb->geom)
341         XkbcFreeGeometry(xkb->geom, XkbGeomAllMask, True);
342     if (which & XkbControlsMask)
343         XkbcFreeControls(xkb, XkbAllControlsMask, True);
344     if (freeAll)
345         free(xkb);
346 }