Stringify public name types
[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     int i;
218
219     if (!from || !into)
220         return BadMatch;
221
222     free(into->map);
223     into->map = NULL;
224     free(into->preserve);
225     into->preserve= NULL;
226     for (i = 0; i < into->num_levels; i++)
227         free((char *) into->level_names[i]);
228     free(into->level_names);
229     into->level_names = NULL;
230
231     *into = *from;
232
233     if (from->map && (into->map_count > 0)) {
234         into->map = _XkbTypedCalloc(into->map_count, struct xkb_kt_map_entry);
235         if (!into->map)
236             return BadAlloc;
237         memcpy(into->map, from->map,
238                into->map_count * sizeof(struct xkb_kt_map_entry));
239     }
240
241     if (from->preserve && (into->map_count > 0)) {
242         into->preserve = _XkbTypedCalloc(into->map_count, struct xkb_mods);
243         if (!into->preserve)
244             return BadAlloc;
245         memcpy(into->preserve, from->preserve,
246                into->map_count * sizeof(struct xkb_mods));
247     }
248
249     if (from->level_names && (into->num_levels > 0)) {
250         into->level_names = _XkbTypedCalloc(into->num_levels, const char *);
251         if (!into->level_names)
252             return BadAlloc;
253         for (i = 0; i < into->num_levels; i++)
254             into->level_names[i] = strdup(from->level_names[i]);
255     }
256
257     return Success;
258 }
259
260 uint32_t *
261 XkbcResizeKeySyms(struct xkb_desc * xkb, xkb_keycode_t key,
262                   unsigned int needed)
263 {
264     uint32_t i, nSyms, nKeySyms;
265     uint32_t nOldSyms;
266     uint32_t *newSyms;
267
268     if (needed == 0) {
269         xkb->map->key_sym_map[key].offset = 0;
270         return xkb->map->syms;
271     }
272
273     nOldSyms = XkbKeyNumSyms(xkb, key);
274     if (nOldSyms >= needed)
275         return XkbKeySymsPtr(xkb, key);
276
277     if (xkb->map->size_syms - xkb->map->num_syms >= needed) {
278         if (nOldSyms > 0)
279             memcpy(&xkb->map->syms[xkb->map->num_syms],
280                    XkbKeySymsPtr(xkb, key), nOldSyms * sizeof(uint32_t));
281
282         if ((needed - nOldSyms) > 0)
283             memset(&xkb->map->syms[xkb->map->num_syms + XkbKeyNumSyms(xkb, key)],
284                    0, (needed - nOldSyms) * sizeof(uint32_t));
285
286         xkb->map->key_sym_map[key].offset = xkb->map->num_syms;
287         xkb->map->num_syms += needed;
288
289         return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
290     }
291
292     xkb->map->size_syms += (needed > 32 ? needed : 32);
293     newSyms = _XkbTypedCalloc(xkb->map->size_syms, uint32_t);
294     if (!newSyms)
295         return NULL;
296
297     newSyms[0] = NoSymbol;
298     nSyms = 1;
299     for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) {
300         int nCopy;
301
302         nCopy = nKeySyms = XkbKeyNumSyms(xkb, i);
303         if ((nKeySyms == 0) && (i != key))
304             continue;
305
306         if (i == key)
307             nKeySyms = needed;
308         if (nCopy != 0)
309            memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i),
310                   nCopy * sizeof(uint32_t));
311         if (nKeySyms > nCopy)
312             memset(&newSyms[nSyms + nCopy], 0,
313                    (nKeySyms - nCopy) * sizeof(uint32_t));
314
315         xkb->map->key_sym_map[i].offset = nSyms;
316         nSyms += nKeySyms;
317     }
318
319     free(xkb->map->syms);
320     xkb->map->syms = newSyms;
321     xkb->map->num_syms = nSyms;
322
323     return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
324 }
325
326 union xkb_action *
327 XkbcResizeKeyActions(struct xkb_desc * xkb, xkb_keycode_t key, int needed)
328 {
329     xkb_keycode_t i, nActs;
330     union xkb_action *newActs;
331
332     if (needed == 0) {
333         xkb->server->key_acts[key] = 0;
334         return NULL;
335     }
336
337     if (XkbKeyHasActions(xkb, key) &&
338         (XkbKeyNumSyms(xkb, key) >= (unsigned)needed))
339         return XkbKeyActionsPtr(xkb, key);
340
341     if (xkb->server->size_acts - xkb->server->num_acts >= (unsigned)needed) {
342         xkb->server->key_acts[key] = xkb->server->num_acts;
343         xkb->server->num_acts += needed;
344
345         return &xkb->server->acts[xkb->server->key_acts[key]];
346     }
347
348     xkb->server->size_acts = xkb->server->num_acts + needed + 8;
349     newActs = _XkbTypedCalloc(xkb->server->size_acts, union xkb_action);
350     if (!newActs)
351         return NULL;
352     newActs[0].type = XkbSA_NoAction;
353     nActs = 1;
354
355     for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) {
356         xkb_keycode_t nKeyActs, nCopy;
357
358         if ((xkb->server->key_acts[i] == 0) && (i != key))
359             continue;
360
361         nCopy = nKeyActs = XkbKeyNumActions(xkb, i);
362         if (i == key) {
363             nKeyActs= needed;
364             if (needed < nCopy)
365                 nCopy = needed;
366         }
367
368         if (nCopy > 0)
369             memcpy(&newActs[nActs], XkbKeyActionsPtr(xkb, i),
370                    nCopy * sizeof(union xkb_action));
371         if (nCopy < nKeyActs)
372             memset(&newActs[nActs + nCopy], 0,
373                    (nKeyActs - nCopy) * sizeof(union xkb_action));
374
375         xkb->server->key_acts[i] = nActs;
376         nActs += nKeyActs;
377     }
378
379     free(xkb->server->acts);
380     xkb->server->acts = newActs;
381     xkb->server->num_acts = nActs;
382
383     return &xkb->server->acts[xkb->server->key_acts[key]];
384 }
385
386 void
387 XkbcFreeClientMap(struct xkb_desc * xkb)
388 {
389     int i;
390     struct xkb_client_map * map;
391     struct xkb_key_type * type;
392
393     if (!xkb || !xkb->map)
394         return;
395
396     map = xkb->map;
397
398     for (i = 0, type = map->types; i < map->num_types && type; i++, type++) {
399         int j;
400         free(type->map);
401         free(type->preserve);
402         for (j = 0; j < type->num_levels; j++)
403             free((char *) type->level_names[j]);
404         free(type->level_names);
405         free((char *) type->name);
406     }
407     free(map->types);
408     free(map->key_sym_map);
409     free(map->syms);
410     free(map->modmap);
411     free(xkb->map);
412     xkb->map = NULL;
413 }
414
415 void
416 XkbcFreeServerMap(struct xkb_desc * xkb)
417 {
418     struct xkb_server_map * map;
419
420     if (!xkb || !xkb->server)
421         return;
422
423     map = xkb->server;
424
425     free(map->explicit);
426     free(map->key_acts);
427     free(map->acts);
428     free(map->behaviors);
429     free(map->vmodmap);
430     free(xkb->server);
431     xkb->server = NULL;
432 }