Edit

IABSD.fr/xenocara/lib/libxkbfile/src/cout.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2012-03-10 17:16:24
    Hash : d1508600
    Message : Update to libxkbfile 1.0.8

  • lib/libxkbfile/src/cout.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_CONFIG_H
    #include <config.h>
    #endif
    #include <stdio.h>
    #include <ctype.h>
    #include <stdlib.h>
    #include <X11/Xos.h>
    #include <X11/Xlib.h>
    #include <X11/XKBlib.h>
    #include <X11/extensions/XKBgeom.h>
    
    #include "XKMformat.h"
    #include "XKBfileInt.h"
    
    #define	lowbit(x)	((x) & (-(x)))
    
    static Bool
    WriteCHdrVMods(FILE *file,Display *dpy,XkbDescPtr xkb)
    {
    register int i,nOut;
    
        if ((!xkb)||(!xkb->names)||(!xkb->names->vmods))
    	return False;
        for (i=nOut=0;i<XkbNumVirtualMods;i++) {
    	if (xkb->names->vmods[i]!=None) {
    	    fprintf(file,"%s#define	vmod_%s	%d\n",(nOut<1?"\n":""),
    				XkbAtomText(dpy,xkb->names->vmods[i],XkbCFile),
    				i);
    	    nOut++;
    	}
        }
        for (i=nOut=0;i<XkbNumVirtualMods;i++) {
    	if (xkb->names->vmods[i]!=None) {
    	    fprintf(file,"%s#define	vmod_%sMask	(1<<%d)\n",
    				(nOut<1?"\n":""),
    				XkbAtomText(dpy,xkb->names->vmods[i],XkbCFile)
    				,i);
    	    nOut++;
    	}
        }
        if (nOut>0)
    	fprintf(file,"\n");
        return True;
    }
    
    static Bool
    WriteCHdrKeycodes(FILE *file,XkbDescPtr xkb)
    {
    Atom			kcName;
    register unsigned 	i;
    char 			buf[8];
    
        if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) {
    	_XkbLibError(_XkbErrMissingNames,"WriteCHdrKeycodes",0);
    	return False;
        }
        kcName= xkb->names->keycodes;
        buf[4]= '\0';
        if (xkb->names->keycodes!=None)
    	 fprintf(file,"/* keycodes name is \"%s\" */\n",
     				XkbAtomText(xkb->dpy,kcName,XkbMessage));
        fprintf(file,"static XkbKeyNameRec	keyNames[NUM_KEYS]= {\n");
        for (i=0;i<=xkb->max_key_code;i++) {
    	sprintf(buf,"\"%s\"",XkbKeyNameText(xkb->names->keys[i].name,XkbCFile));
    	if (i!=xkb->max_key_code)  {
    	    fprintf(file,"    {  %6s  },",buf);
    	    if ((i&3)==3)
    		fprintf(file,"\n");
    	}
    	else {
    	    fprintf(file,"    {  %6s  }\n",buf);
    	}
        }
        fprintf(file,"};\n");
        return True;
    }
    
    static void
    WriteTypePreserve(	FILE *		file,
    			Display *	dpy,
    			char *		prefix,
    			XkbDescPtr	xkb,
    			XkbKeyTypePtr	type)
    {
    register unsigned	i;
    XkbModsPtr		pre;
    
        fprintf(file,"static XkbModsRec preserve_%s[%d]= {\n",prefix,
    							type->map_count);
        for (i=0,pre=type->preserve;i<type->map_count;i++,pre++) {
    	if (i!=0)
    	    fprintf(file,",\n");
    	fprintf(file,"    {   %15s, ",XkbModMaskText(pre->mask,XkbCFile));
    	fprintf(file,"%15s, ",XkbModMaskText(pre->real_mods,XkbCFile));
    	fprintf(file,"%15s }",XkbVModMaskText(dpy,xkb,0,pre->vmods,XkbCFile));
        }
        fprintf(file,"\n};\n");
        return;
    }
    
    static void
    WriteTypeInitFunc(FILE *file,Display *dpy,XkbDescPtr xkb)
    {
    register unsigned 	i,n;
    XkbKeyTypePtr		type;
    Atom *			names;
    char *			prefix = NULL;
    
        fprintf(file,"\n\nstatic void\n");
        fprintf(file,"initTypeNames(DPYTYPE dpy)\n");
        fprintf(file,"{\n");
        for (i=0,type=xkb->map->types;i<xkb->map->num_types;i++,type++) {
    	if (!(prefix = strdup(XkbAtomText(dpy,type->name,XkbCFile)))) {
    		_XkbLibError(_XkbErrBadAlloc,"WriteTypeInitFunc",0);
    		fprintf(file,"#error XkbErrBadAlloc WriteTypeInitFunc\n");
    		break;
    	}
    	if (type->name!=None)
    	    fprintf(file,"    dflt_types[%d].name= GET_ATOM(dpy,\"%s\");\n",i,
    					XkbAtomText(dpy,type->name,XkbCFile));
    	names= type->level_names;
    	if (names!=NULL) {
    	    char *tmp;
    	    for (n=0;n<type->num_levels;n++) {
    		if (names[n]==None)
    		    continue;
    		tmp= XkbAtomText(dpy,names[n],XkbCFile);
    		if (tmp==NULL)
    		    continue;
    		fprintf(file,"    lnames_%s[%d]=	",prefix,n);
    		fprintf(file,"GET_ATOM(dpy,\"%s\");\n",tmp);
    	    }
    	}
    	free(prefix);
    	prefix = NULL;
        }
        fprintf(file,"}\n");
        return;
    }
    
    static Bool
    WriteCHdrKeyTypes(FILE *file,Display *dpy,XkbDescPtr xkb)
    {
    register unsigned	i,n;
    XkbClientMapPtr		map;
    XkbKeyTypePtr		type;
    char * 			prefix = NULL;
    
        if ((!xkb)||(!xkb->map)||(!xkb->map->types)) {
    	_XkbLibError(_XkbErrMissingTypes,"WriteCHdrKeyTypes",0);
    	return False;
        }
        if (xkb->map->num_types<XkbNumRequiredTypes) {
    	_XkbLibError(_XkbErrMissingReqTypes,"WriteCHdrKeyTypes",0);
    	return 0;
        }
        map= xkb->map;
        if ((xkb->names!=NULL)&&(xkb->names->types!=None)) {
    	fprintf(file,"/* types name is \"%s\" */\n",
    				XkbAtomText(dpy,xkb->names->types,XkbCFile));
        }
        for (i=0,type=map->types;i<map->num_types;i++,type++) {
    	if (!(prefix = strdup(XkbAtomText(dpy,type->name,XkbCFile)))) {
    		_XkbLibError(_XkbErrBadAlloc,"WriteCHdrKeyTypes",0);
    		return False;
    	}
    
    	if (type->map_count>0) {
    	    XkbKTMapEntryPtr	entry;
    	    entry= type->map;
    	    fprintf(file,"static XkbKTMapEntryRec map_%s[%d]= {\n",prefix,
    							type->map_count);
    	    for (n=0;n<(unsigned)type->map_count;n++,entry++) {
    		if (n!=0)
    		    fprintf(file,",\n");
    		fprintf(file,"    { %d, %6d, { %15s, %15s, %15s } }",
    			entry->active,
    			entry->level,
    			XkbModMaskText(entry->mods.mask,XkbCFile),
    			XkbModMaskText(entry->mods.real_mods,XkbCFile),
    			XkbVModMaskText(dpy,xkb,0,entry->mods.vmods,XkbCFile));
    	    }
    	    fprintf(file,"\n};\n");
    
    	    if (type->preserve)
    		WriteTypePreserve(file,dpy,prefix,xkb,type);
    	}
    	if (type->level_names!=NULL) {
    	    fprintf(file,"static Atom lnames_%s[%d];\n",prefix,
    							 type->num_levels);
    	}
    	fprintf(file,"\n");
    	free(prefix);
    	prefix = NULL;
        }
        fprintf(file,"static XkbKeyTypeRec dflt_types[]= {\n");
        for (i=0,type=map->types;i<(unsigned)map->num_types;i++,type++) {
    	if (!(prefix = strdup(XkbAtomText(dpy,type->name,XkbCFile)))) {
    		_XkbLibError(_XkbErrBadAlloc,"WriteCHdrKeyTypes",0);
    		return False;
    	}
    	if (i!=0)	fprintf(file,",\n");
    	fprintf(file,"    {\n	{ %15s, %15s, %15s },\n",
    			XkbModMaskText(type->mods.mask,XkbCFile),
    			XkbModMaskText(type->mods.real_mods,XkbCFile),
    			XkbVModMaskText(dpy,xkb,0,type->mods.vmods,XkbCFile));
    	fprintf(file,"	%d,\n",type->num_levels);
    	fprintf(file,"	%d,",type->map_count);
    	if (type->map_count>0)
    	     fprintf(file,"	map_%s,",prefix);
    	else fprintf(file,"	NULL,");
    	if (type->preserve)
    	     fprintf(file,"	preserve_%s,\n",prefix);
    	else fprintf(file,"	NULL,\n");
    	if (type->level_names!=NULL)
    	     fprintf(file,"	None,	lnames_%s\n    }",prefix);
    	else fprintf(file,"	None,	NULL\n    }");
    	free(prefix);
    	prefix = NULL;
        }
        fprintf(file,"\n};\n");
        fprintf(file,"#define num_dflt_types (sizeof(dflt_types)/sizeof(XkbKeyTypeRec))\n");
        WriteTypeInitFunc(file,dpy,xkb);
        return True;
    }
    
    static Bool
    WriteCHdrCompatMap(FILE *file,Display *dpy,XkbDescPtr xkb)
    {
    register unsigned	i;
    XkbCompatMapPtr		compat;
    XkbSymInterpretPtr	interp;
    
        if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) {
    	_XkbLibError(_XkbErrMissingSymInterps,"WriteCHdrInterp",0);
    	return False;
        }
        compat= xkb->compat;
        if ((xkb->names!=NULL)&&(xkb->names->compat!=None)) {
    	fprintf(file,"/* compat name is \"%s\" */\n",
    				XkbAtomText(dpy,xkb->names->compat,XkbCFile));
        }
        fprintf(file,"static XkbSymInterpretRec dfltSI[%d]= {\n",
    						compat->num_si);
        interp= compat->sym_interpret;
        for (i=0;i<compat->num_si;i++,interp++) {
    	XkbAction *act;
    	act= (XkbAction *)&interp->act;
    	if (i!=0)	fprintf(file,",\n");
    	fprintf(file,"    {    %s, ",XkbKeysymText(interp->sym,XkbCFile));
    	fprintf(file,"0x%04x,\n",interp->flags);
    	fprintf(file,"         %s, ",XkbSIMatchText(interp->match,XkbCFile));
    	fprintf(file,"%s,\n",XkbModMaskText(interp->mods,XkbCFile));
    	fprintf(file,"         %d,\n",interp->virtual_mod);
    	fprintf(file,"       %s }",XkbActionText(dpy,xkb,act,XkbCFile));
        }
        fprintf(file,"\n};\n");
        fprintf(file,
    	   "#define num_dfltSI (sizeof(dfltSI)/sizeof(XkbSymInterpretRec))\n");
        fprintf(file,"\nstatic XkbCompatMapRec compatMap= {\n");
        fprintf(file,"    dfltSI,\n");
        fprintf(file,"    {   /* group compatibility */\n        ");
        for (i=0;i<XkbNumKbdGroups;i++) {
    	XkbModsPtr gc;
    	gc= &xkb->compat->groups[i];
    	fprintf(file,"%s{ %12s, %12s, %12s }",
    			((i==0)?"":",\n        "),
    			XkbModMaskText(gc->mask,XkbCFile),
    			XkbModMaskText(gc->real_mods,XkbCFile),
    			XkbVModMaskText(xkb->dpy,xkb,0,gc->vmods,XkbCFile));
        }
        fprintf(file,"\n    },\n");
        fprintf(file,"    num_dfltSI, num_dfltSI\n");
        fprintf(file,"};\n\n");
        return True;
    }
    
    static Bool
    WriteCHdrSymbols(FILE *file,XkbDescPtr xkb)
    {
    register unsigned i;
    
        if ((!xkb)||(!xkb->map)||(!xkb->map->syms)||(!xkb->map->key_sym_map)) {
    	_XkbLibError(_XkbErrMissingSymbols,"WriteCHdrSymbols",0);
    	return False;
        }
        fprintf(file,"#define NUM_SYMBOLS	%d\n",xkb->map->num_syms);
        if (xkb->map->num_syms>0) {
    	register KeySym *sym;
    	sym= xkb->map->syms;
    	fprintf(file,"static KeySym	symCache[NUM_SYMBOLS]= {\n");
    	for (i=0;i<xkb->map->num_syms;i++,sym++) {
    	    if (i==0)		fprintf(file,"    ");
    	    else if (i%4==0)	fprintf(file,",\n    ");
    	    else		fprintf(file,", ");
    	    fprintf(file,"%15s",XkbKeysymText(*sym,XkbCFile));
    	}
    	fprintf(file,"\n};\n");
        }
        if (xkb->max_key_code>0) {
    	register XkbSymMapPtr	map;
    	map= xkb->map->key_sym_map;
    	fprintf(file,"static XkbSymMapRec	symMap[NUM_KEYS]= {\n");
    	for (i=0;i<=xkb->max_key_code;i++,map++) {
    	    if (i==0)		fprintf(file,"    ");
    	    else if ((i&3)==0)	fprintf(file,",\n    ");
    	    else			fprintf(file,", ");
    	    fprintf(file, "{ %2d, 0x%x, %3d }",
    		    map->kt_index[0], map->group_info, map->offset);
    	}
    	fprintf(file,"\n};\n");
        }
        return True;
    }
    
    static Bool
    WriteCHdrClientMap(FILE *file,Display *dpy,XkbDescPtr xkb)
    {
        if ((!xkb)||(!xkb->map)||(!xkb->map->syms)||(!xkb->map->key_sym_map)) {
    	_XkbLibError(_XkbErrMissingSymbols,"WriteCHdrClientMap",0);
    	return False;
        }
        if (!WriteCHdrKeyTypes(file,dpy,xkb))
    	return False;
        if (!WriteCHdrSymbols(file,xkb))
    	return False;
        fprintf(file,"static XkbClientMapRec clientMap= {\n");
        fprintf(file,"    NUM_TYPES,   NUM_TYPES,   types, \n");
        fprintf(file,"    NUM_SYMBOLS, NUM_SYMBOLS, symCache, symMap\n");
        fprintf(file,"};\n\n");
        return True;
    }
    
    static Bool
    WriteCHdrServerMap(FILE *file,Display *dpy,XkbDescPtr xkb)
    {
    register unsigned i;
    
        if ((!xkb)||(!xkb->map)||(!xkb->map->syms)||(!xkb->map->key_sym_map)) {
    	_XkbLibError(_XkbErrMissingSymbols,"WriteCHdrServerMap",0);
    	return False;
        }
        if (xkb->server->num_acts>0) {
    	register XkbAnyAction *act;
    	act= (XkbAnyAction *)xkb->server->acts;
    	fprintf(file,"#define NUM_ACTIONS	%d\n",xkb->server->num_acts);
    	fprintf(file,"static XkbAnyAction 	actionCache[NUM_ACTIONS]= {\n");
    	for (i=0;i<xkb->server->num_acts;i++,act++) {
    	    if (i==0)	fprintf(file,"    ");
    	    else	fprintf(file,",\n    ");
    	    fprintf(file,"%s",XkbActionText(dpy,xkb,(XkbAction *)act,XkbCFile));
    	}
    	fprintf(file,"\n};\n");
        }
        fprintf(file,"static unsigned short	keyActions[NUM_KEYS]= {\n");
        for (i=0;i<=xkb->max_key_code;i++) {
    	if (i==0)		fprintf(file,"    ");
    	else if ((i&0xf)==0)	fprintf(file,",\n    ");
    	else			fprintf(file,", ");
    	fprintf(file,"%2d",xkb->server->key_acts[i]);
        }
        fprintf(file,"\n};\n");
        fprintf(file,"static XkbBehavior behaviors[NUM_KEYS]= {\n");
        for (i=0;i<=xkb->max_key_code;i++) {
    	if (i==0)		fprintf(file,"    ");
    	else if ((i&0x3)==0)	fprintf(file,",\n    ");
    	else			fprintf(file,", ");
    	if (xkb->server->behaviors) {
    	     fprintf(file,"%s",
    		XkbBehaviorText(xkb,&xkb->server->behaviors[i],XkbCFile));
    	}
    	else fprintf(file,"{    0,    0 }");
        }
        fprintf(file,"\n};\n");
        fprintf(file,"static unsigned char explicit_parts[NUM_KEYS]= {\n");
        for (i=0;i<=xkb->max_key_code;i++) {
    	if (i==0)		fprintf(file,"    ");
    	else if ((i&0x7)==0)	fprintf(file,",\n    ");
    	else			fprintf(file,", ");
    	if ((xkb->server->explicit==NULL)||(xkb->server->explicit[i]==0))
    	     fprintf(file,"   0");
    	else fprintf(file,"0x%02x",xkb->server->explicit[i]);
        }
        fprintf(file,"\n};\n");
        fprintf(file,"static unsigned short vmodmap[NUM_KEYS]= {\n");
        for (i=0;i<xkb->max_key_code;i++) {
    	if (i==0)		fprintf(file,"    ");
    	else if ((i&0x7)==0)	fprintf(file,",\n    ");
    	else			fprintf(file,", ");
    	if ((xkb->server->vmodmap==NULL)||(xkb->server->vmodmap[i]==0))
    	     fprintf(file,"     0");
    	else fprintf(file,"0x%04x",xkb->server->vmodmap[i]);
        }
        fprintf(file,"};\n");
        fprintf(file,"static XkbServerMapRec serverMap= {\n");
        fprintf(file,"    %d, %d, (XkbAction *)actionCache,\n",
    				xkb->server->num_acts,xkb->server->num_acts);
        fprintf(file,"    behaviors, keyActions, explicit_parts,\n");
        for (i=0;i<XkbNumVirtualMods;i++) {
    	if (i==0)	fprintf(file,"    { ");
    	else if (i==8)	fprintf(file,",\n      ");
    	else		fprintf(file,", ");
    	fprintf(file,"%3d",xkb->server->vmods[i]);
        }
        fprintf(file," },\n");
        fprintf(file,"    vmodmap\n");
        fprintf(file,"};\n\n");
        return True;
    }
    
    static Bool
    WriteCHdrIndicators(FILE *file,Display *dpy,XkbDescPtr xkb)
    {
    register int 		i,nNames;
    XkbIndicatorMapPtr	imap;
    
        if (xkb->indicators==NULL)
    	return True;
        fprintf(file, "static XkbIndicatorRec indicators= {\n");
        fprintf(file, "    0x%lx,\n    {\n",
    	    (long)xkb->indicators->phys_indicators);
        for (imap=xkb->indicators->maps,i=nNames=0;i<XkbNumIndicators;i++,imap++) {
    	fprintf(file,"%s        { 0x%02x, %s, 0x%02x, %s, { %s, ",
    			(i!=0?",\n":""),
    			imap->flags,
    			XkbIMWhichStateMaskText(imap->which_groups,XkbCFile),
    			imap->groups,
    			XkbIMWhichStateMaskText(imap->which_mods,XkbCFile),
    			XkbModMaskText(imap->mods.mask,XkbCFile));
    	fprintf(file," %s, %s }, %s }",
    			XkbModMaskText(imap->mods.real_mods,XkbCFile),
    			XkbVModMaskText(dpy,xkb,0,imap->mods.vmods,XkbCFile),
    			XkbControlsMaskText(imap->ctrls,XkbCFile));
    	if (xkb->names && (xkb->names->indicators[i]!=None))
    	    nNames++;
        }
        fprintf(file,"\n    }\n};\n");
        if (nNames>0) {
    	fprintf(file,"static void\n");
    	fprintf(file,"initIndicatorNames(DPYTYPE dpy,XkbDescPtr xkb)\n");
    	fprintf(file,"{\n");
    	for (i=0;i<XkbNumIndicators;i++) {
    	    Atom name;
    	    if (xkb->names->indicators[i]==None)
    		continue;
    	    name= xkb->names->indicators[i];
    	    fprintf(file,"    xkb->names->indicators[%2d]=	",i);
    	    fprintf(file,"GET_ATOM(dpy,\"%s\");\n",
    						XkbAtomText(dpy,name,XkbCFile));
    	}
    	fprintf(file,"}\n");
        }
        return True;
    }
    
    static Bool
    WriteCHdrGeomProps(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom)
    {
        if (geom->num_properties>0) {
    	register int i;
    	fprintf(file,"\nstatic XkbPropertyRec g_props[%d]= {\n",
    							geom->num_properties);
    	for (i=0;i<geom->num_properties;i++) {
    	    fprintf(file,"%s	{	\"%s\", \"%s\"	}",(i==0?"":",\n"),
    			XkbStringText(geom->properties[i].name,XkbCFile),
    			XkbStringText(geom->properties[i].value,XkbCFile));
    	}
    	fprintf(file,"\n};\n");
        }
        return True;
    }
    
    static Bool
    WriteCHdrGeomColors(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom)
    {
        if (geom->num_colors>0) {
    	register int i;
    	fprintf(file,"\nstatic XkbColorRec g_colors[%d]= {\n",geom->num_colors);
    	for (i=0;i<geom->num_colors;i++) {
    	    fprintf(file,"%s	{	%3d, \"%s\"	}",(i==0?"":",\n"),
    			geom->colors[i].pixel,
    			XkbStringText(geom->colors[i].spec,XkbCFile));
    	}
    	fprintf(file,"\n};\n");
        }
        return True;
    }
    
    static Bool
    WriteCHdrGeomOutlines(FILE *file,int nOL,XkbOutlinePtr ol,int shapeNdx)
    {
    register int o,p;
    
    
        for (o=0;o<nOL;o++) {
    	fprintf(file,"\nstatic XkbPointRec pts_sh%02do%02d[]= {\n",shapeNdx,o);
    	for (p=0;p<ol[o].num_points;p++) {
    	    if (p==0)			fprintf(file,"	");
    	    else if ((p&0x3)==0)	fprintf(file,",\n	");
    	    else 			fprintf(file,", ");
    	    fprintf(file,"{ %4d, %4d }",
    				ol[o].points[p].x,ol[o].points[p].y);
    	}
    	fprintf(file,"\n};");
        }
        fprintf(file,"\n\nstatic XkbOutlineRec ol_sh%02d[]= {\n",shapeNdx);
        for (o=0;o<nOL;o++) {
    	fprintf(file,"%s	{ %d,	%d,	%d,	pts_sh%02do%02d	}",
    					(o==0?"":",\n"),
    					ol[o].num_points,ol[o].num_points,
    					ol[o].corner_radius,shapeNdx,o);
        }
        fprintf(file,"\n};\n");
        return True;
    }
    
    static Bool
    WriteCHdrGeomShapes(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom)
    {
    register int 		s;
    register XkbShapePtr	shape;
    
        for (s=0,shape=geom->shapes;s<geom->num_shapes;s++,shape++) {
    	WriteCHdrGeomOutlines(file,shape->num_outlines,shape->outlines,s);
        }
        fprintf(file,"\n\nstatic XkbShapeRec g_shapes[%d]= {\n",geom->num_shapes);
        for (s=0,shape=geom->shapes;s<geom->num_shapes;s++,shape++) {
    	fprintf(file,"%s	{ None, %3d, %3d, ol_sh%02d, ",
    					(s==0?"":",\n"),shape->num_outlines,
    					shape->num_outlines,s);
    	if (shape->approx) {
    	    fprintf(file,"&ol_sh%02d[%2d],	",s,
    					XkbOutlineIndex(shape,shape->approx));
    	}
    	else fprintf(file,"        NULL,	");
    	if (shape->primary) {
    	    fprintf(file,"&ol_sh%02d[%2d],\n",s,
    					XkbOutlineIndex(shape,shape->primary));
    	}
    	else fprintf(file,"        NULL,\n");
    	fprintf(file,"					{ %4d, %4d, %4d, %4d } }",
    					shape->bounds.x1,shape->bounds.y1,
    					shape->bounds.x2,shape->bounds.y2);
        }
        fprintf(file,"\n};\n");
        return True;
    }
    
    static Bool
    WriteCHdrGeomDoodads(	FILE *		file,
    			XkbDescPtr	xkb,
    			XkbGeometryPtr	geom,
    			XkbSectionPtr	section,
    			int		section_num)
    {
    int		nd,d;
    XkbDoodadPtr	doodad;
    Display *	dpy;
    
        dpy= xkb->dpy;
        if (section==NULL) {
    	if (geom->num_doodads>0) {
    	    fprintf(file,"static XkbDoodadRec g_doodads[%d];\n",
    							geom->num_doodads);
    	}
    	fprintf(file,"static void\n");
    	fprintf(file,"_InitGeomDoodads(DPYTYPE dpy,XkbGeometryPtr geom)\n");
    	fprintf(file,"{\n");
    	fprintf(file,"register XkbDoodadPtr doodads;\n\n");
    	fprintf(file,"    doodads= geom->doodads;\n");
    	nd= geom->num_doodads;
    	doodad= geom->doodads;
        }
        else {
    	if (section->num_doodads>0) {
    	    fprintf(file,"static XkbDoodadRec doodads_s%02d[%d];\n",
    					section_num,section->num_doodads);
    	}
    	fprintf(file,"static void\n");
    	fprintf(file,"_InitS%02dDoodads(",section_num);
    	fprintf(file,"    DPYTYPE		dpy,\n");
    	fprintf(file,"    XkbGeometryPtr 	geom,\n");
    	fprintf(file,"    XkbSectionPtr 	section)\n");
    	fprintf(file,"{\n");
    	fprintf(file,"register XkbDoodadPtr doodads;\n\n");
    	fprintf(file,"    doodads= section->doodads;\n");
    	nd= geom->num_doodads;
    	doodad= geom->doodads;
        }
        for (d=0;d<nd;d++,doodad++) {
    	if (d!=0)	fprintf(file,"\n");
    	fprintf(file,"    doodads[%d].any.name= GET_ATOM(dpy,\"%s\");\n",d,
    			XkbAtomText(dpy,doodad->any.name,XkbCFile));
    	fprintf(file,"    doodads[%d].any.type= %s;\n",d,
    			XkbDoodadTypeText(doodad->any.type,XkbCFile));
    	fprintf(file,"    doodads[%d].any.priority= %d;\n",d,
    			doodad->any.priority);
    	fprintf(file,"    doodads[%d].any.top= %d;\n",d,doodad->any.top);
    	fprintf(file,"    doodads[%d].any.left= %d;\n",d,doodad->any.left);
    	fprintf(file,"    doodads[%d].any.angle= %d;\n",d,doodad->any.angle);
    	switch (doodad->any.type) {
    	    case XkbOutlineDoodad:
    	    case XkbSolidDoodad:
    		fprintf(file,"    doodads[%d].shape.color_ndx= %d;\n",d,
    					doodad->shape.color_ndx);
    		fprintf(file,"    doodads[%d].shape.shape_ndx= %d;\n",d,
    					doodad->shape.shape_ndx);
    		break;
    	    case XkbTextDoodad:
    		fprintf(file,"    doodads[%d].text.width= %d;\n",d,
    					doodad->text.width);
    		fprintf(file,"    doodads[%d].text.height= %d;\n",d,
    					doodad->text.height);
    		fprintf(file,"    doodads[%d].text.color_ndx= %d;\n",d,
    					doodad->text.color_ndx);
    		fprintf(file,"    doodads[%d].text.text= \"%s\";\n",d,
    				XkbStringText(doodad->text.text,XkbCFile));
    		fprintf(file,"    doodads[%d].text.font= \"%s\";\n",d,
    				XkbStringText(doodad->text.font,XkbCFile));
    		break;
    	    case XkbIndicatorDoodad:
    		fprintf(file,"    doodads[%d].indicator.shape_ndx= %d;\n",d,
    					doodad->indicator.shape_ndx);
    		fprintf(file,"    doodads[%d].indicator.on_color_ndx= %d;\n",d,
    					doodad->indicator.on_color_ndx);
    		fprintf(file,"    doodads[%d].indicator.off_color_ndx= %d;\n",d,
    					doodad->indicator.off_color_ndx);
    		break;
    	    case XkbLogoDoodad:
    		fprintf(file,"    doodads[%d].logo.color_ndx= %d;\n",d,
    					doodad->logo.color_ndx);
    		fprintf(file,"    doodads[%d].logo.shape_ndx= %d;\n",d,
    					doodad->logo.shape_ndx);
    		fprintf(file,"    doodads[%d].logo.logo_name= \"%s\";\n",d,
    				XkbStringText(doodad->logo.logo_name,XkbCFile));
    		break;
    	}
        }
        fprintf(file,"}\n");
        return True;
    }
    
    static Bool
    WriteCHdrGeomOverlays(	FILE *		file,
    			XkbDescPtr	xkb,
    			XkbSectionPtr	section,
    			int		section_num)
    {
    register int		o,r,k;
    XkbOverlayPtr		ol;
    XkbOverlayRowPtr	row;
    XkbOverlayKeyPtr	key;
    
        if (section->num_overlays<1)
    	return True;
        for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
    	for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
    	    fprintf(file,"static XkbOverlayKeyRec olkeys_s%02dr%02d[%d]= {\n",
    						section_num,r,row->num_keys);
    	    for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
    		fprintf(file,"%s	{ {\"%s\"},	{\"%s\"}	}",
    				(k==0?"":",\n"),
    				XkbKeyNameText(key->over.name,XkbCFile),
    				XkbKeyNameText(key->under.name,XkbCFile));
    	    }
    	    fprintf(file,"\n};\n");
    	}
    	fprintf(file,"static XkbOverlayRowRec olrows_s%02d[%d]= {\n",
    						section_num,section->num_rows);
    	for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
    	    fprintf(file,"%s	{ %4d, %4d, %4d, olkeys_s%02dr%02d }",
    				(r==0?"":",\n"),
    				row->row_under,row->num_keys,row->num_keys,
    				section_num,r);
    	}
    	fprintf(file,"\n};\n");
        }
        fprintf(file,"static XkbOverlayRec overlays_s%02d[%d]= {\n",section_num,
    							section->num_overlays);
        for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
    	fprintf(file,"%s	{\n",(o==0?"":",\n"));
    	fprintf(file,"	    None, 	/* name */\n");
    	fprintf(file,"	    NULL,	/* section_under */\n");
    	fprintf(file,"	    %4d,	/* num_rows */\n",ol->num_rows);
    	fprintf(file,"	    %4d,	/* sz_rows */\n",ol->num_rows);
    	fprintf(file,"	    olrows_s%02d,\n",section_num);
    	fprintf(file,"	    NULL	/* bounds */\n");
    	fprintf(file,"	}");
        }
        fprintf(file,"\n};\n");
        fprintf(file,"static void\n");
        fprintf(file,"_InitS%02dOverlay(",section_num);
        fprintf(file,"    DPYTYPE		dpy,\n");
        fprintf(file,"    XkbGeometryPtr 	geom,\n");
        fprintf(file,"    XkbSectionPtr 	section)\n");
        fprintf(file,"{\n");
        fprintf(file,"XkbOverlayPtr	ol;\n\n");
        fprintf(file,"    ol= section->overlays;\n");
        for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
    	fprintf(file,"    ol[%2d].name= GET_ATOM(dpy,\"%s\");\n",o,
    				XkbAtomText(xkb->dpy,ol->name,XkbCFile));
    	fprintf(file,"    ol[%2d].section_under= section;\n",o);
        }
        fprintf(file,"}\n");
        return True;
    }
    
    static Bool
    WriteCHdrGeomRows(	FILE *		file,
    			XkbDescPtr	xkb,
    			XkbSectionPtr	section,
    			int		section_num)
    {
    register int 		k,r;
    register XkbRowPtr	row;
    register XkbKeyPtr	key;
    
        for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
    	fprintf(file,"static XkbKeyRec keys_s%02dr%02d[]= {\n",section_num,r);
    	for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
    	    fprintf(file,"%s	{ { \"%s\" },	%4d, %4d, %4d }",
    				(k==0?"":",\n"),
    				XkbKeyNameText(key->name.name,XkbCFile),
    				key->gap,key->shape_ndx,key->color_ndx);
    	}
    	fprintf(file,"\n};\n");
        }
        fprintf(file,"static XkbRowRec rows_s%02d[]= {\n",section_num);
        for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
    	fprintf(file,"%s	{ %4d, %4d, %2d, %2d, %1d, keys_s%02dr%02d, ",
    				(r==0?"":",\n"),
    				row->top,row->left,row->num_keys,row->num_keys,
    				(row->vertical!=0),
    				section_num,r);
    	fprintf(file," { %4d, %4d, %4d, %4d } }",
    				row->bounds.x1,row->bounds.y1,
    				row->bounds.x2,row->bounds.y2);
        }
        fprintf(file,"\n};\n");
        return True;
    }
    
    static Bool
    WriteCHdrGeomSections(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom)
    {
    register int		s;
    register XkbSectionPtr	section;
    
        for (s=0,section=geom->sections;s<geom->num_sections;s++,section++) {
    	WriteCHdrGeomRows(file,xkb,section,s);
    #ifdef NOTYET
    	if (section->num_doodads>0)
    	    WriteCHdrGeomDoodads(file,xkb,geom,section,s);
    #endif
    	if (section->num_overlays>0)
    	    WriteCHdrGeomOverlays(file,xkb,section,s);
        }
        fprintf(file,"\nstatic XkbSectionRec g_sections[%d]= {\n",
    							geom->num_sections);
        for (s=0,section=geom->sections;s<geom->num_sections;s++,section++) {
    	if (s!=0) fprintf(file,",\n");
    	fprintf(file,"	{\n	    None, /* name */\n");
    	fprintf(file,"	    %4d, /* priority */\n",section->priority);
    	fprintf(file,"	    %4d, /* top */\n",section->top);
    	fprintf(file,"	    %4d, /* left */\n",section->left);
    	fprintf(file,"	    %4d, /* width */\n",section->width);
    	fprintf(file,"	    %4d, /* height */\n",section->height);
    	fprintf(file,"	    %4d, /* angle */\n",section->angle);
    	fprintf(file,"	    %4d, /* num_rows */\n",section->num_rows);
    	fprintf(file,"	    %4d, /* num_doodads */\n",section->num_doodads);
    	fprintf(file,"	    %4d, /* num_overlays */\n",section->num_overlays);
    	fprintf(file,"	    %4d, /* sz_rows */\n",section->num_rows);
    	fprintf(file,"	    %4d, /* sz_doodads */\n",section->num_doodads);
    	fprintf(file,"	    %4d, /* sz_overlays */\n",section->num_overlays);
    	if (section->num_rows>0)
    	     fprintf(file,"	    rows_s%02d,\n",s);
    	else fprintf(file,"	    NULL, /* rows */\n");
    	if (section->num_doodads>0)
    	     fprintf(file,"	    doodads_s%02d,\n",s);
    	else fprintf(file,"	    NULL, /* doodads */\n");
    	fprintf(file,"	    { %4d, %4d, %4d, %4d }, /* bounds */\n",
    					section->bounds.x1,section->bounds.y1,
    					section->bounds.x2,section->bounds.y2);
    	if (section->num_overlays>0)
    	     fprintf(file,"	    overlays_s%02d\n",s);
    	else fprintf(file,"	    NULL /* overlays */\n");
    	fprintf(file,"	}");
        }
        fprintf(file,"\n};\n");
        fprintf(file,"\nstatic Bool\n");
        fprintf(file,"_InitSections(DPYTYPE dpy,XkbGeometryPtr geom)\n");
        fprintf(file,"{\nXkbSectionPtr	sections;\n\n");
        fprintf(file,"    sections= geom->sections;\n");
        for (s=0,section=geom->sections;s<geom->num_sections;s++,section++) {
    	if (section->num_doodads>0) {
    	    fprintf(file,"    _InitS%02dDoodads(dpy,geom,&sections[%d]);\n",
    									s,s);
    	}
    	if (section->num_overlays>0) {
    	    fprintf(file,"    _InitS%02dOverlays(dpy,geom,&sections[%d]);\n",
    									s,s);
    	}
        }
        fprintf(file,"}\n");
        return True;
    }
    
    static Bool
    WriteCHdrGeomAliases(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom)
    {
        if (geom->num_key_aliases>0) {
    	register int i;
    	fprintf(file,"\nstatic XkbKeyAliasRec g_aliases[%d]= {\n",
    						geom->num_key_aliases);
    	for (i=0;i<geom->num_key_aliases;i++) {
    	    fprintf(file,"%s	{	\"%s\", \"%s\"	}",(i==0?"":",\n"),
    			XkbKeyNameText(geom->key_aliases[i].real,XkbCFile),
    			XkbKeyNameText(geom->key_aliases[i].alias,XkbCFile));
    	}
    	fprintf(file,"\n};\n");
        }
        return True;
    }
    
    static Bool
    WriteCHdrGeometry(FILE *file,XkbDescPtr xkb)
    {
    XkbGeometryPtr	geom;
    register int	i;
    
        if ((!xkb)||(!xkb->geom)) {
    	_XkbLibError(_XkbErrMissingGeometry,"WriteCHdrGeometry",0);
    	return False;
        }
        geom= xkb->geom;
        WriteCHdrGeomProps(file,xkb,geom);
        WriteCHdrGeomColors(file,xkb,geom);
        WriteCHdrGeomShapes(file,xkb,geom);
        WriteCHdrGeomSections(file,xkb,geom);
        WriteCHdrGeomDoodads(file,xkb,geom,NULL,0);
        WriteCHdrGeomAliases(file,xkb,geom);
        fprintf(file,"\nstatic XkbGeometryRec	geom= {\n");
        fprintf(file,"	None,			/* name */\n");
        fprintf(file,"	%d, %d,		/* width, height */\n",geom->width_mm,
    							geom->height_mm);
        if (geom->label_font) {
    	 fprintf(file,"	\"%s\",/* label font */\n",
    				XkbStringText(geom->label_font,XkbCFile));
        }
        else fprintf(file,"	NULL,		/* label font */\n");
        if (geom->label_color) {
    	fprintf(file,"	&g_colors[%d],		/* label color */\n",
    				XkbGeomColorIndex(geom,geom->label_color));
        }
        else fprintf(file,"	NULL,			/* label color */\n");
        if (geom->base_color) {
    	fprintf(file,"	&g_colors[%d],		/* base color */\n",
    				XkbGeomColorIndex(geom,geom->base_color));
        }
        else fprintf(file,"	NULL,			/* base color */\n");
        fprintf(file,"	%d,	%d,	%d,	/*  sz: props, colors, shapes */\n",
    				geom->num_properties,geom->num_colors,
    				geom->num_shapes);
        fprintf(file,"	%d,	%d,	%d,	/*  sz: sections, doodads, aliases */\n",
    				geom->num_sections,geom->num_doodads,
    				geom->num_key_aliases);
        fprintf(file,"	%d,	%d,	%d,	/* num: props, colors, shapes */\n",
    				geom->num_properties,geom->num_colors,
    				geom->num_shapes);
        fprintf(file,"	%d,	%d,	%d,	/* num: sections, doodads, aliases */\n",
    				geom->num_sections,geom->num_doodads,
    				geom->num_key_aliases);
        fprintf(file,"	%s,	%s,	%s,\n",
    				(geom->num_properties>0?"g_props":"NULL"),
    				(geom->num_colors>0?"g_colors":"NULL"),
    				(geom->num_shapes>0?"g_shapes":"NULL"));
        fprintf(file,"	%s,	%s,	%s\n",
    				(geom->num_sections>0?"g_sections":"NULL"),
    				(geom->num_doodads>0?"g_doodads":"NULL"),
    				(geom->num_key_aliases>0?"g_aliases":"NULL"));
        fprintf(file,"};\n\n");
        fprintf(file,"static Bool\n");
        fprintf(file,"_InitHdrGeom(DPYTYPE dpy,XkbGeometryPtr geom)\n");
        fprintf(file,"{\n");
        if (geom->name!=None) {
    	fprintf(file,"    geom->name= GET_ATOM(dpy,\"%s\");\n",
    				XkbAtomText(xkb->dpy,geom->name,XkbCFile));
        }
        for (i=0;i<geom->num_shapes;i++) {
    	fprintf(file,"    geom->shapes[%2d].name= GET_ATOM(dpy,\"%s\");\n",i,
    			XkbAtomText(xkb->dpy,geom->shapes[i].name,XkbCFile));
        }
        if (geom->num_doodads>0)
    	fprintf(file,"    _InitGeomDoodads(dpy,geom);\n");
        fprintf(file,"    _InitSections(dpy,geom);\n");
        fprintf(file,"}\n\n");
        return True;
    }
    
    static Bool
    WriteCHdrGeomFile(FILE *file,XkbFileInfo *result)
    {
    Bool		ok;
    
        ok= WriteCHdrGeometry(file,result->xkb);
        return ok;
    }
    
    static Bool
    WriteCHdrLayout(FILE *file,XkbFileInfo *result)
    {
    Bool		ok;
    XkbDescPtr	xkb;
    
        xkb= result->xkb;
        ok= WriteCHdrVMods(file,xkb->dpy,xkb);
        ok= WriteCHdrKeycodes(file,xkb)&&ok;
        ok= WriteCHdrSymbols(file,xkb)&&ok;
        ok= WriteCHdrGeometry(file,xkb)&&ok;
        return ok;
    }
    
    static Bool
    WriteCHdrSemantics(FILE *file,XkbFileInfo *result)
    {
    Bool		ok;
    XkbDescPtr	xkb;
    
        xkb= result->xkb;
        ok= WriteCHdrVMods(file,xkb->dpy,xkb);
        ok= WriteCHdrKeyTypes(file,xkb->dpy,xkb)&&ok;
        ok= WriteCHdrCompatMap(file,xkb->dpy,xkb)&&ok;
        ok= WriteCHdrIndicators(file,xkb->dpy,xkb)&&ok;
        return ok;
    }
    
    static Bool
    WriteCHdrKeymap(FILE *file,XkbFileInfo *result)
    {
    Bool		ok;
    XkbDescPtr	xkb;
    
        xkb= result->xkb;
        ok= WriteCHdrVMods(file,xkb->dpy,xkb);
        ok= ok&&WriteCHdrKeycodes(file,xkb);
        ok= ok&&WriteCHdrClientMap(file,xkb->dpy,xkb);
        ok= ok&&WriteCHdrServerMap(file,xkb->dpy,xkb);
        ok= ok&&WriteCHdrCompatMap(file,xkb->dpy,xkb);
        ok= WriteCHdrIndicators(file,xkb->dpy,xkb)&&ok;
        ok= ok&&WriteCHdrGeometry(file,xkb);
        return ok;
    }
    
    Bool
    XkbWriteCFile(FILE *out,char *name,XkbFileInfo *result)
    {
    Bool	 		ok;
    XkbDescPtr		xkb;
    Bool			(*func)(
    	FILE *		/* file*/,
    	XkbFileInfo *	/* result */
    );
    
        switch (result->type) {
    	case XkmSemanticsFile:
    	    func= WriteCHdrSemantics;
    	    break;
    	case XkmLayoutFile:
    	    func= WriteCHdrLayout;
    	    break;
    	case XkmKeymapFile:
    	    func= WriteCHdrKeymap;
    	    break;
            case XkmGeometryIndex:
            case XkmGeometryFile:
    	    func= WriteCHdrGeomFile;
    	    break;
    	default:
    	    _XkbLibError(_XkbErrIllegalContents,"XkbWriteCFile",result->type);
    	    return False;
        }
        xkb= result->xkb;
        if (out==NULL) {
    	_XkbLibError(_XkbErrFileCannotOpen,"XkbWriteCFile",0);
    	ok= False;
        }
        else {
    	char *tmp,*hdrdef;
    	tmp= (char *)strrchr(name,'/');
    	if (tmp==NULL)
    	     tmp= name;
    	else tmp++;
    	hdrdef= (char *)_XkbCalloc(strlen(tmp)+1,sizeof(char));
    	if (hdrdef) {
    	    strcpy(hdrdef,tmp);
    	    tmp= hdrdef;
    	    while (*tmp) {
    		if (islower(*tmp))		*tmp= toupper(*tmp);
    		else if (!isalnum(*tmp))	*tmp= '_';
    		tmp++;
    	    }
    	    fprintf(out,"/* This file generated automatically by xkbcomp */\n");
    	    fprintf(out,"/* DO  NOT EDIT */\n");
    	    fprintf(out,"#ifndef %s\n",hdrdef);
    	    fprintf(out,"#define %s 1\n\n",hdrdef);
    	}
    	fprintf(out,"#ifndef XKB_IN_SERVER\n");
    	fprintf(out,"#define GET_ATOM(d,s)	XInternAtom(d,s,0)\n");
    	fprintf(out,"#define DPYTYPE	Display *\n");
    	fprintf(out,"#else\n");
    	fprintf(out,"#define GET_ATOM(d,s)	MakeAtom(s,strlen(s),1)\n");
    	fprintf(out,"#define DPYTYPE	char *\n");
    	fprintf(out,"#endif\n");
    	fprintf(out,"#define NUM_KEYS	%d\n",xkb->max_key_code+1);
    	ok= (*func)(out,result);
    	if (hdrdef)
    	    fprintf(out,"#endif /* %s */\n",hdrdef);
        }
    
        if (!ok) {
    	return False;
        }
        return True;
    }