Use xkb_group_index_t for group variables throughout
[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 #include "xkb-priv.h"
27 #include "alloc.h"
28
29 int
30 XkbcCopyKeyType(const struct xkb_key_type *from, struct xkb_key_type *into)
31 {
32     int i;
33
34     if (!from || !into)
35         return BadMatch;
36
37     darray_free(into->map);
38     free(into->preserve);
39     for (i = 0; i < into->num_levels; i++)
40         free(into->level_names[i]);
41     free(into->level_names);
42
43     *into = *from;
44
45     darray_copy(into->map, from->map);
46
47     if (from->preserve && !darray_empty(into->map)) {
48         into->preserve = calloc(darray_size(into->map),
49                                 sizeof(*into->preserve));
50         if (!into->preserve)
51             return BadAlloc;
52         memcpy(into->preserve, from->preserve,
53                darray_size(into->map) * sizeof(*into->preserve));
54     }
55
56     if (from->level_names && into->num_levels > 0) {
57         into->level_names = calloc(into->num_levels,
58                                    sizeof(*into->level_names));
59         if (!into->level_names)
60             return BadAlloc;
61
62         for (i = 0; i < into->num_levels; i++)
63             into->level_names[i] = strdup(from->level_names[i]);
64     }
65
66     return Success;
67 }
68
69 union xkb_action *
70 XkbcResizeKeyActions(struct xkb_keymap *keymap, struct xkb_key *key,
71                      uint32_t needed)
72 {
73     size_t old_ndx, old_num_acts, new_ndx;
74
75     if (needed == 0) {
76         key->acts_index = 0;
77         return NULL;
78     }
79
80     if (XkbKeyHasActions(key) && key->width >= needed)
81         return XkbKeyActionsPtr(keymap, key);
82
83     /*
84      * The key may already be in the array, but without enough space.
85      * This should not happen often, so in order to avoid moving and
86      * copying stuff from acts and key_acts, we just allocate new
87      * space for the key at the end, and leave the old space alone.
88      */
89
90     old_ndx = key->acts_index;
91     old_num_acts = XkbKeyNumActions(key);
92     new_ndx = darray_size(keymap->acts);
93
94     darray_resize0(keymap->acts, new_ndx + needed);
95     key->acts_index = new_ndx;
96
97     /*
98      * The key was already in the array, copy the old actions to the
99      * new space.
100      */
101     if (old_ndx != 0)
102         memcpy(darray_mem(keymap->acts, new_ndx),
103                darray_mem(keymap->acts, old_ndx),
104                old_num_acts * sizeof(union xkb_action));
105
106     return XkbKeyActionsPtr(keymap, key);
107 }
108
109 static void
110 free_types(struct xkb_keymap *keymap)
111 {
112     struct xkb_key_type *type;
113
114     darray_foreach(type, keymap->types) {
115         int j;
116         darray_free(type->map);
117         free(type->preserve);
118         for (j = 0; j < type->num_levels; j++)
119             free(type->level_names[j]);
120         free(type->level_names);
121         free(type->name);
122     }
123     darray_free(keymap->types);
124 }
125
126 static void
127 free_keys(struct xkb_keymap *keymap)
128 {
129     struct xkb_key *key;
130
131     darray_foreach(key, keymap->keys) {
132         free(key->sym_index);
133         free(key->num_syms);
134         darray_free(key->syms);
135     }
136
137     darray_free(keymap->keys);
138 }
139
140 static void
141 free_names(struct xkb_keymap *keymap)
142 {
143     int i;
144
145     for (i = 0; i < XkbNumVirtualMods; i++)
146         free(keymap->vmod_names[i]);
147
148     for (i = 0; i < XkbNumIndicators; i++)
149         free(keymap->indicator_names[i]);
150
151     for (i = 0; i < XkbNumKbdGroups; i++)
152         free(keymap->group_names[i]);
153
154     darray_free(keymap->key_aliases);
155
156     free(keymap->keycodes_section_name);
157     free(keymap->symbols_section_name);
158     free(keymap->types_section_name);
159     free(keymap->compat_section_name);
160 }
161
162 struct xkb_keymap *
163 XkbcAllocKeyboard(struct xkb_context *ctx)
164 {
165     struct xkb_keymap *keymap;
166
167     keymap = uTypedCalloc(1, struct xkb_keymap);
168     if (!keymap)
169         return NULL;
170
171     keymap->refcnt = 1;
172     keymap->ctx = xkb_context_ref(ctx);
173
174     return keymap;
175 }
176
177 void
178 XkbcFreeKeyboard(struct xkb_keymap *keymap)
179 {
180     if (!keymap)
181         return;
182
183     free_types(keymap);
184     darray_free(keymap->acts);
185     darray_free(keymap->sym_interpret);
186     free_names(keymap);
187     free_keys(keymap);
188     xkb_context_unref(keymap->ctx);
189     free(keymap);
190 }