2006-11-25 11:24:24 -07:00
|
|
|
/************************************************************
|
|
|
|
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
|
2012-03-10 10:16:24 -07:00
|
|
|
documentation, and that the name of Silicon Graphics not be
|
|
|
|
used in advertising or publicity pertaining to distribution
|
2006-11-25 11:24:24 -07:00
|
|
|
of the software without specific prior written permission.
|
2012-03-10 10:16:24 -07:00
|
|
|
Silicon Graphics makes no representation about the suitability
|
2006-11-25 11:24:24 -07:00
|
|
|
of this software for any purpose. It is provided "as is"
|
|
|
|
without any express or implied warranty.
|
2012-03-10 10:16:24 -07:00
|
|
|
|
|
|
|
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
|
|
|
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
2006-11-25 11:24:24 -07:00
|
|
|
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
2012-03-10 10:16:24 -07:00
|
|
|
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
|
2006-11-25 11:24:24 -07:00
|
|
|
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 {
|
2015-05-10 03:32:36 -06:00
|
|
|
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;
|
2006-11-25 11:24:24 -07:00
|
|
|
} XkmInfo;
|
|
|
|
|
|
|
|
/***====================================================================***/
|
|
|
|
|
|
|
|
#define xkmPutCARD8(f,v) (putc(v,f),1)
|
|
|
|
|
|
|
|
static int
|
2015-05-10 03:32:36 -06:00
|
|
|
xkmPutCARD16(FILE *file, unsigned val)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
CARD16 tmp = val;
|
2006-11-25 11:24:24 -07:00
|
|
|
|
2015-05-10 03:32:36 -06:00
|
|
|
fwrite(&tmp, 2, 1, file);
|
2006-11-25 11:24:24 -07:00
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-05-10 03:32:36 -06:00
|
|
|
xkmPutCARD32(FILE *file, unsigned long val)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
CARD32 tmp = val;
|
2006-11-25 11:24:24 -07:00
|
|
|
|
2015-05-10 03:32:36 -06:00
|
|
|
fwrite(&tmp, 4, 1, file);
|
2006-11-25 11:24:24 -07:00
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-05-10 03:32:36 -06:00
|
|
|
xkmPutPadding(FILE *file, unsigned pad)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < pad; i++) {
|
|
|
|
putc('\0', file);
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
return pad;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-05-10 03:32:36 -06:00
|
|
|
xkmPutCountedBytes(FILE *file, char *ptr, unsigned count)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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;
|
2006-11-25 11:24:24 -07:00
|
|
|
if (pad)
|
2015-05-10 03:32:36 -06:00
|
|
|
xkmPutPadding(file, pad);
|
|
|
|
return nOut + pad;
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned
|
|
|
|
xkmSizeCountedString(char *str)
|
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
if (str == NULL)
|
|
|
|
return 4;
|
|
|
|
return XkbPaddedSize(strlen(str) + 2);
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-05-10 03:32:36 -06:00
|
|
|
xkmPutCountedString(FILE *file, char *str)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
if (str == NULL)
|
|
|
|
return xkmPutCARD32(file, (unsigned long) 0);
|
|
|
|
return xkmPutCountedBytes(file, str, strlen(str));
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#define xkmSizeCountedAtomString(d,a) \
|
|
|
|
xkmSizeCountedString(XkbAtomGetString((d),(a)))
|
|
|
|
|
|
|
|
#define xkmPutCountedAtomString(d,f,a) \
|
|
|
|
xkmPutCountedString((f),XkbAtomGetString((d),(a)))
|
|
|
|
|
|
|
|
/***====================================================================***/
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
SizeXKMVirtualMods(XkbFileInfo *result, XkmInfo *info,
|
|
|
|
xkmSectionInfo *toc, int *offset_inout)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
Display *dpy;
|
|
|
|
XkbDescPtr xkb;
|
|
|
|
unsigned nBound, bound;
|
|
|
|
unsigned nNamed, named, szNames;
|
|
|
|
register unsigned i, bit;
|
|
|
|
|
|
|
|
xkb = result->xkb;
|
|
|
|
if ((!xkb) || (!xkb->names) || (!xkb->server)) {
|
|
|
|
_XkbLibError(_XkbErrMissingVMods, "SizeXKMVirtualMods", 0);
|
|
|
|
return 0;
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
dpy = xkb->dpy;
|
|
|
|
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++;
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
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;
|
2006-11-25 11:24:24 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
WriteXKMVirtualMods(FILE *file, XkbFileInfo *result, XkmInfo *info)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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]);
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***====================================================================***/
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
SizeXKMKeycodes(XkbFileInfo *result, xkmSectionInfo *toc, int *offset_inout)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
XkbDescPtr xkb;
|
|
|
|
Atom kcName;
|
|
|
|
int size = 0;
|
|
|
|
Display *dpy;
|
|
|
|
|
|
|
|
xkb = result->xkb;
|
|
|
|
if ((!xkb) || (!xkb->names) || (!xkb->names->keys)) {
|
|
|
|
_XkbLibError(_XkbErrMissingNames, "SizeXKMKeycodes", 0);
|
|
|
|
return 0;
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
dpy = xkb->dpy;
|
|
|
|
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;
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
toc->type = XkmKeyNamesIndex;
|
|
|
|
toc->format = MSBFirst;
|
|
|
|
toc->size = size + SIZEOF(xkmSectionInfo);
|
|
|
|
toc->offset = (*offset_inout);
|
|
|
|
(*offset_inout) += toc->size;
|
2006-11-25 11:24:24 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
WriteXKMKeycodes(FILE *file, XkbFileInfo *result)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***====================================================================***/
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
SizeXKMKeyTypes(XkbFileInfo *result, xkmSectionInfo *toc, int *offset_inout)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
register unsigned i, n, size;
|
|
|
|
XkbKeyTypePtr type;
|
|
|
|
XkbDescPtr xkb;
|
|
|
|
Display *dpy;
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
xkb = result->xkb;
|
|
|
|
if ((!xkb) || (!xkb->map) || (!xkb->map->types)) {
|
|
|
|
_XkbLibError(_XkbErrMissingTypes, "SizeXKBKeyTypes", 0);
|
|
|
|
return 0;
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
dpy = xkb->dpy;
|
|
|
|
if (xkb->map->num_types < XkbNumRequiredTypes) {
|
|
|
|
_XkbLibError(_XkbErrMissingReqTypes, "SizeXKBKeyTypes", 0);
|
|
|
|
return 0;
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
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]);
|
|
|
|
}
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
toc->type = XkmTypesIndex;
|
|
|
|
toc->format = MSBFirst;
|
|
|
|
toc->size = size + SIZEOF(xkmSectionInfo);
|
|
|
|
toc->offset = (*offset_inout);
|
|
|
|
(*offset_inout) += toc->size;
|
2006-11-25 11:24:24 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
WriteXKMKeyTypes(FILE *file, XkbFileInfo *result)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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]));
|
|
|
|
}
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***====================================================================***/
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
SizeXKMCompatMap(XkbFileInfo *result, XkmInfo *info,
|
|
|
|
xkmSectionInfo *toc, int *offset_inout)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
XkbDescPtr xkb;
|
|
|
|
char *name;
|
|
|
|
int size;
|
|
|
|
register int i;
|
|
|
|
unsigned groups, nGroups;
|
|
|
|
Display *dpy;
|
|
|
|
|
|
|
|
xkb = result->xkb;
|
|
|
|
if ((!xkb) || (!xkb->compat) || (!xkb->compat->sym_interpret)) {
|
|
|
|
_XkbLibError(_XkbErrMissingCompatMap, "SizeXKMCompatMap", 0);
|
|
|
|
return 0;
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
dpy = xkb->dpy;
|
|
|
|
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++;
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
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;
|
2006-11-25 11:24:24 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
WriteXKMCompatMap(FILE *file, XkbFileInfo *result, XkmInfo *info)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
if (info->group_compat) {
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***====================================================================***/
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
SizeXKMSymbols(XkbFileInfo *result, XkmInfo *info,
|
|
|
|
xkmSectionInfo *toc, int *offset_inout)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
Display *dpy;
|
|
|
|
XkbDescPtr xkb;
|
|
|
|
unsigned size;
|
|
|
|
register int i, nSyms;
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
xkb = result->xkb;
|
|
|
|
if ((!xkb) || (!xkb->map) || ((!xkb->map->syms))) {
|
|
|
|
_XkbLibError(_XkbErrMissingSymbols, "SizeXKMSymbols", 0);
|
|
|
|
return 0;
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
dpy = xkb->dpy;
|
|
|
|
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]);
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
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++;
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
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;
|
2006-11-25 11:24:24 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
WriteXKMSymbols(FILE *file, XkbFileInfo *result, XkmInfo *info)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
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]);
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***====================================================================***/
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
SizeXKMIndicators(XkbFileInfo *result, XkmInfo *info,
|
|
|
|
xkmSectionInfo *toc, int *offset_inout)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
Display *dpy;
|
|
|
|
XkbDescPtr xkb;
|
|
|
|
unsigned size;
|
|
|
|
register unsigned i, nLEDs;
|
|
|
|
|
|
|
|
xkb = result->xkb;
|
|
|
|
if ((xkb == NULL) || (xkb->indicators == NULL)) {
|
2006-11-25 11:24:24 -07:00
|
|
|
/* _XkbLibError(_XkbErrMissingIndicators,"SizeXKMIndicators",0);*/
|
2015-05-10 03:32:36 -06:00
|
|
|
return 0;
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
dpy = xkb->dpy;
|
|
|
|
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++;
|
|
|
|
}
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
info->num_leds = nLEDs;
|
|
|
|
toc->type = XkmIndicatorsIndex;
|
|
|
|
toc->format = MSBFirst;
|
|
|
|
toc->size = size + SIZEOF(xkmSectionInfo);
|
|
|
|
toc->offset = (*offset_inout);
|
|
|
|
(*offset_inout) += toc->size;
|
2006-11-25 11:24:24 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
WriteXKMIndicators(FILE *file, XkbFileInfo *result, XkmInfo *info)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***====================================================================***/
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
SizeXKMGeomDoodad(XkbFileInfo *result, XkbDoodadPtr doodad)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
unsigned size;
|
2006-11-25 11:24:24 -07:00
|
|
|
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
else if (doodad->any.type == XkbLogoDoodad) {
|
|
|
|
size += xkmSizeCountedString(doodad->logo.logo_name);
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
SizeXKMGeomSection(XkbFileInfo *result, XkbSectionPtr section)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
register int i;
|
|
|
|
unsigned size;
|
2006-11-25 11:24:24 -07:00
|
|
|
|
2015-05-10 03:32:36 -06:00
|
|
|
size = SIZEOF(xkmSectionDesc);
|
|
|
|
size += xkmSizeCountedAtomString(result->xkb->dpy, section->name);
|
2006-11-25 11:24:24 -07:00
|
|
|
if (section->rows) {
|
2015-05-10 03:32:36 -06:00
|
|
|
XkbRowPtr row;
|
|
|
|
|
|
|
|
for (row = section->rows, i = 0; i < section->num_rows; i++, row++) {
|
|
|
|
size += SIZEOF(xkmRowDesc);
|
|
|
|
size += row->num_keys * SIZEOF(xkmKeyDesc);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
if (section->doodads) {
|
2015-05-10 03:32:36 -06:00
|
|
|
XkbDoodadPtr doodad;
|
|
|
|
|
|
|
|
for (doodad = section->doodads, i = 0; i < section->num_doodads;
|
|
|
|
i++, doodad++) {
|
|
|
|
size += SizeXKMGeomDoodad(result, doodad);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
if (section->overlays) {
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
SizeXKMGeometry(XkbFileInfo *result, xkmSectionInfo *toc, int *offset_inout)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
register int i;
|
|
|
|
Display *dpy;
|
|
|
|
XkbDescPtr xkb;
|
|
|
|
XkbGeometryPtr geom;
|
|
|
|
unsigned size;
|
|
|
|
|
|
|
|
xkb = result->xkb;
|
|
|
|
if ((!xkb) || (!xkb->geom))
|
|
|
|
return 0;
|
|
|
|
dpy = xkb->dpy;
|
|
|
|
geom = xkb->geom;
|
|
|
|
size = xkmSizeCountedAtomString(dpy, geom->name);
|
|
|
|
size += SIZEOF(xkmGeometryDesc);
|
|
|
|
size += xkmSizeCountedString(geom->label_font);
|
2006-11-25 11:24:24 -07:00
|
|
|
if (geom->properties) {
|
2015-05-10 03:32:36 -06:00
|
|
|
XkbPropertyPtr prop;
|
|
|
|
|
|
|
|
for (i = 0, prop = geom->properties; i < geom->num_properties;
|
|
|
|
i++, prop++) {
|
|
|
|
size += xkmSizeCountedString(prop->name);
|
|
|
|
size += xkmSizeCountedString(prop->value);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
if (geom->colors) {
|
2015-05-10 03:32:36 -06:00
|
|
|
XkbColorPtr color;
|
|
|
|
|
|
|
|
for (i = 0, color = geom->colors; i < geom->num_colors; i++, color++) {
|
|
|
|
size += xkmSizeCountedString(color->spec);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
if (geom->shapes) {
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
if (geom->sections) {
|
2015-05-10 03:32:36 -06:00
|
|
|
XkbSectionPtr section;
|
|
|
|
|
|
|
|
for (i = 0, section = geom->sections; i < geom->num_sections;
|
|
|
|
i++, section++) {
|
|
|
|
size += SizeXKMGeomSection(result, section);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
if (geom->doodads) {
|
|
|
|
XkbDoodadPtr doodad;
|
|
|
|
|
|
|
|
for (i = 0, doodad = geom->doodads; i < geom->num_doodads;
|
|
|
|
i++, doodad++) {
|
|
|
|
size += SizeXKMGeomDoodad(result, doodad);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
if (geom->key_aliases) {
|
2015-05-10 03:32:36 -06:00
|
|
|
size += geom->num_key_aliases * (XkbKeyNameLength * 2);
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
toc->type = XkmGeometryIndex;
|
|
|
|
toc->format = MSBFirst;
|
|
|
|
toc->size = size + SIZEOF(xkmSectionInfo);
|
|
|
|
toc->offset = (*offset_inout);
|
|
|
|
(*offset_inout) += toc->size;
|
2006-11-25 11:24:24 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
WriteXKMGeomDoodad(FILE *file, XkbFileInfo *result, XkbDoodadPtr doodad)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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;
|
2006-11-25 11:24:24 -07:00
|
|
|
switch (doodad->any.type) {
|
2015-05-10 03:32:36 -06:00
|
|
|
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;
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
else if (doodad->any.type == XkbLogoDoodad) {
|
|
|
|
size += xkmPutCountedString(file, doodad->logo.logo_name);
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
WriteXKMGeomOverlay(FILE *file, XkbFileInfo *result, XkbOverlayPtr ol)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2012-03-10 10:16:24 -07:00
|
|
|
return size;
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
WriteXKMGeomSection(FILE *file, XkbFileInfo *result, XkbSectionPtr section)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
2006-11-25 11:24:24 -07:00
|
|
|
if (section->rows) {
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
if (section->doodads) {
|
2015-05-10 03:32:36 -06:00
|
|
|
XkbDoodadPtr doodad;
|
|
|
|
|
|
|
|
for (i = 0, doodad = section->doodads; i < section->num_doodads;
|
|
|
|
i++, doodad++) {
|
|
|
|
size += WriteXKMGeomDoodad(file, result, doodad);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
if (section->overlays) {
|
2015-05-10 03:32:36 -06:00
|
|
|
XkbOverlayPtr ol;
|
|
|
|
|
|
|
|
for (i = 0, ol = section->overlays; i < section->num_overlays;
|
|
|
|
i++, ol++) {
|
|
|
|
size += WriteXKMGeomOverlay(file, result, ol);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned
|
2015-05-10 03:32:36 -06:00
|
|
|
WriteXKMGeometry(FILE *file, XkbFileInfo *result)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
register int i;
|
|
|
|
Display *dpy;
|
|
|
|
XkbDescPtr xkb;
|
|
|
|
XkbGeometryPtr geom;
|
|
|
|
xkmGeometryDesc wire;
|
|
|
|
unsigned tmp, size = 0;
|
|
|
|
|
|
|
|
xkb = result->xkb;
|
|
|
|
if ((!xkb) || (!xkb->geom))
|
|
|
|
return 0;
|
|
|
|
dpy = xkb->dpy;
|
|
|
|
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);
|
2006-11-25 11:24:24 -07:00
|
|
|
if (geom->properties) {
|
2015-05-10 03:32:36 -06:00
|
|
|
XkbPropertyPtr prop;
|
|
|
|
|
|
|
|
for (i = 0, prop = geom->properties; i < geom->num_properties;
|
|
|
|
i++, prop++) {
|
|
|
|
size += xkmPutCountedString(file, prop->name);
|
|
|
|
size += xkmPutCountedString(file, prop->value);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
if (geom->colors) {
|
2015-05-10 03:32:36 -06:00
|
|
|
XkbColorPtr color;
|
|
|
|
|
|
|
|
for (i = 0, color = geom->colors; i < geom->num_colors; i++, color++) {
|
|
|
|
size += xkmPutCountedString(file, color->spec);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
if (geom->shapes) {
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
if (geom->sections) {
|
2015-05-10 03:32:36 -06:00
|
|
|
XkbSectionPtr section;
|
|
|
|
|
|
|
|
for (i = 0, section = geom->sections; i < geom->num_sections;
|
|
|
|
i++, section++) {
|
|
|
|
size += WriteXKMGeomSection(file, result, section);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
if (geom->doodads) {
|
2015-05-10 03:32:36 -06:00
|
|
|
XkbDoodadPtr doodad;
|
|
|
|
|
|
|
|
for (i = 0, doodad = geom->doodads; i < geom->num_doodads;
|
|
|
|
i++, doodad++) {
|
|
|
|
size += WriteXKMGeomDoodad(file, result, doodad);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
if (geom->key_aliases) {
|
2015-05-10 03:32:36 -06:00
|
|
|
tmp =
|
|
|
|
fwrite(geom->key_aliases, 2 * XkbKeyNameLength,
|
|
|
|
geom->num_key_aliases, file);
|
|
|
|
size += tmp * (2 * XkbKeyNameLength);
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***====================================================================***/
|
|
|
|
|
|
|
|
/*ARGSUSED*/
|
|
|
|
static int
|
2015-05-10 03:32:36 -06:00
|
|
|
GetXKMKeyNamesTOC(XkbFileInfo *result, XkmInfo *info,
|
|
|
|
int max_toc, xkmSectionInfo *toc_rtrn)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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++;
|
2006-11-25 11:24:24 -07:00
|
|
|
return num_toc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*ARGSUSED*/
|
|
|
|
static int
|
2015-05-10 03:32:36 -06:00
|
|
|
GetXKMTypesTOC(XkbFileInfo *result, XkmInfo *info,
|
|
|
|
int max_toc, xkmSectionInfo *toc_rtrn)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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++;
|
2006-11-25 11:24:24 -07:00
|
|
|
return num_toc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*ARGSUSED*/
|
|
|
|
static int
|
2015-05-10 03:32:36 -06:00
|
|
|
GetXKMCompatMapTOC(XkbFileInfo *result, XkmInfo *info,
|
|
|
|
int max_toc, xkmSectionInfo *toc_rtrn)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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++;
|
2006-11-25 11:24:24 -07:00
|
|
|
return num_toc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*ARGSUSED*/
|
|
|
|
static int
|
2015-05-10 03:32:36 -06:00
|
|
|
GetXKMSemanticsTOC(XkbFileInfo *result, XkmInfo *info,
|
|
|
|
int max_toc, xkmSectionInfo *toc_rtrn)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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++;
|
2006-11-25 11:24:24 -07:00
|
|
|
return num_toc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*ARGSUSED*/
|
|
|
|
static int
|
2015-05-10 03:32:36 -06:00
|
|
|
GetXKMLayoutTOC(XkbFileInfo *result, XkmInfo *info,
|
|
|
|
int max_toc, xkmSectionInfo *toc_rtrn)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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++;
|
2006-11-25 11:24:24 -07:00
|
|
|
return num_toc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*ARGSUSED*/
|
|
|
|
static int
|
2015-05-10 03:32:36 -06:00
|
|
|
GetXKMKeymapTOC(XkbFileInfo *result, XkmInfo *info,
|
|
|
|
int max_toc, xkmSectionInfo *toc_rtrn)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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++;
|
2006-11-25 11:24:24 -07:00
|
|
|
return num_toc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*ARGSUSED*/
|
|
|
|
static int
|
2015-05-10 03:32:36 -06:00
|
|
|
GetXKMGeometryTOC(XkbFileInfo *result, XkmInfo *info,
|
|
|
|
int max_toc, xkmSectionInfo *toc_rtrn)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
int num_toc;
|
|
|
|
int total_size;
|
2006-11-25 11:24:24 -07:00
|
|
|
|
2015-05-10 03:32:36 -06:00
|
|
|
total_size = num_toc = 0;
|
|
|
|
if (SizeXKMGeometry(result, &toc_rtrn[num_toc], &total_size))
|
|
|
|
num_toc++;
|
2006-11-25 11:24:24 -07:00
|
|
|
return num_toc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
2015-05-10 03:32:36 -06:00
|
|
|
WriteXKMFile(FILE *file, XkbFileInfo *result,
|
|
|
|
int num_toc, xkmSectionInfo *toc, XkmInfo *info)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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;
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
|
|
|
return True;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define MAX_TOC 16
|
|
|
|
|
|
|
|
Bool
|
2015-05-10 03:32:36 -06:00
|
|
|
XkbWriteXKMFile(FILE *out, XkbFileInfo *result)
|
2006-11-25 11:24:24 -07:00
|
|
|
{
|
2015-05-10 03:32:36 -06:00
|
|
|
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 */
|
|
|
|
);
|
2006-11-25 11:24:24 -07:00
|
|
|
|
|
|
|
switch (result->type) {
|
2015-05-10 03:32:36 -06:00
|
|
|
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;
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
xkb = result->xkb;
|
2006-11-25 11:24:24 -07:00
|
|
|
|
2015-05-10 03:32:36 -06:00
|
|
|
bzero((char *) &info, sizeof(XkmInfo));
|
|
|
|
size_toc = (*getTOC) (result, &info, MAX_TOC, toc);
|
|
|
|
if (size_toc < 1) {
|
|
|
|
_XkbLibError(_XkbErrEmptyFile, "XkbWriteXKMFile", 0);
|
|
|
|
return False;
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
if (out == NULL) {
|
|
|
|
_XkbLibError(_XkbErrFileCannotOpen, "XkbWriteXKMFile", 0);
|
|
|
|
return False;
|
2006-11-25 11:24:24 -07:00
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
#ifdef DEBUG
|
2015-05-10 03:32:36 -06:00
|
|
|
else {
|
|
|
|
fprintf(stderr, "Illegal section type %d\n", toc[i].type);
|
|
|
|
fprintf(stderr, "Ignored\n");
|
|
|
|
}
|
2006-11-25 11:24:24 -07:00
|
|
|
#endif
|
|
|
|
}
|
2015-05-10 03:32:36 -06:00
|
|
|
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);
|
2006-11-25 11:24:24 -07:00
|
|
|
return ok;
|
|
|
|
}
|