896 lines
26 KiB
C
896 lines
26 KiB
C
/************************************************************
|
|
Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
|
|
|
|
Permission to use, copy, modify, and distribute this
|
|
software and its documentation for any purpose and without
|
|
fee is hereby granted, provided that the above copyright
|
|
notice appear in all copies and that both that copyright
|
|
notice and this permission notice appear in supporting
|
|
documentation, and that the name of Silicon Graphics not be
|
|
used in advertising or publicity pertaining to distribution
|
|
of the software without specific prior written permission.
|
|
Silicon Graphics makes no representation about the suitability
|
|
of this software for any purpose. It is provided "as is"
|
|
without any express or implied warranty.
|
|
|
|
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
|
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
|
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
|
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
|
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
********************************************************/
|
|
|
|
#ifdef HAVE_DIX_CONFIG_H
|
|
#include <dix-config.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <X11/Xfuncs.h>
|
|
|
|
#include <X11/X.h>
|
|
#define NEED_EVENTS
|
|
#include <X11/keysym.h>
|
|
#include <X11/Xproto.h>
|
|
#include "misc.h"
|
|
#include "inputstr.h"
|
|
#include "dix.h"
|
|
#include "xkbstr.h"
|
|
#define XKBSRV_NEED_FILE_FUNCS 1
|
|
#include <xkbsrv.h>
|
|
|
|
#include "xkbgeom.h"
|
|
#include "xkbfile.h"
|
|
|
|
#define VMOD_HIDE_VALUE 0
|
|
#define VMOD_SHOW_VALUE 1
|
|
#define VMOD_COMMENT_VALUE 2
|
|
|
|
static Bool
|
|
WriteXKBVModDecl(FILE *file,XkbDescPtr xkb,int showValue)
|
|
{
|
|
register int i,nMods;
|
|
Atom * vmodNames;
|
|
|
|
if (xkb==NULL)
|
|
return False;
|
|
if (xkb->names!=NULL)
|
|
vmodNames= xkb->names->vmods;
|
|
else vmodNames= NULL;
|
|
|
|
for (i=nMods=0;i<XkbNumVirtualMods;i++) {
|
|
if ((vmodNames!=NULL)&&(vmodNames[i]!=None)) {
|
|
if (nMods==0) fprintf(file," virtual_modifiers ");
|
|
else fprintf(file,",");
|
|
fprintf(file,"%s",XkbAtomText(vmodNames[i],XkbXKBFile));
|
|
if ((showValue!=VMOD_HIDE_VALUE)&&
|
|
(xkb->server)&&(xkb->server->vmods[i]!=XkbNoModifierMask)) {
|
|
if (showValue==VMOD_COMMENT_VALUE) {
|
|
fprintf(file,"/* = %s */",
|
|
XkbModMaskText(xkb->server->vmods[i],XkbXKBFile));
|
|
}
|
|
else {
|
|
fprintf(file,"= %s",
|
|
XkbModMaskText(xkb->server->vmods[i],XkbXKBFile));
|
|
}
|
|
}
|
|
nMods++;
|
|
}
|
|
}
|
|
if (nMods>0)
|
|
fprintf(file,";\n\n");
|
|
return True;
|
|
}
|
|
|
|
/***====================================================================***/
|
|
|
|
static Bool
|
|
WriteXKBAction(FILE *file,XkbDescPtr xkb,XkbAnyAction *action)
|
|
{
|
|
fprintf(file,"%s",XkbActionText(xkb,(XkbAction *)action,XkbXKBFile));
|
|
return True;
|
|
}
|
|
|
|
/***====================================================================***/
|
|
|
|
Bool
|
|
XkbWriteXKBKeycodes( FILE * file,
|
|
XkbDescPtr xkb,
|
|
Bool topLevel,
|
|
Bool showImplicit,
|
|
XkbFileAddOnFunc addOn,
|
|
void * priv)
|
|
{
|
|
Atom kcName;
|
|
register unsigned i;
|
|
char * alternate;
|
|
|
|
if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) {
|
|
_XkbLibError(_XkbErrMissingNames,"XkbWriteXKBKeycodes",0);
|
|
return False;
|
|
}
|
|
kcName= xkb->names->keycodes;
|
|
if (kcName!=None)
|
|
fprintf(file,"xkb_keycodes \"%s\" {\n",
|
|
XkbAtomText(kcName,XkbXKBFile));
|
|
else fprintf(file,"xkb_keycodes {\n");
|
|
fprintf(file," minimum = %d;\n",xkb->min_key_code);
|
|
fprintf(file," maximum = %d;\n",xkb->max_key_code);
|
|
for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
|
|
if (xkb->names->keys[i].name[0]!='\0') {
|
|
if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,True)!=i)
|
|
alternate= "alternate ";
|
|
else alternate= "";
|
|
fprintf(file," %s%6s = %d;\n",alternate,
|
|
XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile),
|
|
i);
|
|
}
|
|
}
|
|
if (xkb->indicators!=NULL) {
|
|
for (i=0;i<XkbNumIndicators;i++) {
|
|
char *type;
|
|
if (xkb->indicators->phys_indicators&(1<<i))
|
|
type= " ";
|
|
else type= " virtual ";
|
|
if (xkb->names->indicators[i]!=None) {
|
|
fprintf(file,"%sindicator %d = \"%s\";\n",type,i+1,
|
|
XkbAtomText(xkb->names->indicators[i],XkbXKBFile));
|
|
}
|
|
}
|
|
}
|
|
if (xkb->names->key_aliases!=NULL) {
|
|
XkbKeyAliasPtr pAl;
|
|
pAl= xkb->names->key_aliases;
|
|
for (i=0;i<xkb->names->num_key_aliases;i++,pAl++) {
|
|
fprintf(file," alias %6s = %6s;\n",
|
|
XkbKeyNameText(pAl->alias,XkbXKBFile),
|
|
XkbKeyNameText(pAl->real,XkbXKBFile));
|
|
}
|
|
}
|
|
if (addOn)
|
|
(*addOn)(file,xkb,topLevel,showImplicit,XkmKeyNamesIndex,priv);
|
|
fprintf(file,"};\n\n");
|
|
return True;
|
|
}
|
|
|
|
Bool
|
|
XkbWriteXKBKeyTypes( FILE * file,
|
|
XkbDescPtr xkb,
|
|
Bool topLevel,
|
|
Bool showImplicit,
|
|
XkbFileAddOnFunc addOn,
|
|
void * priv)
|
|
{
|
|
register unsigned i,n;
|
|
XkbKeyTypePtr type;
|
|
XkbKTMapEntryPtr entry;
|
|
|
|
if ((!xkb)||(!xkb->map)||(!xkb->map->types)) {
|
|
_XkbLibError(_XkbErrMissingTypes,"XkbWriteXKBKeyTypes",0);
|
|
return False;
|
|
}
|
|
if (xkb->map->num_types<XkbNumRequiredTypes) {
|
|
_XkbLibError(_XkbErrMissingReqTypes,"XkbWriteXKBKeyTypes",0);
|
|
return 0;
|
|
}
|
|
if ((xkb->names==NULL)||(xkb->names->types==None))
|
|
fprintf(file,"xkb_types {\n\n");
|
|
else fprintf(file,"xkb_types \"%s\" {\n\n",
|
|
XkbAtomText(xkb->names->types,XkbXKBFile));
|
|
WriteXKBVModDecl(file,xkb,
|
|
(showImplicit?VMOD_COMMENT_VALUE:VMOD_HIDE_VALUE));
|
|
|
|
type= xkb->map->types;
|
|
for (i=0;i<xkb->map->num_types;i++,type++) {
|
|
fprintf(file," type \"%s\" {\n",
|
|
XkbAtomText(type->name,XkbXKBFile));
|
|
fprintf(file," modifiers= %s;\n",
|
|
XkbVModMaskText(xkb,type->mods.real_mods,type->mods.vmods,
|
|
XkbXKBFile));
|
|
entry= type->map;
|
|
for (n=0;n<type->map_count;n++,entry++) {
|
|
char *str;
|
|
str=XkbVModMaskText(xkb,entry->mods.real_mods,entry->mods.vmods,
|
|
XkbXKBFile);
|
|
fprintf(file," map[%s]= Level%d;\n",str,entry->level+1);
|
|
if ((type->preserve)&&((type->preserve[n].real_mods)||
|
|
(type->preserve[n].vmods))) {
|
|
fprintf(file," preserve[%s]= ",str);
|
|
fprintf(file,"%s;\n",XkbVModMaskText(xkb,
|
|
type->preserve[n].real_mods,
|
|
type->preserve[n].vmods,
|
|
XkbXKBFile));
|
|
}
|
|
}
|
|
if (type->level_names!=NULL) {
|
|
Atom *name= type->level_names;
|
|
for (n=0;n<type->num_levels;n++,name++) {
|
|
if ((*name)==None)
|
|
continue;
|
|
fprintf(file," level_name[Level%d]= \"%s\";\n",n+1,
|
|
XkbAtomText(*name,XkbXKBFile));
|
|
}
|
|
}
|
|
fprintf(file," };\n");
|
|
}
|
|
if (addOn)
|
|
(*addOn)(file,xkb,topLevel,showImplicit,XkmTypesIndex,priv);
|
|
fprintf(file,"};\n\n");
|
|
return True;
|
|
}
|
|
|
|
static Bool
|
|
WriteXKBIndicatorMap( FILE * file,
|
|
XkbDescPtr xkb,
|
|
Atom name,
|
|
XkbIndicatorMapPtr led,
|
|
XkbFileAddOnFunc addOn,
|
|
void * priv)
|
|
{
|
|
|
|
fprintf(file," indicator \"%s\" {\n",XkbAtomGetString(name));
|
|
if (led->flags&XkbIM_NoExplicit)
|
|
fprintf(file," !allowExplicit;\n");
|
|
if (led->flags&XkbIM_LEDDrivesKB)
|
|
fprintf(file," indicatorDrivesKeyboard;\n");
|
|
if (led->which_groups!=0) {
|
|
if (led->which_groups!=XkbIM_UseEffective) {
|
|
fprintf(file," whichGroupState= %s;\n",
|
|
XkbIMWhichStateMaskText(led->which_groups,XkbXKBFile));
|
|
}
|
|
fprintf(file," groups= 0x%02x;\n",led->groups);
|
|
}
|
|
if (led->which_mods!=0) {
|
|
if (led->which_mods!=XkbIM_UseEffective) {
|
|
fprintf(file," whichModState= %s;\n",
|
|
XkbIMWhichStateMaskText(led->which_mods,XkbXKBFile));
|
|
}
|
|
fprintf(file," modifiers= %s;\n",
|
|
XkbVModMaskText(xkb,
|
|
led->mods.real_mods,led->mods.vmods,
|
|
XkbXKBFile));
|
|
}
|
|
if (led->ctrls!=0) {
|
|
fprintf(file," controls= %s;\n",
|
|
XkbControlsMaskText(led->ctrls,XkbXKBFile));
|
|
}
|
|
if (addOn)
|
|
(*addOn)(file,xkb,False,True,XkmIndicatorsIndex,priv);
|
|
fprintf(file," };\n");
|
|
return True;
|
|
}
|
|
|
|
Bool
|
|
XkbWriteXKBCompatMap( FILE * file,
|
|
XkbDescPtr xkb,
|
|
Bool topLevel,
|
|
Bool showImplicit,
|
|
XkbFileAddOnFunc addOn,
|
|
void * priv)
|
|
{
|
|
register unsigned i;
|
|
XkbSymInterpretPtr interp;
|
|
|
|
if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) {
|
|
_XkbLibError(_XkbErrMissingCompatMap,"XkbWriteXKBCompatMap",0);
|
|
return False;
|
|
}
|
|
if ((xkb->names==NULL)||(xkb->names->compat==None))
|
|
fprintf(file,"xkb_compatibility {\n\n");
|
|
else fprintf(file,"xkb_compatibility \"%s\" {\n\n",
|
|
XkbAtomText(xkb->names->compat,XkbXKBFile));
|
|
WriteXKBVModDecl(file,xkb,
|
|
(showImplicit?VMOD_COMMENT_VALUE:VMOD_HIDE_VALUE));
|
|
|
|
fprintf(file," interpret.useModMapMods= AnyLevel;\n");
|
|
fprintf(file," interpret.repeat= False;\n");
|
|
fprintf(file," interpret.locking= False;\n");
|
|
interp= xkb->compat->sym_interpret;
|
|
for (i=0;i<xkb->compat->num_si;i++,interp++) {
|
|
fprintf(file," interpret %s+%s(%s) {\n",
|
|
((interp->sym==NoSymbol)?"Any":
|
|
XkbKeysymText(interp->sym,XkbXKBFile)),
|
|
XkbSIMatchText(interp->match,XkbXKBFile),
|
|
XkbModMaskText(interp->mods,XkbXKBFile));
|
|
if (interp->virtual_mod!=XkbNoModifier) {
|
|
fprintf(file," virtualModifier= %s;\n",
|
|
XkbVModIndexText(xkb,interp->virtual_mod,XkbXKBFile));
|
|
}
|
|
if (interp->match&XkbSI_LevelOneOnly)
|
|
fprintf(file," useModMapMods=level1;\n");
|
|
if (interp->flags&XkbSI_LockingKey)
|
|
fprintf(file," locking= True;\n");
|
|
if (interp->flags&XkbSI_AutoRepeat)
|
|
fprintf(file," repeat= True;\n");
|
|
fprintf(file," action= ");
|
|
WriteXKBAction(file,xkb,&interp->act);
|
|
fprintf(file,";\n");
|
|
fprintf(file," };\n");
|
|
}
|
|
for (i=0;i<XkbNumKbdGroups;i++) {
|
|
XkbModsPtr gc;
|
|
|
|
gc= &xkb->compat->groups[i];
|
|
if ((gc->real_mods==0)&&(gc->vmods==0))
|
|
continue;
|
|
fprintf(file," group %d = %s;\n",i+1,XkbVModMaskText(xkb,
|
|
gc->real_mods,gc->vmods,
|
|
XkbXKBFile));
|
|
}
|
|
if (xkb->indicators) {
|
|
for (i=0;i<XkbNumIndicators;i++) {
|
|
XkbIndicatorMapPtr map= &xkb->indicators->maps[i];
|
|
if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)||
|
|
(map->which_mods!=0)||
|
|
(map->mods.real_mods!=0)||(map->mods.vmods!=0)||
|
|
(map->ctrls!=0)) {
|
|
WriteXKBIndicatorMap(file,xkb,xkb->names->indicators[i],map,
|
|
addOn,priv);
|
|
}
|
|
}
|
|
}
|
|
if (addOn)
|
|
(*addOn)(file,xkb,topLevel,showImplicit,XkmCompatMapIndex,priv);
|
|
fprintf(file,"};\n\n");
|
|
return True;
|
|
}
|
|
|
|
Bool
|
|
XkbWriteXKBSymbols( FILE * file,
|
|
XkbDescPtr xkb,
|
|
Bool topLevel,
|
|
Bool showImplicit,
|
|
XkbFileAddOnFunc addOn,
|
|
void * priv)
|
|
{
|
|
register unsigned i,tmp;
|
|
XkbClientMapPtr map;
|
|
XkbServerMapPtr srv;
|
|
Bool showActions;
|
|
|
|
map= xkb->map;
|
|
srv= xkb->server;
|
|
if ((!xkb)||(!map)||(!map->syms)||(!map->key_sym_map)) {
|
|
_XkbLibError(_XkbErrMissingSymbols,"XkbWriteXKBSymbols",0);
|
|
return False;
|
|
}
|
|
if ((!xkb->names)||(!xkb->names->keys)) {
|
|
_XkbLibError(_XkbErrMissingNames,"XkbWriteXKBSymbols",0);
|
|
return False;
|
|
}
|
|
if ((xkb->names==NULL)||(xkb->names->symbols==None))
|
|
fprintf(file,"xkb_symbols {\n\n");
|
|
else fprintf(file,"xkb_symbols \"%s\" {\n\n",
|
|
XkbAtomText(xkb->names->symbols,XkbXKBFile));
|
|
for (tmp=i=0;i<XkbNumKbdGroups;i++) {
|
|
if (xkb->names->groups[i]!=None) {
|
|
fprintf(file," name[group%d]=\"%s\";\n",i+1,
|
|
XkbAtomText(xkb->names->groups[i],XkbXKBFile));
|
|
tmp++;
|
|
}
|
|
}
|
|
if (tmp>0)
|
|
fprintf(file,"\n");
|
|
for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
|
|
Bool simple;
|
|
if ((int)XkbKeyNumSyms(xkb,i)<1)
|
|
continue;
|
|
if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,True)!=i)
|
|
continue;
|
|
simple= True;
|
|
fprintf(file," key %6s {",
|
|
XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile));
|
|
if (srv->explicit) {
|
|
if (((srv->explicit[i]&XkbExplicitKeyTypesMask)!=0)||
|
|
(showImplicit)) {
|
|
int typeNdx,g;
|
|
Bool multi;
|
|
char * comment=" ";
|
|
|
|
if ((srv->explicit[i]&XkbExplicitKeyTypesMask)==0)
|
|
comment= "//";
|
|
multi= False;
|
|
typeNdx= XkbKeyKeyTypeIndex(xkb,i,0);
|
|
for (g=1;(g<XkbKeyNumGroups(xkb,i))&&(!multi);g++) {
|
|
if (XkbKeyKeyTypeIndex(xkb,i,g)!=typeNdx)
|
|
multi= True;
|
|
}
|
|
if (multi) {
|
|
for (g=0;g<XkbKeyNumGroups(xkb,i);g++) {
|
|
typeNdx= XkbKeyKeyTypeIndex(xkb,i,g);
|
|
if (srv->explicit[i]&(1<<g)) {
|
|
fprintf(file,"\n%s type[group%d]= \"%s\",",
|
|
comment,g+1,
|
|
XkbAtomText(map->types[typeNdx].name,
|
|
XkbXKBFile));
|
|
}
|
|
else if (showImplicit) {
|
|
fprintf(file,"\n// type[group%d]= \"%s\",",g+1,
|
|
XkbAtomText(map->types[typeNdx].name,
|
|
XkbXKBFile));
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
fprintf(file,"\n%s type= \"%s\",",comment,
|
|
XkbAtomText(map->types[typeNdx].name,
|
|
XkbXKBFile));
|
|
}
|
|
simple= False;
|
|
}
|
|
if (((srv->explicit[i]&XkbExplicitAutoRepeatMask)!=0)&&
|
|
(xkb->ctrls!=NULL)) {
|
|
if (xkb->ctrls->per_key_repeat[i/8]&(1<<(i%8)))
|
|
fprintf(file,"\n repeat= Yes,");
|
|
else fprintf(file,"\n repeat= No,");
|
|
simple= False;
|
|
}
|
|
if ((xkb->server!=NULL)&&(xkb->server->vmodmap!=NULL)&&
|
|
(xkb->server->vmodmap[i]!=0)) {
|
|
if ((srv->explicit[i]&XkbExplicitVModMapMask)!=0) {
|
|
fprintf(file,"\n virtualMods= %s,",
|
|
XkbVModMaskText(xkb,0,
|
|
xkb->server->vmodmap[i],
|
|
XkbXKBFile));
|
|
}
|
|
else if (showImplicit) {
|
|
fprintf(file,"\n// virtualMods= %s,",
|
|
XkbVModMaskText(xkb,0,
|
|
xkb->server->vmodmap[i],
|
|
XkbXKBFile));
|
|
}
|
|
}
|
|
}
|
|
switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(xkb,i))) {
|
|
case XkbClampIntoRange:
|
|
fprintf(file,"\n groupsClamp,");
|
|
break;
|
|
case XkbRedirectIntoRange:
|
|
fprintf(file,"\n groupsRedirect= Group%d,",
|
|
XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(xkb,i))+1);
|
|
break;
|
|
}
|
|
if (srv->behaviors!=NULL) {
|
|
unsigned type;
|
|
type= srv->behaviors[i].type&XkbKB_OpMask;
|
|
|
|
if (type!=XkbKB_Default) {
|
|
simple= False;
|
|
fprintf(file,"\n %s,",
|
|
XkbBehaviorText(xkb,&srv->behaviors[i],XkbXKBFile));
|
|
}
|
|
}
|
|
if ((srv->explicit==NULL) || showImplicit ||
|
|
((srv->explicit[i]&XkbExplicitInterpretMask)!=0))
|
|
showActions= XkbKeyHasActions(xkb,i);
|
|
else showActions= False;
|
|
|
|
if (((unsigned)XkbKeyNumGroups(xkb,i)>1)||showActions)
|
|
simple= False;
|
|
if (simple) {
|
|
KeySym *syms;
|
|
unsigned s;
|
|
|
|
syms= XkbKeySymsPtr(xkb,i);
|
|
fprintf(file," [ ");
|
|
for (s=0;s<XkbKeyGroupWidth(xkb,i,XkbGroup1Index);s++) {
|
|
if (s!=0)
|
|
fprintf(file,", ");
|
|
fprintf(file,"%15s",XkbKeysymText(*syms++,XkbXKBFile));
|
|
}
|
|
fprintf(file," ] };\n");
|
|
}
|
|
else {
|
|
unsigned g,s;
|
|
KeySym *syms;
|
|
XkbAction *acts;
|
|
syms= XkbKeySymsPtr(xkb,i);
|
|
acts= XkbKeyActionsPtr(xkb,i);
|
|
for (g=0;g<XkbKeyNumGroups(xkb,i);g++) {
|
|
if (g!=0)
|
|
fprintf(file,",");
|
|
fprintf(file,"\n symbols[Group%d]= [ ",g+1);
|
|
for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) {
|
|
if (s!=0)
|
|
fprintf(file,", ");
|
|
fprintf(file,"%15s",XkbKeysymText(syms[s],XkbXKBFile));
|
|
}
|
|
fprintf(file," ]");
|
|
syms+= XkbKeyGroupsWidth(xkb,i);
|
|
if (showActions) {
|
|
fprintf(file,",\n actions[Group%d]= [ ",g+1);
|
|
for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) {
|
|
if (s!=0)
|
|
fprintf(file,", ");
|
|
WriteXKBAction(file,xkb,(XkbAnyAction *)&acts[s]);
|
|
}
|
|
fprintf(file," ]");
|
|
acts+= XkbKeyGroupsWidth(xkb,i);
|
|
}
|
|
}
|
|
fprintf(file,"\n };\n");
|
|
}
|
|
}
|
|
if (map && map->modmap) {
|
|
for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
|
|
if (map->modmap[i]!=0) {
|
|
register int n,bit;
|
|
for (bit=1,n=0;n<XkbNumModifiers;n++,bit<<=1) {
|
|
if (map->modmap[i]&bit) {
|
|
char buf[5];
|
|
memcpy(buf,xkb->names->keys[i].name,4);
|
|
buf[4]= '\0';
|
|
fprintf(file," modifier_map %s { <%s> };\n",
|
|
XkbModIndexText(n,XkbXKBFile),buf);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (addOn)
|
|
(*addOn)(file,xkb,topLevel,showImplicit,XkmSymbolsIndex,priv);
|
|
fprintf(file,"};\n\n");
|
|
return True;
|
|
}
|
|
|
|
static Bool
|
|
WriteXKBOutline( FILE * file,
|
|
XkbShapePtr shape,
|
|
XkbOutlinePtr outline,
|
|
int lastRadius,
|
|
int first,
|
|
int indent)
|
|
{
|
|
register int i;
|
|
XkbPointPtr pt;
|
|
char * iStr;
|
|
|
|
fprintf(file,"%s",iStr= XkbIndentText(first));
|
|
if (first!=indent)
|
|
iStr= XkbIndentText(indent);
|
|
if (outline->corner_radius!=lastRadius) {
|
|
fprintf(file,"corner= %s,",
|
|
XkbGeomFPText(outline->corner_radius,XkbMessage));
|
|
if (shape!=NULL) {
|
|
fprintf(file,"\n%s",iStr);
|
|
}
|
|
}
|
|
if (shape) {
|
|
if (outline==shape->approx)
|
|
fprintf(file,"approx= ");
|
|
else if (outline==shape->primary)
|
|
fprintf(file,"primary= ");
|
|
}
|
|
fprintf(file,"{");
|
|
for (pt=outline->points,i=0;i<outline->num_points;i++,pt++) {
|
|
if (i==0) fprintf(file," ");
|
|
else if ((i%4)==0) fprintf(file,",\n%s ",iStr);
|
|
else fprintf(file,", ");
|
|
fprintf(file,"[ %3s, %3s ]",XkbGeomFPText(pt->x,XkbXKBFile),
|
|
XkbGeomFPText(pt->y,XkbXKBFile));
|
|
}
|
|
fprintf(file," }");
|
|
return True;
|
|
}
|
|
|
|
static Bool
|
|
WriteXKBDoodad( FILE * file,
|
|
unsigned indent,
|
|
XkbGeometryPtr geom,
|
|
XkbDoodadPtr doodad)
|
|
{
|
|
register char * i_str;
|
|
XkbShapePtr shape;
|
|
XkbColorPtr color;
|
|
|
|
i_str= XkbIndentText(indent);
|
|
fprintf(file,"%s%s \"%s\" {\n",i_str,
|
|
XkbDoodadTypeText(doodad->any.type,XkbMessage),
|
|
XkbAtomText(doodad->any.name,XkbMessage));
|
|
fprintf(file,"%s top= %s;\n",i_str,
|
|
XkbGeomFPText(doodad->any.top,XkbXKBFile));
|
|
fprintf(file,"%s left= %s;\n",i_str,
|
|
XkbGeomFPText(doodad->any.left,XkbXKBFile));
|
|
fprintf(file,"%s priority= %d;\n",i_str,doodad->any.priority);
|
|
switch (doodad->any.type) {
|
|
case XkbOutlineDoodad:
|
|
case XkbSolidDoodad:
|
|
if (doodad->shape.angle!=0) {
|
|
fprintf(file,"%s angle= %s;\n",i_str,
|
|
XkbGeomFPText(doodad->shape.angle,XkbXKBFile));
|
|
}
|
|
if (doodad->shape.color_ndx!=0) {
|
|
fprintf(file,"%s color= \"%s\";\n",i_str,
|
|
XkbShapeDoodadColor(geom,&doodad->shape)->spec);
|
|
}
|
|
shape= XkbShapeDoodadShape(geom,&doodad->shape);
|
|
fprintf(file,"%s shape= \"%s\";\n",i_str,
|
|
XkbAtomText(shape->name,XkbXKBFile));
|
|
break;
|
|
case XkbTextDoodad:
|
|
if (doodad->text.angle!=0) {
|
|
fprintf(file,"%s angle= %s;\n",i_str,
|
|
XkbGeomFPText(doodad->text.angle,XkbXKBFile));
|
|
}
|
|
if (doodad->text.width!=0) {
|
|
fprintf(file,"%s width= %s;\n",i_str,
|
|
XkbGeomFPText(doodad->text.width,XkbXKBFile));
|
|
|
|
}
|
|
if (doodad->text.height!=0) {
|
|
fprintf(file,"%s height= %s;\n",i_str,
|
|
XkbGeomFPText(doodad->text.height,XkbXKBFile));
|
|
|
|
}
|
|
if (doodad->text.color_ndx!=0) {
|
|
color= XkbTextDoodadColor(geom,&doodad->text);
|
|
fprintf(file,"%s color= \"%s\";\n",i_str,
|
|
XkbStringText(color->spec,XkbXKBFile));
|
|
}
|
|
fprintf(file,"%s XFont= \"%s\";\n",i_str,
|
|
XkbStringText(doodad->text.font,XkbXKBFile));
|
|
fprintf(file,"%s text= \"%s\";\n",i_str,
|
|
XkbStringText(doodad->text.text,XkbXKBFile));
|
|
break;
|
|
case XkbIndicatorDoodad:
|
|
shape= XkbIndicatorDoodadShape(geom,&doodad->indicator);
|
|
color= XkbIndicatorDoodadOnColor(geom,&doodad->indicator);
|
|
fprintf(file,"%s onColor= \"%s\";\n",i_str,
|
|
XkbStringText(color->spec,XkbXKBFile));
|
|
color= XkbIndicatorDoodadOffColor(geom,&doodad->indicator);
|
|
fprintf(file,"%s offColor= \"%s\";\n",i_str,
|
|
XkbStringText(color->spec,XkbXKBFile));
|
|
fprintf(file,"%s shape= \"%s\";\n",i_str,
|
|
XkbAtomText(shape->name,XkbXKBFile));
|
|
break;
|
|
case XkbLogoDoodad:
|
|
fprintf(file,"%s logoName= \"%s\";\n",i_str,
|
|
XkbStringText(doodad->logo.logo_name,XkbXKBFile));
|
|
if (doodad->shape.angle!=0) {
|
|
fprintf(file,"%s angle= %s;\n",i_str,
|
|
XkbGeomFPText(doodad->logo.angle,XkbXKBFile));
|
|
}
|
|
if (doodad->shape.color_ndx!=0) {
|
|
fprintf(file,"%s color= \"%s\";\n",i_str,
|
|
XkbLogoDoodadColor(geom,&doodad->logo)->spec);
|
|
}
|
|
shape= XkbLogoDoodadShape(geom,&doodad->logo);
|
|
fprintf(file,"%s shape= \"%s\";\n",i_str,
|
|
XkbAtomText(shape->name,XkbXKBFile));
|
|
break;
|
|
}
|
|
fprintf(file,"%s};\n",i_str);
|
|
return True;
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static Bool
|
|
WriteXKBOverlay( FILE * file,
|
|
unsigned indent,
|
|
XkbGeometryPtr geom,
|
|
XkbOverlayPtr ol)
|
|
{
|
|
register char * i_str;
|
|
int r,k,nOut;
|
|
XkbOverlayRowPtr row;
|
|
XkbOverlayKeyPtr key;
|
|
|
|
i_str= XkbIndentText(indent);
|
|
if (ol->name!=None) {
|
|
fprintf(file,"%soverlay \"%s\" {\n",i_str,
|
|
XkbAtomText(ol->name,XkbMessage));
|
|
}
|
|
else fprintf(file,"%soverlay {\n",i_str);
|
|
for (nOut=r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
|
|
for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
|
|
char *over,*under;
|
|
over= XkbKeyNameText(key->over.name,XkbXKBFile);
|
|
under= XkbKeyNameText(key->under.name,XkbXKBFile);
|
|
if (nOut==0)
|
|
fprintf(file,"%s %6s=%6s",i_str,under,over);
|
|
else if ((nOut%4)==0)
|
|
fprintf(file,",\n%s %6s=%6s",i_str,under,over);
|
|
else fprintf(file,", %6s=%6s",under,over);
|
|
nOut++;
|
|
}
|
|
}
|
|
fprintf(file,"\n%s};\n",i_str);
|
|
return True;
|
|
}
|
|
|
|
static Bool
|
|
WriteXKBSection( FILE * file,
|
|
XkbSectionPtr s,
|
|
XkbGeometryPtr geom)
|
|
{
|
|
register int i;
|
|
XkbRowPtr row;
|
|
int dfltKeyColor = 0;
|
|
|
|
fprintf(file," section \"%s\" {\n",
|
|
XkbAtomText(s->name,XkbXKBFile));
|
|
if (s->rows&&(s->rows->num_keys>0)) {
|
|
dfltKeyColor= s->rows->keys[0].color_ndx;
|
|
fprintf(file," key.color= \"%s\";\n",
|
|
XkbStringText(geom->colors[dfltKeyColor].spec,XkbXKBFile));
|
|
}
|
|
fprintf(file," priority= %d;\n",s->priority);
|
|
fprintf(file," top= %s;\n",XkbGeomFPText(s->top,XkbXKBFile));
|
|
fprintf(file," left= %s;\n",XkbGeomFPText(s->left,XkbXKBFile));
|
|
fprintf(file," width= %s;\n",XkbGeomFPText(s->width,XkbXKBFile));
|
|
fprintf(file," height= %s;\n",
|
|
XkbGeomFPText(s->height,XkbXKBFile));
|
|
if (s->angle!=0) {
|
|
fprintf(file," angle= %s;\n",
|
|
XkbGeomFPText(s->angle,XkbXKBFile));
|
|
}
|
|
for (i=0,row=s->rows;i<s->num_rows;i++,row++) {
|
|
fprintf(file," row {\n");
|
|
fprintf(file," top= %s;\n",
|
|
XkbGeomFPText(row->top,XkbXKBFile));
|
|
fprintf(file," left= %s;\n",
|
|
XkbGeomFPText(row->left,XkbXKBFile));
|
|
if (row->vertical)
|
|
fprintf(file," vertical;\n");
|
|
if (row->num_keys>0) {
|
|
register int k;
|
|
register XkbKeyPtr key;
|
|
int forceNL=0;
|
|
int nThisLine= 0;
|
|
fprintf(file," keys {\n");
|
|
for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
|
|
XkbShapePtr shape;
|
|
if (key->color_ndx!=dfltKeyColor)
|
|
forceNL= 1;
|
|
if (k==0) {
|
|
fprintf(file," ");
|
|
nThisLine= 0;
|
|
}
|
|
else if (((nThisLine%2)==1)||(forceNL)) {
|
|
fprintf(file,",\n ");
|
|
forceNL= nThisLine= 0;
|
|
}
|
|
else {
|
|
fprintf(file,", ");
|
|
nThisLine++;
|
|
}
|
|
shape= XkbKeyShape(geom,key);
|
|
fprintf(file,"{ %6s, \"%s\", %3s",
|
|
XkbKeyNameText(key->name.name,XkbXKBFile),
|
|
XkbAtomText(shape->name,XkbXKBFile),
|
|
XkbGeomFPText(key->gap,XkbXKBFile));
|
|
if (key->color_ndx!=dfltKeyColor) {
|
|
fprintf(file,", color=\"%s\"",XkbKeyColor(geom,key)->spec);
|
|
forceNL= 1;
|
|
}
|
|
fprintf(file," }");
|
|
}
|
|
fprintf(file,"\n };\n");
|
|
}
|
|
fprintf(file," };\n");
|
|
}
|
|
if (s->doodads!=NULL) {
|
|
XkbDoodadPtr doodad;
|
|
for (i=0,doodad=s->doodads;i<s->num_doodads;i++,doodad++) {
|
|
WriteXKBDoodad(file,8,geom,doodad);
|
|
}
|
|
}
|
|
if (s->overlays!=NULL) {
|
|
XkbOverlayPtr ol;
|
|
for (i=0,ol=s->overlays;i<s->num_overlays;i++,ol++) {
|
|
WriteXKBOverlay(file,8,geom,ol);
|
|
}
|
|
}
|
|
fprintf(file," }; // End of \"%s\" section\n\n",
|
|
XkbAtomText(s->name,XkbXKBFile));
|
|
return True;
|
|
}
|
|
|
|
Bool
|
|
XkbWriteXKBGeometry( FILE * file,
|
|
XkbDescPtr xkb,
|
|
Bool topLevel,
|
|
Bool showImplicit,
|
|
XkbFileAddOnFunc addOn,
|
|
void * priv)
|
|
{
|
|
register unsigned i,n;
|
|
XkbGeometryPtr geom;
|
|
|
|
if ((!xkb)||(!xkb->geom)) {
|
|
_XkbLibError(_XkbErrMissingGeometry,"XkbWriteXKBGeometry",0);
|
|
return False;
|
|
}
|
|
geom= xkb->geom;
|
|
if (geom->name==None)
|
|
fprintf(file,"xkb_geometry {\n\n");
|
|
else fprintf(file,"xkb_geometry \"%s\" {\n\n",
|
|
XkbAtomText(geom->name,XkbXKBFile));
|
|
fprintf(file," width= %s;\n",
|
|
XkbGeomFPText(geom->width_mm,XkbXKBFile));
|
|
fprintf(file," height= %s;\n\n",
|
|
XkbGeomFPText(geom->height_mm,XkbXKBFile));
|
|
|
|
if (geom->key_aliases!=NULL) {
|
|
XkbKeyAliasPtr pAl;
|
|
pAl= geom->key_aliases;
|
|
for (i=0;i<geom->num_key_aliases;i++,pAl++) {
|
|
fprintf(file," alias %6s = %6s;\n",
|
|
XkbKeyNameText(pAl->alias,XkbXKBFile),
|
|
XkbKeyNameText(pAl->real,XkbXKBFile));
|
|
}
|
|
fprintf(file,"\n");
|
|
}
|
|
|
|
if (geom->base_color!=NULL)
|
|
fprintf(file," baseColor= \"%s\";\n",
|
|
XkbStringText(geom->base_color->spec,XkbXKBFile));
|
|
if (geom->label_color!=NULL)
|
|
fprintf(file," labelColor= \"%s\";\n",
|
|
XkbStringText(geom->label_color->spec,XkbXKBFile));
|
|
if (geom->label_font!=NULL)
|
|
fprintf(file," xfont= \"%s\";\n",
|
|
XkbStringText(geom->label_font,XkbXKBFile));
|
|
if ((geom->num_colors>0)&&(showImplicit)) {
|
|
XkbColorPtr color;
|
|
for (color=geom->colors,i=0;i<geom->num_colors;i++,color++) {
|
|
fprintf(file,"// color[%d]= \"%s\"\n",i,
|
|
XkbStringText(color->spec,XkbXKBFile));
|
|
}
|
|
fprintf(file,"\n");
|
|
}
|
|
if (geom->num_properties>0) {
|
|
XkbPropertyPtr prop;
|
|
for (prop=geom->properties,i=0;i<geom->num_properties;i++,prop++) {
|
|
fprintf(file," %s= \"%s\";\n",prop->name,
|
|
XkbStringText(prop->value,XkbXKBFile));
|
|
}
|
|
fprintf(file,"\n");
|
|
}
|
|
if (geom->num_shapes>0) {
|
|
XkbShapePtr shape;
|
|
XkbOutlinePtr outline;
|
|
int lastR;
|
|
for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) {
|
|
lastR=0;
|
|
fprintf(file," shape \"%s\" {",
|
|
XkbAtomText(shape->name,XkbXKBFile));
|
|
outline= shape->outlines;
|
|
if (shape->num_outlines>1) {
|
|
for (n=0;n<shape->num_outlines;n++,outline++) {
|
|
if (n==0) fprintf(file,"\n");
|
|
else fprintf(file,",\n");
|
|
WriteXKBOutline(file,shape,outline,lastR,8,8);
|
|
lastR= outline->corner_radius;
|
|
}
|
|
fprintf(file,"\n };\n");
|
|
}
|
|
else {
|
|
WriteXKBOutline(file,NULL,outline,lastR,1,8);
|
|
fprintf(file," };\n");
|
|
}
|
|
}
|
|
}
|
|
if (geom->num_sections>0) {
|
|
XkbSectionPtr section;
|
|
for (section=geom->sections,i=0;i<geom->num_sections;i++,section++){
|
|
WriteXKBSection(file,section,geom);
|
|
}
|
|
}
|
|
if (geom->num_doodads>0) {
|
|
XkbDoodadPtr doodad;
|
|
for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) {
|
|
WriteXKBDoodad(file,4,geom,doodad);
|
|
}
|
|
}
|
|
if (addOn)
|
|
(*addOn)(file,xkb,topLevel,showImplicit,XkmGeometryIndex,priv);
|
|
fprintf(file,"};\n\n");
|
|
return True;
|
|
}
|