1388 lines
38 KiB
C
1388 lines
38 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_CONFIG_H
|
||
|
#include <config.h>
|
||
|
#endif
|
||
|
#include <stdio.h>
|
||
|
#include <ctype.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <X11/Xfuncs.h>
|
||
|
#include <X11/Xlib.h>
|
||
|
#include <X11/XKBlib.h>
|
||
|
#include <X11/extensions/XKBgeom.h>
|
||
|
|
||
|
#include "XKMformat.h"
|
||
|
#include "XKBfileInt.h"
|
||
|
|
||
|
typedef struct _XkmInfo {
|
||
|
unsigned short bound_vmods;
|
||
|
unsigned short named_vmods;
|
||
|
unsigned char num_bound;
|
||
|
unsigned char group_compat;
|
||
|
unsigned short num_group_compat;
|
||
|
unsigned short num_leds;
|
||
|
int total_vmodmaps;
|
||
|
} XkmInfo;
|
||
|
|
||
|
/***====================================================================***/
|
||
|
|
||
|
#define xkmPutCARD8(f,v) (putc(v,f),1)
|
||
|
|
||
|
static int
|
||
|
xkmPutCARD16(FILE *file,unsigned val)
|
||
|
{
|
||
|
CARD16 tmp= val;
|
||
|
|
||
|
fwrite(&tmp,2,1,file);
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
xkmPutCARD32(FILE *file,unsigned long val)
|
||
|
{
|
||
|
CARD32 tmp= val;
|
||
|
|
||
|
fwrite(&tmp,4,1,file);
|
||
|
return 4;
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
xkmPutPadding(FILE *file,unsigned pad)
|
||
|
{
|
||
|
int i;
|
||
|
for (i=0;i<pad;i++) {
|
||
|
putc('\0',file);
|
||
|
}
|
||
|
return pad;
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
xkmPutCountedBytes(FILE *file,char *ptr,unsigned count)
|
||
|
{
|
||
|
register int nOut;
|
||
|
register unsigned pad;
|
||
|
|
||
|
if (count==0)
|
||
|
return xkmPutCARD32(file,(unsigned long)0);
|
||
|
|
||
|
xkmPutCARD16(file,count);
|
||
|
nOut= fwrite(ptr,1,count,file);
|
||
|
if (nOut<0)
|
||
|
return 2;
|
||
|
nOut= count+2;
|
||
|
pad= XkbPaddedSize(nOut)-nOut;
|
||
|
if (pad)
|
||
|
xkmPutPadding(file,pad);
|
||
|
return nOut+pad;
|
||
|
}
|
||
|
|
||
|
static unsigned
|
||
|
xkmSizeCountedString(char *str)
|
||
|
{
|
||
|
if (str==NULL)
|
||
|
return 4;
|
||
|
return XkbPaddedSize(strlen(str)+2);
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
xkmPutCountedString(FILE *file,char *str)
|
||
|
{
|
||
|
if (str==NULL)
|
||
|
return xkmPutCARD32(file,(unsigned long)0);
|
||
|
return xkmPutCountedBytes(file,str,strlen(str));
|
||
|
}
|
||
|
|
||
|
#define xkmSizeCountedAtomString(d,a) \
|
||
|
xkmSizeCountedString(XkbAtomGetString((d),(a)))
|
||
|
|
||
|
#define xkmPutCountedAtomString(d,f,a) \
|
||
|
xkmPutCountedString((f),XkbAtomGetString((d),(a)))
|
||
|
|
||
|
/***====================================================================***/
|
||
|
|
||
|
static unsigned
|
||
|
SizeXKMVirtualMods( XkbFileInfo * result,
|
||
|
XkmInfo * info,
|
||
|
xkmSectionInfo * toc,
|
||
|
int * offset_inout)
|
||
|
{
|
||
|
Display * dpy;
|
||
|
XkbDescPtr xkb;
|
||
|
unsigned nBound,bound;
|
||
|
unsigned nNamed,named,szNames;
|
||
|
register unsigned i,bit;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
if ((!xkb)||(!xkb->names)||(!xkb->server)) {
|
||
|
_XkbLibError(_XkbErrMissingVMods,"SizeXKMVirtualMods",0);
|
||
|
return 0;
|
||
|
}
|
||
|
bound=named=0;
|
||
|
for (i=nBound=nNamed=szNames=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
|
||
|
if (xkb->server->vmods[i]!=XkbNoModifierMask) {
|
||
|
bound|= bit;
|
||
|
nBound++;
|
||
|
}
|
||
|
if (xkb->names->vmods[i]!=None) {
|
||
|
named|= bit;
|
||
|
szNames+= xkmSizeCountedAtomString(dpy,xkb->names->vmods[i]);
|
||
|
nNamed++;
|
||
|
}
|
||
|
}
|
||
|
info->num_bound= nBound;
|
||
|
info->bound_vmods= bound;
|
||
|
info->named_vmods= named;
|
||
|
if ((nBound==0)&&(nNamed==0))
|
||
|
return 0;
|
||
|
toc->type= XkmVirtualModsIndex;
|
||
|
toc->format= MSBFirst;
|
||
|
toc->size= 4+XkbPaddedSize(nBound)+szNames+SIZEOF(xkmSectionInfo);
|
||
|
toc->offset= *offset_inout;
|
||
|
(*offset_inout)+= toc->size;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static unsigned
|
||
|
WriteXKMVirtualMods(FILE *file,XkbFileInfo *result,XkmInfo *info)
|
||
|
{
|
||
|
register unsigned int i,bit;
|
||
|
XkbDescPtr xkb;
|
||
|
Display * dpy;
|
||
|
unsigned size= 0;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
size+= xkmPutCARD16(file,info->bound_vmods);
|
||
|
size+= xkmPutCARD16(file,info->named_vmods);
|
||
|
for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
|
||
|
if (info->bound_vmods&bit)
|
||
|
size+= xkmPutCARD8(file,xkb->server->vmods[i]);
|
||
|
}
|
||
|
if ((i= XkbPaddedSize(info->num_bound)-info->num_bound)>0)
|
||
|
size+= xkmPutPadding(file,i);
|
||
|
for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
|
||
|
if (info->named_vmods&bit) {
|
||
|
register char *name;
|
||
|
name= XkbAtomGetString(dpy,xkb->names->vmods[i]);
|
||
|
size+= xkmPutCountedString(file,name);
|
||
|
}
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
/***====================================================================***/
|
||
|
|
||
|
static unsigned
|
||
|
SizeXKMKeycodes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout)
|
||
|
{
|
||
|
XkbDescPtr xkb;
|
||
|
Atom kcName;
|
||
|
int size=0;
|
||
|
Display * dpy;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) {
|
||
|
_XkbLibError(_XkbErrMissingNames,"SizeXKMKeycodes",0);
|
||
|
return 0;
|
||
|
}
|
||
|
kcName= xkb->names->keycodes;
|
||
|
size+= 4; /* min and max keycode */
|
||
|
size+= xkmSizeCountedAtomString(dpy,kcName);
|
||
|
size+= XkbNumKeys(xkb)*sizeof(XkbKeyNameRec);
|
||
|
if (xkb->names->num_key_aliases>0) {
|
||
|
if (xkb->names->key_aliases!=NULL)
|
||
|
size+= xkb->names->num_key_aliases*sizeof(XkbKeyAliasRec);
|
||
|
else xkb->names->num_key_aliases= 0;
|
||
|
}
|
||
|
toc->type= XkmKeyNamesIndex;
|
||
|
toc->format= MSBFirst;
|
||
|
toc->size= size+SIZEOF(xkmSectionInfo);
|
||
|
toc->offset= (*offset_inout);
|
||
|
(*offset_inout)+= toc->size;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static unsigned
|
||
|
WriteXKMKeycodes(FILE *file,XkbFileInfo *result)
|
||
|
{
|
||
|
XkbDescPtr xkb;
|
||
|
Atom kcName;
|
||
|
char *start;
|
||
|
Display * dpy;
|
||
|
unsigned tmp,size= 0;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
kcName= xkb->names->keycodes;
|
||
|
start= xkb->names->keys[xkb->min_key_code].name;
|
||
|
|
||
|
size+= xkmPutCountedString(file,XkbAtomGetString(dpy,kcName));
|
||
|
size+= xkmPutCARD8(file,xkb->min_key_code);
|
||
|
size+= xkmPutCARD8(file,xkb->max_key_code);
|
||
|
size+= xkmPutCARD8(file,xkb->names->num_key_aliases);
|
||
|
size+= xkmPutPadding(file,1);
|
||
|
tmp= fwrite(start,sizeof(XkbKeyNameRec),XkbNumKeys(xkb),file);
|
||
|
size+= tmp*sizeof(XkbKeyNameRec);
|
||
|
if (xkb->names->num_key_aliases>0) {
|
||
|
tmp= fwrite((char *)xkb->names->key_aliases,
|
||
|
sizeof(XkbKeyAliasRec),xkb->names->num_key_aliases,
|
||
|
file);
|
||
|
size+= tmp*sizeof(XkbKeyAliasRec);
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
/***====================================================================***/
|
||
|
|
||
|
static unsigned
|
||
|
SizeXKMKeyTypes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout)
|
||
|
{
|
||
|
register unsigned i,n,size;
|
||
|
XkbKeyTypePtr type;
|
||
|
XkbDescPtr xkb;
|
||
|
Display * dpy;
|
||
|
char * name;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
if ((!xkb)||(!xkb->map)||(!xkb->map->types)) {
|
||
|
_XkbLibError(_XkbErrMissingTypes,"SizeXKBKeyTypes",0);
|
||
|
return 0;
|
||
|
}
|
||
|
if (xkb->map->num_types<XkbNumRequiredTypes) {
|
||
|
_XkbLibError(_XkbErrMissingReqTypes,"SizeXKBKeyTypes",0);
|
||
|
return 0;
|
||
|
}
|
||
|
if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->types);
|
||
|
else name= NULL;
|
||
|
size= xkmSizeCountedString(name);
|
||
|
size+= 4; /* room for # of key types + padding */
|
||
|
for (i=0,type=xkb->map->types;i<xkb->map->num_types;i++,type++) {
|
||
|
size+= SIZEOF(xkmKeyTypeDesc);
|
||
|
size+= SIZEOF(xkmKTMapEntryDesc)*type->map_count;
|
||
|
size+= xkmSizeCountedAtomString(dpy,type->name);
|
||
|
if (type->preserve)
|
||
|
size+= SIZEOF(xkmModsDesc)*type->map_count;
|
||
|
if (type->level_names) {
|
||
|
Atom *names;
|
||
|
names= type->level_names;
|
||
|
for (n=0;n<(unsigned)type->num_levels;n++) {
|
||
|
size+= xkmSizeCountedAtomString(dpy,names[n]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
toc->type= XkmTypesIndex;
|
||
|
toc->format= MSBFirst;
|
||
|
toc->size= size+SIZEOF(xkmSectionInfo);
|
||
|
toc->offset= (*offset_inout);
|
||
|
(*offset_inout)+= toc->size;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static unsigned
|
||
|
WriteXKMKeyTypes(FILE *file,XkbFileInfo *result)
|
||
|
{
|
||
|
register unsigned i,n;
|
||
|
XkbDescPtr xkb;
|
||
|
XkbKeyTypePtr type;
|
||
|
xkmKeyTypeDesc wire;
|
||
|
XkbKTMapEntryPtr entry;
|
||
|
xkmKTMapEntryDesc wire_entry;
|
||
|
Atom * names;
|
||
|
Display * dpy;
|
||
|
unsigned tmp,size= 0;
|
||
|
char * name;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->types);
|
||
|
else name= NULL;
|
||
|
size+= xkmPutCountedString(file,name);
|
||
|
size+= xkmPutCARD16(file,xkb->map->num_types);
|
||
|
size+= xkmPutPadding(file,2);
|
||
|
type= xkb->map->types;
|
||
|
for (i=0;i<xkb->map->num_types;i++,type++) {
|
||
|
wire.realMods= type->mods.real_mods;
|
||
|
wire.virtualMods= type->mods.vmods;
|
||
|
wire.numLevels= type->num_levels;
|
||
|
wire.nMapEntries= type->map_count;
|
||
|
wire.preserve= (type->preserve!=NULL);
|
||
|
if (type->level_names!=NULL)
|
||
|
wire.nLevelNames= type->num_levels;
|
||
|
else wire.nLevelNames= 0;
|
||
|
tmp= fwrite(&wire,SIZEOF(xkmKeyTypeDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmKeyTypeDesc);
|
||
|
for (n=0,entry= type->map;n<type->map_count;n++,entry++) {
|
||
|
wire_entry.level= entry->level;
|
||
|
wire_entry.realMods= entry->mods.real_mods;
|
||
|
wire_entry.virtualMods= entry->mods.vmods;
|
||
|
tmp= fwrite(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmKTMapEntryDesc);
|
||
|
}
|
||
|
size+= xkmPutCountedString(file,XkbAtomGetString(dpy,type->name));
|
||
|
if (type->preserve) {
|
||
|
xkmModsDesc p_entry;
|
||
|
XkbModsPtr pre;
|
||
|
for (n=0,pre=type->preserve;n<type->map_count;n++,pre++) {
|
||
|
p_entry.realMods= pre->real_mods;
|
||
|
p_entry.virtualMods= pre->vmods;
|
||
|
tmp= fwrite(&p_entry,SIZEOF(xkmModsDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmModsDesc);
|
||
|
}
|
||
|
}
|
||
|
if (type->level_names!=NULL) {
|
||
|
names= type->level_names;
|
||
|
for (n=0;n<wire.nLevelNames;n++) {
|
||
|
size+= xkmPutCountedString(file,XkbAtomGetString(dpy,names[n]));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
/***====================================================================***/
|
||
|
|
||
|
static unsigned
|
||
|
SizeXKMCompatMap( XkbFileInfo * result,
|
||
|
XkmInfo * info,
|
||
|
xkmSectionInfo * toc,
|
||
|
int * offset_inout)
|
||
|
{
|
||
|
XkbDescPtr xkb;
|
||
|
char * name;
|
||
|
int size;
|
||
|
register int i;
|
||
|
unsigned groups,nGroups;
|
||
|
Display * dpy;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) {
|
||
|
_XkbLibError(_XkbErrMissingCompatMap,"SizeXKMCompatMap",0);
|
||
|
return 0;
|
||
|
}
|
||
|
if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->compat);
|
||
|
else name= NULL;
|
||
|
|
||
|
for (i=groups=nGroups=0;i<XkbNumKbdGroups;i++) {
|
||
|
if ((xkb->compat->groups[i].real_mods!=0)||
|
||
|
(xkb->compat->groups[i].vmods!=0)) {
|
||
|
groups|= (1<<i);
|
||
|
nGroups++;
|
||
|
}
|
||
|
}
|
||
|
info->group_compat= groups;
|
||
|
info->num_group_compat= nGroups;
|
||
|
size= 4; /* room for num_si and group_compat mask */
|
||
|
size+= xkmSizeCountedString(name);
|
||
|
size+= (SIZEOF(xkmSymInterpretDesc)*xkb->compat->num_si);
|
||
|
size+= (SIZEOF(xkmModsDesc)*nGroups);
|
||
|
toc->type= XkmCompatMapIndex;
|
||
|
toc->format= MSBFirst;
|
||
|
toc->size= size+SIZEOF(xkmSectionInfo);
|
||
|
toc->offset= (*offset_inout);
|
||
|
(*offset_inout)+= toc->size;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static unsigned
|
||
|
WriteXKMCompatMap(FILE *file,XkbFileInfo *result,XkmInfo *info)
|
||
|
{
|
||
|
register unsigned i;
|
||
|
char * name;
|
||
|
XkbDescPtr xkb;
|
||
|
XkbSymInterpretPtr interp;
|
||
|
xkmSymInterpretDesc wire;
|
||
|
Display * dpy;
|
||
|
unsigned tmp,size=0;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->compat);
|
||
|
else name= NULL;
|
||
|
size+= xkmPutCountedString(file,name);
|
||
|
size+= xkmPutCARD16(file,xkb->compat->num_si);
|
||
|
size+= xkmPutCARD8(file,info->group_compat);
|
||
|
size+= xkmPutPadding(file,1);
|
||
|
interp= xkb->compat->sym_interpret;
|
||
|
for (i=0;i<xkb->compat->num_si;i++,interp++) {
|
||
|
wire.sym= interp->sym;
|
||
|
wire.mods= interp->mods;
|
||
|
wire.match= interp->match;
|
||
|
wire.virtualMod= interp->virtual_mod;
|
||
|
wire.flags= interp->flags;
|
||
|
wire.actionType= interp->act.type;
|
||
|
wire.actionData[0]= interp->act.data[0];
|
||
|
wire.actionData[1]= interp->act.data[1];
|
||
|
wire.actionData[2]= interp->act.data[2];
|
||
|
wire.actionData[3]= interp->act.data[3];
|
||
|
wire.actionData[4]= interp->act.data[4];
|
||
|
wire.actionData[5]= interp->act.data[5];
|
||
|
wire.actionData[6]= interp->act.data[6];
|
||
|
tmp= fwrite(&wire,SIZEOF(xkmSymInterpretDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmSymInterpretDesc);
|
||
|
}
|
||
|
if (info->group_compat) {
|
||
|
register unsigned bit;
|
||
|
xkmModsDesc modsWire;
|
||
|
for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
|
||
|
if (info->group_compat&bit) {
|
||
|
modsWire.realMods= xkb->compat->groups[i].real_mods;
|
||
|
modsWire.virtualMods= xkb->compat->groups[i].vmods;
|
||
|
fwrite(&modsWire,SIZEOF(xkmModsDesc),1,file);
|
||
|
size+= SIZEOF(xkmModsDesc);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
/***====================================================================***/
|
||
|
|
||
|
static unsigned
|
||
|
SizeXKMSymbols( XkbFileInfo * result,
|
||
|
XkmInfo * info,
|
||
|
xkmSectionInfo * toc,
|
||
|
int * offset_inout)
|
||
|
{
|
||
|
Display * dpy;
|
||
|
XkbDescPtr xkb;
|
||
|
unsigned size;
|
||
|
register int i,nSyms;
|
||
|
char * name;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
if ((!xkb)||(!xkb->map)||((!xkb->map->syms))) {
|
||
|
_XkbLibError(_XkbErrMissingSymbols,"SizeXKMSymbols",0);
|
||
|
return 0;
|
||
|
}
|
||
|
if (xkb->names && (xkb->names->symbols!=None))
|
||
|
name= XkbAtomGetString(dpy,xkb->names->symbols);
|
||
|
else name= NULL;
|
||
|
size= xkmSizeCountedString(name);
|
||
|
size+= 4; /* min and max keycode, group names mask */
|
||
|
for (i=0;i<XkbNumKbdGroups;i++) {
|
||
|
if (xkb->names->groups[i]!=None)
|
||
|
size+= xkmSizeCountedAtomString(dpy,xkb->names->groups[i]);
|
||
|
}
|
||
|
info->total_vmodmaps= 0;
|
||
|
for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
|
||
|
nSyms= XkbKeyNumSyms(xkb,i);
|
||
|
size+= SIZEOF(xkmKeySymMapDesc)+(nSyms*4);
|
||
|
if (xkb->server) {
|
||
|
if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) {
|
||
|
register int g;
|
||
|
for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) {
|
||
|
if (xkb->server->explicit[i]&(1<<g)) {
|
||
|
XkbKeyTypePtr type;
|
||
|
char * name;
|
||
|
type= XkbKeyKeyType(xkb,i,g);
|
||
|
name= XkbAtomGetString(dpy,type->name);
|
||
|
if (name!=NULL)
|
||
|
size+= xkmSizeCountedString(name);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (XkbKeyHasActions(xkb,i))
|
||
|
size+= nSyms*SIZEOF(xkmActionDesc);
|
||
|
if (xkb->server->behaviors[i].type!=XkbKB_Default)
|
||
|
size+= SIZEOF(xkmBehaviorDesc);
|
||
|
if (xkb->server->vmodmap && (xkb->server->vmodmap[i]!=0))
|
||
|
info->total_vmodmaps++;
|
||
|
}
|
||
|
}
|
||
|
size+= info->total_vmodmaps*SIZEOF(xkmVModMapDesc);
|
||
|
toc->type= XkmSymbolsIndex;
|
||
|
toc->format= MSBFirst;
|
||
|
toc->size= size+SIZEOF(xkmSectionInfo);
|
||
|
toc->offset= (*offset_inout);
|
||
|
(*offset_inout)+= toc->size;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static unsigned
|
||
|
WriteXKMSymbols(FILE *file,XkbFileInfo *result,XkmInfo *info)
|
||
|
{
|
||
|
Display * dpy;
|
||
|
XkbDescPtr xkb;
|
||
|
register int i,n;
|
||
|
xkmKeySymMapDesc wireMap;
|
||
|
char * name;
|
||
|
unsigned tmp,size= 0;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
if (xkb->names && (xkb->names->symbols!=None))
|
||
|
name= XkbAtomGetString(dpy,xkb->names->symbols);
|
||
|
else name= NULL;
|
||
|
size+= xkmPutCountedString(file,name);
|
||
|
for (tmp=i=0;i<XkbNumKbdGroups;i++) {
|
||
|
if (xkb->names->groups[i]!=None)
|
||
|
tmp|= (1<<i);
|
||
|
}
|
||
|
size+= xkmPutCARD8(file,xkb->min_key_code);
|
||
|
size+= xkmPutCARD8(file,xkb->max_key_code);
|
||
|
size+= xkmPutCARD8(file,tmp);
|
||
|
size+= xkmPutCARD8(file,info->total_vmodmaps);
|
||
|
for (i=0,n=1;i<XkbNumKbdGroups;i++,n<<=1) {
|
||
|
if ((tmp&n)==0)
|
||
|
continue;
|
||
|
size+= xkmPutCountedAtomString(dpy,file,xkb->names->groups[i]);
|
||
|
}
|
||
|
for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
|
||
|
char *typeName[XkbNumKbdGroups];
|
||
|
wireMap.width= XkbKeyGroupsWidth(xkb,i);
|
||
|
wireMap.num_groups= XkbKeyGroupInfo(xkb,i);
|
||
|
if (xkb->map && xkb->map->modmap)
|
||
|
wireMap.modifier_map= xkb->map->modmap[i];
|
||
|
else wireMap.modifier_map= 0;
|
||
|
wireMap.flags= 0;
|
||
|
bzero((char *)typeName,XkbNumKbdGroups*sizeof(char *));
|
||
|
if (xkb->server) {
|
||
|
if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) {
|
||
|
register int g;
|
||
|
for (g=0;g<XkbKeyNumGroups(xkb,i);g++) {
|
||
|
if (xkb->server->explicit[i]&(1<<g)) {
|
||
|
XkbKeyTypePtr type;
|
||
|
type= XkbKeyKeyType(xkb,i,g);
|
||
|
typeName[g]= XkbAtomGetString(dpy,type->name);
|
||
|
if (typeName[g]!=NULL)
|
||
|
wireMap.flags|= (1<<g);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (XkbKeyHasActions(xkb,i))
|
||
|
wireMap.flags|= XkmKeyHasActions;
|
||
|
if (xkb->server->behaviors[i].type!=XkbKB_Default)
|
||
|
wireMap.flags|= XkmKeyHasBehavior;
|
||
|
if ((xkb->server->explicit[i]&XkbExplicitAutoRepeatMask)&&
|
||
|
(xkb->ctrls!=NULL)) {
|
||
|
if (xkb->ctrls->per_key_repeat[(i/8)]&(1<<(i%8)))
|
||
|
wireMap.flags|= XkmRepeatingKey;
|
||
|
else wireMap.flags|= XkmNonRepeatingKey;
|
||
|
}
|
||
|
}
|
||
|
tmp= fwrite(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmKeySymMapDesc);
|
||
|
if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) {
|
||
|
register int g;
|
||
|
for (g=0;g<XkbNumKbdGroups;g++) {
|
||
|
if (typeName[g]!=NULL)
|
||
|
size+= xkmPutCountedString(file,typeName[g]);
|
||
|
}
|
||
|
}
|
||
|
if (XkbNumGroups(wireMap.num_groups)>0) {
|
||
|
KeySym *sym;
|
||
|
sym= XkbKeySymsPtr(xkb,i);
|
||
|
for (n=XkbKeyNumSyms(xkb,i);n>0;n--,sym++) {
|
||
|
size+= xkmPutCARD32(file,(CARD32)*sym);
|
||
|
}
|
||
|
if (wireMap.flags&XkmKeyHasActions) {
|
||
|
XkbAction * act;
|
||
|
act= XkbKeyActionsPtr(xkb,i);
|
||
|
for (n=XkbKeyNumActions(xkb,i);n>0;n--,act++) {
|
||
|
tmp= fwrite(act,SIZEOF(xkmActionDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmActionDesc);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (wireMap.flags&XkmKeyHasBehavior) {
|
||
|
xkmBehaviorDesc b;
|
||
|
b.type= xkb->server->behaviors[i].type;
|
||
|
b.data= xkb->server->behaviors[i].data;
|
||
|
tmp= fwrite(&b,SIZEOF(xkmBehaviorDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmBehaviorDesc);
|
||
|
}
|
||
|
}
|
||
|
if (info->total_vmodmaps>0) {
|
||
|
xkmVModMapDesc v;
|
||
|
for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
|
||
|
if (xkb->server->vmodmap[i]!=0) {
|
||
|
v.key= i;
|
||
|
v.vmods= xkb->server->vmodmap[i];
|
||
|
tmp= fwrite(&v,SIZEOF(xkmVModMapDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmVModMapDesc);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
/***====================================================================***/
|
||
|
|
||
|
static unsigned
|
||
|
SizeXKMIndicators(XkbFileInfo *result,XkmInfo *info,xkmSectionInfo *toc,
|
||
|
int *offset_inout)
|
||
|
{
|
||
|
Display * dpy;
|
||
|
XkbDescPtr xkb;
|
||
|
unsigned size;
|
||
|
register unsigned i,nLEDs;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
if ((xkb==NULL)||(xkb->indicators==NULL)) {
|
||
|
/* _XkbLibError(_XkbErrMissingIndicators,"SizeXKMIndicators",0);*/
|
||
|
return 0;
|
||
|
}
|
||
|
nLEDs=0;
|
||
|
size= 8; /* number of indicator maps/physical indicators */
|
||
|
if (xkb->indicators!=NULL) {
|
||
|
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) ||
|
||
|
(xkb->names && (xkb->names->indicators[i]!=None))) {
|
||
|
char *name;
|
||
|
if (xkb->names && xkb->names->indicators[i]!=None) {
|
||
|
name= XkbAtomGetString(dpy,xkb->names->indicators[i]);
|
||
|
}
|
||
|
else name= NULL;
|
||
|
size+= xkmSizeCountedString(name);
|
||
|
size+= SIZEOF(xkmIndicatorMapDesc);
|
||
|
nLEDs++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
info->num_leds= nLEDs;
|
||
|
toc->type= XkmIndicatorsIndex;
|
||
|
toc->format= MSBFirst;
|
||
|
toc->size= size+SIZEOF(xkmSectionInfo);
|
||
|
toc->offset= (*offset_inout);
|
||
|
(*offset_inout)+= toc->size;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static unsigned
|
||
|
WriteXKMIndicators(FILE *file,XkbFileInfo *result,XkmInfo *info)
|
||
|
{
|
||
|
Display * dpy;
|
||
|
XkbDescPtr xkb;
|
||
|
register unsigned i;
|
||
|
xkmIndicatorMapDesc wire;
|
||
|
unsigned tmp,size= 0;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
size+= xkmPutCARD8(file,info->num_leds);
|
||
|
size+= xkmPutPadding(file,3);
|
||
|
size+= xkmPutCARD32(file,xkb->indicators->phys_indicators);
|
||
|
if (xkb->indicators!=NULL) {
|
||
|
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) ||
|
||
|
(xkb->names && (xkb->names->indicators[i]!=None))) {
|
||
|
char *name;
|
||
|
if (xkb->names && xkb->names->indicators[i]!=None) {
|
||
|
name= XkbAtomGetString(dpy,xkb->names->indicators[i]);
|
||
|
}
|
||
|
else name= NULL;
|
||
|
size+= xkmPutCountedString(file,name);
|
||
|
wire.indicator= i+1;
|
||
|
wire.flags= map->flags;
|
||
|
wire.which_mods= map->which_mods;
|
||
|
wire.real_mods= map->mods.real_mods;
|
||
|
wire.vmods= map->mods.vmods;
|
||
|
wire.which_groups= map->which_groups;
|
||
|
wire.groups= map->groups;
|
||
|
wire.ctrls= map->ctrls;
|
||
|
tmp= fwrite(&wire,SIZEOF(xkmIndicatorMapDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmIndicatorMapDesc);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
/***====================================================================***/
|
||
|
|
||
|
static unsigned
|
||
|
SizeXKMGeomDoodad(XkbFileInfo *result,XkbDoodadPtr doodad)
|
||
|
{
|
||
|
unsigned size;
|
||
|
|
||
|
size= SIZEOF(xkmAnyDoodadDesc);
|
||
|
size+= xkmSizeCountedAtomString(result->xkb->dpy,doodad->any.name);
|
||
|
if (doodad->any.type==XkbTextDoodad) {
|
||
|
size+= xkmSizeCountedString(doodad->text.text);
|
||
|
size+= xkmSizeCountedString(doodad->text.font);
|
||
|
}
|
||
|
else if (doodad->any.type==XkbLogoDoodad) {
|
||
|
size+= xkmSizeCountedString(doodad->logo.logo_name);
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
static unsigned
|
||
|
SizeXKMGeomSection(XkbFileInfo *result,XkbSectionPtr section)
|
||
|
{
|
||
|
register int i;
|
||
|
unsigned size;
|
||
|
|
||
|
size= SIZEOF(xkmSectionDesc);
|
||
|
size+= xkmSizeCountedAtomString(result->xkb->dpy,section->name);
|
||
|
if (section->rows) {
|
||
|
XkbRowPtr row;
|
||
|
for (row=section->rows,i=0;i<section->num_rows;i++,row++) {
|
||
|
size+= SIZEOF(xkmRowDesc);
|
||
|
size+= row->num_keys*SIZEOF(xkmKeyDesc);
|
||
|
}
|
||
|
}
|
||
|
if (section->doodads) {
|
||
|
XkbDoodadPtr doodad;
|
||
|
for (doodad=section->doodads,i=0;i<section->num_doodads;i++,doodad++) {
|
||
|
size+= SizeXKMGeomDoodad(result,doodad);
|
||
|
}
|
||
|
}
|
||
|
if (section->overlays) {
|
||
|
XkbOverlayPtr ol;
|
||
|
for (ol=section->overlays,i=0;i<section->num_overlays;i++,ol++) {
|
||
|
register int r;
|
||
|
XkbOverlayRowPtr row;
|
||
|
size+= xkmSizeCountedAtomString(result->xkb->dpy,ol->name);
|
||
|
size+= SIZEOF(xkmOverlayDesc);
|
||
|
for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
|
||
|
size+= SIZEOF(xkmOverlayRowDesc);
|
||
|
size+= row->num_keys*SIZEOF(xkmOverlayKeyDesc);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
static unsigned
|
||
|
SizeXKMGeometry(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout)
|
||
|
{
|
||
|
register int i;
|
||
|
Display * dpy;
|
||
|
XkbDescPtr xkb;
|
||
|
XkbGeometryPtr geom;
|
||
|
unsigned size;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
if ((!xkb)||(!xkb->geom))
|
||
|
return 0;
|
||
|
geom= xkb->geom;
|
||
|
size= xkmSizeCountedAtomString(dpy,geom->name);
|
||
|
size+= SIZEOF(xkmGeometryDesc);
|
||
|
size+= xkmSizeCountedString(geom->label_font);
|
||
|
if (geom->properties) {
|
||
|
XkbPropertyPtr prop;
|
||
|
for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
|
||
|
size+= xkmSizeCountedString(prop->name);
|
||
|
size+= xkmSizeCountedString(prop->value);
|
||
|
}
|
||
|
}
|
||
|
if (geom->colors) {
|
||
|
XkbColorPtr color;
|
||
|
for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
|
||
|
size+= xkmSizeCountedString(color->spec);
|
||
|
}
|
||
|
}
|
||
|
if (geom->shapes) {
|
||
|
XkbShapePtr shape;
|
||
|
for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
|
||
|
register int n;
|
||
|
register XkbOutlinePtr ol;
|
||
|
size+= xkmSizeCountedAtomString(dpy,shape->name);
|
||
|
size+= SIZEOF(xkmShapeDesc);
|
||
|
for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) {
|
||
|
size+= SIZEOF(xkmOutlineDesc);
|
||
|
size+= ol->num_points*SIZEOF(xkmPointDesc);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (geom->sections) {
|
||
|
XkbSectionPtr section;
|
||
|
for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
|
||
|
size+= SizeXKMGeomSection(result,section);
|
||
|
}
|
||
|
}
|
||
|
if (geom->doodads) {
|
||
|
XkbDoodadPtr doodad;
|
||
|
for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) {
|
||
|
size+= SizeXKMGeomDoodad(result,doodad);
|
||
|
}
|
||
|
}
|
||
|
if (geom->key_aliases) {
|
||
|
size+= geom->num_key_aliases*(XkbKeyNameLength*2);
|
||
|
}
|
||
|
toc->type= XkmGeometryIndex;
|
||
|
toc->format= MSBFirst;
|
||
|
toc->size= size+SIZEOF(xkmSectionInfo);
|
||
|
toc->offset= (*offset_inout);
|
||
|
(*offset_inout)+= toc->size;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static unsigned
|
||
|
WriteXKMGeomDoodad(FILE *file,XkbFileInfo *result,XkbDoodadPtr doodad)
|
||
|
{
|
||
|
Display * dpy;
|
||
|
XkbDescPtr xkb;
|
||
|
xkmDoodadDesc doodadWire;
|
||
|
unsigned tmp,size= 0;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
bzero((char *)&doodadWire,sizeof(doodadWire));
|
||
|
doodadWire.any.type= doodad->any.type;
|
||
|
doodadWire.any.priority= doodad->any.priority;
|
||
|
doodadWire.any.top= doodad->any.top;
|
||
|
doodadWire.any.left= doodad->any.left;
|
||
|
switch (doodad->any.type) {
|
||
|
case XkbOutlineDoodad:
|
||
|
case XkbSolidDoodad:
|
||
|
doodadWire.shape.angle= doodad->shape.angle;
|
||
|
doodadWire.shape.color_ndx= doodad->shape.color_ndx;
|
||
|
doodadWire.shape.shape_ndx= doodad->shape.shape_ndx;
|
||
|
break;
|
||
|
case XkbTextDoodad:
|
||
|
doodadWire.text.angle= doodad->text.angle;
|
||
|
doodadWire.text.width= doodad->text.width;
|
||
|
doodadWire.text.height= doodad->text.height;
|
||
|
doodadWire.text.color_ndx= doodad->text.color_ndx;
|
||
|
break;
|
||
|
case XkbIndicatorDoodad:
|
||
|
doodadWire.indicator.shape_ndx= doodad->indicator.shape_ndx;
|
||
|
doodadWire.indicator.on_color_ndx= doodad->indicator.on_color_ndx;
|
||
|
doodadWire.indicator.off_color_ndx= doodad->indicator.off_color_ndx;
|
||
|
break;
|
||
|
case XkbLogoDoodad:
|
||
|
doodadWire.logo.angle= doodad->logo.angle;
|
||
|
doodadWire.logo.color_ndx= doodad->logo.color_ndx;
|
||
|
doodadWire.logo.shape_ndx= doodad->logo.shape_ndx;
|
||
|
break;
|
||
|
default:
|
||
|
_XkbLibError(_XkbErrIllegalDoodad,"WriteXKMGeomDoodad",
|
||
|
doodad->any.type);
|
||
|
return 0;
|
||
|
}
|
||
|
size+= xkmPutCountedAtomString(dpy,file,doodad->any.name);
|
||
|
tmp= fwrite(&doodadWire,SIZEOF(xkmDoodadDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmDoodadDesc);
|
||
|
if (doodad->any.type==XkbTextDoodad) {
|
||
|
size+= xkmPutCountedString(file,doodad->text.text);
|
||
|
size+= xkmPutCountedString(file,doodad->text.font);
|
||
|
}
|
||
|
else if (doodad->any.type==XkbLogoDoodad) {
|
||
|
size+= xkmPutCountedString(file,doodad->logo.logo_name);
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
static unsigned
|
||
|
WriteXKMGeomOverlay(FILE *file,XkbFileInfo *result,XkbOverlayPtr ol)
|
||
|
{
|
||
|
register int r,k;
|
||
|
Display * dpy;
|
||
|
XkbDescPtr xkb;
|
||
|
XkbOverlayRowPtr row;
|
||
|
xkmOverlayDesc olWire;
|
||
|
xkmOverlayRowDesc rowWire;
|
||
|
xkmOverlayKeyDesc keyWire;
|
||
|
unsigned tmp,size= 0;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
bzero((char *)&olWire,sizeof(olWire));
|
||
|
bzero((char *)&rowWire,sizeof(rowWire));
|
||
|
bzero((char *)&keyWire,sizeof(keyWire));
|
||
|
size+= xkmPutCountedAtomString(dpy,file,ol->name);
|
||
|
olWire.num_rows= ol->num_rows;
|
||
|
tmp= fwrite(&olWire,SIZEOF(xkmOverlayDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmOverlayDesc);
|
||
|
for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
|
||
|
XkbOverlayKeyPtr key;
|
||
|
rowWire.row_under= row->row_under;
|
||
|
rowWire.num_keys= row->num_keys;
|
||
|
tmp= fwrite(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmOverlayRowDesc);
|
||
|
for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
|
||
|
memcpy(keyWire.over,key->over.name,XkbKeyNameLength);
|
||
|
memcpy(keyWire.under,key->under.name,XkbKeyNameLength);
|
||
|
tmp= fwrite(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmOverlayKeyDesc);
|
||
|
}
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
static unsigned
|
||
|
WriteXKMGeomSection(FILE *file,XkbFileInfo *result,XkbSectionPtr section)
|
||
|
{
|
||
|
register int i;
|
||
|
Display * dpy;
|
||
|
XkbDescPtr xkb;
|
||
|
xkmSectionDesc sectionWire;
|
||
|
unsigned tmp,size= 0;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
size+= xkmPutCountedAtomString(dpy,file,section->name);
|
||
|
sectionWire.top= section->top;
|
||
|
sectionWire.left= section->left;
|
||
|
sectionWire.width= section->width;
|
||
|
sectionWire.height= section->height;
|
||
|
sectionWire.angle= section->angle;
|
||
|
sectionWire.priority= section->priority;
|
||
|
sectionWire.num_rows= section->num_rows;
|
||
|
sectionWire.num_doodads= section->num_doodads;
|
||
|
sectionWire.num_overlays= section->num_overlays;
|
||
|
tmp= fwrite(§ionWire,SIZEOF(xkmSectionDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmSectionDesc);
|
||
|
if (section->rows) {
|
||
|
register unsigned k;
|
||
|
XkbRowPtr row;
|
||
|
xkmRowDesc rowWire;
|
||
|
XkbKeyPtr key;
|
||
|
xkmKeyDesc keyWire;
|
||
|
for (i=0,row=section->rows;i<section->num_rows;i++,row++) {
|
||
|
rowWire.top= row->top;
|
||
|
rowWire.left= row->left;
|
||
|
rowWire.num_keys= row->num_keys;
|
||
|
rowWire.vertical= row->vertical;
|
||
|
tmp= fwrite(&rowWire,SIZEOF(xkmRowDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmRowDesc);
|
||
|
for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
|
||
|
memcpy(keyWire.name,key->name.name,XkbKeyNameLength);
|
||
|
keyWire.gap= key->gap;
|
||
|
keyWire.shape_ndx= key->shape_ndx;
|
||
|
keyWire.color_ndx= key->color_ndx;
|
||
|
tmp= fwrite(&keyWire,SIZEOF(xkmKeyDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmKeyDesc);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (section->doodads) {
|
||
|
XkbDoodadPtr doodad;
|
||
|
for (i=0,doodad=section->doodads;i<section->num_doodads;i++,doodad++) {
|
||
|
size+= WriteXKMGeomDoodad(file,result,doodad);
|
||
|
}
|
||
|
}
|
||
|
if (section->overlays) {
|
||
|
XkbOverlayPtr ol;
|
||
|
for (i=0,ol=section->overlays;i<section->num_overlays;i++,ol++) {
|
||
|
size+= WriteXKMGeomOverlay(file,result,ol);
|
||
|
}
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
static unsigned
|
||
|
WriteXKMGeometry(FILE *file,XkbFileInfo *result)
|
||
|
{
|
||
|
register int i;
|
||
|
Display * dpy;
|
||
|
XkbDescPtr xkb;
|
||
|
XkbGeometryPtr geom;
|
||
|
xkmGeometryDesc wire;
|
||
|
unsigned tmp,size= 0;
|
||
|
|
||
|
xkb= result->xkb;
|
||
|
dpy= xkb->dpy;
|
||
|
if ((!xkb)||(!xkb->geom))
|
||
|
return 0;
|
||
|
geom= xkb->geom;
|
||
|
wire.width_mm= geom->width_mm;
|
||
|
wire.height_mm= geom->height_mm;
|
||
|
wire.base_color_ndx= XkbGeomColorIndex(geom,geom->base_color);
|
||
|
wire.label_color_ndx= XkbGeomColorIndex(geom,geom->label_color);
|
||
|
wire.num_properties= geom->num_properties;
|
||
|
wire.num_colors= geom->num_colors;
|
||
|
wire.num_shapes= geom->num_shapes;
|
||
|
wire.num_sections= geom->num_sections;
|
||
|
wire.num_doodads= geom->num_doodads;
|
||
|
wire.num_key_aliases= geom->num_key_aliases;
|
||
|
size+= xkmPutCountedAtomString(dpy,file,geom->name);
|
||
|
tmp= fwrite(&wire,SIZEOF(xkmGeometryDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmGeometryDesc);
|
||
|
size+= xkmPutCountedString(file,geom->label_font);
|
||
|
if (geom->properties) {
|
||
|
XkbPropertyPtr prop;
|
||
|
for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
|
||
|
size+= xkmPutCountedString(file,prop->name);
|
||
|
size+= xkmPutCountedString(file,prop->value);
|
||
|
}
|
||
|
}
|
||
|
if (geom->colors) {
|
||
|
XkbColorPtr color;
|
||
|
for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
|
||
|
size+= xkmPutCountedString(file,color->spec);
|
||
|
}
|
||
|
}
|
||
|
if (geom->shapes) {
|
||
|
XkbShapePtr shape;
|
||
|
xkmShapeDesc shapeWire;
|
||
|
|
||
|
for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
|
||
|
register int n;
|
||
|
XkbOutlinePtr ol;
|
||
|
xkmOutlineDesc olWire;
|
||
|
bzero((char *)&shapeWire,sizeof(xkmShapeDesc));
|
||
|
size+= xkmPutCountedAtomString(dpy,file,shape->name);
|
||
|
shapeWire.num_outlines= shape->num_outlines;
|
||
|
if (shape->primary!=NULL)
|
||
|
shapeWire.primary_ndx= XkbOutlineIndex(shape,shape->primary);
|
||
|
else shapeWire.primary_ndx= XkbNoShape;
|
||
|
if (shape->approx!=NULL)
|
||
|
shapeWire.approx_ndx= XkbOutlineIndex(shape,shape->approx);
|
||
|
else shapeWire.approx_ndx= XkbNoShape;
|
||
|
tmp= fwrite(&shapeWire,SIZEOF(xkmShapeDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmShapeDesc);
|
||
|
for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) {
|
||
|
register int p;
|
||
|
XkbPointPtr pt;
|
||
|
xkmPointDesc ptWire;
|
||
|
olWire.num_points= ol->num_points;
|
||
|
olWire.corner_radius= ol->corner_radius;
|
||
|
tmp= fwrite(&olWire,SIZEOF(xkmOutlineDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmOutlineDesc);
|
||
|
for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) {
|
||
|
ptWire.x= pt->x;
|
||
|
ptWire.y= pt->y;
|
||
|
tmp= fwrite(&ptWire,SIZEOF(xkmPointDesc),1,file);
|
||
|
size+= tmp*SIZEOF(xkmPointDesc);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (geom->sections) {
|
||
|
XkbSectionPtr section;
|
||
|
for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
|
||
|
size+= WriteXKMGeomSection(file,result,section);
|
||
|
}
|
||
|
}
|
||
|
if (geom->doodads) {
|
||
|
XkbDoodadPtr doodad;
|
||
|
for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) {
|
||
|
size+= WriteXKMGeomDoodad(file,result,doodad);
|
||
|
}
|
||
|
}
|
||
|
if (geom->key_aliases) {
|
||
|
tmp= fwrite(geom->key_aliases,2*XkbKeyNameLength,geom->num_key_aliases,
|
||
|
file);
|
||
|
size+= tmp*(2*XkbKeyNameLength);
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
/***====================================================================***/
|
||
|
|
||
|
/*ARGSUSED*/
|
||
|
static int
|
||
|
GetXKMKeyNamesTOC( XkbFileInfo * result,
|
||
|
XkmInfo * info,
|
||
|
int max_toc,
|
||
|
xkmSectionInfo *toc_rtrn)
|
||
|
{
|
||
|
int num_toc;
|
||
|
int total_size;
|
||
|
|
||
|
total_size= num_toc=0;
|
||
|
if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
return num_toc;
|
||
|
}
|
||
|
|
||
|
/*ARGSUSED*/
|
||
|
static int
|
||
|
GetXKMTypesTOC( XkbFileInfo * result,
|
||
|
XkmInfo * info,
|
||
|
int max_toc,
|
||
|
xkmSectionInfo *toc_rtrn)
|
||
|
{
|
||
|
int num_toc;
|
||
|
int total_size;
|
||
|
|
||
|
total_size= num_toc=0;
|
||
|
if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
return num_toc;
|
||
|
}
|
||
|
|
||
|
/*ARGSUSED*/
|
||
|
static int
|
||
|
GetXKMCompatMapTOC( XkbFileInfo * result,
|
||
|
XkmInfo * info,
|
||
|
int max_toc,
|
||
|
xkmSectionInfo *toc_rtrn)
|
||
|
{
|
||
|
int num_toc;
|
||
|
int total_size;
|
||
|
|
||
|
total_size= num_toc=0;
|
||
|
if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
return num_toc;
|
||
|
}
|
||
|
|
||
|
/*ARGSUSED*/
|
||
|
static int
|
||
|
GetXKMSemanticsTOC( XkbFileInfo * result,
|
||
|
XkmInfo * info,
|
||
|
int max_toc,
|
||
|
xkmSectionInfo *toc_rtrn)
|
||
|
{
|
||
|
int num_toc;
|
||
|
int total_size;
|
||
|
|
||
|
total_size= num_toc=0;
|
||
|
if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
return num_toc;
|
||
|
}
|
||
|
|
||
|
/*ARGSUSED*/
|
||
|
static int
|
||
|
GetXKMLayoutTOC( XkbFileInfo * result,
|
||
|
XkmInfo * info,
|
||
|
int max_toc,
|
||
|
xkmSectionInfo *toc_rtrn)
|
||
|
{
|
||
|
int num_toc;
|
||
|
int total_size;
|
||
|
|
||
|
total_size= num_toc=0;
|
||
|
if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMSymbols(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
return num_toc;
|
||
|
}
|
||
|
|
||
|
/*ARGSUSED*/
|
||
|
static int
|
||
|
GetXKMKeymapTOC( XkbFileInfo * result,
|
||
|
XkmInfo * info,
|
||
|
int max_toc,
|
||
|
xkmSectionInfo *toc_rtrn)
|
||
|
{
|
||
|
int num_toc;
|
||
|
int total_size;
|
||
|
|
||
|
total_size= num_toc=0;
|
||
|
if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMSymbols(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
return num_toc;
|
||
|
}
|
||
|
|
||
|
/*ARGSUSED*/
|
||
|
static int
|
||
|
GetXKMGeometryTOC( XkbFileInfo * result,
|
||
|
XkmInfo * info,
|
||
|
int max_toc,
|
||
|
xkmSectionInfo *toc_rtrn)
|
||
|
{
|
||
|
int num_toc;
|
||
|
int total_size;
|
||
|
|
||
|
total_size= num_toc=0;
|
||
|
if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size))
|
||
|
num_toc++;
|
||
|
return num_toc;
|
||
|
}
|
||
|
|
||
|
static Bool
|
||
|
WriteXKMFile( FILE * file,
|
||
|
XkbFileInfo * result,
|
||
|
int num_toc,
|
||
|
xkmSectionInfo *toc,
|
||
|
XkmInfo * info)
|
||
|
{
|
||
|
register int i;
|
||
|
unsigned tmp,size,total= 0;
|
||
|
|
||
|
for (i=0;i<num_toc;i++) {
|
||
|
tmp= fwrite(&toc[i],SIZEOF(xkmSectionInfo),1,file);
|
||
|
total+= tmp*SIZEOF(xkmSectionInfo);
|
||
|
switch (toc[i].type) {
|
||
|
case XkmTypesIndex:
|
||
|
size= WriteXKMKeyTypes(file,result);
|
||
|
break;
|
||
|
case XkmCompatMapIndex:
|
||
|
size= WriteXKMCompatMap(file,result,info);
|
||
|
break;
|
||
|
case XkmSymbolsIndex:
|
||
|
size= WriteXKMSymbols(file,result,info);
|
||
|
break;
|
||
|
case XkmIndicatorsIndex:
|
||
|
size= WriteXKMIndicators(file,result,info);
|
||
|
break;
|
||
|
case XkmKeyNamesIndex:
|
||
|
size= WriteXKMKeycodes(file,result);
|
||
|
break;
|
||
|
case XkmGeometryIndex:
|
||
|
size= WriteXKMGeometry(file,result);
|
||
|
break;
|
||
|
case XkmVirtualModsIndex:
|
||
|
size= WriteXKMVirtualMods(file,result,info);
|
||
|
break;
|
||
|
default:
|
||
|
_XkbLibError(_XkbErrIllegalTOCType,"WriteXKMFile",toc[i].type);
|
||
|
return False;
|
||
|
}
|
||
|
size+= SIZEOF(xkmSectionInfo);
|
||
|
if (size!=toc[i].size) {
|
||
|
_XkbLibError(_XkbErrBadLength,XkbConfigText(toc[i].type,XkbMessage),
|
||
|
size-toc[i].size);
|
||
|
return False;
|
||
|
}
|
||
|
}
|
||
|
return True;
|
||
|
}
|
||
|
|
||
|
|
||
|
#define MAX_TOC 16
|
||
|
|
||
|
Bool
|
||
|
XkbWriteXKMFile(FILE *out,XkbFileInfo *result)
|
||
|
{
|
||
|
Bool ok;
|
||
|
XkbDescPtr xkb;
|
||
|
XkmInfo info;
|
||
|
int size_toc,i;
|
||
|
unsigned hdr,present;
|
||
|
xkmFileInfo fileInfo;
|
||
|
xkmSectionInfo toc[MAX_TOC];
|
||
|
int (*getTOC)(
|
||
|
XkbFileInfo * /* result */,
|
||
|
XkmInfo * /* info */,
|
||
|
int /* max_to */,
|
||
|
xkmSectionInfo */* toc_rtrn */
|
||
|
);
|
||
|
|
||
|
switch (result->type) {
|
||
|
case XkmKeyNamesIndex:
|
||
|
getTOC= GetXKMKeyNamesTOC;
|
||
|
break;
|
||
|
case XkmTypesIndex:
|
||
|
getTOC= GetXKMTypesTOC;
|
||
|
break;
|
||
|
case XkmCompatMapIndex:
|
||
|
getTOC= GetXKMCompatMapTOC;
|
||
|
break;
|
||
|
case XkmSemanticsFile:
|
||
|
getTOC= GetXKMSemanticsTOC;
|
||
|
break;
|
||
|
case XkmLayoutFile:
|
||
|
getTOC= GetXKMLayoutTOC;
|
||
|
break;
|
||
|
case XkmKeymapFile:
|
||
|
getTOC= GetXKMKeymapTOC;
|
||
|
break;
|
||
|
case XkmGeometryFile:
|
||
|
case XkmGeometryIndex:
|
||
|
getTOC= GetXKMGeometryTOC;
|
||
|
break;
|
||
|
default:
|
||
|
_XkbLibError(_XkbErrIllegalContents,
|
||
|
XkbConfigText(result->type,XkbMessage),0);
|
||
|
return False;
|
||
|
}
|
||
|
xkb= result->xkb;
|
||
|
|
||
|
bzero((char *)&info,sizeof(XkmInfo));
|
||
|
size_toc= (*getTOC)(result,&info,MAX_TOC,toc);
|
||
|
if (size_toc<1) {
|
||
|
_XkbLibError(_XkbErrEmptyFile,"XkbWriteXKMFile",0);
|
||
|
return False;
|
||
|
}
|
||
|
if (out==NULL) {
|
||
|
_XkbLibError(_XkbErrFileCannotOpen,"XkbWriteXKMFile",0);
|
||
|
return False;
|
||
|
}
|
||
|
for (i=present=0;i<size_toc;i++) {
|
||
|
toc[i].offset+= 4+SIZEOF(xkmFileInfo);
|
||
|
toc[i].offset+= (size_toc*SIZEOF(xkmSectionInfo));
|
||
|
if (toc[i].type<=XkmLastIndex) {
|
||
|
present|= (1<<toc[i].type);
|
||
|
}
|
||
|
#ifdef DEBUG
|
||
|
else {
|
||
|
fprintf(stderr,"Illegal section type %d\n",toc[i].type);
|
||
|
fprintf(stderr,"Ignored\n");
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
|
||
|
xkmPutCARD32(out,(unsigned long)hdr);
|
||
|
fileInfo.type= result->type;
|
||
|
fileInfo.min_kc= xkb->min_key_code;
|
||
|
fileInfo.max_kc= xkb->max_key_code;
|
||
|
fileInfo.num_toc= size_toc;
|
||
|
fileInfo.present= present;
|
||
|
fileInfo.pad= 0;
|
||
|
fwrite(&fileInfo,SIZEOF(xkmFileInfo),1,out);
|
||
|
fwrite(toc,SIZEOF(xkmSectionInfo),size_toc,out);
|
||
|
ok= WriteXKMFile(out,result,size_toc,toc,&info);
|
||
|
return ok;
|
||
|
}
|