alloc/galloc: Coding style cleanup
[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 "X11/extensions/XKBcommon.h"
30 #include "XKBcommonint.h"
31 #include <X11/X.h>
32 #include <X11/Xdefs.h>
33 #include <X11/extensions/XKB.h>
34
35 int
36 XkbcAllocCompatMap(XkbcDescPtr xkb, unsigned which, unsigned nSI)
37 {
38     XkbCompatMapPtr compat;
39     XkbSymInterpretRec *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, XkbSymInterpretRec);
56         if (!compat->sym_interpret) {
57             _XkbFree(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, XkbSymInterpretRec);
65
66         return Success;
67     }
68
69     compat = _XkbTypedCalloc(1, XkbCompatMapRec);
70     if (!compat)
71         return BadAlloc;
72
73     if (nSI > 0) {
74         compat->sym_interpret = _XkbTypedCalloc(nSI, XkbSymInterpretRec);
75         if (!compat->sym_interpret) {
76             _XkbFree(compat);
77             return BadAlloc;
78         }
79     }
80     compat->size_si = nSI;
81     compat->num_si = 0;
82     bzero(&compat->groups[0], XkbNumKbdGroups * sizeof(XkbModsRec));
83     xkb->compat = compat;
84
85     return Success;
86 }
87
88
89 void
90 XkbcFreeCompatMap(XkbcDescPtr xkb, unsigned which, Bool freeMap)
91 {
92     XkbCompatMapPtr 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         bzero(&compat->groups[0], XkbNumKbdGroups * sizeof(XkbModsRec));
103
104     if (which & XkbSymInterpMask) {
105         if (compat->sym_interpret && (compat->size_si > 0))
106             _XkbFree(compat->sym_interpret);
107         compat->size_si = compat->num_si = 0;
108         compat->sym_interpret = NULL;
109     }
110
111     if (freeMap) {
112         _XkbFree(compat);
113         xkb->compat = NULL;
114     }
115 }
116
117 int
118 XkbcAllocNames(XkbcDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases)
119 {
120     XkbNamesPtr names;
121
122     if (!xkb)
123         return BadMatch;
124
125     if (!xkb->names) {
126         xkb->names = _XkbTypedCalloc(1, XkbNamesRec);
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         XkbKeyTypePtr 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, Atom);
140                 if (!type->level_names)
141                     return BadAlloc;
142             }
143         }
144     }
145
146     if ((which & XkbKeyNamesMask) && names->keys) {
147         if ((!XkbIsLegalKeycode(xkb->min_key_code)) ||
148             (!XkbIsLegalKeycode(xkb->max_key_code)) ||
149             (xkb->max_key_code < xkb->min_key_code))
150             return BadValue;
151
152         names->keys = _XkbTypedCalloc(xkb->max_key_code + 1, XkbKeyNameRec);
153         if (!names->keys)
154             return BadAlloc;
155     }
156
157     if ((which & XkbKeyAliasesMask) && (nTotalAliases > 0)) {
158         if (!names->key_aliases)
159             names->key_aliases = _XkbTypedCalloc(nTotalAliases,
160                                                  XkbKeyAliasRec);
161         else if (nTotalAliases > names->num_key_aliases) {
162             XkbKeyAliasRec *prev_aliases = names->key_aliases;
163
164             names->key_aliases = _XkbTypedRealloc(names->key_aliases,
165                                                   nTotalAliases,
166                                                   XkbKeyAliasRec);
167             if (names->key_aliases)
168                 _XkbClearElems(names->key_aliases, names->num_key_aliases,
169                                nTotalAliases - 1, XkbKeyAliasRec);
170             else
171                 _XkbFree(prev_aliases);
172         }
173
174         if (!names->key_aliases) {
175             names->num_key_aliases = 0;
176             return BadAlloc;
177         }
178
179         names->num_key_aliases = nTotalAliases;
180     }
181
182     if ((which & XkbRGNamesMask) && (nTotalRG > 0)) {
183         if (!names->radio_groups)
184             names->radio_groups = _XkbTypedCalloc(nTotalRG, Atom);
185         else if (nTotalRG > names->num_rg) {
186             Atom *prev_radio_groups = names->radio_groups;
187
188             names->radio_groups = _XkbTypedRealloc(names->radio_groups,
189                                                    nTotalRG, Atom);
190             if (names->radio_groups)
191                 _XkbClearElems(names->radio_groups, names->num_rg,
192                                nTotalRG - 1, Atom);
193             else
194                 _XkbFree(prev_radio_groups);
195         }
196
197         if (!names->radio_groups)
198             return BadAlloc;
199
200         names->num_rg = nTotalRG;
201     }
202
203     return Success;
204 }
205
206 void
207 XkbcFreeNames(XkbcDescPtr xkb, unsigned which, Bool freeMap)
208 {
209     XkbNamesPtr names;
210
211     if (!xkb || !xkb->names)
212         return;
213
214     names = xkb->names;
215     if (freeMap)
216         which = XkbAllNamesMask;
217
218     if (which & XkbKTLevelNamesMask) {
219         XkbClientMapPtr map = xkb->map;
220
221         if (map && map->types) {
222             int i;
223             XkbKeyTypePtr type = map->types;
224
225             for (i = 0; i < map->num_types; i++, type++) {
226                 if (type->level_names) {
227                     _XkbFree(type->level_names);
228                     type->level_names = NULL;
229                 }
230             }
231         }
232     }
233
234     if ((which & XkbKeyNamesMask) && names->keys) {
235         _XkbFree(names->keys);
236         names->keys = NULL;
237         names->num_keys = 0;
238     }
239
240     if ((which & XkbKeyAliasesMask) && names->key_aliases) {
241         _XkbFree(names->key_aliases);
242         names->key_aliases = NULL;
243         names->num_key_aliases = 0;
244     }
245
246     if ((which & XkbRGNamesMask) && names->radio_groups) {
247         _XkbFree(names->radio_groups);
248         names->radio_groups = NULL;
249         names->num_rg = 0;
250     }
251
252     if (freeMap) {
253         _XkbFree(names);
254         xkb->names = NULL;
255     }
256 }
257
258 int
259 XkbcAllocControls(XkbcDescPtr xkb, unsigned which)
260 {
261     if (!xkb)
262         return BadMatch;
263
264     if (!xkb->ctrls) {
265         xkb->ctrls = _XkbTypedCalloc(1, XkbControlsRec);
266         if (!xkb->ctrls)
267             return BadAlloc;
268     }
269
270     return Success;
271 }
272
273 void
274 XkbcFreeControls(XkbcDescPtr xkb, unsigned which, Bool freeMap)
275 {
276     if (freeMap && xkb && xkb->ctrls) {
277         _XkbFree(xkb->ctrls);
278         xkb->ctrls = NULL;
279     }
280 }
281
282 int
283 XkbcAllocIndicatorMaps(XkbcDescPtr xkb)
284 {
285     if (!xkb)
286         return BadMatch;
287
288     if (!xkb->indicators) {
289         xkb->indicators = _XkbTypedCalloc(1, XkbIndicatorRec);
290         if (!xkb->indicators)
291             return BadAlloc;
292     }
293
294     return Success;
295 }
296
297 void
298 XkbcFreeIndicatorMaps(XkbcDescPtr xkb)
299 {
300     if (xkb && xkb->indicators) {
301         _XkbFree(xkb->indicators);
302         xkb->indicators = NULL;
303     }
304 }
305
306 XkbcDescRec *
307 XkbcAllocKeyboard(void)
308 {
309     XkbcDescRec *xkb;
310
311     xkb = _XkbTypedCalloc(1, XkbcDescRec);
312     if (xkb)
313         xkb->device_spec = XkbUseCoreKbd;
314     return xkb;
315 }
316
317 void
318 XkbcFreeKeyboard(XkbcDescPtr xkb, unsigned which, Bool freeAll)
319 {
320     if (!xkb)
321         return;
322
323     if (freeAll)
324         which = XkbAllComponentsMask;
325
326     if (which & XkbClientMapMask)
327         XkbcFreeClientMap(xkb, XkbAllClientInfoMask, True);
328     if (which & XkbServerMapMask)
329         XkbcFreeServerMap(xkb, XkbAllServerInfoMask, True);
330     if (which & XkbCompatMapMask)
331         XkbcFreeCompatMap(xkb, XkbAllCompatMask, True);
332     if (which & XkbIndicatorMapMask)
333         XkbcFreeIndicatorMaps(xkb);
334     if (which & XkbNamesMask)
335         XkbcFreeNames(xkb, XkbAllNamesMask, True);
336     if ((which & XkbGeometryMask) && xkb->geom)
337         XkbcFreeGeometry(xkb->geom, XkbGeomAllMask, True);
338     if (which & XkbControlsMask)
339         XkbcFreeControls(xkb, XkbAllControlsMask, True);
340     if (freeAll)
341         _XkbFree(xkb);
342 }
343
344 int
345 XkbcAllocClientMap(XkbcDescPtr xkb, unsigned which, unsigned nTotalTypes)
346 {
347     int i;
348     XkbClientMapPtr map;
349
350     if (!xkb || ((nTotalTypes > 0) && (nTotalTypes < XkbNumRequiredTypes)))
351         return BadValue;
352
353     if ((which & XkbKeySymsMask) &&
354         ((!XkbIsLegalKeycode(xkb->min_key_code)) ||
355          (!XkbIsLegalKeycode(xkb->max_key_code)) ||
356          (xkb->max_key_code < xkb->min_key_code))) {
357 #ifdef DEBUG
358         fprintf(stderr, "bad keycode (%d,%d) in XkbAllocClientMap\n",
359                 xkb->min_key_code, xkb->max_key_code);
360 #endif
361         return BadValue;
362     }
363
364     if (!xkb->map) {
365         map = _XkbTypedCalloc(1, XkbClientMapRec);
366         if (!map)
367             return BadAlloc;
368         xkb->map = map;
369     }
370     else
371         map = xkb->map;
372
373     if ((which & XkbKeyTypesMask) && (nTotalTypes > 0)) {
374         if (!map->types) {
375             map->types = _XkbTypedCalloc(nTotalTypes, XkbKeyTypeRec);
376             if (!map->types)
377                 return BadAlloc;
378
379             map->num_types = 0;
380             map->size_types = nTotalTypes;
381         }
382         else if (map->size_types < nTotalTypes) {
383             XkbKeyTypeRec *prev_types = map->types;
384
385             map->types = _XkbTypedRealloc(map->types, nTotalTypes,
386                                           XkbKeyTypeRec);
387             if (!map->types) {
388                 _XkbFree(prev_types);
389                 map->num_types = map->size_types = 0;
390                 return BadAlloc;
391             }
392
393             map->size_types = nTotalTypes;
394             bzero(&map->types[map->num_types],
395                   (map->size_types - map->num_types) * sizeof(XkbKeyTypeRec));
396         }
397     }
398
399     if (which & XkbKeySymsMask) {
400         int nKeys = XkbNumKeys(xkb);
401
402         if (!map->syms) {
403             map->size_syms = (nKeys * 15) / 10;
404             map->syms = _XkbTypedCalloc(map->size_syms, KeySym);
405             if (!map->syms) {
406                 map->size_syms = 0;
407                 return BadAlloc;
408             }
409             map->num_syms = 1;
410             map->syms[0] = NoSymbol;
411         }
412
413         if (!map->key_sym_map) {
414             i = xkb->max_key_code + 1;
415             map->key_sym_map = _XkbTypedCalloc(i, XkbSymMapRec);
416             if (!map->key_sym_map)
417                 return BadAlloc;
418         }
419     }
420
421     if (which & XkbModifierMapMask) {
422         if ((!XkbIsLegalKeycode(xkb->min_key_code)) ||
423             (!XkbIsLegalKeycode(xkb->max_key_code)) ||
424             (xkb->max_key_code < xkb->min_key_code))
425             return BadMatch;
426
427         if (!map->modmap) {
428             i = xkb->max_key_code + 1;
429             map->modmap = _XkbTypedCalloc(i, unsigned char);
430             if (!map->modmap)
431                 return BadAlloc;
432         }
433     }
434
435     return Success;
436 }
437
438 int
439 XkbcAllocServerMap(XkbcDescPtr xkb, unsigned which, unsigned nNewActions)
440 {
441     int i;
442     XkbServerMapPtr map;
443
444     if (!xkb)
445         return BadMatch;
446
447     if (!xkb->server) {
448         map = _XkbTypedCalloc(1, XkbServerMapRec);
449         if (!map)
450             return BadAlloc;
451
452         for (i = 0; i < XkbNumVirtualMods; i++)
453             map->vmods[i] = XkbNoModifierMask;
454
455         xkb->server = map;
456     }
457     else
458         map = xkb->server;
459
460     if (which & XkbExplicitComponentsMask) {
461         if ((!XkbIsLegalKeycode(xkb->min_key_code)) ||
462             (!XkbIsLegalKeycode(xkb->max_key_code)) ||
463             (xkb->max_key_code < xkb->min_key_code))
464             return BadMatch;
465
466         if (!map->explicit) {
467             i = xkb->max_key_code + 1;
468             map->explicit = _XkbTypedCalloc(i, unsigned char);
469             if (!map->explicit)
470                 return BadAlloc;
471         }
472     }
473
474     if (which&XkbKeyActionsMask) {
475         if ((!XkbIsLegalKeycode(xkb->min_key_code)) ||
476             (!XkbIsLegalKeycode(xkb->max_key_code)) ||
477             (xkb->max_key_code < xkb->min_key_code))
478             return BadMatch;
479
480         if (nNewActions < 1)
481             nNewActions = 1;
482
483         if (!map->acts) {
484             map->acts = _XkbTypedCalloc(nNewActions + 1, XkbAction);
485             if (!map->acts)
486                 return BadAlloc;
487             map->num_acts = 1;
488             map->size_acts = nNewActions + 1;
489         }
490         else if ((map->size_acts - map->num_acts) < nNewActions) {
491             unsigned need;
492             XkbAction *prev_acts = map->acts;
493
494             need = map->num_acts + nNewActions;
495             map->acts = _XkbTypedRealloc(map->acts, need, XkbAction);
496             if (!map->acts) {
497                 _XkbFree(prev_acts);
498                 map->num_acts = map->size_acts = 0;
499                 return BadAlloc;
500             }
501
502             map->size_acts = need;
503             bzero(&map->acts[map->num_acts],
504                   (map->size_acts - map->num_acts) * sizeof(XkbAction));
505         }
506
507         if (!map->key_acts) {
508             i = xkb->max_key_code + 1;
509             map->key_acts = _XkbTypedCalloc(i, unsigned short);
510             if (!map->key_acts)
511                 return BadAlloc;
512         }
513     }
514
515     if (which & XkbKeyBehaviorsMask) {
516         if ((!XkbIsLegalKeycode(xkb->min_key_code)) ||
517             (!XkbIsLegalKeycode(xkb->max_key_code)) ||
518             (xkb->max_key_code < xkb->min_key_code))
519             return BadMatch;
520
521         if (!map->behaviors) {
522             i = xkb->max_key_code + 1;
523             map->behaviors = _XkbTypedCalloc(i, XkbBehavior);
524             if (!map->behaviors)
525                 return BadAlloc;
526         }
527     }
528
529     if (which & XkbVirtualModMapMask) {
530         if ((!XkbIsLegalKeycode(xkb->min_key_code)) ||
531             (!XkbIsLegalKeycode(xkb->max_key_code)) ||
532             (xkb->max_key_code < xkb->min_key_code))
533             return BadMatch;
534
535         if (!map->vmodmap) {
536             i = xkb->max_key_code + 1;
537             map->vmodmap = _XkbTypedCalloc(i, unsigned short);
538             if (!map->vmodmap)
539                 return BadAlloc;
540         }
541     }
542
543     return Success;
544 }
545
546 void
547 XkbcFreeClientMap(XkbcDescPtr xkb, unsigned what, Bool freeMap)
548 {
549     XkbClientMapPtr map;
550
551     if (!xkb || !xkb->map)
552         return;
553
554     if (freeMap)
555         what = XkbAllClientInfoMask;
556     map = xkb->map;
557
558     if (what & XkbKeyTypesMask) {
559         if (map->types) {
560             if (map->num_types > 0) {
561                 int i;
562                 XkbKeyTypePtr type;
563
564                 for (i = 0, type = map->types; i < map->num_types; i++, type++) {
565                     if (type->map) {
566                         _XkbFree(type->map);
567                         type->map = NULL;
568                     }
569                     if (type->preserve) {
570                         _XkbFree(type->preserve);
571                         type->preserve = NULL;
572                     }
573                     type->map_count = 0;
574                     if (type->level_names) {
575                         _XkbFree(type->level_names);
576                         type->level_names = NULL;
577                     }
578                 }
579             }
580             _XkbFree(map->types);
581             map->num_types = map->size_types = 0;
582             map->types = NULL;
583         }
584     }
585
586     if (what & XkbKeySymsMask) {
587         if (map->key_sym_map) {
588             _XkbFree(map->key_sym_map);
589             map->key_sym_map = NULL;
590         }
591         if (map->syms) {
592             _XkbFree(map->syms);
593             map->size_syms = map->num_syms = 0;
594             map->syms = NULL;
595         }
596     }
597
598     if ((what & XkbModifierMapMask) && map->modmap) {
599         _XkbFree(map->modmap);
600         map->modmap = NULL;
601     }
602
603     if (freeMap) {
604         _XkbFree(xkb->map);
605         xkb->map = NULL;
606     }
607 }
608
609 void
610 XkbcFreeServerMap(XkbcDescPtr xkb, unsigned what, Bool freeMap)
611 {
612     XkbServerMapPtr map;
613
614     if (!xkb || !xkb->server)
615         return;
616
617     if (freeMap)
618         what = XkbAllServerInfoMask;
619     map = xkb->server;
620
621     if ((what & XkbExplicitComponentsMask) && map->explicit) {
622         _XkbFree(map->explicit);
623         map->explicit = NULL;
624     }
625
626     if (what & XkbKeyActionsMask) {
627         if (map->key_acts) {
628             _XkbFree(map->key_acts);
629             map->key_acts = NULL;
630         }
631         if (map->acts) {
632             _XkbFree(map->acts);
633             map->num_acts = map->size_acts = 0;
634             map->acts = NULL;
635         }
636     }
637
638     if ((what & XkbKeyBehaviorsMask) && map->behaviors) {
639         _XkbFree(map->behaviors);
640         map->behaviors = NULL;
641     }
642
643     if ((what & XkbVirtualModMapMask) && map->vmodmap) {
644         _XkbFree(map->vmodmap);
645         map->vmodmap = NULL;
646     }
647
648     if (freeMap) {
649         _XkbFree(xkb->server);
650         xkb->server = NULL;
651     }
652 }