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