| @@ -1,1003 +1,1003 @@ | | | @@ -1,1003 +1,1003 @@ |
1 | /************************************************************ | | 1 | /************************************************************ |
2 | Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. | | 2 | Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. |
3 | | | 3 | |
4 | Permission to use, copy, modify, and distribute this | | 4 | Permission to use, copy, modify, and distribute this |
5 | software and its documentation for any purpose and without | | 5 | software and its documentation for any purpose and without |
6 | fee is hereby granted, provided that the above copyright | | 6 | fee is hereby granted, provided that the above copyright |
7 | notice appear in all copies and that both that copyright | | 7 | notice appear in all copies and that both that copyright |
8 | notice and this permission notice appear in supporting | | 8 | notice and this permission notice appear in supporting |
9 | documentation, and that the name of Silicon Graphics not be | | 9 | documentation, and that the name of Silicon Graphics not be |
10 | used in advertising or publicity pertaining to distribution | | 10 | used in advertising or publicity pertaining to distribution |
11 | of the software without specific prior written permission. | | 11 | of the software without specific prior written permission. |
12 | Silicon Graphics makes no representation about the suitability | | 12 | Silicon Graphics makes no representation about the suitability |
13 | of this software for any purpose. It is provided "as is" | | 13 | of this software for any purpose. It is provided "as is" |
14 | without any express or implied warranty. | | 14 | without any express or implied warranty. |
15 | | | 15 | |
16 | SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS | | 16 | SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS |
17 | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | | 17 | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
18 | AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON | | 18 | AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON |
19 | GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL | | 19 | GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL |
20 | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | | 20 | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, |
21 | DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE | | 21 | DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
22 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH | | 22 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH |
23 | THE USE OR PERFORMANCE OF THIS SOFTWARE. | | 23 | THE USE OR PERFORMANCE OF THIS SOFTWARE. |
24 | | | 24 | |
25 | ********************************************************/ | | 25 | ********************************************************/ |
26 | | | 26 | |
27 | #ifdef HAVE_CONFIG_H | | 27 | #ifdef HAVE_CONFIG_H |
28 | #include <config.h> | | 28 | #include <config.h> |
29 | #endif | | 29 | #endif |
30 | | | 30 | |
31 | | | 31 | |
32 | #include <stdio.h> | | 32 | #include <stdio.h> |
33 | #include "Xlibint.h" | | 33 | #include "Xlibint.h" |
34 | #include <X11/extensions/XKBproto.h> | | 34 | #include <X11/extensions/XKBproto.h> |
35 | #include <X11/keysym.h> | | 35 | #include <X11/keysym.h> |
36 | #include "XKBlibint.h" | | 36 | #include "XKBlibint.h" |
37 | | | 37 | |
38 | | | 38 | |
39 | /***====================================================================***/ | | 39 | /***====================================================================***/ |
40 | | | 40 | |
41 | Status | | 41 | Status |
42 | XkbAllocClientMap(XkbDescPtr xkb, unsigned which, unsigned nTotalTypes) | | 42 | XkbAllocClientMap(XkbDescPtr xkb, unsigned which, unsigned nTotalTypes) |
43 | { | | 43 | { |
44 | register int i; | | 44 | register int i; |
45 | XkbClientMapPtr map; | | 45 | XkbClientMapPtr map; |
46 | | | 46 | |
47 | if ((xkb == NULL) || | | 47 | if ((xkb == NULL) || |
48 | ((nTotalTypes > 0) && (nTotalTypes < XkbNumRequiredTypes))) | | 48 | ((nTotalTypes > 0) && (nTotalTypes < XkbNumRequiredTypes))) |
49 | return BadValue; | | 49 | return BadValue; |
50 | if ((which & XkbKeySymsMask) && | | 50 | if ((which & XkbKeySymsMask) && |
51 | ((!XkbIsLegalKeycode(xkb->min_key_code)) || | | 51 | ((!XkbIsLegalKeycode(xkb->min_key_code)) || |
52 | (!XkbIsLegalKeycode(xkb->max_key_code)) || | | 52 | (!XkbIsLegalKeycode(xkb->max_key_code)) || |
53 | (xkb->max_key_code < xkb->min_key_code))) { | | 53 | (xkb->max_key_code < xkb->min_key_code))) { |
54 | #ifdef DEBUG | | 54 | #ifdef DEBUG |
55 | fprintf(stderr, "bad keycode (%d,%d) in XkbAllocClientMap\n", | | 55 | fprintf(stderr, "bad keycode (%d,%d) in XkbAllocClientMap\n", |
56 | xkb->min_key_code, xkb->max_key_code); | | 56 | xkb->min_key_code, xkb->max_key_code); |
57 | #endif | | 57 | #endif |
58 | return BadValue; | | 58 | return BadValue; |
59 | } | | 59 | } |
60 | | | 60 | |
61 | if (xkb->map == NULL) { | | 61 | if (xkb->map == NULL) { |
62 | map = _XkbTypedCalloc(1, XkbClientMapRec); | | 62 | map = _XkbTypedCalloc(1, XkbClientMapRec); |
63 | if (map == NULL) | | 63 | if (map == NULL) |
64 | return BadAlloc; | | 64 | return BadAlloc; |
65 | xkb->map = map; | | 65 | xkb->map = map; |
66 | } | | 66 | } |
67 | else | | 67 | else |
68 | map = xkb->map; | | 68 | map = xkb->map; |
69 | | | 69 | |
70 | if ((which & XkbKeyTypesMask) && (nTotalTypes > 0)) { | | 70 | if ((which & XkbKeyTypesMask) && (nTotalTypes > 0)) { |
71 | if (map->types == NULL) { | | 71 | if (map->types == NULL) { |
72 | map->types = _XkbTypedCalloc(nTotalTypes, XkbKeyTypeRec); | | 72 | map->types = _XkbTypedCalloc(nTotalTypes, XkbKeyTypeRec); |
73 | if (map->types == NULL) | | 73 | if (map->types == NULL) |
74 | return BadAlloc; | | 74 | return BadAlloc; |
75 | map->num_types = 0; | | 75 | map->num_types = 0; |
76 | map->size_types = nTotalTypes; | | 76 | map->size_types = nTotalTypes; |
77 | } | | 77 | } |
78 | else if (map->size_types < nTotalTypes) { | | 78 | else if (map->size_types < nTotalTypes) { |
79 | XkbKeyTypeRec *prev_types = map->types; | | 79 | XkbKeyTypeRec *prev_types = map->types; |
80 | | | 80 | |
81 | map->types = | | 81 | map->types = |
82 | _XkbTypedRealloc(map->types, nTotalTypes, XkbKeyTypeRec); | | 82 | _XkbTypedRealloc(map->types, nTotalTypes, XkbKeyTypeRec); |
83 | if (map->types == NULL) { | | 83 | if (map->types == NULL) { |
84 | _XkbFree(prev_types); | | 84 | _XkbFree(prev_types); |
85 | map->num_types = map->size_types = 0; | | 85 | map->num_types = map->size_types = 0; |
86 | return BadAlloc; | | 86 | return BadAlloc; |
87 | } | | 87 | } |
88 | map->size_types = nTotalTypes; | | 88 | map->size_types = nTotalTypes; |
89 | bzero(&map->types[map->num_types], | | 89 | bzero(&map->types[map->num_types], |
90 | ((map->size_types - map->num_types) * sizeof(XkbKeyTypeRec))); | | 90 | ((map->size_types - map->num_types) * sizeof(XkbKeyTypeRec))); |
91 | } | | 91 | } |
92 | } | | 92 | } |
93 | if (which & XkbKeySymsMask) { | | 93 | if (which & XkbKeySymsMask) { |
94 | int nKeys = XkbNumKeys(xkb); | | 94 | int nKeys = XkbNumKeys(xkb); |
95 | | | 95 | |
96 | if (map->syms == NULL) { | | 96 | if (map->syms == NULL) { |
97 | map->size_syms = (nKeys * 15) / 10; | | 97 | map->size_syms = (nKeys * 15) / 10; |
98 | map->syms = _XkbTypedCalloc(map->size_syms, KeySym); | | 98 | map->syms = _XkbTypedCalloc(map->size_syms, KeySym); |
99 | if (!map->syms) { | | 99 | if (!map->syms) { |
100 | map->size_syms = 0; | | 100 | map->size_syms = 0; |
101 | return BadAlloc; | | 101 | return BadAlloc; |
102 | } | | 102 | } |
103 | map->num_syms = 1; | | 103 | map->num_syms = 1; |
104 | map->syms[0] = NoSymbol; | | 104 | map->syms[0] = NoSymbol; |
105 | } | | 105 | } |
106 | if (map->key_sym_map == NULL) { | | 106 | if (map->key_sym_map == NULL) { |
107 | i = xkb->max_key_code + 1; | | 107 | i = xkb->max_key_code + 1; |
108 | map->key_sym_map = _XkbTypedCalloc(i, XkbSymMapRec); | | 108 | map->key_sym_map = _XkbTypedCalloc(i, XkbSymMapRec); |
109 | if (map->key_sym_map == NULL) | | 109 | if (map->key_sym_map == NULL) |
110 | return BadAlloc; | | 110 | return BadAlloc; |
111 | } | | 111 | } |
112 | } | | 112 | } |
113 | if (which & XkbModifierMapMask) { | | 113 | if (which & XkbModifierMapMask) { |
114 | if ((!XkbIsLegalKeycode(xkb->min_key_code)) || | | 114 | if ((!XkbIsLegalKeycode(xkb->min_key_code)) || |
115 | (!XkbIsLegalKeycode(xkb->max_key_code)) || | | 115 | (!XkbIsLegalKeycode(xkb->max_key_code)) || |
116 | (xkb->max_key_code < xkb->min_key_code)) | | 116 | (xkb->max_key_code < xkb->min_key_code)) |
117 | return BadMatch; | | 117 | return BadMatch; |
118 | if (map->modmap == NULL) { | | 118 | if (map->modmap == NULL) { |
119 | i = xkb->max_key_code + 1; | | 119 | i = xkb->max_key_code + 1; |
120 | map->modmap = _XkbTypedCalloc(i, unsigned char); | | 120 | map->modmap = _XkbTypedCalloc(i, unsigned char); |
121 | if (map->modmap == NULL) | | 121 | if (map->modmap == NULL) |
122 | return BadAlloc; | | 122 | return BadAlloc; |
123 | } | | 123 | } |
124 | } | | 124 | } |
125 | return Success; | | 125 | return Success; |
126 | } | | 126 | } |
127 | | | 127 | |
128 | Status | | 128 | Status |
129 | XkbAllocServerMap(XkbDescPtr xkb, unsigned which, unsigned nNewActions) | | 129 | XkbAllocServerMap(XkbDescPtr xkb, unsigned which, unsigned nNewActions) |
130 | { | | 130 | { |
131 | register int i; | | 131 | register int i; |
132 | XkbServerMapPtr map; | | 132 | XkbServerMapPtr map; |
133 | | | 133 | |
134 | if (xkb == NULL) | | 134 | if (xkb == NULL) |
135 | return BadMatch; | | 135 | return BadMatch; |
136 | if (xkb->server == NULL) { | | 136 | if (xkb->server == NULL) { |
137 | map = _XkbTypedCalloc(1, XkbServerMapRec); | | 137 | map = _XkbTypedCalloc(1, XkbServerMapRec); |
138 | if (map == NULL) | | 138 | if (map == NULL) |
139 | return BadAlloc; | | 139 | return BadAlloc; |
140 | for (i = 0; i < XkbNumVirtualMods; i++) { | | 140 | for (i = 0; i < XkbNumVirtualMods; i++) { |
141 | map->vmods[i] = XkbNoModifierMask; | | 141 | map->vmods[i] = XkbNoModifierMask; |
142 | } | | 142 | } |
143 | xkb->server = map; | | 143 | xkb->server = map; |
144 | } | | 144 | } |
145 | else | | 145 | else |
146 | map = xkb->server; | | 146 | map = xkb->server; |
147 | if (which & XkbExplicitComponentsMask) { | | 147 | if (which & XkbExplicitComponentsMask) { |
148 | if ((!XkbIsLegalKeycode(xkb->min_key_code)) || | | 148 | if ((!XkbIsLegalKeycode(xkb->min_key_code)) || |
149 | (!XkbIsLegalKeycode(xkb->max_key_code)) || | | 149 | (!XkbIsLegalKeycode(xkb->max_key_code)) || |
150 | (xkb->max_key_code < xkb->min_key_code)) | | 150 | (xkb->max_key_code < xkb->min_key_code)) |
151 | return BadMatch; | | 151 | return BadMatch; |
152 | if (map->explicit == NULL) { | | 152 | if (map->explicit == NULL) { |
153 | i = xkb->max_key_code + 1; | | 153 | i = xkb->max_key_code + 1; |
154 | map->explicit = _XkbTypedCalloc(i, unsigned char); | | 154 | map->explicit = _XkbTypedCalloc(i, unsigned char); |
155 | if (map->explicit == NULL) | | 155 | if (map->explicit == NULL) |
156 | return BadAlloc; | | 156 | return BadAlloc; |
157 | } | | 157 | } |
158 | } | | 158 | } |
159 | if (which & XkbKeyActionsMask) { | | 159 | if (which & XkbKeyActionsMask) { |
160 | if ((!XkbIsLegalKeycode(xkb->min_key_code)) || | | 160 | if ((!XkbIsLegalKeycode(xkb->min_key_code)) || |
161 | (!XkbIsLegalKeycode(xkb->max_key_code)) || | | 161 | (!XkbIsLegalKeycode(xkb->max_key_code)) || |
162 | (xkb->max_key_code < xkb->min_key_code)) | | 162 | (xkb->max_key_code < xkb->min_key_code)) |
163 | return BadMatch; | | 163 | return BadMatch; |
164 | if (nNewActions < 1) | | 164 | if (nNewActions < 1) |
165 | nNewActions = 1; | | 165 | nNewActions = 1; |
166 | if (map->acts == NULL) { | | 166 | if (map->acts == NULL) { |
167 | map->acts = _XkbTypedCalloc((nNewActions + 1), XkbAction); | | 167 | map->acts = _XkbTypedCalloc((nNewActions + 1), XkbAction); |
168 | if (map->acts == NULL) | | 168 | if (map->acts == NULL) |
169 | return BadAlloc; | | 169 | return BadAlloc; |
170 | map->num_acts = 1; | | 170 | map->num_acts = 1; |
171 | map->size_acts = nNewActions + 1; | | 171 | map->size_acts = nNewActions + 1; |
172 | } | | 172 | } |
173 | else if ((map->size_acts - map->num_acts) < nNewActions) { | | 173 | else if ((map->size_acts - map->num_acts) < nNewActions) { |
174 | unsigned need; | | 174 | unsigned need; |
175 | XkbAction *prev_acts = map->acts; | | 175 | XkbAction *prev_acts = map->acts; |
176 | | | 176 | |
177 | need = map->num_acts + nNewActions; | | 177 | need = map->num_acts + nNewActions; |
178 | map->acts = _XkbTypedRealloc(map->acts, need, XkbAction); | | 178 | map->acts = _XkbTypedRealloc(map->acts, need, XkbAction); |
179 | if (map->acts == NULL) { | | 179 | if (map->acts == NULL) { |
180 | _XkbFree(prev_acts); | | 180 | _XkbFree(prev_acts); |
181 | map->num_acts = map->size_acts = 0; | | 181 | map->num_acts = map->size_acts = 0; |
182 | return BadAlloc; | | 182 | return BadAlloc; |
183 | } | | 183 | } |
184 | map->size_acts = need; | | 184 | map->size_acts = need; |
185 | bzero(&map->acts[map->num_acts], | | 185 | bzero(&map->acts[map->num_acts], |
186 | ((map->size_acts - map->num_acts) * sizeof(XkbAction))); | | 186 | ((map->size_acts - map->num_acts) * sizeof(XkbAction))); |
187 | } | | 187 | } |
188 | if (map->key_acts == NULL) { | | 188 | if (map->key_acts == NULL) { |
189 | i = xkb->max_key_code + 1; | | 189 | i = xkb->max_key_code + 1; |
190 | map->key_acts = _XkbTypedCalloc(i, unsigned short); | | 190 | map->key_acts = _XkbTypedCalloc(i, unsigned short); |
191 | if (map->key_acts == NULL) | | 191 | if (map->key_acts == NULL) |
192 | return BadAlloc; | | 192 | return BadAlloc; |
193 | } | | 193 | } |
194 | } | | 194 | } |
195 | if (which & XkbKeyBehaviorsMask) { | | 195 | if (which & XkbKeyBehaviorsMask) { |
196 | if ((!XkbIsLegalKeycode(xkb->min_key_code)) || | | 196 | if ((!XkbIsLegalKeycode(xkb->min_key_code)) || |
197 | (!XkbIsLegalKeycode(xkb->max_key_code)) || | | 197 | (!XkbIsLegalKeycode(xkb->max_key_code)) || |
198 | (xkb->max_key_code < xkb->min_key_code)) | | 198 | (xkb->max_key_code < xkb->min_key_code)) |
199 | return BadMatch; | | 199 | return BadMatch; |
200 | if (map->behaviors == NULL) { | | 200 | if (map->behaviors == NULL) { |
201 | i = xkb->max_key_code + 1; | | 201 | i = xkb->max_key_code + 1; |
202 | map->behaviors = _XkbTypedCalloc(i, XkbBehavior); | | 202 | map->behaviors = _XkbTypedCalloc(i, XkbBehavior); |
203 | if (map->behaviors == NULL) | | 203 | if (map->behaviors == NULL) |
204 | return BadAlloc; | | 204 | return BadAlloc; |
205 | } | | 205 | } |
206 | } | | 206 | } |
207 | if (which & XkbVirtualModMapMask) { | | 207 | if (which & XkbVirtualModMapMask) { |
208 | if ((!XkbIsLegalKeycode(xkb->min_key_code)) || | | 208 | if ((!XkbIsLegalKeycode(xkb->min_key_code)) || |
209 | (!XkbIsLegalKeycode(xkb->max_key_code)) || | | 209 | (!XkbIsLegalKeycode(xkb->max_key_code)) || |
210 | (xkb->max_key_code < xkb->min_key_code)) | | 210 | (xkb->max_key_code < xkb->min_key_code)) |
211 | return BadMatch; | | 211 | return BadMatch; |
212 | if (map->vmodmap == NULL) { | | 212 | if (map->vmodmap == NULL) { |
213 | i = xkb->max_key_code + 1; | | 213 | i = xkb->max_key_code + 1; |
214 | map->vmodmap = _XkbTypedCalloc(i, unsigned short); | | 214 | map->vmodmap = _XkbTypedCalloc(i, unsigned short); |
215 | if (map->vmodmap == NULL) | | 215 | if (map->vmodmap == NULL) |
216 | return BadAlloc; | | 216 | return BadAlloc; |
217 | } | | 217 | } |
218 | } | | 218 | } |
219 | return Success; | | 219 | return Success; |
220 | } | | 220 | } |
221 | | | 221 | |
222 | /***====================================================================***/ | | 222 | /***====================================================================***/ |
223 | | | 223 | |
224 | Status | | 224 | Status |
225 | XkbCopyKeyType(XkbKeyTypePtr from, XkbKeyTypePtr into) | | 225 | XkbCopyKeyType(XkbKeyTypePtr from, XkbKeyTypePtr into) |
226 | { | | 226 | { |
227 | if ((!from) || (!into)) | | 227 | if ((!from) || (!into)) |
228 | return BadMatch; | | 228 | return BadMatch; |
229 | if (into->map) { | | 229 | if (into->map) { |
230 | _XkbFree(into->map); | | 230 | _XkbFree(into->map); |
231 | into->map = NULL; | | 231 | into->map = NULL; |
232 | } | | 232 | } |
233 | if (into->preserve) { | | 233 | if (into->preserve) { |
234 | _XkbFree(into->preserve); | | 234 | _XkbFree(into->preserve); |
235 | into->preserve = NULL; | | 235 | into->preserve = NULL; |
236 | } | | 236 | } |
237 | if (into->level_names) { | | 237 | if (into->level_names) { |
238 | _XkbFree(into->level_names); | | 238 | _XkbFree(into->level_names); |
239 | into->level_names = NULL; | | 239 | into->level_names = NULL; |
240 | } | | 240 | } |
241 | *into = *from; | | 241 | *into = *from; |
242 | if ((from->map) && (into->map_count > 0)) { | | 242 | if ((from->map) && (into->map_count > 0)) { |
243 | into->map = _XkbTypedCalloc(into->map_count, XkbKTMapEntryRec); | | 243 | into->map = _XkbTypedCalloc(into->map_count, XkbKTMapEntryRec); |
244 | if (!into->map) | | 244 | if (!into->map) |
245 | return BadAlloc; | | 245 | return BadAlloc; |
246 | memcpy(into->map, from->map, | | 246 | memcpy(into->map, from->map, |
247 | into->map_count * sizeof(XkbKTMapEntryRec)); | | 247 | into->map_count * sizeof(XkbKTMapEntryRec)); |
248 | } | | 248 | } |
249 | if ((from->preserve) && (into->map_count > 0)) { | | 249 | if ((from->preserve) && (into->map_count > 0)) { |
250 | into->preserve = _XkbTypedCalloc(into->map_count, XkbModsRec); | | 250 | into->preserve = _XkbTypedCalloc(into->map_count, XkbModsRec); |
251 | if (!into->preserve) | | 251 | if (!into->preserve) |
252 | return BadAlloc; | | 252 | return BadAlloc; |
253 | memcpy(into->preserve, from->preserve, | | 253 | memcpy(into->preserve, from->preserve, |
254 | into->map_count * sizeof(XkbModsRec)); | | 254 | into->map_count * sizeof(XkbModsRec)); |
255 | } | | 255 | } |
256 | if ((from->level_names) && (into->num_levels > 0)) { | | 256 | if ((from->level_names) && (into->num_levels > 0)) { |
257 | into->level_names = _XkbTypedCalloc(into->num_levels, Atom); | | 257 | into->level_names = _XkbTypedCalloc(into->num_levels, Atom); |
258 | if (!into->level_names) | | 258 | if (!into->level_names) |
259 | return BadAlloc; | | 259 | return BadAlloc; |
260 | memcpy(into->level_names, from->level_names, | | 260 | memcpy(into->level_names, from->level_names, |
261 | into->num_levels * sizeof(Atom)); | | 261 | into->num_levels * sizeof(Atom)); |
262 | } | | 262 | } |
263 | return Success; | | 263 | return Success; |
264 | } | | 264 | } |
265 | | | 265 | |
266 | Status | | 266 | Status |
267 | XkbCopyKeyTypes(XkbKeyTypePtr from, XkbKeyTypePtr into, int num_types) | | 267 | XkbCopyKeyTypes(XkbKeyTypePtr from, XkbKeyTypePtr into, int num_types) |
268 | { | | 268 | { |
269 | register int i, rtrn; | | 269 | register int i, rtrn; |
270 | | | 270 | |
271 | if ((!from) || (!into) || (num_types < 0)) | | 271 | if ((!from) || (!into) || (num_types < 0)) |
272 | return BadMatch; | | 272 | return BadMatch; |
273 | for (i = 0; i < num_types; i++) { | | 273 | for (i = 0; i < num_types; i++) { |
274 | if ((rtrn = XkbCopyKeyType(from++, into++)) != Success) | | 274 | if ((rtrn = XkbCopyKeyType(from++, into++)) != Success) |
275 | return rtrn; | | 275 | return rtrn; |
276 | } | | 276 | } |
277 | return Success; | | 277 | return Success; |
278 | } | | 278 | } |
279 | | | 279 | |
280 | XkbKeyTypePtr | | 280 | XkbKeyTypePtr |
281 | XkbAddKeyType(XkbDescPtr xkb, | | 281 | XkbAddKeyType(XkbDescPtr xkb, |
282 | Atom name, | | 282 | Atom name, |
283 | int map_count, | | 283 | int map_count, |
284 | Bool want_preserve, | | 284 | Bool want_preserve, |
285 | int num_lvls) | | 285 | int num_lvls) |
286 | { | | 286 | { |
287 | register int i; | | 287 | register int i; |
288 | unsigned tmp; | | 288 | unsigned tmp; |
289 | XkbKeyTypePtr type; | | 289 | XkbKeyTypePtr type; |
290 | XkbClientMapPtr map; | | 290 | XkbClientMapPtr map; |
291 | | | 291 | |
292 | if ((!xkb) || (num_lvls < 1)) | | 292 | if ((!xkb) || (num_lvls < 1)) |
293 | return NULL; | | 293 | return NULL; |
294 | map = xkb->map; | | 294 | map = xkb->map; |
295 | if ((map) && (map->types)) { | | 295 | if ((map) && (map->types)) { |
296 | for (i = 0; i < map->num_types; i++) { | | 296 | for (i = 0; i < map->num_types; i++) { |
297 | if (map->types[i].name == name) { | | 297 | if (map->types[i].name == name) { |
298 | Status status = | | 298 | Status status = |
299 | XkbResizeKeyType(xkb, i, map_count, want_preserve, | | 299 | XkbResizeKeyType(xkb, i, map_count, want_preserve, |
300 | num_lvls); | | 300 | num_lvls); |
301 | return (status == Success ? &map->types[i] : NULL); | | 301 | return (status == Success ? &map->types[i] : NULL); |
302 | } | | 302 | } |
303 | } | | 303 | } |
304 | } | | 304 | } |
305 | if ((!map) || (!map->types) || !(map->num_types < XkbNumRequiredTypes)) { | | 305 | if ((!map) || (!map->types) || (map->num_types < XkbNumRequiredTypes)) { |
306 | tmp = XkbNumRequiredTypes + 1; | | 306 | tmp = XkbNumRequiredTypes + 1; |
307 | if (XkbAllocClientMap(xkb, XkbKeyTypesMask, tmp) != Success) | | 307 | if (XkbAllocClientMap(xkb, XkbKeyTypesMask, tmp) != Success) |
308 | return NULL; | | 308 | return NULL; |
309 | if (!map) | | 309 | if (!map) |
310 | map = xkb->map; | | 310 | map = xkb->map; |
311 | tmp = 0; | | 311 | tmp = 0; |
312 | if (map->num_types <= XkbKeypadIndex) | | 312 | if (map->num_types <= XkbKeypadIndex) |
313 | tmp |= XkbKeypadMask; | | 313 | tmp |= XkbKeypadMask; |
314 | if (map->num_types <= XkbAlphabeticIndex) | | 314 | if (map->num_types <= XkbAlphabeticIndex) |
315 | tmp |= XkbAlphabeticMask; | | 315 | tmp |= XkbAlphabeticMask; |
316 | if (map->num_types <= XkbTwoLevelIndex) | | 316 | if (map->num_types <= XkbTwoLevelIndex) |
317 | tmp |= XkbTwoLevelMask; | | 317 | tmp |= XkbTwoLevelMask; |
318 | if (map->num_types <= XkbOneLevelIndex) | | 318 | if (map->num_types <= XkbOneLevelIndex) |
319 | tmp |= XkbOneLevelMask; | | 319 | tmp |= XkbOneLevelMask; |
320 | if (XkbInitCanonicalKeyTypes(xkb, tmp, XkbNoModifier) == Success) { | | 320 | if (XkbInitCanonicalKeyTypes(xkb, tmp, XkbNoModifier) == Success) { |
321 | for (i = 0; i < map->num_types; i++) { | | 321 | for (i = 0; i < map->num_types; i++) { |
322 | Status status; | | 322 | Status status; |
323 | | | 323 | |
324 | if (map->types[i].name != name) | | 324 | if (map->types[i].name != name) |
325 | continue; | | 325 | continue; |
326 | status = XkbResizeKeyType(xkb, i, map_count, want_preserve, | | 326 | status = XkbResizeKeyType(xkb, i, map_count, want_preserve, |
327 | num_lvls); | | 327 | num_lvls); |
328 | return (status == Success ? &map->types[i] : NULL); | | 328 | return (status == Success ? &map->types[i] : NULL); |
329 | } | | 329 | } |
330 | } | | 330 | } |
331 | } | | 331 | } |
332 | if ((map->num_types <= map->size_types) && | | 332 | if ((map->num_types <= map->size_types) && |
333 | (XkbAllocClientMap(xkb, XkbKeyTypesMask, map->num_types + 1) != | | 333 | (XkbAllocClientMap(xkb, XkbKeyTypesMask, map->num_types + 1) != |
334 | Success)) { | | 334 | Success)) { |
335 | return NULL; | | 335 | return NULL; |
336 | } | | 336 | } |
337 | type = &map->types[map->num_types]; | | 337 | type = &map->types[map->num_types]; |
338 | map->num_types++; | | 338 | map->num_types++; |
339 | bzero((char *) type, sizeof(XkbKeyTypeRec)); | | 339 | bzero((char *) type, sizeof(XkbKeyTypeRec)); |
340 | type->num_levels = num_lvls; | | 340 | type->num_levels = num_lvls; |
341 | type->map_count = map_count; | | 341 | type->map_count = map_count; |
342 | type->name = name; | | 342 | type->name = name; |
343 | if (map_count > 0) { | | 343 | if (map_count > 0) { |
344 | type->map = _XkbTypedCalloc(map_count, XkbKTMapEntryRec); | | 344 | type->map = _XkbTypedCalloc(map_count, XkbKTMapEntryRec); |
345 | if (!type->map) { | | 345 | if (!type->map) { |
346 | map->num_types--; | | 346 | map->num_types--; |
347 | return NULL; | | 347 | return NULL; |
348 | } | | 348 | } |
349 | if (want_preserve) { | | 349 | if (want_preserve) { |
350 | type->preserve = _XkbTypedCalloc(map_count, XkbModsRec); | | 350 | type->preserve = _XkbTypedCalloc(map_count, XkbModsRec); |
351 | if (!type->preserve) { | | 351 | if (!type->preserve) { |
352 | _XkbFree(type->map); | | 352 | _XkbFree(type->map); |
353 | map->num_types--; | | 353 | map->num_types--; |
354 | return NULL; | | 354 | return NULL; |
355 | } | | 355 | } |
356 | } | | 356 | } |
357 | } | | 357 | } |
358 | return type; | | 358 | return type; |
359 | } | | 359 | } |
360 | | | 360 | |
361 | Status | | 361 | Status |
362 | XkbResizeKeyType(XkbDescPtr xkb, | | 362 | XkbResizeKeyType(XkbDescPtr xkb, |
363 | int type_ndx, | | 363 | int type_ndx, |
364 | int map_count, | | 364 | int map_count, |
365 | Bool want_preserve, | | 365 | Bool want_preserve, |
366 | int new_num_lvls) | | 366 | int new_num_lvls) |
367 | { | | 367 | { |
368 | XkbKeyTypePtr type; | | 368 | XkbKeyTypePtr type; |
369 | KeyCode matchingKeys[XkbMaxKeyCount], nMatchingKeys; | | 369 | KeyCode matchingKeys[XkbMaxKeyCount], nMatchingKeys; |
370 | | | 370 | |
371 | if ((type_ndx < 0) || (type_ndx >= xkb->map->num_types) || (map_count < 0) | | 371 | if ((type_ndx < 0) || (type_ndx >= xkb->map->num_types) || (map_count < 0) |
372 | || (new_num_lvls < 1)) | | 372 | || (new_num_lvls < 1)) |
373 | return BadValue; | | 373 | return BadValue; |
374 | switch (type_ndx) { | | 374 | switch (type_ndx) { |
375 | case XkbOneLevelIndex: | | 375 | case XkbOneLevelIndex: |
376 | if (new_num_lvls != 1) | | 376 | if (new_num_lvls != 1) |
377 | return BadMatch; | | 377 | return BadMatch; |
378 | break; | | 378 | break; |
379 | case XkbTwoLevelIndex: | | 379 | case XkbTwoLevelIndex: |
380 | case XkbAlphabeticIndex: | | 380 | case XkbAlphabeticIndex: |
381 | case XkbKeypadIndex: | | 381 | case XkbKeypadIndex: |
382 | if (new_num_lvls != 2) | | 382 | if (new_num_lvls != 2) |
383 | return BadMatch; | | 383 | return BadMatch; |
384 | break; | | 384 | break; |
385 | } | | 385 | } |
386 | type = &xkb->map->types[type_ndx]; | | 386 | type = &xkb->map->types[type_ndx]; |
387 | if (map_count == 0) { | | 387 | if (map_count == 0) { |
388 | if (type->map != NULL) | | 388 | if (type->map != NULL) |
389 | _XkbFree(type->map); | | 389 | _XkbFree(type->map); |
390 | type->map = NULL; | | 390 | type->map = NULL; |
391 | if (type->preserve != NULL) | | 391 | if (type->preserve != NULL) |
392 | _XkbFree(type->preserve); | | 392 | _XkbFree(type->preserve); |
393 | type->preserve = NULL; | | 393 | type->preserve = NULL; |
394 | type->map_count = 0; | | 394 | type->map_count = 0; |
395 | } | | 395 | } |
396 | else { | | 396 | else { |
397 | XkbKTMapEntryRec *prev_map = type->map; | | 397 | XkbKTMapEntryRec *prev_map = type->map; |
398 | | | 398 | |
399 | if ((map_count > type->map_count) || (type->map == NULL)) | | 399 | if ((map_count > type->map_count) || (type->map == NULL)) |
400 | type->map = | | 400 | type->map = |
401 | _XkbTypedRealloc(type->map, map_count, XkbKTMapEntryRec); | | 401 | _XkbTypedRealloc(type->map, map_count, XkbKTMapEntryRec); |
402 | if (!type->map) { | | 402 | if (!type->map) { |
403 | if (prev_map) | | 403 | if (prev_map) |
404 | _XkbFree(prev_map); | | 404 | _XkbFree(prev_map); |
405 | return BadAlloc; | | 405 | return BadAlloc; |
406 | } | | 406 | } |
407 | if (want_preserve) { | | 407 | if (want_preserve) { |
408 | XkbModsRec *prev_preserve = type->preserve; | | 408 | XkbModsRec *prev_preserve = type->preserve; |
409 | | | 409 | |
410 | if ((map_count > type->map_count) || (type->preserve == NULL)) { | | 410 | if ((map_count > type->map_count) || (type->preserve == NULL)) { |
411 | type->preserve = _XkbTypedRealloc(type->preserve, map_count, | | 411 | type->preserve = _XkbTypedRealloc(type->preserve, map_count, |
412 | XkbModsRec); | | 412 | XkbModsRec); |
413 | } | | 413 | } |
414 | if (!type->preserve) { | | 414 | if (!type->preserve) { |
415 | if (prev_preserve) | | 415 | if (prev_preserve) |
416 | _XkbFree(prev_preserve); | | 416 | _XkbFree(prev_preserve); |
417 | return BadAlloc; | | 417 | return BadAlloc; |
418 | } | | 418 | } |
419 | } | | 419 | } |
420 | else if (type->preserve != NULL) { | | 420 | else if (type->preserve != NULL) { |
421 | _XkbFree(type->preserve); | | 421 | _XkbFree(type->preserve); |
422 | type->preserve = NULL; | | 422 | type->preserve = NULL; |
423 | } | | 423 | } |
424 | type->map_count = map_count; | | 424 | type->map_count = map_count; |
425 | } | | 425 | } |
426 | | | 426 | |
427 | if ((new_num_lvls > type->num_levels) || (type->level_names == NULL)) { | | 427 | if ((new_num_lvls > type->num_levels) || (type->level_names == NULL)) { |
428 | Atom *prev_level_names = type->level_names; | | 428 | Atom *prev_level_names = type->level_names; |
429 | | | 429 | |
430 | type->level_names = | | 430 | type->level_names = |
431 | _XkbTypedRealloc(type->level_names, new_num_lvls, Atom); | | 431 | _XkbTypedRealloc(type->level_names, new_num_lvls, Atom); |
432 | if (!type->level_names) { | | 432 | if (!type->level_names) { |
433 | if (prev_level_names) | | 433 | if (prev_level_names) |
434 | _XkbFree(prev_level_names); | | 434 | _XkbFree(prev_level_names); |
435 | return BadAlloc; | | 435 | return BadAlloc; |
436 | } | | 436 | } |
437 | } | | 437 | } |
438 | /* | | 438 | /* |
439 | * Here's the theory: | | 439 | * Here's the theory: |
440 | * If the width of the type changed, we might have to resize the symbol | | 440 | * If the width of the type changed, we might have to resize the symbol |
441 | * maps for any keys that use the type for one or more groups. This is | | 441 | * maps for any keys that use the type for one or more groups. This is |
442 | * expensive, so we'll try to cull out any keys that are obviously okay: | | 442 | * expensive, so we'll try to cull out any keys that are obviously okay: |
443 | * In any case: | | 443 | * In any case: |
444 | * - keys that have a group width <= the old width are okay (because | | 444 | * - keys that have a group width <= the old width are okay (because |
445 | * they could not possibly have been associated with the old type) | | 445 | * they could not possibly have been associated with the old type) |
446 | * If the key type increased in size: | | 446 | * If the key type increased in size: |
447 | * - keys that already have a group width >= to the new width are okay | | 447 | * - keys that already have a group width >= to the new width are okay |
448 | * + keys that have a group width >= the old width but < the new width | | 448 | * + keys that have a group width >= the old width but < the new width |
449 | * might have to be enlarged. | | 449 | * might have to be enlarged. |
450 | * If the key type decreased in size: | | 450 | * If the key type decreased in size: |
451 | * - keys that have a group width > the old width don't have to be | | 451 | * - keys that have a group width > the old width don't have to be |
452 | * resized (because they must have some other wider type associated | | 452 | * resized (because they must have some other wider type associated |
453 | * with some group). | | 453 | * with some group). |
454 | * + keys that have a group width == the old width might have to be | | 454 | * + keys that have a group width == the old width might have to be |
455 | * shrunk. | | 455 | * shrunk. |
456 | * The possibilities marked with '+' require us to examine the key types | | 456 | * The possibilities marked with '+' require us to examine the key types |
457 | * associated with each group for the key. | | 457 | * associated with each group for the key. |
458 | */ | | 458 | */ |
459 | bzero(matchingKeys, XkbMaxKeyCount * sizeof(KeyCode)); | | 459 | bzero(matchingKeys, XkbMaxKeyCount * sizeof(KeyCode)); |
460 | nMatchingKeys = 0; | | 460 | nMatchingKeys = 0; |
461 | if (new_num_lvls > type->num_levels) { | | 461 | if (new_num_lvls > type->num_levels) { |
462 | int nTotal; | | 462 | int nTotal; |
463 | KeySym *newSyms; | | 463 | KeySym *newSyms; |
464 | int width, match, nResize; | | 464 | int width, match, nResize; |
465 | register int i, g, nSyms; | | 465 | register int i, g, nSyms; |
466 | | | 466 | |
467 | nResize = 0; | | 467 | nResize = 0; |
468 | for (nTotal = 1, i = xkb->min_key_code; i <= xkb->max_key_code; i++) { | | 468 | for (nTotal = 1, i = xkb->min_key_code; i <= xkb->max_key_code; i++) { |
469 | width = XkbKeyGroupsWidth(xkb, i); | | 469 | width = XkbKeyGroupsWidth(xkb, i); |
470 | if (width < type->num_levels) | | 470 | if (width < type->num_levels) |
471 | continue; | | 471 | continue; |
472 | for (match = 0, g = XkbKeyNumGroups(xkb, i) - 1; | | 472 | for (match = 0, g = XkbKeyNumGroups(xkb, i) - 1; |
473 | (g >= 0) && (!match); g--) { | | 473 | (g >= 0) && (!match); g--) { |
474 | if (XkbKeyKeyTypeIndex(xkb, i, g) == type_ndx) { | | 474 | if (XkbKeyKeyTypeIndex(xkb, i, g) == type_ndx) { |
475 | matchingKeys[nMatchingKeys++] = i; | | 475 | matchingKeys[nMatchingKeys++] = i; |
476 | match = 1; | | 476 | match = 1; |
477 | } | | 477 | } |
478 | } | | 478 | } |
479 | if ((!match) || (width >= new_num_lvls)) | | 479 | if ((!match) || (width >= new_num_lvls)) |
480 | nTotal += XkbKeyNumSyms(xkb, i); | | 480 | nTotal += XkbKeyNumSyms(xkb, i); |
481 | else { | | 481 | else { |
482 | nTotal += XkbKeyNumGroups(xkb, i) * new_num_lvls; | | 482 | nTotal += XkbKeyNumGroups(xkb, i) * new_num_lvls; |
483 | nResize++; | | 483 | nResize++; |
484 | } | | 484 | } |
485 | } | | 485 | } |
486 | if (nResize > 0) { | | 486 | if (nResize > 0) { |
487 | int nextMatch; | | 487 | int nextMatch; |
488 | | | 488 | |
489 | xkb->map->size_syms = (nTotal * 12) / 10; | | 489 | xkb->map->size_syms = (nTotal * 12) / 10; |
490 | newSyms = _XkbTypedCalloc(xkb->map->size_syms, KeySym); | | 490 | newSyms = _XkbTypedCalloc(xkb->map->size_syms, KeySym); |
491 | if (newSyms == NULL) | | 491 | if (newSyms == NULL) |
492 | return BadAlloc; | | 492 | return BadAlloc; |
493 | nextMatch = 0; | | 493 | nextMatch = 0; |
494 | nSyms = 1; | | 494 | nSyms = 1; |
495 | for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { | | 495 | for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { |
496 | if (matchingKeys[nextMatch] == i) { | | 496 | if (matchingKeys[nextMatch] == i) { |
497 | KeySym *pOld; | | 497 | KeySym *pOld; |
498 | | | 498 | |
499 | nextMatch++; | | 499 | nextMatch++; |
500 | width = XkbKeyGroupsWidth(xkb, i); | | 500 | width = XkbKeyGroupsWidth(xkb, i); |
501 | pOld = XkbKeySymsPtr(xkb, i); | | 501 | pOld = XkbKeySymsPtr(xkb, i); |
502 | for (g = XkbKeyNumGroups(xkb, i) - 1; g >= 0; g--) { | | 502 | for (g = XkbKeyNumGroups(xkb, i) - 1; g >= 0; g--) { |
503 | memcpy(&newSyms[nSyms + (new_num_lvls * g)], | | 503 | memcpy(&newSyms[nSyms + (new_num_lvls * g)], |
504 | &pOld[width * g], width * sizeof(KeySym)); | | 504 | &pOld[width * g], width * sizeof(KeySym)); |
505 | } | | 505 | } |
506 | xkb->map->key_sym_map[i].offset = nSyms; | | 506 | xkb->map->key_sym_map[i].offset = nSyms; |
507 | nSyms += XkbKeyNumGroups(xkb, i) * new_num_lvls; | | 507 | nSyms += XkbKeyNumGroups(xkb, i) * new_num_lvls; |
508 | } | | 508 | } |
509 | else { | | 509 | else { |
510 | memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i), | | 510 | memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i), |
511 | XkbKeyNumSyms(xkb, i) * sizeof(KeySym)); | | 511 | XkbKeyNumSyms(xkb, i) * sizeof(KeySym)); |
512 | xkb->map->key_sym_map[i].offset = nSyms; | | 512 | xkb->map->key_sym_map[i].offset = nSyms; |
513 | nSyms += XkbKeyNumSyms(xkb, i); | | 513 | nSyms += XkbKeyNumSyms(xkb, i); |
514 | } | | 514 | } |
515 | } | | 515 | } |
516 | type->num_levels = new_num_lvls; | | 516 | type->num_levels = new_num_lvls; |
517 | _XkbFree(xkb->map->syms); | | 517 | _XkbFree(xkb->map->syms); |
518 | xkb->map->syms = newSyms; | | 518 | xkb->map->syms = newSyms; |
519 | xkb->map->num_syms = nSyms; | | 519 | xkb->map->num_syms = nSyms; |
520 | return Success; | | 520 | return Success; |
521 | } | | 521 | } |
522 | } | | 522 | } |
523 | else if (new_num_lvls < type->num_levels) { | | 523 | else if (new_num_lvls < type->num_levels) { |
524 | int width, match; | | 524 | int width, match; |
525 | register int g, i; | | 525 | register int g, i; |
526 | | | 526 | |
527 | for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { | | 527 | for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { |
528 | width = XkbKeyGroupsWidth(xkb, i); | | 528 | width = XkbKeyGroupsWidth(xkb, i); |
529 | if (width < type->num_levels) | | 529 | if (width < type->num_levels) |
530 | continue; | | 530 | continue; |
531 | for (match = 0, g = XkbKeyNumGroups(xkb, i) - 1; | | 531 | for (match = 0, g = XkbKeyNumGroups(xkb, i) - 1; |
532 | (g >= 0) && (!match); g--) { | | 532 | (g >= 0) && (!match); g--) { |
533 | if (XkbKeyKeyTypeIndex(xkb, i, g) == type_ndx) { | | 533 | if (XkbKeyKeyTypeIndex(xkb, i, g) == type_ndx) { |
534 | matchingKeys[nMatchingKeys++] = i; | | 534 | matchingKeys[nMatchingKeys++] = i; |
535 | match = 1; | | 535 | match = 1; |
536 | } | | 536 | } |
537 | } | | 537 | } |
538 | } | | 538 | } |
539 | } | | 539 | } |
540 | if (nMatchingKeys > 0) { | | 540 | if (nMatchingKeys > 0) { |
541 | int key, firstClear; | | 541 | int key, firstClear; |
542 | register int i, g; | | 542 | register int i, g; |
543 | | | 543 | |
544 | if (new_num_lvls > type->num_levels) | | 544 | if (new_num_lvls > type->num_levels) |
545 | firstClear = type->num_levels; | | 545 | firstClear = type->num_levels; |
546 | else | | 546 | else |
547 | firstClear = new_num_lvls; | | 547 | firstClear = new_num_lvls; |
548 | for (i = 0; i < nMatchingKeys; i++) { | | 548 | for (i = 0; i < nMatchingKeys; i++) { |
549 | KeySym *pSyms; | | 549 | KeySym *pSyms; |
550 | int width, nClear; | | 550 | int width, nClear; |
551 | | | 551 | |
552 | key = matchingKeys[i]; | | 552 | key = matchingKeys[i]; |
553 | width = XkbKeyGroupsWidth(xkb, key); | | 553 | width = XkbKeyGroupsWidth(xkb, key); |
554 | nClear = width - firstClear; | | 554 | nClear = width - firstClear; |
555 | pSyms = XkbKeySymsPtr(xkb, key); | | 555 | pSyms = XkbKeySymsPtr(xkb, key); |
556 | for (g = XkbKeyNumGroups(xkb, key) - 1; g >= 0; g--) { | | 556 | for (g = XkbKeyNumGroups(xkb, key) - 1; g >= 0; g--) { |
557 | if (XkbKeyKeyTypeIndex(xkb, key, g) == type_ndx) { | | 557 | if (XkbKeyKeyTypeIndex(xkb, key, g) == type_ndx) { |
558 | if (nClear > 0) | | 558 | if (nClear > 0) |
559 | bzero(&pSyms[g * width + firstClear], | | 559 | bzero(&pSyms[g * width + firstClear], |
560 | nClear * sizeof(KeySym)); | | 560 | nClear * sizeof(KeySym)); |
561 | } | | 561 | } |
562 | } | | 562 | } |
563 | } | | 563 | } |
564 | } | | 564 | } |
565 | type->num_levels = new_num_lvls; | | 565 | type->num_levels = new_num_lvls; |
566 | return Success; | | 566 | return Success; |
567 | } | | 567 | } |
568 | | | 568 | |
569 | KeySym * | | 569 | KeySym * |
570 | XkbResizeKeySyms(XkbDescPtr xkb, int key, int needed) | | 570 | XkbResizeKeySyms(XkbDescPtr xkb, int key, int needed) |
571 | { | | 571 | { |
572 | register int i, nSyms, nKeySyms; | | 572 | register int i, nSyms, nKeySyms; |
573 | unsigned nOldSyms; | | 573 | unsigned nOldSyms; |
574 | KeySym *newSyms; | | 574 | KeySym *newSyms; |
575 | | | 575 | |
576 | if (needed == 0) { | | 576 | if (needed == 0) { |
577 | xkb->map->key_sym_map[key].offset = 0; | | 577 | xkb->map->key_sym_map[key].offset = 0; |
578 | return xkb->map->syms; | | 578 | return xkb->map->syms; |
579 | } | | 579 | } |
580 | nOldSyms = XkbKeyNumSyms(xkb, key); | | 580 | nOldSyms = XkbKeyNumSyms(xkb, key); |
581 | if (nOldSyms >= (unsigned) needed) { | | 581 | if (nOldSyms >= (unsigned) needed) { |
582 | return XkbKeySymsPtr(xkb, key); | | 582 | return XkbKeySymsPtr(xkb, key); |
583 | } | | 583 | } |
584 | if (xkb->map->size_syms - xkb->map->num_syms >= (unsigned) needed) { | | 584 | if (xkb->map->size_syms - xkb->map->num_syms >= (unsigned) needed) { |
585 | if (nOldSyms > 0) { | | 585 | if (nOldSyms > 0) { |
586 | memcpy(&xkb->map->syms[xkb->map->num_syms], XkbKeySymsPtr(xkb, key), | | 586 | memcpy(&xkb->map->syms[xkb->map->num_syms], XkbKeySymsPtr(xkb, key), |
587 | nOldSyms * sizeof(KeySym)); | | 587 | nOldSyms * sizeof(KeySym)); |
588 | } | | 588 | } |
589 | if ((needed - nOldSyms) > 0) { | | 589 | if ((needed - nOldSyms) > 0) { |
590 | bzero(&xkb->map->syms[xkb->map->num_syms + XkbKeyNumSyms(xkb, key)], | | 590 | bzero(&xkb->map->syms[xkb->map->num_syms + XkbKeyNumSyms(xkb, key)], |
591 | (needed - nOldSyms) * sizeof(KeySym)); | | 591 | (needed - nOldSyms) * sizeof(KeySym)); |
592 | } | | 592 | } |
593 | xkb->map->key_sym_map[key].offset = xkb->map->num_syms; | | 593 | xkb->map->key_sym_map[key].offset = xkb->map->num_syms; |
594 | xkb->map->num_syms += needed; | | 594 | xkb->map->num_syms += needed; |
595 | return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; | | 595 | return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; |
596 | } | | 596 | } |
597 | xkb->map->size_syms += (needed > 32 ? needed : 32); | | 597 | xkb->map->size_syms += (needed > 32 ? needed : 32); |
598 | newSyms = _XkbTypedCalloc(xkb->map->size_syms, KeySym); | | 598 | newSyms = _XkbTypedCalloc(xkb->map->size_syms, KeySym); |
599 | if (newSyms == NULL) | | 599 | if (newSyms == NULL) |
600 | return NULL; | | 600 | return NULL; |
601 | newSyms[0] = NoSymbol; | | 601 | newSyms[0] = NoSymbol; |
602 | nSyms = 1; | | 602 | nSyms = 1; |
603 | for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { | | 603 | for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { |
604 | int nCopy; | | 604 | int nCopy; |
605 | | | 605 | |
606 | nCopy = nKeySyms = XkbKeyNumSyms(xkb, i); | | 606 | nCopy = nKeySyms = XkbKeyNumSyms(xkb, i); |
607 | if ((nKeySyms == 0) && (i != key)) | | 607 | if ((nKeySyms == 0) && (i != key)) |
608 | continue; | | 608 | continue; |
609 | if (i == key) | | 609 | if (i == key) |
610 | nKeySyms = needed; | | 610 | nKeySyms = needed; |
611 | if (nCopy != 0) | | 611 | if (nCopy != 0) |
612 | memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i), | | 612 | memcpy(&newSyms[nSyms], XkbKeySymsPtr(xkb, i), |
613 | nCopy * sizeof(KeySym)); | | 613 | nCopy * sizeof(KeySym)); |
614 | if (nKeySyms > nCopy) | | 614 | if (nKeySyms > nCopy) |
615 | bzero(&newSyms[nSyms + nCopy], (nKeySyms - nCopy) * sizeof(KeySym)); | | 615 | bzero(&newSyms[nSyms + nCopy], (nKeySyms - nCopy) * sizeof(KeySym)); |
616 | xkb->map->key_sym_map[i].offset = nSyms; | | 616 | xkb->map->key_sym_map[i].offset = nSyms; |
617 | nSyms += nKeySyms; | | 617 | nSyms += nKeySyms; |
618 | } | | 618 | } |
619 | _XkbFree(xkb->map->syms); | | 619 | _XkbFree(xkb->map->syms); |
620 | xkb->map->syms = newSyms; | | 620 | xkb->map->syms = newSyms; |
621 | xkb->map->num_syms = nSyms; | | 621 | xkb->map->num_syms = nSyms; |
622 | return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; | | 622 | return &xkb->map->syms[xkb->map->key_sym_map[key].offset]; |
623 | } | | 623 | } |
624 | | | 624 | |
625 | static unsigned | | 625 | static unsigned |
626 | _ExtendRange(unsigned int old_flags, | | 626 | _ExtendRange(unsigned int old_flags, |
627 | unsigned int flag, | | 627 | unsigned int flag, |
628 | KeyCode newKC, | | 628 | KeyCode newKC, |
629 | KeyCode *old_min, | | 629 | KeyCode *old_min, |
630 | unsigned char *old_num) | | 630 | unsigned char *old_num) |
631 | { | | 631 | { |
632 | if ((old_flags & flag) == 0) { | | 632 | if ((old_flags & flag) == 0) { |
633 | old_flags |= flag; | | 633 | old_flags |= flag; |
634 | *old_min = newKC; | | 634 | *old_min = newKC; |
635 | *old_num = 1; | | 635 | *old_num = 1; |
636 | } | | 636 | } |
637 | else { | | 637 | else { |
638 | int last = (*old_min) + (*old_num) - 1; | | 638 | int last = (*old_min) + (*old_num) - 1; |
639 | | | 639 | |
640 | if (newKC < *old_min) { | | 640 | if (newKC < *old_min) { |
641 | *old_min = newKC; | | 641 | *old_min = newKC; |
642 | *old_num = (last - newKC) + 1; | | 642 | *old_num = (last - newKC) + 1; |
643 | } | | 643 | } |
644 | else if (newKC > last) { | | 644 | else if (newKC > last) { |
645 | *old_num = (newKC - (*old_min)) + 1; | | 645 | *old_num = (newKC - (*old_min)) + 1; |
646 | } | | 646 | } |
647 | } | | 647 | } |
648 | return old_flags; | | 648 | return old_flags; |
649 | } | | 649 | } |
650 | | | 650 | |
651 | Status | | 651 | Status |
652 | XkbChangeKeycodeRange(XkbDescPtr xkb, | | 652 | XkbChangeKeycodeRange(XkbDescPtr xkb, |
653 | int minKC, | | 653 | int minKC, |
654 | int maxKC, | | 654 | int maxKC, |
655 | XkbChangesPtr changes) | | 655 | XkbChangesPtr changes) |
656 | { | | 656 | { |
657 | int tmp; | | 657 | int tmp; |
658 | | | 658 | |
659 | if ((!xkb) || (minKC < XkbMinLegalKeyCode) || (maxKC > XkbMaxLegalKeyCode)) | | 659 | if ((!xkb) || (minKC < XkbMinLegalKeyCode) || (maxKC > XkbMaxLegalKeyCode)) |
660 | return BadValue; | | 660 | return BadValue; |
661 | if (minKC > maxKC) | | 661 | if (minKC > maxKC) |
662 | return BadMatch; | | 662 | return BadMatch; |
663 | if (minKC < xkb->min_key_code) { | | 663 | if (minKC < xkb->min_key_code) { |
664 | if (changes) | | 664 | if (changes) |
665 | changes->map.min_key_code = minKC; | | 665 | changes->map.min_key_code = minKC; |
666 | tmp = xkb->min_key_code - minKC; | | 666 | tmp = xkb->min_key_code - minKC; |
667 | if (xkb->map) { | | 667 | if (xkb->map) { |
668 | if (xkb->map->key_sym_map) { | | 668 | if (xkb->map->key_sym_map) { |
669 | bzero((char *) &xkb->map->key_sym_map[minKC], | | 669 | bzero((char *) &xkb->map->key_sym_map[minKC], |
670 | tmp * sizeof(XkbSymMapRec)); | | 670 | tmp * sizeof(XkbSymMapRec)); |
671 | if (changes) { | | 671 | if (changes) { |
672 | changes->map.changed = _ExtendRange(changes->map.changed, | | 672 | changes->map.changed = _ExtendRange(changes->map.changed, |
673 | XkbKeySymsMask, minKC, | | 673 | XkbKeySymsMask, minKC, |
674 | &changes->map.first_key_sym, | | 674 | &changes->map.first_key_sym, |
675 | &changes->map.num_key_syms); | | 675 | &changes->map.num_key_syms); |
676 | } | | 676 | } |
677 | } | | 677 | } |
678 | if (xkb->map->modmap) { | | 678 | if (xkb->map->modmap) { |
679 | bzero((char *) &xkb->map->modmap[minKC], tmp); | | 679 | bzero((char *) &xkb->map->modmap[minKC], tmp); |
680 | if (changes) { | | 680 | if (changes) { |
681 | changes->map.changed = _ExtendRange(changes->map.changed, | | 681 | changes->map.changed = _ExtendRange(changes->map.changed, |
682 | XkbModifierMapMask, minKC, | | 682 | XkbModifierMapMask, minKC, |
683 | &changes->map.first_modmap_key, | | 683 | &changes->map.first_modmap_key, |
684 | &changes->map.num_modmap_keys); | | 684 | &changes->map.num_modmap_keys); |
685 | } | | 685 | } |
686 | } | | 686 | } |
687 | } | | 687 | } |
688 | if (xkb->server) { | | 688 | if (xkb->server) { |
689 | if (xkb->server->behaviors) { | | 689 | if (xkb->server->behaviors) { |
690 | bzero((char *) &xkb->server->behaviors[minKC], | | 690 | bzero((char *) &xkb->server->behaviors[minKC], |
691 | tmp * sizeof(XkbBehavior)); | | 691 | tmp * sizeof(XkbBehavior)); |
692 | if (changes) { | | 692 | if (changes) { |
693 | changes->map.changed = _ExtendRange(changes->map.changed, | | 693 | changes->map.changed = _ExtendRange(changes->map.changed, |
694 | XkbKeyBehaviorsMask, minKC, | | 694 | XkbKeyBehaviorsMask, minKC, |
695 | &changes->map.first_key_behavior, | | 695 | &changes->map.first_key_behavior, |
696 | &changes->map.num_key_behaviors); | | 696 | &changes->map.num_key_behaviors); |
697 | } | | 697 | } |
698 | } | | 698 | } |
699 | if (xkb->server->key_acts) { | | 699 | if (xkb->server->key_acts) { |
700 | bzero((char *) &xkb->server->key_acts[minKC], | | 700 | bzero((char *) &xkb->server->key_acts[minKC], |
701 | tmp * sizeof(unsigned short)); | | 701 | tmp * sizeof(unsigned short)); |
702 | if (changes) { | | 702 | if (changes) { |
703 | changes->map.changed = _ExtendRange(changes->map.changed, | | 703 | changes->map.changed = _ExtendRange(changes->map.changed, |
704 | XkbKeyActionsMask, minKC, | | 704 | XkbKeyActionsMask, minKC, |
705 | &changes->map.first_key_act, | | 705 | &changes->map.first_key_act, |
706 | &changes->map.num_key_acts); | | 706 | &changes->map.num_key_acts); |
707 | } | | 707 | } |
708 | } | | 708 | } |
709 | if (xkb->server->vmodmap) { | | 709 | if (xkb->server->vmodmap) { |
710 | bzero((char *) &xkb->server->vmodmap[minKC], | | 710 | bzero((char *) &xkb->server->vmodmap[minKC], |
711 | tmp * sizeof(unsigned short)); | | 711 | tmp * sizeof(unsigned short)); |
712 | if (changes) { | | 712 | if (changes) { |
713 | changes->map.changed = _ExtendRange(changes->map.changed, | | 713 | changes->map.changed = _ExtendRange(changes->map.changed, |
714 | XkbVirtualModMapMask, minKC, | | 714 | XkbVirtualModMapMask, minKC, |
715 | &changes->map.first_modmap_key, | | 715 | &changes->map.first_modmap_key, |
716 | &changes->map.num_vmodmap_keys); | | 716 | &changes->map.num_vmodmap_keys); |
717 | } | | 717 | } |
718 | } | | 718 | } |
719 | } | | 719 | } |
720 | if ((xkb->names) && (xkb->names->keys)) { | | 720 | if ((xkb->names) && (xkb->names->keys)) { |
721 | bzero((char *) &xkb->names->keys[minKC], | | 721 | bzero((char *) &xkb->names->keys[minKC], |
722 | tmp * sizeof(XkbKeyNameRec)); | | 722 | tmp * sizeof(XkbKeyNameRec)); |
723 | if (changes) { | | 723 | if (changes) { |
724 | changes->names.changed = _ExtendRange(changes->names.changed, | | 724 | changes->names.changed = _ExtendRange(changes->names.changed, |
725 | XkbKeyNamesMask, minKC, | | 725 | XkbKeyNamesMask, minKC, |
726 | &changes->names.first_key, | | 726 | &changes->names.first_key, |
727 | &changes->names.num_keys); | | 727 | &changes->names.num_keys); |
728 | } | | 728 | } |
729 | } | | 729 | } |
730 | xkb->min_key_code = minKC; | | 730 | xkb->min_key_code = minKC; |
731 | } | | 731 | } |
732 | if (maxKC > xkb->max_key_code) { | | 732 | if (maxKC > xkb->max_key_code) { |
733 | if (changes) | | 733 | if (changes) |
734 | changes->map.max_key_code = maxKC; | | 734 | changes->map.max_key_code = maxKC; |
735 | tmp = maxKC - xkb->max_key_code; | | 735 | tmp = maxKC - xkb->max_key_code; |
736 | if (xkb->map) { | | 736 | if (xkb->map) { |
737 | if (xkb->map->key_sym_map) { | | 737 | if (xkb->map->key_sym_map) { |
738 | XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map; | | 738 | XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map; |
739 | | | 739 | |
740 | xkb->map->key_sym_map = _XkbTypedRealloc(xkb->map->key_sym_map, | | 740 | xkb->map->key_sym_map = _XkbTypedRealloc(xkb->map->key_sym_map, |
741 | (maxKC + 1), XkbSymMapRec); | | 741 | (maxKC + 1), XkbSymMapRec); |
742 | if (!xkb->map->key_sym_map) { | | 742 | if (!xkb->map->key_sym_map) { |
743 | _XkbFree(prev_key_sym_map); | | 743 | _XkbFree(prev_key_sym_map); |
744 | return BadAlloc; | | 744 | return BadAlloc; |
745 | } | | 745 | } |
746 | bzero((char *) &xkb->map->key_sym_map[xkb->max_key_code], | | 746 | bzero((char *) &xkb->map->key_sym_map[xkb->max_key_code], |
747 | tmp * sizeof(XkbSymMapRec)); | | 747 | tmp * sizeof(XkbSymMapRec)); |
748 | if (changes) { | | 748 | if (changes) { |
749 | changes->map.changed = _ExtendRange(changes->map.changed, | | 749 | changes->map.changed = _ExtendRange(changes->map.changed, |
750 | XkbKeySymsMask, maxKC, | | 750 | XkbKeySymsMask, maxKC, |
751 | &changes->map.first_key_sym, | | 751 | &changes->map.first_key_sym, |
752 | &changes->map.num_key_syms); | | 752 | &changes->map.num_key_syms); |
753 | } | | 753 | } |
754 | } | | 754 | } |
755 | if (xkb->map->modmap) { | | 755 | if (xkb->map->modmap) { |
756 | unsigned char *prev_modmap = xkb->map->modmap; | | 756 | unsigned char *prev_modmap = xkb->map->modmap; |
757 | | | 757 | |
758 | xkb->map->modmap = _XkbTypedRealloc(xkb->map->modmap, | | 758 | xkb->map->modmap = _XkbTypedRealloc(xkb->map->modmap, |
759 | (maxKC + 1), unsigned char); | | 759 | (maxKC + 1), unsigned char); |
760 | if (!xkb->map->modmap) { | | 760 | if (!xkb->map->modmap) { |
761 | _XkbFree(prev_modmap); | | 761 | _XkbFree(prev_modmap); |
762 | return BadAlloc; | | 762 | return BadAlloc; |
763 | } | | 763 | } |
764 | bzero((char *) &xkb->map->modmap[xkb->max_key_code], tmp); | | 764 | bzero((char *) &xkb->map->modmap[xkb->max_key_code], tmp); |
765 | if (changes) { | | 765 | if (changes) { |
766 | changes->map.changed = _ExtendRange(changes->map.changed, | | 766 | changes->map.changed = _ExtendRange(changes->map.changed, |
767 | XkbModifierMapMask, maxKC, | | 767 | XkbModifierMapMask, maxKC, |
768 | &changes->map.first_modmap_key, | | 768 | &changes->map.first_modmap_key, |
769 | &changes->map.num_modmap_keys); | | 769 | &changes->map.num_modmap_keys); |
770 | } | | 770 | } |
771 | } | | 771 | } |
772 | } | | 772 | } |
773 | if (xkb->server) { | | 773 | if (xkb->server) { |
774 | if (xkb->server->behaviors) { | | 774 | if (xkb->server->behaviors) { |
775 | XkbBehavior *prev_behaviors = xkb->server->behaviors; | | 775 | XkbBehavior *prev_behaviors = xkb->server->behaviors; |
776 | | | 776 | |
777 | xkb->server->behaviors = | | 777 | xkb->server->behaviors = |
778 | _XkbTypedRealloc(xkb->server->behaviors, (maxKC + 1), | | 778 | _XkbTypedRealloc(xkb->server->behaviors, (maxKC + 1), |
779 | XkbBehavior); | | 779 | XkbBehavior); |
780 | if (!xkb->server->behaviors) { | | 780 | if (!xkb->server->behaviors) { |
781 | _XkbFree(prev_behaviors); | | 781 | _XkbFree(prev_behaviors); |
782 | return BadAlloc; | | 782 | return BadAlloc; |
783 | } | | 783 | } |
784 | bzero((char *) &xkb->server->behaviors[xkb->max_key_code], | | 784 | bzero((char *) &xkb->server->behaviors[xkb->max_key_code], |
785 | tmp * sizeof(XkbBehavior)); | | 785 | tmp * sizeof(XkbBehavior)); |
786 | if (changes) { | | 786 | if (changes) { |
787 | changes->map.changed = _ExtendRange(changes->map.changed, | | 787 | changes->map.changed = _ExtendRange(changes->map.changed, |
788 | XkbKeyBehaviorsMask, maxKC, | | 788 | XkbKeyBehaviorsMask, maxKC, |
789 | &changes->map.first_key_behavior, | | 789 | &changes->map.first_key_behavior, |
790 | &changes->map.num_key_behaviors); | | 790 | &changes->map.num_key_behaviors); |
791 | } | | 791 | } |
792 | } | | 792 | } |
793 | if (xkb->server->key_acts) { | | 793 | if (xkb->server->key_acts) { |
794 | unsigned short *prev_key_acts = xkb->server->key_acts; | | 794 | unsigned short *prev_key_acts = xkb->server->key_acts; |
795 | | | 795 | |
796 | xkb->server->key_acts = _XkbTypedRealloc(xkb->server->key_acts, | | 796 | xkb->server->key_acts = _XkbTypedRealloc(xkb->server->key_acts, |
797 | (maxKC + 1), unsigned short); | | 797 | (maxKC + 1), unsigned short); |
798 | if (!xkb->server->key_acts) { | | 798 | if (!xkb->server->key_acts) { |
799 | _XkbFree(prev_key_acts); | | 799 | _XkbFree(prev_key_acts); |
800 | return BadAlloc; | | 800 | return BadAlloc; |
801 | } | | 801 | } |
802 | bzero((char *) &xkb->server->key_acts[xkb->max_key_code], | | 802 | bzero((char *) &xkb->server->key_acts[xkb->max_key_code], |
803 | tmp * sizeof(unsigned short)); | | 803 | tmp * sizeof(unsigned short)); |
804 | if (changes) { | | 804 | if (changes) { |
805 | changes->map.changed = _ExtendRange(changes->map.changed, | | 805 | changes->map.changed = _ExtendRange(changes->map.changed, |
806 | XkbKeyActionsMask, maxKC, | | 806 | XkbKeyActionsMask, maxKC, |
807 | &changes->map.first_key_act, | | 807 | &changes->map.first_key_act, |
808 | &changes->map.num_key_acts); | | 808 | &changes->map.num_key_acts); |
809 | } | | 809 | } |
810 | } | | 810 | } |
811 | if (xkb->server->vmodmap) { | | 811 | if (xkb->server->vmodmap) { |
812 | unsigned short *prev_vmodmap = xkb->server->vmodmap; | | 812 | unsigned short *prev_vmodmap = xkb->server->vmodmap; |
813 | | | 813 | |
814 | xkb->server->vmodmap = _XkbTypedRealloc(xkb->server->vmodmap, | | 814 | xkb->server->vmodmap = _XkbTypedRealloc(xkb->server->vmodmap, |
815 | (maxKC + 1), unsigned short); | | 815 | (maxKC + 1), unsigned short); |
816 | if (!xkb->server->vmodmap) { | | 816 | if (!xkb->server->vmodmap) { |
817 | _XkbFree(prev_vmodmap); | | 817 | _XkbFree(prev_vmodmap); |
818 | return BadAlloc; | | 818 | return BadAlloc; |
819 | } | | 819 | } |
820 | bzero((char *) &xkb->server->vmodmap[xkb->max_key_code], | | 820 | bzero((char *) &xkb->server->vmodmap[xkb->max_key_code], |
821 | tmp * sizeof(unsigned short)); | | 821 | tmp * sizeof(unsigned short)); |
822 | if (changes) { | | 822 | if (changes) { |
823 | changes->map.changed = _ExtendRange(changes->map.changed, | | 823 | changes->map.changed = _ExtendRange(changes->map.changed, |
824 | XkbVirtualModMapMask, maxKC, | | 824 | XkbVirtualModMapMask, maxKC, |
825 | &changes->map.first_modmap_key, | | 825 | &changes->map.first_modmap_key, |
826 | &changes->map.num_vmodmap_keys); | | 826 | &changes->map.num_vmodmap_keys); |
827 | } | | 827 | } |
828 | } | | 828 | } |
829 | } | | 829 | } |
830 | if ((xkb->names) && (xkb->names->keys)) { | | 830 | if ((xkb->names) && (xkb->names->keys)) { |
831 | XkbKeyNameRec *prev_keys = xkb->names->keys; | | 831 | XkbKeyNameRec *prev_keys = xkb->names->keys; |
832 | | | 832 | |
833 | xkb->names->keys = _XkbTypedRealloc(xkb->names->keys, | | 833 | xkb->names->keys = _XkbTypedRealloc(xkb->names->keys, |
834 | (maxKC + 1), XkbKeyNameRec); | | 834 | (maxKC + 1), XkbKeyNameRec); |
835 | if (!xkb->names->keys) { | | 835 | if (!xkb->names->keys) { |
836 | _XkbFree(prev_keys); | | 836 | _XkbFree(prev_keys); |
837 | return BadAlloc; | | 837 | return BadAlloc; |
838 | } | | 838 | } |
839 | bzero((char *) &xkb->names->keys[xkb->max_key_code], | | 839 | bzero((char *) &xkb->names->keys[xkb->max_key_code], |
840 | tmp * sizeof(XkbKeyNameRec)); | | 840 | tmp * sizeof(XkbKeyNameRec)); |
841 | if (changes) { | | 841 | if (changes) { |
842 | changes->names.changed = _ExtendRange(changes->names.changed, | | 842 | changes->names.changed = _ExtendRange(changes->names.changed, |
843 | XkbKeyNamesMask, maxKC, | | 843 | XkbKeyNamesMask, maxKC, |
844 | &changes->names.first_key, | | 844 | &changes->names.first_key, |
845 | &changes->names.num_keys); | | 845 | &changes->names.num_keys); |
846 | } | | 846 | } |
847 | } | | 847 | } |
848 | xkb->max_key_code = maxKC; | | 848 | xkb->max_key_code = maxKC; |
849 | } | | 849 | } |
850 | return Success; | | 850 | return Success; |
851 | } | | 851 | } |
852 | | | 852 | |
853 | XkbAction * | | 853 | XkbAction * |
854 | XkbResizeKeyActions(XkbDescPtr xkb, int key, int needed) | | 854 | XkbResizeKeyActions(XkbDescPtr xkb, int key, int needed) |
855 | { | | 855 | { |
856 | register int i, nActs; | | 856 | register int i, nActs; |
857 | XkbAction *newActs; | | 857 | XkbAction *newActs; |
858 | | | 858 | |
859 | if (needed == 0) { | | 859 | if (needed == 0) { |
860 | xkb->server->key_acts[key] = 0; | | 860 | xkb->server->key_acts[key] = 0; |
861 | return NULL; | | 861 | return NULL; |
862 | } | | 862 | } |
863 | if (XkbKeyHasActions(xkb, key) && | | 863 | if (XkbKeyHasActions(xkb, key) && |
864 | (XkbKeyNumSyms(xkb, key) >= (unsigned) needed)) | | 864 | (XkbKeyNumSyms(xkb, key) >= (unsigned) needed)) |
865 | return XkbKeyActionsPtr(xkb, key); | | 865 | return XkbKeyActionsPtr(xkb, key); |
866 | if (xkb->server->size_acts - xkb->server->num_acts >= (unsigned) needed) { | | 866 | if (xkb->server->size_acts - xkb->server->num_acts >= (unsigned) needed) { |
867 | xkb->server->key_acts[key] = xkb->server->num_acts; | | 867 | xkb->server->key_acts[key] = xkb->server->num_acts; |
868 | xkb->server->num_acts += needed; | | 868 | xkb->server->num_acts += needed; |
869 | return &xkb->server->acts[xkb->server->key_acts[key]]; | | 869 | return &xkb->server->acts[xkb->server->key_acts[key]]; |
870 | } | | 870 | } |
871 | xkb->server->size_acts = xkb->server->num_acts + needed + 8; | | 871 | xkb->server->size_acts = xkb->server->num_acts + needed + 8; |
872 | newActs = _XkbTypedCalloc(xkb->server->size_acts, XkbAction); | | 872 | newActs = _XkbTypedCalloc(xkb->server->size_acts, XkbAction); |
873 | if (newActs == NULL) | | 873 | if (newActs == NULL) |
874 | return NULL; | | 874 | return NULL; |
875 | newActs[0].type = XkbSA_NoAction; | | 875 | newActs[0].type = XkbSA_NoAction; |
876 | nActs = 1; | | 876 | nActs = 1; |
877 | for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { | | 877 | for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { |
878 | int nKeyActs, nCopy; | | 878 | int nKeyActs, nCopy; |
879 | | | 879 | |
880 | if ((xkb->server->key_acts[i] == 0) && (i != key)) | | 880 | if ((xkb->server->key_acts[i] == 0) && (i != key)) |
881 | continue; | | 881 | continue; |
882 | | | 882 | |
883 | nCopy = nKeyActs = XkbKeyNumActions(xkb, i); | | 883 | nCopy = nKeyActs = XkbKeyNumActions(xkb, i); |
884 | if (i == key) { | | 884 | if (i == key) { |
885 | nKeyActs = needed; | | 885 | nKeyActs = needed; |
886 | if (needed < nCopy) | | 886 | if (needed < nCopy) |
887 | nCopy = needed; | | 887 | nCopy = needed; |
888 | } | | 888 | } |
889 | | | 889 | |
890 | if (nCopy > 0) | | 890 | if (nCopy > 0) |
891 | memcpy(&newActs[nActs], XkbKeyActionsPtr(xkb, i), | | 891 | memcpy(&newActs[nActs], XkbKeyActionsPtr(xkb, i), |
892 | nCopy * sizeof(XkbAction)); | | 892 | nCopy * sizeof(XkbAction)); |
893 | if (nCopy < nKeyActs) | | 893 | if (nCopy < nKeyActs) |
894 | bzero(&newActs[nActs + nCopy], | | 894 | bzero(&newActs[nActs + nCopy], |
895 | (nKeyActs - nCopy) * sizeof(XkbAction)); | | 895 | (nKeyActs - nCopy) * sizeof(XkbAction)); |
896 | xkb->server->key_acts[i] = nActs; | | 896 | xkb->server->key_acts[i] = nActs; |
897 | nActs += nKeyActs; | | 897 | nActs += nKeyActs; |
898 | } | | 898 | } |
899 | _XkbFree(xkb->server->acts); | | 899 | _XkbFree(xkb->server->acts); |
900 | xkb->server->acts = newActs; | | 900 | xkb->server->acts = newActs; |
901 | xkb->server->num_acts = nActs; | | 901 | xkb->server->num_acts = nActs; |
902 | return &xkb->server->acts[xkb->server->key_acts[key]]; | | 902 | return &xkb->server->acts[xkb->server->key_acts[key]]; |
903 | } | | 903 | } |
904 | | | 904 | |
905 | void | | 905 | void |
906 | XkbFreeClientMap(XkbDescPtr xkb, unsigned what, Bool freeMap) | | 906 | XkbFreeClientMap(XkbDescPtr xkb, unsigned what, Bool freeMap) |
907 | { | | 907 | { |
908 | XkbClientMapPtr map; | | 908 | XkbClientMapPtr map; |
909 | | | 909 | |
910 | if ((xkb == NULL) || (xkb->map == NULL)) | | 910 | if ((xkb == NULL) || (xkb->map == NULL)) |
911 | return; | | 911 | return; |
912 | if (freeMap) | | 912 | if (freeMap) |
913 | what = XkbAllClientInfoMask; | | 913 | what = XkbAllClientInfoMask; |
914 | map = xkb->map; | | 914 | map = xkb->map; |
915 | if (what & XkbKeyTypesMask) { | | 915 | if (what & XkbKeyTypesMask) { |
916 | if (map->types != NULL) { | | 916 | if (map->types != NULL) { |
917 | if (map->num_types > 0) { | | 917 | if (map->num_types > 0) { |
918 | register int i; | | 918 | register int i; |
919 | XkbKeyTypePtr type; | | 919 | XkbKeyTypePtr type; |
920 | | | 920 | |
921 | for (i = 0, type = map->types; i < map->num_types; i++, type++) { | | 921 | for (i = 0, type = map->types; i < map->num_types; i++, type++) { |
922 | if (type->map != NULL) { | | 922 | if (type->map != NULL) { |
923 | _XkbFree(type->map); | | 923 | _XkbFree(type->map); |
924 | type->map = NULL; | | 924 | type->map = NULL; |
925 | } | | 925 | } |
926 | if (type->preserve != NULL) { | | 926 | if (type->preserve != NULL) { |
927 | _XkbFree(type->preserve); | | 927 | _XkbFree(type->preserve); |
928 | type->preserve = NULL; | | 928 | type->preserve = NULL; |
929 | } | | 929 | } |
930 | type->map_count = 0; | | 930 | type->map_count = 0; |
931 | if (type->level_names != NULL) { | | 931 | if (type->level_names != NULL) { |
932 | _XkbFree(type->level_names); | | 932 | _XkbFree(type->level_names); |
933 | type->level_names = NULL; | | 933 | type->level_names = NULL; |
934 | } | | 934 | } |
935 | } | | 935 | } |
936 | } | | 936 | } |
937 | _XkbFree(map->types); | | 937 | _XkbFree(map->types); |
938 | map->num_types = map->size_types = 0; | | 938 | map->num_types = map->size_types = 0; |
939 | map->types = NULL; | | 939 | map->types = NULL; |
940 | } | | 940 | } |
941 | } | | 941 | } |
942 | if (what & XkbKeySymsMask) { | | 942 | if (what & XkbKeySymsMask) { |
943 | if (map->key_sym_map != NULL) { | | 943 | if (map->key_sym_map != NULL) { |
944 | _XkbFree(map->key_sym_map); | | 944 | _XkbFree(map->key_sym_map); |
945 | map->key_sym_map = NULL; | | 945 | map->key_sym_map = NULL; |
946 | } | | 946 | } |
947 | if (map->syms != NULL) { | | 947 | if (map->syms != NULL) { |
948 | _XkbFree(map->syms); | | 948 | _XkbFree(map->syms); |
949 | map->size_syms = map->num_syms = 0; | | 949 | map->size_syms = map->num_syms = 0; |
950 | map->syms = NULL; | | 950 | map->syms = NULL; |
951 | } | | 951 | } |
952 | } | | 952 | } |
953 | if ((what & XkbModifierMapMask) && (map->modmap != NULL)) { | | 953 | if ((what & XkbModifierMapMask) && (map->modmap != NULL)) { |
954 | _XkbFree(map->modmap); | | 954 | _XkbFree(map->modmap); |
955 | map->modmap = NULL; | | 955 | map->modmap = NULL; |
956 | } | | 956 | } |
957 | if (freeMap) { | | 957 | if (freeMap) { |
958 | _XkbFree(xkb->map); | | 958 | _XkbFree(xkb->map); |
959 | xkb->map = NULL; | | 959 | xkb->map = NULL; |
960 | } | | 960 | } |
961 | return; | | 961 | return; |
962 | } | | 962 | } |
963 | | | 963 | |
964 | void | | 964 | void |
965 | XkbFreeServerMap(XkbDescPtr xkb, unsigned what, Bool freeMap) | | 965 | XkbFreeServerMap(XkbDescPtr xkb, unsigned what, Bool freeMap) |
966 | { | | 966 | { |
967 | XkbServerMapPtr map; | | 967 | XkbServerMapPtr map; |
968 | | | 968 | |
969 | if ((xkb == NULL) || (xkb->server == NULL)) | | 969 | if ((xkb == NULL) || (xkb->server == NULL)) |
970 | return; | | 970 | return; |
971 | if (freeMap) | | 971 | if (freeMap) |
972 | what = XkbAllServerInfoMask; | | 972 | what = XkbAllServerInfoMask; |
973 | map = xkb->server; | | 973 | map = xkb->server; |
974 | if ((what & XkbExplicitComponentsMask) && (map->explicit != NULL)) { | | 974 | if ((what & XkbExplicitComponentsMask) && (map->explicit != NULL)) { |
975 | _XkbFree(map->explicit); | | 975 | _XkbFree(map->explicit); |
976 | map->explicit = NULL; | | 976 | map->explicit = NULL; |
977 | } | | 977 | } |
978 | if (what & XkbKeyActionsMask) { | | 978 | if (what & XkbKeyActionsMask) { |
979 | if (map->key_acts != NULL) { | | 979 | if (map->key_acts != NULL) { |
980 | _XkbFree(map->key_acts); | | 980 | _XkbFree(map->key_acts); |
981 | map->key_acts = NULL; | | 981 | map->key_acts = NULL; |
982 | } | | 982 | } |
983 | if (map->acts != NULL) { | | 983 | if (map->acts != NULL) { |
984 | _XkbFree(map->acts); | | 984 | _XkbFree(map->acts); |
985 | map->num_acts = map->size_acts = 0; | | 985 | map->num_acts = map->size_acts = 0; |
986 | map->acts = NULL; | | 986 | map->acts = NULL; |
987 | } | | 987 | } |
988 | } | | 988 | } |
989 | if ((what & XkbKeyBehaviorsMask) && (map->behaviors != NULL)) { | | 989 | if ((what & XkbKeyBehaviorsMask) && (map->behaviors != NULL)) { |
990 | _XkbFree(map->behaviors); | | 990 | _XkbFree(map->behaviors); |
991 | map->behaviors = NULL; | | 991 | map->behaviors = NULL; |
992 | } | | 992 | } |
993 | if ((what & XkbVirtualModMapMask) && (map->vmodmap != NULL)) { | | 993 | if ((what & XkbVirtualModMapMask) && (map->vmodmap != NULL)) { |
994 | _XkbFree(map->vmodmap); | | 994 | _XkbFree(map->vmodmap); |
995 | map->vmodmap = NULL; | | 995 | map->vmodmap = NULL; |
996 | } | | 996 | } |
997 | | | 997 | |
998 | if (freeMap) { | | 998 | if (freeMap) { |
999 | _XkbFree(xkb->server); | | 999 | _XkbFree(xkb->server); |
1000 | xkb->server = NULL; | | 1000 | xkb->server = NULL; |
1001 | } | | 1001 | } |
1002 | return; | | 1002 | return; |
1003 | } | | 1003 | } |