18c9fbc29Smrg/************************************************************ 28c9fbc29Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 38c9fbc29Smrg 48c9fbc29Smrg Permission to use, copy, modify, and distribute this 58c9fbc29Smrg software and its documentation for any purpose and without 68c9fbc29Smrg fee is hereby granted, provided that the above copyright 78c9fbc29Smrg notice appear in all copies and that both that copyright 88c9fbc29Smrg notice and this permission notice appear in supporting 94cd6a3aeSmrg documentation, and that the name of Silicon Graphics not be 104cd6a3aeSmrg used in advertising or publicity pertaining to distribution 118c9fbc29Smrg of the software without specific prior written permission. 124cd6a3aeSmrg Silicon Graphics makes no representation about the suitability 138c9fbc29Smrg of this software for any purpose. It is provided "as is" 148c9fbc29Smrg without any express or implied warranty. 154cd6a3aeSmrg 164cd6a3aeSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 174cd6a3aeSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 188c9fbc29Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 194cd6a3aeSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 204cd6a3aeSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 214cd6a3aeSmrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 228c9fbc29Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 238c9fbc29Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 248c9fbc29Smrg 258c9fbc29Smrg ********************************************************/ 268c9fbc29Smrg 278c9fbc29Smrg#ifdef HAVE_DIX_CONFIG_H 288c9fbc29Smrg#include <dix-config.h> 298c9fbc29Smrg#elif defined(HAVE_CONFIG_H) 308c9fbc29Smrg#include <config.h> 318c9fbc29Smrg#endif 328c9fbc29Smrg 338c9fbc29Smrg#include <stdio.h> 348c9fbc29Smrg#include <ctype.h> 358c9fbc29Smrg#include <stdlib.h> 368c9fbc29Smrg#include <X11/Xfuncs.h> 378c9fbc29Smrg 388c9fbc29Smrg 398c9fbc29Smrg#include <X11/Xlib.h> 408c9fbc29Smrg#include <X11/XKBlib.h> 418c9fbc29Smrg#include <X11/extensions/XKBgeom.h> 428c9fbc29Smrg 438c9fbc29Smrg#include "XKMformat.h" 448c9fbc29Smrg#include "XKBfileInt.h" 458c9fbc29Smrg 468c9fbc29Smrg 478c9fbc29Smrg#define VMOD_HIDE_VALUE 0 488c9fbc29Smrg#define VMOD_SHOW_VALUE 1 498c9fbc29Smrg#define VMOD_COMMENT_VALUE 2 508c9fbc29Smrg 518c9fbc29Smrgstatic Bool 5270728a38SmrgWriteXKBVModDecl(FILE *file, Display *dpy, XkbDescPtr xkb, int showValue) 538c9fbc29Smrg{ 5470728a38Smrg register int i, nMods; 5570728a38Smrg Atom *vmodNames; 5670728a38Smrg 5770728a38Smrg if (xkb == NULL) 5870728a38Smrg return False; 5970728a38Smrg if (xkb->names != NULL) 6070728a38Smrg vmodNames = xkb->names->vmods; 6170728a38Smrg else 6270728a38Smrg vmodNames = NULL; 6370728a38Smrg 6470728a38Smrg for (i = nMods = 0; i < XkbNumVirtualMods; i++) { 6570728a38Smrg if ((vmodNames != NULL) && (vmodNames[i] != None)) { 6670728a38Smrg if (nMods == 0) 6770728a38Smrg fprintf(file, " virtual_modifiers "); 6870728a38Smrg else 6970728a38Smrg fprintf(file, ","); 7070728a38Smrg fprintf(file, "%s", XkbAtomText(dpy, vmodNames[i], XkbXKBFile)); 7170728a38Smrg if ((showValue != VMOD_HIDE_VALUE) && 7270728a38Smrg (xkb->server) && (xkb->server->vmods[i] != XkbNoModifierMask)) { 7370728a38Smrg if (showValue == VMOD_COMMENT_VALUE) { 7470728a38Smrg fprintf(file, "/* = %s */", 7570728a38Smrg XkbModMaskText(xkb->server->vmods[i], XkbXKBFile)); 7670728a38Smrg } 7770728a38Smrg else { 7870728a38Smrg fprintf(file, "= %s", 7970728a38Smrg XkbModMaskText(xkb->server->vmods[i], XkbXKBFile)); 8070728a38Smrg } 8170728a38Smrg } 8270728a38Smrg nMods++; 8370728a38Smrg } 848c9fbc29Smrg } 8570728a38Smrg if (nMods > 0) 8670728a38Smrg fprintf(file, ";\n\n"); 878c9fbc29Smrg return True; 888c9fbc29Smrg} 898c9fbc29Smrg 908c9fbc29Smrg/***====================================================================***/ 918c9fbc29Smrg 928c9fbc29Smrgstatic Bool 9370728a38SmrgWriteXKBAction(FILE *file, XkbFileInfo *result, XkbAnyAction *action) 948c9fbc29Smrg{ 9570728a38Smrg XkbDescPtr xkb; 9670728a38Smrg Display *dpy; 978c9fbc29Smrg 9870728a38Smrg xkb = result->xkb; 9970728a38Smrg dpy = xkb->dpy; 10070728a38Smrg fprintf(file, "%s", 10170728a38Smrg XkbActionText(dpy, xkb, (XkbAction *) action, XkbXKBFile)); 1028c9fbc29Smrg return True; 1038c9fbc29Smrg} 1048c9fbc29Smrg 1058c9fbc29Smrg/***====================================================================***/ 1068c9fbc29Smrg 1078c9fbc29SmrgBool 10870728a38SmrgXkbWriteXKBKeycodes(FILE * file, 10970728a38Smrg XkbFileInfo * result, 11070728a38Smrg Bool topLevel, 11170728a38Smrg Bool showImplicit, 11270728a38Smrg XkbFileAddOnFunc addOn, 11370728a38Smrg void * priv) 1148c9fbc29Smrg{ 11570728a38Smrg Atom kcName; 11670728a38Smrg register unsigned i; 11770728a38Smrg XkbDescPtr xkb; 11870728a38Smrg Display *dpy; 11970728a38Smrg const char *alternate; 12070728a38Smrg 12170728a38Smrg xkb = result->xkb; 12270728a38Smrg if ((!xkb) || (!xkb->names) || (!xkb->names->keys)) { 12370728a38Smrg _XkbLibError(_XkbErrMissingNames, "XkbWriteXKBKeycodes", 0); 12470728a38Smrg return False; 1258c9fbc29Smrg } 12670728a38Smrg dpy = xkb->dpy; 12770728a38Smrg kcName = xkb->names->keycodes; 12870728a38Smrg if (kcName != None) 12970728a38Smrg fprintf(file, "xkb_keycodes \"%s\" {\n", 13070728a38Smrg XkbAtomText(dpy, kcName, XkbXKBFile)); 13170728a38Smrg else 13270728a38Smrg fprintf(file, "xkb_keycodes {\n"); 13370728a38Smrg fprintf(file, " minimum = %d;\n", xkb->min_key_code); 13470728a38Smrg fprintf(file, " maximum = %d;\n", xkb->max_key_code); 13570728a38Smrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 13670728a38Smrg if (xkb->names->keys[i].name[0] != '\0') { 13770728a38Smrg if (XkbFindKeycodeByName(xkb, xkb->names->keys[i].name, True) != i) 13870728a38Smrg alternate = "alternate "; 13970728a38Smrg else 14070728a38Smrg alternate = ""; 14170728a38Smrg fprintf(file, " %s%6s = %d;\n", alternate, 14270728a38Smrg XkbKeyNameText(xkb->names->keys[i].name, XkbXKBFile), i); 14370728a38Smrg } 1448c9fbc29Smrg } 14570728a38Smrg if (xkb->indicators != NULL) { 14670728a38Smrg for (i = 0; i < XkbNumIndicators; i++) { 14770728a38Smrg const char *type; 14870728a38Smrg 14970728a38Smrg if (xkb->indicators->phys_indicators & (1 << i)) 15070728a38Smrg type = " "; 15170728a38Smrg else 15270728a38Smrg type = " virtual "; 15370728a38Smrg if (xkb->names->indicators[i] != None) { 15470728a38Smrg fprintf(file, "%sindicator %d = \"%s\";\n", type, i + 1, 15570728a38Smrg XkbAtomText(dpy, xkb->names->indicators[i], 15670728a38Smrg XkbXKBFile)); 15770728a38Smrg } 15870728a38Smrg } 1598c9fbc29Smrg } 16070728a38Smrg if (xkb->names->key_aliases != NULL) { 16170728a38Smrg XkbKeyAliasPtr pAl; 16270728a38Smrg 16370728a38Smrg pAl = xkb->names->key_aliases; 16470728a38Smrg for (i = 0; i < xkb->names->num_key_aliases; i++, pAl++) { 16570728a38Smrg fprintf(file, " alias %6s = %6s;\n", 16670728a38Smrg XkbKeyNameText(pAl->alias, XkbXKBFile), 16770728a38Smrg XkbKeyNameText(pAl->real, XkbXKBFile)); 16870728a38Smrg } 1698c9fbc29Smrg } 1708c9fbc29Smrg if (addOn) 17170728a38Smrg (*addOn) (file, result, topLevel, showImplicit, XkmKeyNamesIndex, priv); 17270728a38Smrg fprintf(file, "};\n\n"); 1738c9fbc29Smrg return True; 1748c9fbc29Smrg} 1758c9fbc29Smrg 1768c9fbc29SmrgBool 17770728a38SmrgXkbWriteXKBKeyTypes(FILE * file, 17870728a38Smrg XkbFileInfo * result, 17970728a38Smrg Bool topLevel, 18070728a38Smrg Bool showImplicit, 18170728a38Smrg XkbFileAddOnFunc addOn, 18270728a38Smrg void * priv) 1838c9fbc29Smrg{ 18470728a38Smrg Display *dpy; 18570728a38Smrg register unsigned i, n; 18670728a38Smrg XkbKeyTypePtr type; 18770728a38Smrg XkbKTMapEntryPtr entry; 18870728a38Smrg XkbDescPtr xkb; 18970728a38Smrg 19070728a38Smrg xkb = result->xkb; 19170728a38Smrg if ((!xkb) || (!xkb->map) || (!xkb->map->types)) { 19270728a38Smrg _XkbLibError(_XkbErrMissingTypes, "XkbWriteXKBKeyTypes", 0); 19370728a38Smrg return False; 1948c9fbc29Smrg } 19570728a38Smrg dpy = xkb->dpy; 19670728a38Smrg if (xkb->map->num_types < XkbNumRequiredTypes) { 19770728a38Smrg _XkbLibError(_XkbErrMissingReqTypes, "XkbWriteXKBKeyTypes", 0); 19870728a38Smrg return 0; 1998c9fbc29Smrg } 20070728a38Smrg if ((xkb->names == NULL) || (xkb->names->types == None)) 20170728a38Smrg fprintf(file, "xkb_types {\n\n"); 20270728a38Smrg else 20370728a38Smrg fprintf(file, "xkb_types \"%s\" {\n\n", 20470728a38Smrg XkbAtomText(dpy, xkb->names->types, XkbXKBFile)); 20570728a38Smrg WriteXKBVModDecl(file, dpy, xkb, 20670728a38Smrg (showImplicit ? VMOD_COMMENT_VALUE : VMOD_HIDE_VALUE)); 20770728a38Smrg 20870728a38Smrg type = xkb->map->types; 20970728a38Smrg for (i = 0; i < xkb->map->num_types; i++, type++) { 21070728a38Smrg fprintf(file, " type \"%s\" {\n", 21170728a38Smrg XkbAtomText(dpy, type->name, XkbXKBFile)); 21270728a38Smrg fprintf(file, " modifiers= %s;\n", 21370728a38Smrg XkbVModMaskText(dpy, xkb, type->mods.real_mods, 21470728a38Smrg type->mods.vmods, XkbXKBFile)); 21570728a38Smrg entry = type->map; 21670728a38Smrg for (n = 0; n < type->map_count; n++, entry++) { 21770728a38Smrg char *str; 21870728a38Smrg 21970728a38Smrg str = 22070728a38Smrg XkbVModMaskText(dpy, xkb, entry->mods.real_mods, 22170728a38Smrg entry->mods.vmods, XkbXKBFile); 22270728a38Smrg fprintf(file, " map[%s]= Level%d;\n", str, entry->level + 1); 22370728a38Smrg if ((type->preserve) && ((type->preserve[n].real_mods) || 22470728a38Smrg (type->preserve[n].vmods))) { 22570728a38Smrg fprintf(file, " preserve[%s]= ", str); 22670728a38Smrg fprintf(file, "%s;\n", XkbVModMaskText(dpy, xkb, 22770728a38Smrg type->preserve[n]. 22870728a38Smrg real_mods, 22970728a38Smrg type->preserve[n].vmods, 23070728a38Smrg XkbXKBFile)); 23170728a38Smrg } 23270728a38Smrg } 23370728a38Smrg if (type->level_names != NULL) { 23470728a38Smrg Atom *name = type->level_names; 23570728a38Smrg 23670728a38Smrg for (n = 0; n < type->num_levels; n++, name++) { 23770728a38Smrg if ((*name) == None) 23870728a38Smrg continue; 23970728a38Smrg fprintf(file, " level_name[Level%d]= \"%s\";\n", n + 1, 24070728a38Smrg XkbAtomText(dpy, *name, XkbXKBFile)); 24170728a38Smrg } 24270728a38Smrg } 24370728a38Smrg fprintf(file, " };\n"); 2448c9fbc29Smrg } 2458c9fbc29Smrg if (addOn) 24670728a38Smrg (*addOn) (file, result, topLevel, showImplicit, XkmTypesIndex, priv); 24770728a38Smrg fprintf(file, "};\n\n"); 2488c9fbc29Smrg return True; 2498c9fbc29Smrg} 2508c9fbc29Smrg 2518c9fbc29Smrgstatic Bool 25270728a38SmrgWriteXKBIndicatorMap(FILE * file, 25370728a38Smrg XkbFileInfo * result, 25470728a38Smrg Atom name, 25570728a38Smrg XkbIndicatorMapPtr led, 25670728a38Smrg XkbFileAddOnFunc addOn, 25770728a38Smrg void * priv) 2588c9fbc29Smrg{ 25970728a38Smrg XkbDescPtr xkb; 26070728a38Smrg char *tmp; 2618c9fbc29Smrg 26270728a38Smrg xkb = result->xkb; 2638c9fbc29Smrg tmp = XkbAtomGetString(xkb->dpy, name); 26470728a38Smrg fprintf(file, " indicator \"%s\" {\n", tmp); 2658c9fbc29Smrg _XkbFree(tmp); 26670728a38Smrg if (led->flags & XkbIM_NoExplicit) 26770728a38Smrg fprintf(file, " !allowExplicit;\n"); 26870728a38Smrg if (led->flags & XkbIM_LEDDrivesKB) 26970728a38Smrg fprintf(file, " indicatorDrivesKeyboard;\n"); 27070728a38Smrg if (led->which_groups != 0) { 27170728a38Smrg if (led->which_groups != XkbIM_UseEffective) { 27270728a38Smrg fprintf(file, " whichGroupState= %s;\n", 27370728a38Smrg XkbIMWhichStateMaskText(led->which_groups, XkbXKBFile)); 27470728a38Smrg } 27570728a38Smrg fprintf(file, " groups= 0x%02x;\n", led->groups); 2768c9fbc29Smrg } 27770728a38Smrg if (led->which_mods != 0) { 27870728a38Smrg if (led->which_mods != XkbIM_UseEffective) { 27970728a38Smrg fprintf(file, " whichModState= %s;\n", 28070728a38Smrg XkbIMWhichStateMaskText(led->which_mods, XkbXKBFile)); 28170728a38Smrg } 28270728a38Smrg fprintf(file, " modifiers= %s;\n", 28370728a38Smrg XkbVModMaskText(xkb->dpy, xkb, 28470728a38Smrg led->mods.real_mods, led->mods.vmods, 28570728a38Smrg XkbXKBFile)); 2868c9fbc29Smrg } 28770728a38Smrg if (led->ctrls != 0) { 28870728a38Smrg fprintf(file, " controls= %s;\n", 28970728a38Smrg XkbControlsMaskText(led->ctrls, XkbXKBFile)); 2908c9fbc29Smrg } 2918c9fbc29Smrg if (addOn) 29270728a38Smrg (*addOn) (file, result, False, True, XkmIndicatorsIndex, priv); 29370728a38Smrg fprintf(file, " };\n"); 2948c9fbc29Smrg return True; 2958c9fbc29Smrg} 2968c9fbc29Smrg 2978c9fbc29SmrgBool 29870728a38SmrgXkbWriteXKBCompatMap(FILE * file, 29970728a38Smrg XkbFileInfo * result, 30070728a38Smrg Bool topLevel, 30170728a38Smrg Bool showImplicit, 30270728a38Smrg XkbFileAddOnFunc addOn, 30370728a38Smrg void * priv) 3048c9fbc29Smrg{ 30570728a38Smrg Display * dpy; 30670728a38Smrg register unsigned i; 30770728a38Smrg XkbSymInterpretPtr interp; 30870728a38Smrg XkbDescPtr xkb; 30970728a38Smrg 31070728a38Smrg xkb = result->xkb; 31170728a38Smrg if ((!xkb) || (!xkb->compat) || (!xkb->compat->sym_interpret)) { 31270728a38Smrg _XkbLibError(_XkbErrMissingCompatMap, "XkbWriteXKBCompatMap", 0); 31370728a38Smrg return False; 3148c9fbc29Smrg } 31570728a38Smrg dpy = xkb->dpy; 31670728a38Smrg if ((xkb->names == NULL) || (xkb->names->compat == None)) 31770728a38Smrg fprintf(file, "xkb_compatibility {\n\n"); 31870728a38Smrg else 31970728a38Smrg fprintf(file, "xkb_compatibility \"%s\" {\n\n", 32070728a38Smrg XkbAtomText(dpy, xkb->names->compat, XkbXKBFile)); 32170728a38Smrg WriteXKBVModDecl(file, dpy, xkb, 32270728a38Smrg (showImplicit ? VMOD_COMMENT_VALUE : VMOD_HIDE_VALUE)); 32370728a38Smrg 32470728a38Smrg fprintf(file, " interpret.useModMapMods= AnyLevel;\n"); 32570728a38Smrg fprintf(file, " interpret.repeat= False;\n"); 32670728a38Smrg fprintf(file, " interpret.locking= False;\n"); 32770728a38Smrg interp = xkb->compat->sym_interpret; 32870728a38Smrg for (i = 0; i < xkb->compat->num_si; i++, interp++) { 32970728a38Smrg fprintf(file, " interpret %s+%s(%s) {\n", 33070728a38Smrg ((interp->sym == NoSymbol) ? "Any" : 33170728a38Smrg XkbKeysymText(interp->sym, XkbXKBFile)), 33270728a38Smrg XkbSIMatchText(interp->match, XkbXKBFile), 33370728a38Smrg XkbModMaskText(interp->mods, XkbXKBFile)); 33470728a38Smrg if (interp->virtual_mod != XkbNoModifier) { 33570728a38Smrg fprintf(file, " virtualModifier= %s;\n", 33670728a38Smrg XkbVModIndexText(dpy, xkb, interp->virtual_mod, 33770728a38Smrg XkbXKBFile)); 33870728a38Smrg } 33970728a38Smrg if (interp->match & XkbSI_LevelOneOnly) 34070728a38Smrg fprintf(file, " useModMapMods=level1;\n"); 34170728a38Smrg if (interp->flags & XkbSI_LockingKey) 34270728a38Smrg fprintf(file, " locking= True;\n"); 34370728a38Smrg if (interp->flags & XkbSI_AutoRepeat) 34470728a38Smrg fprintf(file, " repeat= True;\n"); 34570728a38Smrg fprintf(file, " action= "); 34670728a38Smrg WriteXKBAction(file, result, &interp->act); 34770728a38Smrg fprintf(file, ";\n"); 34870728a38Smrg fprintf(file, " };\n"); 3498c9fbc29Smrg } 35070728a38Smrg for (i = 0; i < XkbNumKbdGroups; i++) { 35170728a38Smrg XkbModsPtr gc; 35270728a38Smrg 35370728a38Smrg gc = &xkb->compat->groups[i]; 35470728a38Smrg if ((gc->real_mods == 0) && (gc->vmods == 0)) 35570728a38Smrg continue; 35670728a38Smrg fprintf(file, " group %d = %s;\n", i + 1, 35770728a38Smrg XkbVModMaskText(xkb->dpy, xkb, gc->real_mods, gc->vmods, 35870728a38Smrg XkbXKBFile)); 3598c9fbc29Smrg } 3608c9fbc29Smrg if (xkb->indicators) { 36170728a38Smrg for (i = 0; i < XkbNumIndicators; i++) { 36270728a38Smrg XkbIndicatorMapPtr map = &xkb->indicators->maps[i]; 36370728a38Smrg 36470728a38Smrg if ((map->flags != 0) || (map->which_groups != 0) || 36570728a38Smrg (map->groups != 0) || (map->which_mods != 0) || 36670728a38Smrg (map->mods.real_mods != 0) || (map->mods.vmods != 0) || 36770728a38Smrg (map->ctrls != 0)) { 36870728a38Smrg WriteXKBIndicatorMap(file, result, xkb->names->indicators[i], 36970728a38Smrg map, addOn, priv); 37070728a38Smrg } 37170728a38Smrg } 3728c9fbc29Smrg } 3738c9fbc29Smrg if (addOn) 37470728a38Smrg (*addOn) (file, result, topLevel, showImplicit, XkmCompatMapIndex, 37570728a38Smrg priv); 37670728a38Smrg fprintf(file, "};\n\n"); 3778c9fbc29Smrg return True; 3788c9fbc29Smrg} 3798c9fbc29Smrg 3808c9fbc29SmrgBool 38170728a38SmrgXkbWriteXKBSymbols(FILE * file, 38270728a38Smrg XkbFileInfo * result, 38370728a38Smrg Bool topLevel, 38470728a38Smrg Bool showImplicit, 38570728a38Smrg XkbFileAddOnFunc addOn, 38670728a38Smrg void * priv) 3878c9fbc29Smrg{ 38870728a38Smrg Display *dpy; 38970728a38Smrg register unsigned i, tmp; 39070728a38Smrg XkbDescPtr xkb; 39170728a38Smrg XkbClientMapPtr map; 39270728a38Smrg XkbServerMapPtr srv; 39370728a38Smrg Bool showActions; 39470728a38Smrg 39570728a38Smrg xkb = result->xkb; 39670728a38Smrg 39770728a38Smrg if ((!xkb) || (!xkb->map) || (!xkb->map->syms) || (!xkb->map->key_sym_map)) { 39870728a38Smrg _XkbLibError(_XkbErrMissingSymbols, "XkbWriteXKBSymbols", 0); 39970728a38Smrg return False; 4008c9fbc29Smrg } 40170728a38Smrg if ((!xkb->names) || (!xkb->names->keys)) { 40270728a38Smrg _XkbLibError(_XkbErrMissingNames, "XkbWriteXKBSymbols", 0); 40370728a38Smrg return False; 4048c9fbc29Smrg } 4058c9fbc29Smrg 40670728a38Smrg map = xkb->map; 40770728a38Smrg srv = xkb->server; 40870728a38Smrg dpy = xkb->dpy; 40970728a38Smrg 41070728a38Smrg if ((xkb->names == NULL) || (xkb->names->symbols == None)) 41170728a38Smrg fprintf(file, "xkb_symbols {\n\n"); 41270728a38Smrg else 41370728a38Smrg fprintf(file, "xkb_symbols \"%s\" {\n\n", 41470728a38Smrg XkbAtomText(dpy, xkb->names->symbols, XkbXKBFile)); 41570728a38Smrg for (tmp = i = 0; i < XkbNumKbdGroups; i++) { 41670728a38Smrg if (xkb->names->groups[i] != None) { 41770728a38Smrg fprintf(file, " name[group%d]=\"%s\";\n", i + 1, 41870728a38Smrg XkbAtomText(dpy, xkb->names->groups[i], XkbXKBFile)); 41970728a38Smrg tmp++; 42070728a38Smrg } 4218c9fbc29Smrg } 42270728a38Smrg if (tmp > 0) 42370728a38Smrg fprintf(file, "\n"); 42470728a38Smrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 42570728a38Smrg Bool simple; 42670728a38Smrg 42770728a38Smrg if ((int) XkbKeyNumSyms(xkb, i) < 1) 42870728a38Smrg continue; 42970728a38Smrg if (XkbFindKeycodeByName(xkb, xkb->names->keys[i].name, True) != i) 43070728a38Smrg continue; 43170728a38Smrg simple = True; 43270728a38Smrg fprintf(file, " key %6s {", 43370728a38Smrg XkbKeyNameText(xkb->names->keys[i].name, XkbXKBFile)); 43470728a38Smrg if (srv->explicit) { 43570728a38Smrg if (((srv->explicit[i] & XkbExplicitKeyTypesMask) != 0) || 43670728a38Smrg (showImplicit)) { 43770728a38Smrg int typeNdx, g; 43870728a38Smrg Bool multi; 43970728a38Smrg const char *comment = " "; 44070728a38Smrg 44170728a38Smrg if ((srv->explicit[i] & XkbExplicitKeyTypesMask) == 0) 44270728a38Smrg comment = "//"; 44370728a38Smrg multi = False; 44470728a38Smrg typeNdx = XkbKeyKeyTypeIndex(xkb, i, 0); 44570728a38Smrg for (g = 1; (g < XkbKeyNumGroups(xkb, i)) && (!multi); g++) { 44670728a38Smrg if (XkbKeyKeyTypeIndex(xkb, i, g) != typeNdx) 44770728a38Smrg multi = True; 44870728a38Smrg } 44970728a38Smrg if (multi) { 45070728a38Smrg for (g = 0; g < XkbKeyNumGroups(xkb, i); g++) { 45170728a38Smrg typeNdx = XkbKeyKeyTypeIndex(xkb, i, g); 45270728a38Smrg if (srv->explicit[i] & (1 << g)) { 45370728a38Smrg fprintf(file, "\n%s type[group%d]= \"%s\",", 45470728a38Smrg comment, g + 1, 45570728a38Smrg XkbAtomText(dpy, map->types[typeNdx].name, 45670728a38Smrg XkbXKBFile)); 45770728a38Smrg } 45870728a38Smrg else if (showImplicit) { 45970728a38Smrg fprintf(file, "\n// type[group%d]= \"%s\",", 46070728a38Smrg g + 1, 46170728a38Smrg XkbAtomText(dpy, map->types[typeNdx].name, 46270728a38Smrg XkbXKBFile)); 46370728a38Smrg } 46470728a38Smrg } 46570728a38Smrg } 46670728a38Smrg else { 46770728a38Smrg fprintf(file, "\n%s type= \"%s\",", comment, 46870728a38Smrg XkbAtomText(dpy, map->types[typeNdx].name, 46970728a38Smrg XkbXKBFile)); 47070728a38Smrg } 47170728a38Smrg simple = False; 47270728a38Smrg } 47370728a38Smrg if (((srv->explicit[i] & XkbExplicitAutoRepeatMask) != 0) && 47470728a38Smrg (xkb->ctrls != NULL)) { 47570728a38Smrg if (xkb->ctrls->per_key_repeat[i / 8] & (1 << (i % 8))) 47670728a38Smrg fprintf(file, "\n repeat= Yes,"); 47770728a38Smrg else 47870728a38Smrg fprintf(file, "\n repeat= No,"); 47970728a38Smrg simple = False; 48070728a38Smrg } 48170728a38Smrg if ((xkb->server != NULL) && (xkb->server->vmodmap != NULL) && 48270728a38Smrg (xkb->server->vmodmap[i] != 0)) { 48370728a38Smrg if ((srv->explicit[i] & XkbExplicitVModMapMask) != 0) { 48470728a38Smrg fprintf(file, "\n virtualMods= %s,", 48570728a38Smrg XkbVModMaskText(dpy, xkb, 0, 48670728a38Smrg xkb->server->vmodmap[i], 48770728a38Smrg XkbXKBFile)); 48870728a38Smrg } 48970728a38Smrg else if (showImplicit) { 49070728a38Smrg fprintf(file, "\n// virtualMods= %s,", 49170728a38Smrg XkbVModMaskText(dpy, xkb, 0, 49270728a38Smrg xkb->server->vmodmap[i], 49370728a38Smrg XkbXKBFile)); 49470728a38Smrg } 49570728a38Smrg } 49670728a38Smrg } 49770728a38Smrg switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(xkb, i))) { 49870728a38Smrg case XkbClampIntoRange: 49970728a38Smrg fprintf(file, "\n groupsClamp,"); 50070728a38Smrg break; 50170728a38Smrg case XkbRedirectIntoRange: 50270728a38Smrg fprintf(file, "\n groupsRedirect= Group%d,", 50370728a38Smrg XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(xkb, i)) + 1); 50470728a38Smrg break; 50570728a38Smrg } 50670728a38Smrg if (srv->behaviors != NULL) { 50770728a38Smrg unsigned type; 50870728a38Smrg 50970728a38Smrg type = srv->behaviors[i].type & XkbKB_OpMask; 51070728a38Smrg 51170728a38Smrg if (type != XkbKB_Default) { 51270728a38Smrg simple = False; 51370728a38Smrg fprintf(file, "\n %s,", 51470728a38Smrg XkbBehaviorText(xkb, &srv->behaviors[i], XkbXKBFile)); 51570728a38Smrg } 51670728a38Smrg } 51770728a38Smrg if ((srv->explicit == NULL) || showImplicit || 51870728a38Smrg ((srv->explicit[i] & XkbExplicitInterpretMask) != 0)) 51970728a38Smrg showActions = XkbKeyHasActions(xkb, i); 52070728a38Smrg else 52170728a38Smrg showActions = False; 52270728a38Smrg 52370728a38Smrg if (((unsigned) XkbKeyNumGroups(xkb, i) > 1) || showActions) 52470728a38Smrg simple = False; 52570728a38Smrg if (simple) { 52670728a38Smrg KeySym *syms; 52770728a38Smrg unsigned s; 52870728a38Smrg 52970728a38Smrg syms = XkbKeySymsPtr(xkb, i); 53070728a38Smrg fprintf(file, " [ "); 53170728a38Smrg for (s = 0; s < XkbKeyGroupWidth(xkb, i, XkbGroup1Index); s++) { 53270728a38Smrg if (s != 0) 53370728a38Smrg fprintf(file, ", "); 53470728a38Smrg fprintf(file, "%15s", XkbKeysymText(*syms++, XkbXKBFile)); 53570728a38Smrg } 53670728a38Smrg fprintf(file, " ] };\n"); 53770728a38Smrg } 53870728a38Smrg else { 53970728a38Smrg unsigned g, s; 54070728a38Smrg KeySym *syms; 54170728a38Smrg XkbAction *acts; 54270728a38Smrg 54370728a38Smrg syms = XkbKeySymsPtr(xkb, i); 54470728a38Smrg acts = XkbKeyActionsPtr(xkb, i); 54570728a38Smrg for (g = 0; g < XkbKeyNumGroups(xkb, i); g++) { 54670728a38Smrg if (g != 0) 54770728a38Smrg fprintf(file, ","); 54870728a38Smrg fprintf(file, "\n symbols[Group%d]= [ ", g + 1); 54970728a38Smrg for (s = 0; s < XkbKeyGroupWidth(xkb, i, g); s++) { 55070728a38Smrg if (s != 0) 55170728a38Smrg fprintf(file, ", "); 55270728a38Smrg fprintf(file, "%15s", XkbKeysymText(syms[s], XkbXKBFile)); 55370728a38Smrg } 55470728a38Smrg fprintf(file, " ]"); 55570728a38Smrg syms += XkbKeyGroupsWidth(xkb, i); 55670728a38Smrg if (showActions) { 55770728a38Smrg fprintf(file, ",\n actions[Group%d]= [ ", g + 1); 55870728a38Smrg for (s = 0; s < XkbKeyGroupWidth(xkb, i, g); s++) { 55970728a38Smrg if (s != 0) 56070728a38Smrg fprintf(file, ", "); 56170728a38Smrg WriteXKBAction(file, result, 56270728a38Smrg (XkbAnyAction *) & acts[s]); 56370728a38Smrg } 56470728a38Smrg fprintf(file, " ]"); 56570728a38Smrg acts += XkbKeyGroupsWidth(xkb, i); 56670728a38Smrg } 56770728a38Smrg } 56870728a38Smrg fprintf(file, "\n };\n"); 56970728a38Smrg } 5708c9fbc29Smrg } 5718c9fbc29Smrg if (map && map->modmap) { 57270728a38Smrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 57370728a38Smrg if (map->modmap[i] != 0) { 57470728a38Smrg register int n, bit; 57570728a38Smrg 57670728a38Smrg for (bit = 1, n = 0; n < XkbNumModifiers; n++, bit <<= 1) { 57770728a38Smrg if (map->modmap[i] & bit) { 57870728a38Smrg char buf[5]; 57970728a38Smrg 58070728a38Smrg memcpy(buf, xkb->names->keys[i].name, 4); 58170728a38Smrg buf[4] = '\0'; 58270728a38Smrg fprintf(file, " modifier_map %s { <%s> };\n", 58370728a38Smrg XkbModIndexText(n, XkbXKBFile), buf); 58470728a38Smrg } 58570728a38Smrg } 58670728a38Smrg } 58770728a38Smrg } 5888c9fbc29Smrg } 5898c9fbc29Smrg if (addOn) 59070728a38Smrg (*addOn) (file, result, topLevel, showImplicit, XkmSymbolsIndex, priv); 59170728a38Smrg fprintf(file, "};\n\n"); 5928c9fbc29Smrg return True; 5938c9fbc29Smrg} 5948c9fbc29Smrg 5958c9fbc29Smrgstatic Bool 59670728a38SmrgWriteXKBOutline(FILE * file, 59770728a38Smrg XkbShapePtr shape, 59870728a38Smrg XkbOutlinePtr outline, 59970728a38Smrg int lastRadius, 60070728a38Smrg int first, 60170728a38Smrg int indent) 6028c9fbc29Smrg{ 60370728a38Smrg register int i; 60470728a38Smrg XkbPointPtr pt; 60570728a38Smrg char *iStr; 60670728a38Smrg 60770728a38Smrg fprintf(file, "%s", iStr = XkbIndentText(first)); 60870728a38Smrg if (first != indent) 60970728a38Smrg iStr = XkbIndentText(indent); 61070728a38Smrg if (outline->corner_radius != lastRadius) { 61170728a38Smrg fprintf(file, "corner= %s,", 61270728a38Smrg XkbGeomFPText(outline->corner_radius, XkbMessage)); 61370728a38Smrg if (shape != NULL) { 61470728a38Smrg fprintf(file, "\n%s", iStr); 61570728a38Smrg } 6168c9fbc29Smrg } 6178c9fbc29Smrg if (shape) { 61870728a38Smrg if (outline == shape->approx) 61970728a38Smrg fprintf(file, "approx= "); 62070728a38Smrg else if (outline == shape->primary) 62170728a38Smrg fprintf(file, "primary= "); 6228c9fbc29Smrg } 62370728a38Smrg fprintf(file, "{"); 62470728a38Smrg for (pt = outline->points, i = 0; i < outline->num_points; i++, pt++) { 62570728a38Smrg if (i == 0) 62670728a38Smrg fprintf(file, " "); 62770728a38Smrg else if ((i % 4) == 0) 62870728a38Smrg fprintf(file, ",\n%s ", iStr); 62970728a38Smrg else 63070728a38Smrg fprintf(file, ", "); 63170728a38Smrg fprintf(file, "[ %3s, %3s ]", XkbGeomFPText(pt->x, XkbXKBFile), 63270728a38Smrg XkbGeomFPText(pt->y, XkbXKBFile)); 6338c9fbc29Smrg } 63470728a38Smrg fprintf(file, " }"); 6358c9fbc29Smrg return True; 6368c9fbc29Smrg} 6378c9fbc29Smrg 6388c9fbc29Smrgstatic Bool 63970728a38SmrgWriteXKBDoodad(FILE * file, 64070728a38Smrg Display * dpy, 64170728a38Smrg unsigned indent, 64270728a38Smrg XkbGeometryPtr geom, 64370728a38Smrg XkbDoodadPtr doodad) 6448c9fbc29Smrg{ 64570728a38Smrg register char *i_str; 64670728a38Smrg XkbShapePtr shape; 64770728a38Smrg XkbColorPtr color; 64870728a38Smrg 64970728a38Smrg i_str = XkbIndentText(indent); 65070728a38Smrg fprintf(file, "%s%s \"%s\" {\n", i_str, 65170728a38Smrg XkbDoodadTypeText(doodad->any.type, XkbMessage), 65270728a38Smrg XkbAtomText(dpy, doodad->any.name, XkbMessage)); 65370728a38Smrg fprintf(file, "%s top= %s;\n", i_str, 65470728a38Smrg XkbGeomFPText(doodad->any.top, XkbXKBFile)); 65570728a38Smrg fprintf(file, "%s left= %s;\n", i_str, 65670728a38Smrg XkbGeomFPText(doodad->any.left, XkbXKBFile)); 65770728a38Smrg fprintf(file, "%s priority= %d;\n", i_str, doodad->any.priority); 6588c9fbc29Smrg switch (doodad->any.type) { 65970728a38Smrg case XkbOutlineDoodad: 66070728a38Smrg case XkbSolidDoodad: 66170728a38Smrg if (doodad->shape.angle != 0) { 66270728a38Smrg fprintf(file, "%s angle= %s;\n", i_str, 66370728a38Smrg XkbGeomFPText(doodad->shape.angle, XkbXKBFile)); 66470728a38Smrg } 66570728a38Smrg if (doodad->shape.color_ndx != 0) { 66670728a38Smrg fprintf(file, "%s color= \"%s\";\n", i_str, 66770728a38Smrg XkbShapeDoodadColor(geom, &doodad->shape)->spec); 66870728a38Smrg } 66970728a38Smrg shape = XkbShapeDoodadShape(geom, &doodad->shape); 67070728a38Smrg fprintf(file, "%s shape= \"%s\";\n", i_str, 67170728a38Smrg XkbAtomText(dpy, shape->name, XkbXKBFile)); 67270728a38Smrg break; 67370728a38Smrg case XkbTextDoodad: 67470728a38Smrg if (doodad->text.angle != 0) { 67570728a38Smrg fprintf(file, "%s angle= %s;\n", i_str, 67670728a38Smrg XkbGeomFPText(doodad->text.angle, XkbXKBFile)); 67770728a38Smrg } 67870728a38Smrg if (doodad->text.width != 0) { 67970728a38Smrg fprintf(file, "%s width= %s;\n", i_str, 68070728a38Smrg XkbGeomFPText(doodad->text.width, XkbXKBFile)); 68170728a38Smrg 68270728a38Smrg } 68370728a38Smrg if (doodad->text.height != 0) { 68470728a38Smrg fprintf(file, "%s height= %s;\n", i_str, 68570728a38Smrg XkbGeomFPText(doodad->text.height, XkbXKBFile)); 68670728a38Smrg 68770728a38Smrg } 68870728a38Smrg if (doodad->text.color_ndx != 0) { 68970728a38Smrg color = XkbTextDoodadColor(geom, &doodad->text); 69070728a38Smrg fprintf(file, "%s color= \"%s\";\n", i_str, 69170728a38Smrg XkbStringText(color->spec, XkbXKBFile)); 69270728a38Smrg } 69370728a38Smrg fprintf(file, "%s XFont= \"%s\";\n", i_str, 69470728a38Smrg XkbStringText(doodad->text.font, XkbXKBFile)); 69570728a38Smrg fprintf(file, "%s text= \"%s\";\n", i_str, 69670728a38Smrg XkbStringText(doodad->text.text, XkbXKBFile)); 69770728a38Smrg break; 69870728a38Smrg case XkbIndicatorDoodad: 69970728a38Smrg shape = XkbIndicatorDoodadShape(geom, &doodad->indicator); 70070728a38Smrg color = XkbIndicatorDoodadOnColor(geom, &doodad->indicator); 70170728a38Smrg fprintf(file, "%s onColor= \"%s\";\n", i_str, 70270728a38Smrg XkbStringText(color->spec, XkbXKBFile)); 70370728a38Smrg color = XkbIndicatorDoodadOffColor(geom, &doodad->indicator); 70470728a38Smrg fprintf(file, "%s offColor= \"%s\";\n", i_str, 70570728a38Smrg XkbStringText(color->spec, XkbXKBFile)); 70670728a38Smrg fprintf(file, "%s shape= \"%s\";\n", i_str, 70770728a38Smrg XkbAtomText(dpy, shape->name, XkbXKBFile)); 70870728a38Smrg break; 70970728a38Smrg case XkbLogoDoodad: 71070728a38Smrg fprintf(file, "%s logoName= \"%s\";\n", i_str, 71170728a38Smrg XkbStringText(doodad->logo.logo_name, XkbXKBFile)); 71270728a38Smrg if (doodad->shape.angle != 0) { 71370728a38Smrg fprintf(file, "%s angle= %s;\n", i_str, 71470728a38Smrg XkbGeomFPText(doodad->logo.angle, XkbXKBFile)); 71570728a38Smrg } 71670728a38Smrg if (doodad->shape.color_ndx != 0) { 71770728a38Smrg fprintf(file, "%s color= \"%s\";\n", i_str, 71870728a38Smrg XkbLogoDoodadColor(geom, &doodad->logo)->spec); 71970728a38Smrg } 72070728a38Smrg shape = XkbLogoDoodadShape(geom, &doodad->logo); 72170728a38Smrg fprintf(file, "%s shape= \"%s\";\n", i_str, 72270728a38Smrg XkbAtomText(dpy, shape->name, XkbXKBFile)); 72370728a38Smrg break; 7248c9fbc29Smrg } 72570728a38Smrg fprintf(file, "%s};\n", i_str); 7268c9fbc29Smrg return True; 7278c9fbc29Smrg} 7288c9fbc29Smrg 7298c9fbc29Smrg/*ARGSUSED*/ 7308c9fbc29Smrgstatic Bool 73170728a38SmrgWriteXKBOverlay(FILE * file, 73270728a38Smrg Display * dpy, 73370728a38Smrg unsigned indent, 73470728a38Smrg XkbGeometryPtr geom, 73570728a38Smrg XkbOverlayPtr ol) 7368c9fbc29Smrg{ 73770728a38Smrg register char *i_str; 73870728a38Smrg int r, k, nOut; 73970728a38Smrg XkbOverlayRowPtr row; 74070728a38Smrg XkbOverlayKeyPtr key; 74170728a38Smrg 74270728a38Smrg i_str = XkbIndentText(indent); 74370728a38Smrg if (ol->name != None) { 74470728a38Smrg fprintf(file, "%soverlay \"%s\" {\n", i_str, 74570728a38Smrg XkbAtomText(dpy, ol->name, XkbMessage)); 7468c9fbc29Smrg } 74770728a38Smrg else 74870728a38Smrg fprintf(file, "%soverlay {\n", i_str); 74970728a38Smrg for (nOut = r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { 75070728a38Smrg for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 75170728a38Smrg char *over, *under; 75270728a38Smrg 75370728a38Smrg over = XkbKeyNameText(key->over.name, XkbXKBFile); 75470728a38Smrg under = XkbKeyNameText(key->under.name, XkbXKBFile); 75570728a38Smrg if (nOut == 0) 75670728a38Smrg fprintf(file, "%s %6s=%6s", i_str, under, over); 75770728a38Smrg else if ((nOut % 4) == 0) 75870728a38Smrg fprintf(file, ",\n%s %6s=%6s", i_str, under, over); 75970728a38Smrg else 76070728a38Smrg fprintf(file, ", %6s=%6s", under, over); 76170728a38Smrg nOut++; 76270728a38Smrg } 7638c9fbc29Smrg } 76470728a38Smrg fprintf(file, "\n%s};\n", i_str); 7658c9fbc29Smrg return True; 7668c9fbc29Smrg} 7678c9fbc29Smrg 7688c9fbc29Smrgstatic Bool 76970728a38SmrgWriteXKBSection(FILE * file, 77070728a38Smrg Display * dpy, 77170728a38Smrg XkbSectionPtr s, 77270728a38Smrg XkbGeometryPtr geom) 7738c9fbc29Smrg{ 77470728a38Smrg register int i; 77570728a38Smrg XkbRowPtr row; 77670728a38Smrg int dfltKeyColor = 0; 77770728a38Smrg 77870728a38Smrg fprintf(file, " section \"%s\" {\n", 77970728a38Smrg XkbAtomText(dpy, s->name, XkbXKBFile)); 78070728a38Smrg if (s->rows && (s->rows->num_keys > 0)) { 78170728a38Smrg dfltKeyColor = s->rows->keys[0].color_ndx; 78270728a38Smrg fprintf(file, " key.color= \"%s\";\n", 78370728a38Smrg XkbStringText(geom->colors[dfltKeyColor].spec, XkbXKBFile)); 7848c9fbc29Smrg } 78570728a38Smrg fprintf(file, " priority= %d;\n", s->priority); 78670728a38Smrg fprintf(file, " top= %s;\n", 78770728a38Smrg XkbGeomFPText(s->top, XkbXKBFile)); 78870728a38Smrg fprintf(file, " left= %s;\n", 78970728a38Smrg XkbGeomFPText(s->left, XkbXKBFile)); 79070728a38Smrg fprintf(file, " width= %s;\n", 79170728a38Smrg XkbGeomFPText(s->width, XkbXKBFile)); 79270728a38Smrg fprintf(file, " height= %s;\n", 79370728a38Smrg XkbGeomFPText(s->height, XkbXKBFile)); 79470728a38Smrg if (s->angle != 0) { 79570728a38Smrg fprintf(file, " angle= %s;\n", 79670728a38Smrg XkbGeomFPText(s->angle, XkbXKBFile)); 7978c9fbc29Smrg } 79870728a38Smrg for (i = 0, row = s->rows; row && i < s->num_rows; i++, row++) { 79970728a38Smrg fprintf(file, " row {\n"); 80070728a38Smrg fprintf(file, " top= %s;\n", 80170728a38Smrg XkbGeomFPText(row->top, XkbXKBFile)); 80270728a38Smrg fprintf(file, " left= %s;\n", 80370728a38Smrg XkbGeomFPText(row->left, XkbXKBFile)); 80470728a38Smrg if (row->vertical) 80570728a38Smrg fprintf(file, " vertical;\n"); 80670728a38Smrg if (row->num_keys > 0) { 80770728a38Smrg register int k; 80870728a38Smrg register XkbKeyPtr key; 80970728a38Smrg int forceNL = 0; 81070728a38Smrg int nThisLine = 0; 81170728a38Smrg 81270728a38Smrg fprintf(file, " keys {\n"); 81370728a38Smrg for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 81470728a38Smrg XkbShapePtr shape; 81570728a38Smrg 81670728a38Smrg if (key->color_ndx != dfltKeyColor) 81770728a38Smrg forceNL = 1; 81870728a38Smrg if (k == 0) { 81970728a38Smrg fprintf(file, " "); 82070728a38Smrg nThisLine = 0; 82170728a38Smrg } 82270728a38Smrg else if (((nThisLine % 2) == 1) || (forceNL)) { 82370728a38Smrg fprintf(file, ",\n "); 82470728a38Smrg forceNL = nThisLine = 0; 82570728a38Smrg } 82670728a38Smrg else { 82770728a38Smrg fprintf(file, ", "); 82870728a38Smrg nThisLine++; 82970728a38Smrg } 83070728a38Smrg shape = XkbKeyShape(geom, key); 83170728a38Smrg fprintf(file, "{ %6s, \"%s\", %3s", 83270728a38Smrg XkbKeyNameText(key->name.name, XkbXKBFile), 83370728a38Smrg XkbAtomText(dpy, shape->name, XkbXKBFile), 83470728a38Smrg XkbGeomFPText(key->gap, XkbXKBFile)); 83570728a38Smrg if (key->color_ndx != dfltKeyColor) { 83670728a38Smrg fprintf(file, ", color=\"%s\"", 83770728a38Smrg XkbKeyColor(geom, key)->spec); 83870728a38Smrg forceNL = 1; 83970728a38Smrg } 84070728a38Smrg fprintf(file, " }"); 84170728a38Smrg } 84270728a38Smrg fprintf(file, "\n };\n"); 84370728a38Smrg } 84470728a38Smrg fprintf(file, " };\n"); 8458c9fbc29Smrg } 84670728a38Smrg if (s->doodads != NULL) { 84770728a38Smrg XkbDoodadPtr doodad; 84870728a38Smrg 84970728a38Smrg for (i = 0, doodad = s->doodads; i < s->num_doodads; i++, doodad++) { 85070728a38Smrg WriteXKBDoodad(file, dpy, 8, geom, doodad); 85170728a38Smrg } 8528c9fbc29Smrg } 85370728a38Smrg if (s->overlays != NULL) { 85470728a38Smrg XkbOverlayPtr ol; 85570728a38Smrg 85670728a38Smrg for (i = 0, ol = s->overlays; i < s->num_overlays; i++, ol++) { 85770728a38Smrg WriteXKBOverlay(file, dpy, 8, geom, ol); 85870728a38Smrg } 8598c9fbc29Smrg } 86070728a38Smrg fprintf(file, " }; // End of \"%s\" section\n\n", 86170728a38Smrg XkbAtomText(dpy, s->name, XkbXKBFile)); 8628c9fbc29Smrg return True; 8638c9fbc29Smrg} 8648c9fbc29Smrg 8658c9fbc29SmrgBool 86670728a38SmrgXkbWriteXKBGeometry(FILE * file, 86770728a38Smrg XkbFileInfo * result, 86870728a38Smrg Bool topLevel, 86970728a38Smrg Bool showImplicit, 87070728a38Smrg XkbFileAddOnFunc addOn, 87170728a38Smrg void * priv) 8728c9fbc29Smrg{ 87370728a38Smrg Display *dpy; 87470728a38Smrg register unsigned i, n; 87570728a38Smrg XkbDescPtr xkb; 87670728a38Smrg XkbGeometryPtr geom; 87770728a38Smrg 87870728a38Smrg xkb = result->xkb; 87970728a38Smrg if ((!xkb) || (!xkb->geom)) { 88070728a38Smrg _XkbLibError(_XkbErrMissingGeometry, "XkbWriteXKBGeometry", 0); 88170728a38Smrg return False; 8828c9fbc29Smrg } 88370728a38Smrg dpy = xkb->dpy; 88470728a38Smrg geom = xkb->geom; 88570728a38Smrg if (geom->name == None) 88670728a38Smrg fprintf(file, "xkb_geometry {\n\n"); 88770728a38Smrg else 88870728a38Smrg fprintf(file, "xkb_geometry \"%s\" {\n\n", 88970728a38Smrg XkbAtomText(dpy, geom->name, XkbXKBFile)); 89070728a38Smrg fprintf(file, " width= %s;\n", 89170728a38Smrg XkbGeomFPText(geom->width_mm, XkbXKBFile)); 89270728a38Smrg fprintf(file, " height= %s;\n\n", 89370728a38Smrg XkbGeomFPText(geom->height_mm, XkbXKBFile)); 89470728a38Smrg 89570728a38Smrg if (geom->key_aliases != NULL) { 89670728a38Smrg XkbKeyAliasPtr pAl; 89770728a38Smrg 89870728a38Smrg pAl = geom->key_aliases; 89970728a38Smrg for (i = 0; i < geom->num_key_aliases; i++, pAl++) { 90070728a38Smrg fprintf(file, " alias %6s = %6s;\n", 90170728a38Smrg XkbKeyNameText(pAl->alias, XkbXKBFile), 90270728a38Smrg XkbKeyNameText(pAl->real, XkbXKBFile)); 90370728a38Smrg } 90470728a38Smrg fprintf(file, "\n"); 9058c9fbc29Smrg } 9068c9fbc29Smrg 90770728a38Smrg if (geom->base_color != NULL) 90870728a38Smrg fprintf(file, " baseColor= \"%s\";\n", 90970728a38Smrg XkbStringText(geom->base_color->spec, XkbXKBFile)); 91070728a38Smrg if (geom->label_color != NULL) 91170728a38Smrg fprintf(file, " labelColor= \"%s\";\n", 91270728a38Smrg XkbStringText(geom->label_color->spec, XkbXKBFile)); 91370728a38Smrg if (geom->label_font != NULL) 91470728a38Smrg fprintf(file, " xfont= \"%s\";\n", 91570728a38Smrg XkbStringText(geom->label_font, XkbXKBFile)); 91670728a38Smrg if ((geom->num_colors > 0) && (showImplicit)) { 91770728a38Smrg XkbColorPtr color; 91870728a38Smrg 91970728a38Smrg for (color = geom->colors, i = 0; i < geom->num_colors; i++, color++) { 92070728a38Smrg fprintf(file, "// color[%d]= \"%s\"\n", i, 92170728a38Smrg XkbStringText(color->spec, XkbXKBFile)); 92270728a38Smrg } 92370728a38Smrg fprintf(file, "\n"); 9248c9fbc29Smrg } 92570728a38Smrg if (geom->num_properties > 0) { 92670728a38Smrg XkbPropertyPtr prop; 92770728a38Smrg 92870728a38Smrg for (prop = geom->properties, i = 0; i < geom->num_properties; 92970728a38Smrg i++, prop++) { 93070728a38Smrg fprintf(file, " %s= \"%s\";\n", prop->name, 93170728a38Smrg XkbStringText(prop->value, XkbXKBFile)); 93270728a38Smrg } 93370728a38Smrg fprintf(file, "\n"); 9348c9fbc29Smrg } 93570728a38Smrg if (geom->num_shapes > 0) { 93670728a38Smrg XkbShapePtr shape; 93770728a38Smrg XkbOutlinePtr outline; 93870728a38Smrg int lastR; 93970728a38Smrg 94070728a38Smrg for (shape = geom->shapes, i = 0; i < geom->num_shapes; i++, shape++) { 94170728a38Smrg lastR = 0; 94270728a38Smrg fprintf(file, " shape \"%s\" {", 94370728a38Smrg XkbAtomText(dpy, shape->name, XkbXKBFile)); 94470728a38Smrg outline = shape->outlines; 94570728a38Smrg if (shape->num_outlines > 1) { 94670728a38Smrg for (n = 0; n < shape->num_outlines; n++, outline++) { 94770728a38Smrg if (n == 0) 94870728a38Smrg fprintf(file, "\n"); 94970728a38Smrg else 95070728a38Smrg fprintf(file, ",\n"); 95170728a38Smrg WriteXKBOutline(file, shape, outline, lastR, 8, 8); 95270728a38Smrg lastR = outline->corner_radius; 95370728a38Smrg } 95470728a38Smrg fprintf(file, "\n };\n"); 95570728a38Smrg } 95670728a38Smrg else { 95770728a38Smrg WriteXKBOutline(file, NULL, outline, lastR, 1, 8); 95870728a38Smrg fprintf(file, " };\n"); 95970728a38Smrg } 96070728a38Smrg } 9618c9fbc29Smrg } 96270728a38Smrg if (geom->num_sections > 0) { 96370728a38Smrg XkbSectionPtr section; 96470728a38Smrg 96570728a38Smrg for (section = geom->sections, i = 0; i < geom->num_sections; 96670728a38Smrg i++, section++) { 96770728a38Smrg WriteXKBSection(file, dpy, section, geom); 96870728a38Smrg } 9698c9fbc29Smrg } 97070728a38Smrg if (geom->num_doodads > 0) { 97170728a38Smrg XkbDoodadPtr doodad; 97270728a38Smrg 97370728a38Smrg for (i = 0, doodad = geom->doodads; i < geom->num_doodads; 97470728a38Smrg i++, doodad++) { 97570728a38Smrg WriteXKBDoodad(file, dpy, 4, geom, doodad); 97670728a38Smrg } 9778c9fbc29Smrg } 9788c9fbc29Smrg if (addOn) 97970728a38Smrg (*addOn) (file, result, topLevel, showImplicit, XkmGeometryIndex, priv); 98070728a38Smrg fprintf(file, "};\n\n"); 9818c9fbc29Smrg return True; 9828c9fbc29Smrg} 9838c9fbc29Smrg 9848c9fbc29Smrg/*ARGSUSED*/ 9858c9fbc29SmrgBool 98670728a38SmrgXkbWriteXKBSemantics(FILE * file, 98770728a38Smrg XkbFileInfo * result, 98870728a38Smrg Bool topLevel, 98970728a38Smrg Bool showImplicit, 99070728a38Smrg XkbFileAddOnFunc addOn, 99170728a38Smrg void * priv) 9928c9fbc29Smrg{ 99370728a38Smrg Bool ok; 9948c9fbc29Smrg 99570728a38Smrg fprintf(file, "xkb_semantics {\n"); 99670728a38Smrg ok = XkbWriteXKBKeyTypes(file, result, False, False, addOn, priv); 99770728a38Smrg ok = ok && XkbWriteXKBCompatMap(file, result, False, False, addOn, priv); 99870728a38Smrg fprintf(file, "};\n"); 9998c9fbc29Smrg return ok; 10008c9fbc29Smrg} 10018c9fbc29Smrg 10028c9fbc29Smrg/*ARGSUSED*/ 10038c9fbc29SmrgBool 100470728a38SmrgXkbWriteXKBLayout(FILE * file, 100570728a38Smrg XkbFileInfo * result, 100670728a38Smrg Bool topLevel, 100770728a38Smrg Bool showImplicit, 100870728a38Smrg XkbFileAddOnFunc addOn, 100970728a38Smrg void * priv) 10108c9fbc29Smrg{ 101170728a38Smrg Bool ok; 101270728a38Smrg XkbDescPtr xkb; 101370728a38Smrg 101470728a38Smrg xkb = result->xkb; 101570728a38Smrg fprintf(file, "xkb_layout {\n"); 101670728a38Smrg ok = XkbWriteXKBKeycodes(file, result, False, showImplicit, addOn, priv); 101770728a38Smrg ok = ok && 101870728a38Smrg XkbWriteXKBKeyTypes(file, result, False, showImplicit, addOn, priv); 101970728a38Smrg ok = ok && 102070728a38Smrg XkbWriteXKBSymbols(file, result, False, showImplicit, addOn, priv); 10218c9fbc29Smrg if (xkb->geom) 102270728a38Smrg ok = ok && 102370728a38Smrg XkbWriteXKBGeometry(file, result, False, showImplicit, addOn, priv); 102470728a38Smrg fprintf(file, "};\n"); 10258c9fbc29Smrg return ok; 10268c9fbc29Smrg} 10278c9fbc29Smrg 10288c9fbc29Smrg/*ARGSUSED*/ 10298c9fbc29SmrgBool 103070728a38SmrgXkbWriteXKBKeymap(FILE * file, 103170728a38Smrg XkbFileInfo * result, 103270728a38Smrg Bool topLevel, 103370728a38Smrg Bool showImplicit, 103470728a38Smrg XkbFileAddOnFunc addOn, 103570728a38Smrg void * priv) 10368c9fbc29Smrg{ 103770728a38Smrg Bool ok; 103870728a38Smrg XkbDescPtr xkb; 103970728a38Smrg 104070728a38Smrg xkb = result->xkb; 104170728a38Smrg fprintf(file, "xkb_keymap {\n"); 104270728a38Smrg ok = XkbWriteXKBKeycodes(file, result, False, showImplicit, addOn, priv); 104370728a38Smrg ok = ok && 104470728a38Smrg XkbWriteXKBKeyTypes(file, result, False, showImplicit, addOn, priv); 104570728a38Smrg ok = ok && 104670728a38Smrg XkbWriteXKBCompatMap(file, result, False, showImplicit, addOn, priv); 104770728a38Smrg ok = ok && 104870728a38Smrg XkbWriteXKBSymbols(file, result, False, showImplicit, addOn, priv); 10498c9fbc29Smrg if (xkb->geom) 105070728a38Smrg ok = ok && 105170728a38Smrg XkbWriteXKBGeometry(file, result, False, showImplicit, addOn, priv); 105270728a38Smrg fprintf(file, "};\n"); 10538c9fbc29Smrg return ok; 10548c9fbc29Smrg} 10558c9fbc29Smrg 10568c9fbc29SmrgBool 105770728a38SmrgXkbWriteXKBFile(FILE * out, 105870728a38Smrg XkbFileInfo * result, 105970728a38Smrg Bool showImplicit, 106070728a38Smrg XkbFileAddOnFunc addOn, 106170728a38Smrg void * priv) 10628c9fbc29Smrg{ 106370728a38Smrg Bool ok = False; 106470728a38Smrg 106570728a38Smrg Bool (*func) (FILE * /* file */ , 106670728a38Smrg XkbFileInfo * /* result */ , 106770728a38Smrg Bool /* topLevel */ , 106870728a38Smrg Bool /* showImplicit */ , 106970728a38Smrg XkbFileAddOnFunc /* addOn */ , 107070728a38Smrg void * /* priv */ 107170728a38Smrg ) = NULL; 10728c9fbc29Smrg 10738c9fbc29Smrg switch (result->type) { 107470728a38Smrg case XkmSemanticsFile: 107570728a38Smrg func = XkbWriteXKBSemantics; 107670728a38Smrg break; 107770728a38Smrg case XkmLayoutFile: 107870728a38Smrg func = XkbWriteXKBLayout; 107970728a38Smrg break; 108070728a38Smrg case XkmKeymapFile: 108170728a38Smrg func = XkbWriteXKBKeymap; 108270728a38Smrg break; 108370728a38Smrg case XkmTypesIndex: 108470728a38Smrg func = XkbWriteXKBKeyTypes; 108570728a38Smrg break; 108670728a38Smrg case XkmCompatMapIndex: 108770728a38Smrg func = XkbWriteXKBCompatMap; 108870728a38Smrg break; 108970728a38Smrg case XkmSymbolsIndex: 109070728a38Smrg func = XkbWriteXKBSymbols; 109170728a38Smrg break; 109270728a38Smrg case XkmKeyNamesIndex: 109370728a38Smrg func = XkbWriteXKBKeycodes; 109470728a38Smrg break; 109570728a38Smrg case XkmGeometryFile: 109670728a38Smrg case XkmGeometryIndex: 109770728a38Smrg func = XkbWriteXKBGeometry; 109870728a38Smrg break; 109970728a38Smrg case XkmVirtualModsIndex: 110070728a38Smrg case XkmIndicatorsIndex: 110170728a38Smrg _XkbLibError(_XkbErrBadImplementation, 110270728a38Smrg XkbConfigText(result->type, XkbMessage), 0); 110370728a38Smrg return False; 11048c9fbc29Smrg } 110570728a38Smrg if (out == NULL) { 110670728a38Smrg _XkbLibError(_XkbErrFileCannotOpen, "XkbWriteXkbFile", 0); 110770728a38Smrg ok = False; 11088c9fbc29Smrg } 11098c9fbc29Smrg else if (func) { 111070728a38Smrg ok = (*func) (out, result, True, showImplicit, addOn, priv); 11118c9fbc29Smrg } 11128c9fbc29Smrg return ok; 11138c9fbc29Smrg} 1114