File: | xkb/xkbout.c |
Location: | line 750, column 31 |
Description: | Access to field 'top' results in a dereference of a null pointer (loaded from variable 'row') |
1 | /************************************************************ | |||
2 | Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. | |||
3 | ||||
4 | Permission to use, copy, modify, and distribute this | |||
5 | software and its documentation for any purpose and without | |||
6 | fee is hereby granted, provided that the above copyright | |||
7 | notice appear in all copies and that both that copyright | |||
8 | notice and this permission notice appear in supporting | |||
9 | documentation, and that the name of Silicon Graphics not be | |||
10 | used in advertising or publicity pertaining to distribution | |||
11 | of the software without specific prior written permission. | |||
12 | Silicon Graphics makes no representation about the suitability | |||
13 | of this software for any purpose. It is provided "as is" | |||
14 | without any express or implied warranty. | |||
15 | ||||
16 | SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS | |||
17 | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | |||
18 | AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON | |||
19 | GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL | |||
20 | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |||
21 | DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE | |||
22 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH | |||
23 | THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
24 | ||||
25 | ********************************************************/ | |||
26 | ||||
27 | #ifdef HAVE_DIX_CONFIG_H1 | |||
28 | #include <dix-config.h> | |||
29 | #endif | |||
30 | ||||
31 | #include <stdio.h> | |||
32 | #include <ctype.h> | |||
33 | #include <stdlib.h> | |||
34 | #include <X11/Xfuncs.h> | |||
35 | ||||
36 | #include <X11/X.h> | |||
37 | #include <X11/keysym.h> | |||
38 | #include <X11/Xproto.h> | |||
39 | #include <X11/extensions/XKMformat.h> | |||
40 | #include "misc.h" | |||
41 | #include "inputstr.h" | |||
42 | #include "dix.h" | |||
43 | #include "xkbstr.h" | |||
44 | #define XKBSRV_NEED_FILE_FUNCS1 1 | |||
45 | #include <xkbsrv.h> | |||
46 | ||||
47 | #include "xkbgeom.h" | |||
48 | #include "xkbfile.h" | |||
49 | ||||
50 | #define VMOD_HIDE_VALUE0 0 | |||
51 | #define VMOD_SHOW_VALUE1 1 | |||
52 | #define VMOD_COMMENT_VALUE2 2 | |||
53 | ||||
54 | static Bool | |||
55 | WriteXKBVModDecl(FILE * file, XkbDescPtr xkb, int showValue) | |||
56 | { | |||
57 | register int i, nMods; | |||
58 | Atom *vmodNames; | |||
59 | ||||
60 | if (xkb == NULL((void*)0)) | |||
61 | return FALSE0; | |||
62 | if (xkb->names != NULL((void*)0)) | |||
63 | vmodNames = xkb->names->vmods; | |||
64 | else | |||
65 | vmodNames = NULL((void*)0); | |||
66 | ||||
67 | for (i = nMods = 0; i < XkbNumVirtualMods16; i++) { | |||
68 | if ((vmodNames != NULL((void*)0)) && (vmodNames[i] != None0L)) { | |||
69 | if (nMods == 0) | |||
70 | fprintf(file, " virtual_modifiers "); | |||
71 | else | |||
72 | fprintf(file, ","); | |||
73 | fprintf(file, "%s", XkbAtomText(vmodNames[i], XkbXKBFile2)); | |||
74 | if ((showValue != VMOD_HIDE_VALUE0) && | |||
75 | (xkb->server) && (xkb->server->vmods[i] != XkbNoModifierMask0)) { | |||
76 | if (showValue == VMOD_COMMENT_VALUE2) { | |||
77 | fprintf(file, "/* = %s */", | |||
78 | XkbModMaskText(xkb->server->vmods[i], XkbXKBFile2)); | |||
79 | } | |||
80 | else { | |||
81 | fprintf(file, "= %s", | |||
82 | XkbModMaskText(xkb->server->vmods[i], XkbXKBFile2)); | |||
83 | } | |||
84 | } | |||
85 | nMods++; | |||
86 | } | |||
87 | } | |||
88 | if (nMods > 0) | |||
89 | fprintf(file, ";\n\n"); | |||
90 | return TRUE1; | |||
91 | } | |||
92 | ||||
93 | /***====================================================================***/ | |||
94 | ||||
95 | static Bool | |||
96 | WriteXKBAction(FILE * file, XkbDescPtr xkb, XkbAnyAction * action) | |||
97 | { | |||
98 | fprintf(file, "%s", XkbActionText(xkb, (XkbAction *) action, XkbXKBFile2)); | |||
99 | return TRUE1; | |||
100 | } | |||
101 | ||||
102 | /***====================================================================***/ | |||
103 | ||||
104 | Bool | |||
105 | XkbWriteXKBKeycodes(FILE * file, | |||
106 | XkbDescPtr xkb, | |||
107 | Bool topLevel, | |||
108 | Bool showImplicit, XkbFileAddOnFunc addOn, void *priv) | |||
109 | { | |||
110 | Atom kcName; | |||
111 | register unsigned i; | |||
112 | const char *alternate; | |||
113 | ||||
114 | if ((!xkb) || (!xkb->names) || (!xkb->names->keys)) { | |||
115 | _XkbLibError(_XkbErrMissingNames, "XkbWriteXKBKeycodes", 0); | |||
116 | return FALSE0; | |||
117 | } | |||
118 | kcName = xkb->names->keycodes; | |||
119 | if (kcName != None0L) | |||
120 | fprintf(file, "xkb_keycodes \"%s\" {\n", | |||
121 | XkbAtomText(kcName, XkbXKBFile2)); | |||
122 | else | |||
123 | fprintf(file, "xkb_keycodes {\n"); | |||
124 | fprintf(file, " minimum = %d;\n", xkb->min_key_code); | |||
125 | fprintf(file, " maximum = %d;\n", xkb->max_key_code); | |||
126 | for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { | |||
127 | if (xkb->names->keys[i].name[0] != '\0') { | |||
128 | if (XkbFindKeycodeByName(xkb, xkb->names->keys[i].name, TRUE1) != i) | |||
129 | alternate = "alternate "; | |||
130 | else | |||
131 | alternate = ""; | |||
132 | fprintf(file, " %s%6s = %d;\n", alternate, | |||
133 | XkbKeyNameText(xkb->names->keys[i].name, XkbXKBFile2), i); | |||
134 | } | |||
135 | } | |||
136 | if (xkb->indicators != NULL((void*)0)) { | |||
137 | for (i = 0; i < XkbNumIndicators32; i++) { | |||
138 | const char *type; | |||
139 | ||||
140 | if (xkb->indicators->phys_indicators & (1 << i)) | |||
141 | type = " "; | |||
142 | else | |||
143 | type = " virtual "; | |||
144 | if (xkb->names->indicators[i] != None0L) { | |||
145 | fprintf(file, "%sindicator %d = \"%s\";\n", type, i + 1, | |||
146 | XkbAtomText(xkb->names->indicators[i], XkbXKBFile2)); | |||
147 | } | |||
148 | } | |||
149 | } | |||
150 | if (xkb->names->key_aliases != NULL((void*)0)) { | |||
151 | XkbKeyAliasPtr pAl; | |||
152 | ||||
153 | pAl = xkb->names->key_aliases; | |||
154 | for (i = 0; i < xkb->names->num_key_aliases; i++, pAl++) { | |||
155 | fprintf(file, " alias %6s = %6s;\n", | |||
156 | XkbKeyNameText(pAl->alias, XkbXKBFile2), | |||
157 | XkbKeyNameText(pAl->real, XkbXKBFile2)); | |||
158 | } | |||
159 | } | |||
160 | if (addOn) | |||
161 | (*addOn) (file, xkb, topLevel, showImplicit, XkmKeyNamesIndex4, priv); | |||
162 | fprintf(file, "};\n\n"); | |||
163 | return TRUE1; | |||
164 | } | |||
165 | ||||
166 | Bool | |||
167 | XkbWriteXKBKeyTypes(FILE * file, | |||
168 | XkbDescPtr xkb, | |||
169 | Bool topLevel, | |||
170 | Bool showImplicit, XkbFileAddOnFunc addOn, void *priv) | |||
171 | { | |||
172 | register unsigned i, n; | |||
173 | XkbKeyTypePtr type; | |||
174 | XkbKTMapEntryPtr entry; | |||
175 | ||||
176 | if ((!xkb) || (!xkb->map) || (!xkb->map->types)) { | |||
177 | _XkbLibError(_XkbErrMissingTypes, "XkbWriteXKBKeyTypes", 0); | |||
178 | return FALSE0; | |||
179 | } | |||
180 | if (xkb->map->num_types < XkbNumRequiredTypes(3 +1)) { | |||
181 | _XkbLibError(_XkbErrMissingReqTypes, "XkbWriteXKBKeyTypes", 0); | |||
182 | return 0; | |||
183 | } | |||
184 | if ((xkb->names == NULL((void*)0)) || (xkb->names->types == None0L)) | |||
185 | fprintf(file, "xkb_types {\n\n"); | |||
186 | else | |||
187 | fprintf(file, "xkb_types \"%s\" {\n\n", | |||
188 | XkbAtomText(xkb->names->types, XkbXKBFile2)); | |||
189 | WriteXKBVModDecl(file, xkb, | |||
190 | (showImplicit ? VMOD_COMMENT_VALUE2 : VMOD_HIDE_VALUE0)); | |||
191 | ||||
192 | type = xkb->map->types; | |||
193 | for (i = 0; i < xkb->map->num_types; i++, type++) { | |||
194 | fprintf(file, " type \"%s\" {\n", | |||
195 | XkbAtomText(type->name, XkbXKBFile2)); | |||
196 | fprintf(file, " modifiers= %s;\n", | |||
197 | XkbVModMaskText(xkb, type->mods.real_mods, type->mods.vmods, | |||
198 | XkbXKBFile2)); | |||
199 | entry = type->map; | |||
200 | for (n = 0; n < type->map_count; n++, entry++) { | |||
201 | char *str; | |||
202 | ||||
203 | str = XkbVModMaskText(xkb, entry->mods.real_mods, entry->mods.vmods, | |||
204 | XkbXKBFile2); | |||
205 | fprintf(file, " map[%s]= Level%d;\n", str, entry->level + 1); | |||
206 | if ((type->preserve) && ((type->preserve[n].real_mods) || | |||
207 | (type->preserve[n].vmods))) { | |||
208 | fprintf(file, " preserve[%s]= ", str); | |||
209 | fprintf(file, "%s;\n", XkbVModMaskText(xkb, | |||
210 | type->preserve[n]. | |||
211 | real_mods, | |||
212 | type->preserve[n].vmods, | |||
213 | XkbXKBFile2)); | |||
214 | } | |||
215 | } | |||
216 | if (type->level_names != NULL((void*)0)) { | |||
217 | Atom *name = type->level_names; | |||
218 | ||||
219 | for (n = 0; n < type->num_levels; n++, name++) { | |||
220 | if ((*name) == None0L) | |||
221 | continue; | |||
222 | fprintf(file, " level_name[Level%d]= \"%s\";\n", n + 1, | |||
223 | XkbAtomText(*name, XkbXKBFile2)); | |||
224 | } | |||
225 | } | |||
226 | fprintf(file, " };\n"); | |||
227 | } | |||
228 | if (addOn) | |||
229 | (*addOn) (file, xkb, topLevel, showImplicit, XkmTypesIndex0, priv); | |||
230 | fprintf(file, "};\n\n"); | |||
231 | return TRUE1; | |||
232 | } | |||
233 | ||||
234 | static Bool | |||
235 | WriteXKBIndicatorMap(FILE * file, | |||
236 | XkbDescPtr xkb, | |||
237 | Atom name, | |||
238 | XkbIndicatorMapPtr led, XkbFileAddOnFunc addOn, void *priv) | |||
239 | { | |||
240 | ||||
241 | fprintf(file, " indicator \"%s\" {\n", NameForAtom(name)); | |||
242 | if (led->flags & XkbIM_NoExplicit(1L << 7)) | |||
243 | fprintf(file, " !allowExplicit;\n"); | |||
244 | if (led->flags & XkbIM_LEDDrivesKB(1L << 5)) | |||
245 | fprintf(file, " indicatorDrivesKeyboard;\n"); | |||
246 | if (led->which_groups != 0) { | |||
247 | if (led->which_groups != XkbIM_UseEffective(1L << 3)) { | |||
248 | fprintf(file, " whichGroupState= %s;\n", | |||
249 | XkbIMWhichStateMaskText(led->which_groups, XkbXKBFile2)); | |||
250 | } | |||
251 | fprintf(file, " groups= 0x%02x;\n", led->groups); | |||
252 | } | |||
253 | if (led->which_mods != 0) { | |||
254 | if (led->which_mods != XkbIM_UseEffective(1L << 3)) { | |||
255 | fprintf(file, " whichModState= %s;\n", | |||
256 | XkbIMWhichStateMaskText(led->which_mods, XkbXKBFile2)); | |||
257 | } | |||
258 | fprintf(file, " modifiers= %s;\n", | |||
259 | XkbVModMaskText(xkb, | |||
260 | led->mods.real_mods, led->mods.vmods, | |||
261 | XkbXKBFile2)); | |||
262 | } | |||
263 | if (led->ctrls != 0) { | |||
264 | fprintf(file, " controls= %s;\n", | |||
265 | XkbControlsMaskText(led->ctrls, XkbXKBFile2)); | |||
266 | } | |||
267 | if (addOn) | |||
268 | (*addOn) (file, xkb, FALSE0, TRUE1, XkmIndicatorsIndex3, priv); | |||
269 | fprintf(file, " };\n"); | |||
270 | return TRUE1; | |||
271 | } | |||
272 | ||||
273 | Bool | |||
274 | XkbWriteXKBCompatMap(FILE * file, | |||
275 | XkbDescPtr xkb, | |||
276 | Bool topLevel, | |||
277 | Bool showImplicit, XkbFileAddOnFunc addOn, void *priv) | |||
278 | { | |||
279 | register unsigned i; | |||
280 | XkbSymInterpretPtr interp; | |||
281 | ||||
282 | if ((!xkb) || (!xkb->compat) || (!xkb->compat->sym_interpret)) { | |||
283 | _XkbLibError(_XkbErrMissingCompatMap, "XkbWriteXKBCompatMap", 0); | |||
284 | return FALSE0; | |||
285 | } | |||
286 | if ((xkb->names == NULL((void*)0)) || (xkb->names->compat == None0L)) | |||
287 | fprintf(file, "xkb_compatibility {\n\n"); | |||
288 | else | |||
289 | fprintf(file, "xkb_compatibility \"%s\" {\n\n", | |||
290 | XkbAtomText(xkb->names->compat, XkbXKBFile2)); | |||
291 | WriteXKBVModDecl(file, xkb, | |||
292 | (showImplicit ? VMOD_COMMENT_VALUE2 : VMOD_HIDE_VALUE0)); | |||
293 | ||||
294 | fprintf(file, " interpret.useModMapMods= AnyLevel;\n"); | |||
295 | fprintf(file, " interpret.repeat= FALSE;\n"); | |||
296 | fprintf(file, " interpret.locking= FALSE;\n"); | |||
297 | interp = xkb->compat->sym_interpret; | |||
298 | for (i = 0; i < xkb->compat->num_si; i++, interp++) { | |||
299 | fprintf(file, " interpret %s+%s(%s) {\n", | |||
300 | ((interp->sym == NoSymbol0L) ? "Any" : | |||
301 | XkbKeysymText(interp->sym, XkbXKBFile2)), | |||
302 | XkbSIMatchText(interp->match, XkbXKBFile2), | |||
303 | XkbModMaskText(interp->mods, XkbXKBFile2)); | |||
304 | if (interp->virtual_mod != XkbNoModifier0xff) { | |||
305 | fprintf(file, " virtualModifier= %s;\n", | |||
306 | XkbVModIndexText(xkb, interp->virtual_mod, XkbXKBFile2)); | |||
307 | } | |||
308 | if (interp->match & XkbSI_LevelOneOnly(0x80)) | |||
309 | fprintf(file, " useModMapMods=level1;\n"); | |||
310 | if (interp->flags & XkbSI_LockingKey(1<<1)) | |||
311 | fprintf(file, " locking= TRUE;\n"); | |||
312 | if (interp->flags & XkbSI_AutoRepeat(1<<0)) | |||
313 | fprintf(file, " repeat= TRUE;\n"); | |||
314 | fprintf(file, " action= "); | |||
315 | WriteXKBAction(file, xkb, &interp->act); | |||
316 | fprintf(file, ";\n"); | |||
317 | fprintf(file, " };\n"); | |||
318 | } | |||
319 | for (i = 0; i < XkbNumKbdGroups4; i++) { | |||
320 | XkbModsPtr gc; | |||
321 | ||||
322 | gc = &xkb->compat->groups[i]; | |||
323 | if ((gc->real_mods == 0) && (gc->vmods == 0)) | |||
324 | continue; | |||
325 | fprintf(file, " group %d = %s;\n", i + 1, XkbVModMaskText(xkb, | |||
326 | gc-> | |||
327 | real_mods, | |||
328 | gc->vmods, | |||
329 | XkbXKBFile2)); | |||
330 | } | |||
331 | if (xkb->indicators) { | |||
332 | for (i = 0; i < XkbNumIndicators32; i++) { | |||
333 | XkbIndicatorMapPtr map = &xkb->indicators->maps[i]; | |||
334 | ||||
335 | if ((map->flags != 0) || (map->which_groups != 0) || | |||
336 | (map->groups != 0) || (map->which_mods != 0) || | |||
337 | (map->mods.real_mods != 0) || (map->mods.vmods != 0) || | |||
338 | (map->ctrls != 0)) { | |||
339 | WriteXKBIndicatorMap(file, xkb, xkb->names->indicators[i], map, | |||
340 | addOn, priv); | |||
341 | } | |||
342 | } | |||
343 | } | |||
344 | if (addOn) | |||
345 | (*addOn) (file, xkb, topLevel, showImplicit, XkmCompatMapIndex1, priv); | |||
346 | fprintf(file, "};\n\n"); | |||
347 | return TRUE1; | |||
348 | } | |||
349 | ||||
350 | Bool | |||
351 | XkbWriteXKBSymbols(FILE * file, | |||
352 | XkbDescPtr xkb, | |||
353 | Bool topLevel, | |||
354 | Bool showImplicit, XkbFileAddOnFunc addOn, void *priv) | |||
355 | { | |||
356 | register unsigned i, tmp; | |||
357 | XkbClientMapPtr map; | |||
358 | XkbServerMapPtr srv; | |||
359 | Bool showActions; | |||
360 | ||||
361 | if (!xkb) { | |||
362 | _XkbLibError(_XkbErrMissingSymbols, "XkbWriteXKBSymbols", 0); | |||
363 | return FALSE0; | |||
364 | } | |||
365 | ||||
366 | map = xkb->map; | |||
367 | if ((!map) || (!map->syms) || (!map->key_sym_map)) { | |||
368 | _XkbLibError(_XkbErrMissingSymbols, "XkbWriteXKBSymbols", 0); | |||
369 | return FALSE0; | |||
370 | } | |||
371 | if ((!xkb->names) || (!xkb->names->keys)) { | |||
372 | _XkbLibError(_XkbErrMissingNames, "XkbWriteXKBSymbols", 0); | |||
373 | return FALSE0; | |||
374 | } | |||
375 | if ((xkb->names == NULL((void*)0)) || (xkb->names->symbols == None0L)) | |||
376 | fprintf(file, "xkb_symbols {\n\n"); | |||
377 | else | |||
378 | fprintf(file, "xkb_symbols \"%s\" {\n\n", | |||
379 | XkbAtomText(xkb->names->symbols, XkbXKBFile2)); | |||
380 | for (tmp = i = 0; i < XkbNumKbdGroups4; i++) { | |||
381 | if (xkb->names->groups[i] != None0L) { | |||
382 | fprintf(file, " name[group%d]=\"%s\";\n", i + 1, | |||
383 | XkbAtomText(xkb->names->groups[i], XkbXKBFile2)); | |||
384 | tmp++; | |||
385 | } | |||
386 | } | |||
387 | if (tmp > 0) | |||
388 | fprintf(file, "\n"); | |||
389 | srv = xkb->server; | |||
390 | for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { | |||
391 | Bool simple; | |||
392 | ||||
393 | if ((int) XkbKeyNumSyms(xkb, i)((((((xkb)->map))->key_sym_map[(((i)))].width) * (((((( xkb)->map))->key_sym_map[(((i)))].group_info)&0x0f) ))) < 1) | |||
394 | continue; | |||
395 | if (XkbFindKeycodeByName(xkb, xkb->names->keys[i].name, TRUE1) != i) | |||
396 | continue; | |||
397 | simple = TRUE1; | |||
398 | fprintf(file, " key %6s {", | |||
399 | XkbKeyNameText(xkb->names->keys[i].name, XkbXKBFile2)); | |||
400 | if (srv->explicit) { | |||
401 | if (((srv->explicit[i] & XkbExplicitKeyTypesMask(0x0f)) != 0) || | |||
402 | (showImplicit)) { | |||
403 | int typeNdx, g; | |||
404 | Bool multi; | |||
405 | const char *comment = " "; | |||
406 | ||||
407 | if ((srv->explicit[i] & XkbExplicitKeyTypesMask(0x0f)) == 0) | |||
408 | comment = "//"; | |||
409 | multi = FALSE0; | |||
410 | typeNdx = XkbKeyKeyTypeIndex(xkb, i, 0)((((xkb)->map)->key_sym_map[((i))].kt_index[((0)) & 0x3])); | |||
411 | for (g = 1; (g < XkbKeyNumGroups(xkb, i)((((((xkb)->map)->key_sym_map[((i))].group_info)&0x0f )))) && (!multi); g++) { | |||
412 | if (XkbKeyKeyTypeIndex(xkb, i, g)((((xkb)->map)->key_sym_map[((i))].kt_index[((g)) & 0x3])) != typeNdx) | |||
413 | multi = TRUE1; | |||
414 | } | |||
415 | if (multi) { | |||
416 | for (g = 0; g < XkbKeyNumGroups(xkb, i)((((((xkb)->map)->key_sym_map[((i))].group_info)&0x0f ))); g++) { | |||
417 | typeNdx = XkbKeyKeyTypeIndex(xkb, i, g)((((xkb)->map)->key_sym_map[((i))].kt_index[((g)) & 0x3])); | |||
418 | if (srv->explicit[i] & (1 << g)) { | |||
419 | fprintf(file, "\n%s type[group%d]= \"%s\",", | |||
420 | comment, g + 1, | |||
421 | XkbAtomText(map->types[typeNdx].name, | |||
422 | XkbXKBFile2)); | |||
423 | } | |||
424 | else if (showImplicit) { | |||
425 | fprintf(file, "\n// type[group%d]= \"%s\",", | |||
426 | g + 1, XkbAtomText(map->types[typeNdx].name, | |||
427 | XkbXKBFile2)); | |||
428 | } | |||
429 | } | |||
430 | } | |||
431 | else { | |||
432 | fprintf(file, "\n%s type= \"%s\",", comment, | |||
433 | XkbAtomText(map->types[typeNdx].name, XkbXKBFile2)); | |||
434 | } | |||
435 | simple = FALSE0; | |||
436 | } | |||
437 | if (((srv->explicit[i] & XkbExplicitAutoRepeatMask(1<<5)) != 0) && | |||
438 | (xkb->ctrls != NULL((void*)0))) { | |||
439 | if (xkb->ctrls->per_key_repeat[i / 8] & (1 << (i % 8))) | |||
440 | fprintf(file, "\n repeat= Yes,"); | |||
441 | else | |||
442 | fprintf(file, "\n repeat= No,"); | |||
443 | simple = FALSE0; | |||
444 | } | |||
445 | if ((xkb->server != NULL((void*)0)) && (xkb->server->vmodmap != NULL((void*)0)) && | |||
446 | (xkb->server->vmodmap[i] != 0)) { | |||
447 | if ((srv->explicit[i] & XkbExplicitVModMapMask(1<<7)) != 0) { | |||
448 | fprintf(file, "\n virtualMods= %s,", | |||
449 | XkbVModMaskText(xkb, 0, | |||
450 | xkb->server->vmodmap[i], | |||
451 | XkbXKBFile2)); | |||
452 | } | |||
453 | else if (showImplicit) { | |||
454 | fprintf(file, "\n// virtualMods= %s,", | |||
455 | XkbVModMaskText(xkb, 0, | |||
456 | xkb->server->vmodmap[i], | |||
457 | XkbXKBFile2)); | |||
458 | } | |||
459 | } | |||
460 | } | |||
461 | switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(xkb, i))((((((xkb)->map)->key_sym_map[((i))].group_info)))& 0xc0)) { | |||
462 | case XkbClampIntoRange(0x40): | |||
463 | fprintf(file, "\n groupsClamp,"); | |||
464 | break; | |||
465 | case XkbRedirectIntoRange(0x80): | |||
466 | fprintf(file, "\n groupsRedirect= Group%d,", | |||
467 | XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(xkb, i))(((((((xkb)->map)->key_sym_map[((i))].group_info)))& 0x30)>>4) + 1); | |||
468 | break; | |||
469 | } | |||
470 | if (srv->behaviors != NULL((void*)0)) { | |||
471 | unsigned type; | |||
472 | ||||
473 | type = srv->behaviors[i].type & XkbKB_OpMask0x7f; | |||
474 | ||||
475 | if (type != XkbKB_Default0x00) { | |||
476 | simple = FALSE0; | |||
477 | fprintf(file, "\n %s,", | |||
478 | XkbBehaviorText(xkb, &srv->behaviors[i], XkbXKBFile2)); | |||
479 | } | |||
480 | } | |||
481 | if ((srv->explicit == NULL((void*)0)) || showImplicit || | |||
482 | ((srv->explicit[i] & XkbExplicitInterpretMask(1<<4)) != 0)) | |||
483 | showActions = XkbKeyHasActions(xkb, i)(!!(xkb)->server->key_acts[(i)]); | |||
484 | else | |||
485 | showActions = FALSE0; | |||
486 | ||||
487 | if (((unsigned) XkbKeyNumGroups(xkb, i)((((((xkb)->map)->key_sym_map[((i))].group_info)&0x0f ))) > 1) || showActions) | |||
488 | simple = FALSE0; | |||
489 | if (simple) { | |||
490 | KeySym *syms; | |||
491 | unsigned s; | |||
492 | ||||
493 | syms = XkbKeySymsPtr(xkb, i)((&((xkb)->map)->syms[((((xkb)->map))->key_sym_map [(((i)))].offset)])); | |||
494 | fprintf(file, " [ "); | |||
495 | for (s = 0; s < XkbKeyGroupWidth(xkb, i, XkbGroup1Index)(((&(((xkb)->map))->types[(((((xkb)->map)))-> key_sym_map[((((i))))].kt_index[((((0)))) & 0x3])])->num_levels )); s++) { | |||
496 | if (s != 0) | |||
497 | fprintf(file, ", "); | |||
498 | fprintf(file, "%15s", XkbKeysymText(*syms++, XkbXKBFile2)); | |||
499 | } | |||
500 | fprintf(file, " ] };\n"); | |||
501 | } | |||
502 | else { | |||
503 | unsigned g, s; | |||
504 | KeySym *syms; | |||
505 | XkbAction *acts; | |||
506 | ||||
507 | syms = XkbKeySymsPtr(xkb, i)((&((xkb)->map)->syms[((((xkb)->map))->key_sym_map [(((i)))].offset)])); | |||
508 | acts = XkbKeyActionsPtr(xkb, i)((&((xkb)->server)->acts[((xkb)->server)->key_acts [((i))]])); | |||
509 | for (g = 0; g < XkbKeyNumGroups(xkb, i)((((((xkb)->map)->key_sym_map[((i))].group_info)&0x0f ))); g++) { | |||
510 | if (g != 0) | |||
511 | fprintf(file, ","); | |||
512 | fprintf(file, "\n symbols[Group%d]= [ ", g + 1); | |||
513 | for (s = 0; s < XkbKeyGroupWidth(xkb, i, g)(((&(((xkb)->map))->types[(((((xkb)->map)))-> key_sym_map[((((i))))].kt_index[((((g)))) & 0x3])])->num_levels )); s++) { | |||
514 | if (s != 0) | |||
515 | fprintf(file, ", "); | |||
516 | fprintf(file, "%15s", XkbKeysymText(syms[s], XkbXKBFile2)); | |||
517 | } | |||
518 | fprintf(file, " ]"); | |||
519 | syms += XkbKeyGroupsWidth(xkb, i)((((xkb)->map)->key_sym_map[((i))].width)); | |||
520 | if (showActions) { | |||
521 | fprintf(file, ",\n actions[Group%d]= [ ", g + 1); | |||
522 | for (s = 0; s < XkbKeyGroupWidth(xkb, i, g)(((&(((xkb)->map))->types[(((((xkb)->map)))-> key_sym_map[((((i))))].kt_index[((((g)))) & 0x3])])->num_levels )); s++) { | |||
523 | if (s != 0) | |||
524 | fprintf(file, ", "); | |||
525 | WriteXKBAction(file, xkb, (XkbAnyAction *) &acts[s]); | |||
526 | } | |||
527 | fprintf(file, " ]"); | |||
528 | acts += XkbKeyGroupsWidth(xkb, i)((((xkb)->map)->key_sym_map[((i))].width)); | |||
529 | } | |||
530 | } | |||
531 | fprintf(file, "\n };\n"); | |||
532 | } | |||
533 | } | |||
534 | if (map && map->modmap) { | |||
535 | for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { | |||
536 | if (map->modmap[i] != 0) { | |||
537 | register int n, bit; | |||
538 | ||||
539 | for (bit = 1, n = 0; n < XkbNumModifiers8; n++, bit <<= 1) { | |||
540 | if (map->modmap[i] & bit) { | |||
541 | char buf[5]; | |||
542 | ||||
543 | memcpy(buf, xkb->names->keys[i].name, 4)__builtin___memcpy_chk (buf, xkb->names->keys[i].name, 4 , __builtin_object_size (buf, 0)); | |||
544 | buf[4] = '\0'; | |||
545 | fprintf(file, " modifier_map %s { <%s> };\n", | |||
546 | XkbModIndexText(n, XkbXKBFile2), buf); | |||
547 | } | |||
548 | } | |||
549 | } | |||
550 | } | |||
551 | } | |||
552 | if (addOn) | |||
553 | (*addOn) (file, xkb, topLevel, showImplicit, XkmSymbolsIndex2, priv); | |||
554 | fprintf(file, "};\n\n"); | |||
555 | return TRUE1; | |||
556 | } | |||
557 | ||||
558 | static Bool | |||
559 | WriteXKBOutline(FILE * file, | |||
560 | XkbShapePtr shape, | |||
561 | XkbOutlinePtr outline, int lastRadius, int first, int indent) | |||
562 | { | |||
563 | register int i; | |||
564 | XkbPointPtr pt; | |||
565 | char *iStr; | |||
566 | ||||
567 | fprintf(file, "%s", iStr = XkbIndentText(first)); | |||
568 | if (first != indent) | |||
569 | iStr = XkbIndentText(indent); | |||
570 | if (outline->corner_radius != lastRadius) { | |||
571 | fprintf(file, "corner= %s,", | |||
572 | XkbGeomFPText(outline->corner_radius, XkbMessage3)); | |||
573 | if (shape != NULL((void*)0)) { | |||
574 | fprintf(file, "\n%s", iStr); | |||
575 | } | |||
576 | } | |||
577 | if (shape) { | |||
578 | if (outline == shape->approx) | |||
579 | fprintf(file, "approx= "); | |||
580 | else if (outline == shape->primary) | |||
581 | fprintf(file, "primary= "); | |||
582 | } | |||
583 | fprintf(file, "{"); | |||
584 | for (pt = outline->points, i = 0; i < outline->num_points; i++, pt++) { | |||
585 | if (i == 0) | |||
586 | fprintf(file, " "); | |||
587 | else if ((i % 4) == 0) | |||
588 | fprintf(file, ",\n%s ", iStr); | |||
589 | else | |||
590 | fprintf(file, ", "); | |||
591 | fprintf(file, "[ %3s, %3s ]", XkbGeomFPText(pt->x, XkbXKBFile2), | |||
592 | XkbGeomFPText(pt->y, XkbXKBFile2)); | |||
593 | } | |||
594 | fprintf(file, " }"); | |||
595 | return TRUE1; | |||
596 | } | |||
597 | ||||
598 | static Bool | |||
599 | WriteXKBDoodad(FILE * file, | |||
600 | unsigned indent, XkbGeometryPtr geom, XkbDoodadPtr doodad) | |||
601 | { | |||
602 | register char *i_str; | |||
603 | XkbShapePtr shape; | |||
604 | XkbColorPtr color; | |||
605 | ||||
606 | i_str = XkbIndentText(indent); | |||
607 | fprintf(file, "%s%s \"%s\" {\n", i_str, | |||
608 | XkbDoodadTypeText(doodad->any.type, XkbMessage3), | |||
609 | XkbAtomText(doodad->any.name, XkbMessage3)); | |||
610 | fprintf(file, "%s top= %s;\n", i_str, | |||
611 | XkbGeomFPText(doodad->any.top, XkbXKBFile2)); | |||
612 | fprintf(file, "%s left= %s;\n", i_str, | |||
613 | XkbGeomFPText(doodad->any.left, XkbXKBFile2)); | |||
614 | fprintf(file, "%s priority= %d;\n", i_str, doodad->any.priority); | |||
615 | switch (doodad->any.type) { | |||
616 | case XkbOutlineDoodad1: | |||
617 | case XkbSolidDoodad2: | |||
618 | if (doodad->shape.angle != 0) { | |||
619 | fprintf(file, "%s angle= %s;\n", i_str, | |||
620 | XkbGeomFPText(doodad->shape.angle, XkbXKBFile2)); | |||
621 | } | |||
622 | if (doodad->shape.color_ndx != 0) { | |||
623 | fprintf(file, "%s color= \"%s\";\n", i_str, | |||
624 | XkbShapeDoodadColor(geom, &doodad->shape)(&(geom)->colors[(&doodad->shape)->color_ndx ])->spec); | |||
625 | } | |||
626 | shape = XkbShapeDoodadShape(geom, &doodad->shape)(&(geom)->shapes[(&doodad->shape)->shape_ndx ]); | |||
627 | fprintf(file, "%s shape= \"%s\";\n", i_str, | |||
628 | XkbAtomText(shape->name, XkbXKBFile2)); | |||
629 | break; | |||
630 | case XkbTextDoodad3: | |||
631 | if (doodad->text.angle != 0) { | |||
632 | fprintf(file, "%s angle= %s;\n", i_str, | |||
633 | XkbGeomFPText(doodad->text.angle, XkbXKBFile2)); | |||
634 | } | |||
635 | if (doodad->text.width != 0) { | |||
636 | fprintf(file, "%s width= %s;\n", i_str, | |||
637 | XkbGeomFPText(doodad->text.width, XkbXKBFile2)); | |||
638 | ||||
639 | } | |||
640 | if (doodad->text.height != 0) { | |||
641 | fprintf(file, "%s height= %s;\n", i_str, | |||
642 | XkbGeomFPText(doodad->text.height, XkbXKBFile2)); | |||
643 | ||||
644 | } | |||
645 | if (doodad->text.color_ndx != 0) { | |||
646 | color = XkbTextDoodadColor(geom, &doodad->text)(&(geom)->colors[(&doodad->text)->color_ndx] ); | |||
647 | fprintf(file, "%s color= \"%s\";\n", i_str, | |||
648 | XkbStringText(color->spec, XkbXKBFile2)); | |||
649 | } | |||
650 | fprintf(file, "%s XFont= \"%s\";\n", i_str, | |||
651 | XkbStringText(doodad->text.font, XkbXKBFile2)); | |||
652 | fprintf(file, "%s text= \"%s\";\n", i_str, | |||
653 | XkbStringText(doodad->text.text, XkbXKBFile2)); | |||
654 | break; | |||
655 | case XkbIndicatorDoodad4: | |||
656 | shape = XkbIndicatorDoodadShape(geom, &doodad->indicator)(&(geom)->shapes[(&doodad->indicator)->shape_ndx ]); | |||
657 | color = XkbIndicatorDoodadOnColor(geom, &doodad->indicator)(&(geom)->colors[(&doodad->indicator)->on_color_ndx ]); | |||
658 | fprintf(file, "%s onColor= \"%s\";\n", i_str, | |||
659 | XkbStringText(color->spec, XkbXKBFile2)); | |||
660 | color = XkbIndicatorDoodadOffColor(geom, &doodad->indicator)(&(geom)->colors[(&doodad->indicator)->off_color_ndx ]); | |||
661 | fprintf(file, "%s offColor= \"%s\";\n", i_str, | |||
662 | XkbStringText(color->spec, XkbXKBFile2)); | |||
663 | fprintf(file, "%s shape= \"%s\";\n", i_str, | |||
664 | XkbAtomText(shape->name, XkbXKBFile2)); | |||
665 | break; | |||
666 | case XkbLogoDoodad5: | |||
667 | fprintf(file, "%s logoName= \"%s\";\n", i_str, | |||
668 | XkbStringText(doodad->logo.logo_name, XkbXKBFile2)); | |||
669 | if (doodad->shape.angle != 0) { | |||
670 | fprintf(file, "%s angle= %s;\n", i_str, | |||
671 | XkbGeomFPText(doodad->logo.angle, XkbXKBFile2)); | |||
672 | } | |||
673 | if (doodad->shape.color_ndx != 0) { | |||
674 | fprintf(file, "%s color= \"%s\";\n", i_str, | |||
675 | XkbLogoDoodadColor(geom, &doodad->logo)(&(geom)->colors[(&doodad->logo)->color_ndx] )->spec); | |||
676 | } | |||
677 | shape = XkbLogoDoodadShape(geom, &doodad->logo)(&(geom)->shapes[(&doodad->logo)->shape_ndx] ); | |||
678 | fprintf(file, "%s shape= \"%s\";\n", i_str, | |||
679 | XkbAtomText(shape->name, XkbXKBFile2)); | |||
680 | break; | |||
681 | } | |||
682 | fprintf(file, "%s};\n", i_str); | |||
683 | return TRUE1; | |||
684 | } | |||
685 | ||||
686 | /*ARGSUSED*/ static Bool | |||
687 | WriteXKBOverlay(FILE * file, | |||
688 | unsigned indent, XkbGeometryPtr geom, XkbOverlayPtr ol) | |||
689 | { | |||
690 | register char *i_str; | |||
691 | int r, k, nOut; | |||
692 | XkbOverlayRowPtr row; | |||
693 | XkbOverlayKeyPtr key; | |||
694 | ||||
695 | i_str = XkbIndentText(indent); | |||
696 | if (ol->name != None0L) { | |||
697 | fprintf(file, "%soverlay \"%s\" {\n", i_str, | |||
698 | XkbAtomText(ol->name, XkbMessage3)); | |||
699 | } | |||
700 | else | |||
701 | fprintf(file, "%soverlay {\n", i_str); | |||
702 | for (nOut = r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { | |||
703 | for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { | |||
704 | char *over, *under; | |||
705 | ||||
706 | over = XkbKeyNameText(key->over.name, XkbXKBFile2); | |||
707 | under = XkbKeyNameText(key->under.name, XkbXKBFile2); | |||
708 | if (nOut == 0) | |||
709 | fprintf(file, "%s %6s=%6s", i_str, under, over); | |||
710 | else if ((nOut % 4) == 0) | |||
711 | fprintf(file, ",\n%s %6s=%6s", i_str, under, over); | |||
712 | else | |||
713 | fprintf(file, ", %6s=%6s", under, over); | |||
714 | nOut++; | |||
715 | } | |||
716 | } | |||
717 | fprintf(file, "\n%s};\n", i_str); | |||
718 | return TRUE1; | |||
719 | } | |||
720 | ||||
721 | static Bool | |||
722 | WriteXKBSection(FILE * file, XkbSectionPtr s, XkbGeometryPtr geom) | |||
723 | { | |||
724 | register int i; | |||
725 | XkbRowPtr row; | |||
726 | int dfltKeyColor = 0; | |||
727 | ||||
728 | fprintf(file, " section \"%s\" {\n", XkbAtomText(s->name, XkbXKBFile2)); | |||
729 | if (s->rows && (s->rows->num_keys > 0)) { | |||
730 | dfltKeyColor = s->rows->keys[0].color_ndx; | |||
731 | fprintf(file, " key.color= \"%s\";\n", | |||
732 | XkbStringText(geom->colors[dfltKeyColor].spec, XkbXKBFile2)); | |||
733 | } | |||
734 | fprintf(file, " priority= %d;\n", s->priority); | |||
735 | fprintf(file, " top= %s;\n", | |||
736 | XkbGeomFPText(s->top, XkbXKBFile2)); | |||
737 | fprintf(file, " left= %s;\n", | |||
738 | XkbGeomFPText(s->left, XkbXKBFile2)); | |||
739 | fprintf(file, " width= %s;\n", | |||
740 | XkbGeomFPText(s->width, XkbXKBFile2)); | |||
741 | fprintf(file, " height= %s;\n", | |||
742 | XkbGeomFPText(s->height, XkbXKBFile2)); | |||
743 | if (s->angle != 0) { | |||
744 | fprintf(file, " angle= %s;\n", | |||
745 | XkbGeomFPText(s->angle, XkbXKBFile2)); | |||
746 | } | |||
747 | for (i = 0, row = s->rows; i < s->num_rows; i++, row++) { | |||
748 | fprintf(file, " row {\n"); | |||
749 | fprintf(file, " top= %s;\n", | |||
750 | XkbGeomFPText(row->top, XkbXKBFile2)); | |||
| ||||
751 | fprintf(file, " left= %s;\n", | |||
752 | XkbGeomFPText(row->left, XkbXKBFile2)); | |||
753 | if (row->vertical) | |||
754 | fprintf(file, " vertical;\n"); | |||
755 | if (row->num_keys > 0) { | |||
756 | register int k; | |||
757 | register XkbKeyPtr key; | |||
758 | int forceNL = 0; | |||
759 | int nThisLine = 0; | |||
760 | ||||
761 | fprintf(file, " keys {\n"); | |||
762 | for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { | |||
763 | XkbShapePtr shape; | |||
764 | ||||
765 | if (key->color_ndx != dfltKeyColor) | |||
766 | forceNL = 1; | |||
767 | if (k == 0) { | |||
768 | fprintf(file, " "); | |||
769 | nThisLine = 0; | |||
770 | } | |||
771 | else if (((nThisLine % 2) == 1) || (forceNL)) { | |||
772 | fprintf(file, ",\n "); | |||
773 | forceNL = nThisLine = 0; | |||
774 | } | |||
775 | else { | |||
776 | fprintf(file, ", "); | |||
777 | nThisLine++; | |||
778 | } | |||
779 | shape = XkbKeyShape(geom, key)(&(geom)->shapes[(key)->shape_ndx]); | |||
780 | fprintf(file, "{ %6s, \"%s\", %3s", | |||
781 | XkbKeyNameText(key->name.name, XkbXKBFile2), | |||
782 | XkbAtomText(shape->name, XkbXKBFile2), | |||
783 | XkbGeomFPText(key->gap, XkbXKBFile2)); | |||
784 | if (key->color_ndx != dfltKeyColor) { | |||
785 | fprintf(file, ", color=\"%s\"", | |||
786 | XkbKeyColor(geom, key)(&(geom)->colors[(key)->color_ndx])->spec); | |||
787 | forceNL = 1; | |||
788 | } | |||
789 | fprintf(file, " }"); | |||
790 | } | |||
791 | fprintf(file, "\n };\n"); | |||
792 | } | |||
793 | fprintf(file, " };\n"); | |||
794 | } | |||
795 | if (s->doodads != NULL((void*)0)) { | |||
796 | XkbDoodadPtr doodad; | |||
797 | ||||
798 | for (i = 0, doodad = s->doodads; i < s->num_doodads; i++, doodad++) { | |||
799 | WriteXKBDoodad(file, 8, geom, doodad); | |||
800 | } | |||
801 | } | |||
802 | if (s->overlays != NULL((void*)0)) { | |||
803 | XkbOverlayPtr ol; | |||
804 | ||||
805 | for (i = 0, ol = s->overlays; i < s->num_overlays; i++, ol++) { | |||
806 | WriteXKBOverlay(file, 8, geom, ol); | |||
807 | } | |||
808 | } | |||
809 | fprintf(file, " }; // End of \"%s\" section\n\n", | |||
810 | XkbAtomText(s->name, XkbXKBFile2)); | |||
811 | return TRUE1; | |||
812 | } | |||
813 | ||||
814 | Bool | |||
815 | XkbWriteXKBGeometry(FILE * file, | |||
816 | XkbDescPtr xkb, | |||
817 | Bool topLevel, | |||
818 | Bool showImplicit, XkbFileAddOnFunc addOn, void *priv) | |||
819 | { | |||
820 | register unsigned i, n; | |||
821 | XkbGeometryPtr geom; | |||
822 | ||||
823 | if ((!xkb) || (!xkb->geom)) { | |||
| ||||
824 | _XkbLibError(_XkbErrMissingGeometry, "XkbWriteXKBGeometry", 0); | |||
825 | return FALSE0; | |||
826 | } | |||
827 | geom = xkb->geom; | |||
828 | if (geom->name == None0L) | |||
829 | fprintf(file, "xkb_geometry {\n\n"); | |||
830 | else | |||
831 | fprintf(file, "xkb_geometry \"%s\" {\n\n", | |||
832 | XkbAtomText(geom->name, XkbXKBFile2)); | |||
833 | fprintf(file, " width= %s;\n", | |||
834 | XkbGeomFPText(geom->width_mm, XkbXKBFile2)); | |||
835 | fprintf(file, " height= %s;\n\n", | |||
836 | XkbGeomFPText(geom->height_mm, XkbXKBFile2)); | |||
837 | ||||
838 | if (geom->key_aliases != NULL((void*)0)) { | |||
839 | XkbKeyAliasPtr pAl; | |||
840 | ||||
841 | pAl = geom->key_aliases; | |||
842 | for (i = 0; i < geom->num_key_aliases; i++, pAl++) { | |||
843 | fprintf(file, " alias %6s = %6s;\n", | |||
844 | XkbKeyNameText(pAl->alias, XkbXKBFile2), | |||
845 | XkbKeyNameText(pAl->real, XkbXKBFile2)); | |||
846 | } | |||
847 | fprintf(file, "\n"); | |||
848 | } | |||
849 | ||||
850 | if (geom->base_color != NULL((void*)0)) | |||
851 | fprintf(file, " baseColor= \"%s\";\n", | |||
852 | XkbStringText(geom->base_color->spec, XkbXKBFile2)); | |||
853 | if (geom->label_color != NULL((void*)0)) | |||
854 | fprintf(file, " labelColor= \"%s\";\n", | |||
855 | XkbStringText(geom->label_color->spec, XkbXKBFile2)); | |||
856 | if (geom->label_font != NULL((void*)0)) | |||
857 | fprintf(file, " xfont= \"%s\";\n", | |||
858 | XkbStringText(geom->label_font, XkbXKBFile2)); | |||
859 | if ((geom->num_colors > 0) && (showImplicit)) { | |||
860 | XkbColorPtr color; | |||
861 | ||||
862 | for (color = geom->colors, i = 0; i < geom->num_colors; i++, color++) { | |||
863 | fprintf(file, "// color[%d]= \"%s\"\n", i, | |||
864 | XkbStringText(color->spec, XkbXKBFile2)); | |||
865 | } | |||
866 | fprintf(file, "\n"); | |||
867 | } | |||
868 | if (geom->num_properties > 0) { | |||
869 | XkbPropertyPtr prop; | |||
870 | ||||
871 | for (prop = geom->properties, i = 0; i < geom->num_properties; | |||
872 | i++, prop++) { | |||
873 | fprintf(file, " %s= \"%s\";\n", prop->name, | |||
874 | XkbStringText(prop->value, XkbXKBFile2)); | |||
875 | } | |||
876 | fprintf(file, "\n"); | |||
877 | } | |||
878 | if (geom->num_shapes > 0) { | |||
879 | XkbShapePtr shape; | |||
880 | XkbOutlinePtr outline; | |||
881 | int lastR; | |||
882 | ||||
883 | for (shape = geom->shapes, i = 0; i < geom->num_shapes; i++, shape++) { | |||
884 | lastR = 0; | |||
885 | fprintf(file, " shape \"%s\" {", | |||
886 | XkbAtomText(shape->name, XkbXKBFile2)); | |||
887 | outline = shape->outlines; | |||
888 | if (shape->num_outlines > 1) { | |||
889 | for (n = 0; n < shape->num_outlines; n++, outline++) { | |||
890 | if (n == 0) | |||
891 | fprintf(file, "\n"); | |||
892 | else | |||
893 | fprintf(file, ",\n"); | |||
894 | WriteXKBOutline(file, shape, outline, lastR, 8, 8); | |||
895 | lastR = outline->corner_radius; | |||
896 | } | |||
897 | fprintf(file, "\n };\n"); | |||
898 | } | |||
899 | else { | |||
900 | WriteXKBOutline(file, NULL((void*)0), outline, lastR, 1, 8); | |||
901 | fprintf(file, " };\n"); | |||
902 | } | |||
903 | } | |||
904 | } | |||
905 | if (geom->num_sections > 0) { | |||
906 | XkbSectionPtr section; | |||
907 | ||||
908 | for (section = geom->sections, i = 0; i < geom->num_sections; | |||
909 | i++, section++) { | |||
910 | WriteXKBSection(file, section, geom); | |||
911 | } | |||
912 | } | |||
913 | if (geom->num_doodads > 0) { | |||
914 | XkbDoodadPtr doodad; | |||
915 | ||||
916 | for (i = 0, doodad = geom->doodads; i < geom->num_doodads; | |||
917 | i++, doodad++) { | |||
918 | WriteXKBDoodad(file, 4, geom, doodad); | |||
919 | } | |||
920 | } | |||
921 | if (addOn) | |||
922 | (*addOn) (file, xkb, topLevel, showImplicit, XkmGeometryIndex5, priv); | |||
923 | fprintf(file, "};\n\n"); | |||
924 | return TRUE1; | |||
925 | } |