18c9fbc29Smrg/************************************************************ 28c9fbc29Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 38c9fbc29Smrg 48c9fbc29Smrg Permission to use, copy, modify, and distribute this 58c9fbc29Smrg software and its documentation for any purpose and without 68c9fbc29Smrg fee is hereby granted, provided that the above copyright 78c9fbc29Smrg notice appear in all copies and that both that copyright 88c9fbc29Smrg notice and this permission notice appear in supporting 94cd6a3aeSmrg documentation, and that the name of Silicon Graphics not be 104cd6a3aeSmrg used in advertising or publicity pertaining to distribution 118c9fbc29Smrg of the software without specific prior written permission. 124cd6a3aeSmrg Silicon Graphics makes no representation about the suitability 138c9fbc29Smrg of this software for any purpose. It is provided "as is" 148c9fbc29Smrg without any express or implied warranty. 154cd6a3aeSmrg 164cd6a3aeSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 174cd6a3aeSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 188c9fbc29Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 194cd6a3aeSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 204cd6a3aeSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 214cd6a3aeSmrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 228c9fbc29Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 238c9fbc29Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 248c9fbc29Smrg 258c9fbc29Smrg ********************************************************/ 268c9fbc29Smrg 278c9fbc29Smrg#ifdef HAVE_CONFIG_H 288c9fbc29Smrg#include <config.h> 298c9fbc29Smrg#endif 308c9fbc29Smrg#include <stdio.h> 318c9fbc29Smrg#include <ctype.h> 328c9fbc29Smrg#include <stdlib.h> 338c9fbc29Smrg#include <X11/Xfuncs.h> 348c9fbc29Smrg#include <X11/Xlib.h> 358c9fbc29Smrg#include <X11/XKBlib.h> 368c9fbc29Smrg#include <X11/extensions/XKBgeom.h> 378c9fbc29Smrg 388c9fbc29Smrg#include "XKMformat.h" 398c9fbc29Smrg#include "XKBfileInt.h" 408c9fbc29Smrg 418c9fbc29Smrgtypedef struct _XkmInfo { 4270728a38Smrg unsigned short bound_vmods; 4370728a38Smrg unsigned short named_vmods; 4470728a38Smrg unsigned char num_bound; 4570728a38Smrg unsigned char group_compat; 4670728a38Smrg unsigned short num_group_compat; 4770728a38Smrg unsigned short num_leds; 4870728a38Smrg int total_vmodmaps; 498c9fbc29Smrg} XkmInfo; 508c9fbc29Smrg 518c9fbc29Smrg/***====================================================================***/ 528c9fbc29Smrg 538c9fbc29Smrg#define xkmPutCARD8(f,v) (putc(v,f),1) 548c9fbc29Smrg 558c9fbc29Smrgstatic int 5670728a38SmrgxkmPutCARD16(FILE *file, unsigned val) 578c9fbc29Smrg{ 5870728a38Smrg CARD16 tmp = val; 598c9fbc29Smrg 6070728a38Smrg fwrite(&tmp, 2, 1, file); 618c9fbc29Smrg return 2; 628c9fbc29Smrg} 638c9fbc29Smrg 648c9fbc29Smrgstatic int 6570728a38SmrgxkmPutCARD32(FILE *file, unsigned long val) 668c9fbc29Smrg{ 6770728a38Smrg CARD32 tmp = val; 688c9fbc29Smrg 6970728a38Smrg fwrite(&tmp, 4, 1, file); 708c9fbc29Smrg return 4; 718c9fbc29Smrg} 728c9fbc29Smrg 738c9fbc29Smrgstatic int 7470728a38SmrgxkmPutPadding(FILE *file, unsigned pad) 758c9fbc29Smrg{ 7670728a38Smrg int i; 7770728a38Smrg 7870728a38Smrg for (i = 0; i < pad; i++) { 7970728a38Smrg putc('\0', file); 808c9fbc29Smrg } 818c9fbc29Smrg return pad; 828c9fbc29Smrg} 838c9fbc29Smrg 848c9fbc29Smrgstatic int 8570728a38SmrgxkmPutCountedBytes(FILE *file, char *ptr, unsigned count) 868c9fbc29Smrg{ 8770728a38Smrg register int nOut; 8870728a38Smrg register unsigned pad; 8970728a38Smrg 9070728a38Smrg if (count == 0) 9170728a38Smrg return xkmPutCARD32(file, (unsigned long) 0); 9270728a38Smrg 9370728a38Smrg xkmPutCARD16(file, count); 9470728a38Smrg nOut = fwrite(ptr, 1, count, file); 9570728a38Smrg if (nOut < 0) 9670728a38Smrg return 2; 9770728a38Smrg nOut = count + 2; 9870728a38Smrg pad = XkbPaddedSize(nOut) - nOut; 998c9fbc29Smrg if (pad) 10070728a38Smrg xkmPutPadding(file, pad); 10170728a38Smrg return nOut + pad; 1028c9fbc29Smrg} 1038c9fbc29Smrg 1048c9fbc29Smrgstatic unsigned 1058c9fbc29SmrgxkmSizeCountedString(char *str) 1068c9fbc29Smrg{ 10770728a38Smrg if (str == NULL) 10870728a38Smrg return 4; 10970728a38Smrg return XkbPaddedSize(strlen(str) + 2); 1108c9fbc29Smrg} 1118c9fbc29Smrg 1128c9fbc29Smrgstatic int 11370728a38SmrgxkmPutCountedString(FILE *file, char *str) 1148c9fbc29Smrg{ 11570728a38Smrg if (str == NULL) 11670728a38Smrg return xkmPutCARD32(file, (unsigned long) 0); 11770728a38Smrg return xkmPutCountedBytes(file, str, strlen(str)); 1188c9fbc29Smrg} 1198c9fbc29Smrg 1208c9fbc29Smrg#define xkmSizeCountedAtomString(d,a) \ 1218c9fbc29Smrg xkmSizeCountedString(XkbAtomGetString((d),(a))) 1228c9fbc29Smrg 1238c9fbc29Smrg#define xkmPutCountedAtomString(d,f,a) \ 1248c9fbc29Smrg xkmPutCountedString((f),XkbAtomGetString((d),(a))) 1258c9fbc29Smrg 1268c9fbc29Smrg/***====================================================================***/ 1278c9fbc29Smrg 1288c9fbc29Smrgstatic unsigned 12970728a38SmrgSizeXKMVirtualMods(XkbFileInfo *result, XkmInfo *info, 13070728a38Smrg xkmSectionInfo *toc, int *offset_inout) 1318c9fbc29Smrg{ 13270728a38Smrg Display *dpy; 13370728a38Smrg XkbDescPtr xkb; 13470728a38Smrg unsigned nBound, bound; 13570728a38Smrg unsigned nNamed, named, szNames; 13670728a38Smrg register unsigned i, bit; 13770728a38Smrg 13870728a38Smrg xkb = result->xkb; 13970728a38Smrg if ((!xkb) || (!xkb->names) || (!xkb->server)) { 14070728a38Smrg _XkbLibError(_XkbErrMissingVMods, "SizeXKMVirtualMods", 0); 14170728a38Smrg return 0; 1428c9fbc29Smrg } 14370728a38Smrg dpy = xkb->dpy; 14470728a38Smrg bound = named = 0; 14570728a38Smrg for (i = nBound = nNamed = szNames = 0, bit = 1; i < XkbNumVirtualMods; 14670728a38Smrg i++, bit <<= 1) { 14770728a38Smrg if (xkb->server->vmods[i] != XkbNoModifierMask) { 14870728a38Smrg bound |= bit; 14970728a38Smrg nBound++; 15070728a38Smrg } 15170728a38Smrg if (xkb->names->vmods[i] != None) { 15270728a38Smrg named |= bit; 15370728a38Smrg szNames += xkmSizeCountedAtomString(dpy, xkb->names->vmods[i]); 15470728a38Smrg nNamed++; 15570728a38Smrg } 1568c9fbc29Smrg } 15770728a38Smrg info->num_bound = nBound; 15870728a38Smrg info->bound_vmods = bound; 15970728a38Smrg info->named_vmods = named; 16070728a38Smrg if ((nBound == 0) && (nNamed == 0)) 16170728a38Smrg return 0; 16270728a38Smrg toc->type = XkmVirtualModsIndex; 16370728a38Smrg toc->format = MSBFirst; 16470728a38Smrg toc->size = 4 + XkbPaddedSize(nBound) + szNames + SIZEOF(xkmSectionInfo); 16570728a38Smrg toc->offset = *offset_inout; 16670728a38Smrg (*offset_inout) += toc->size; 1678c9fbc29Smrg return 1; 1688c9fbc29Smrg} 1698c9fbc29Smrg 1708c9fbc29Smrgstatic unsigned 17170728a38SmrgWriteXKMVirtualMods(FILE *file, XkbFileInfo *result, XkmInfo *info) 1728c9fbc29Smrg{ 17370728a38Smrg register unsigned int i, bit; 17470728a38Smrg XkbDescPtr xkb; 17570728a38Smrg Display *dpy; 17670728a38Smrg unsigned size = 0; 17770728a38Smrg 17870728a38Smrg xkb = result->xkb; 17970728a38Smrg dpy = xkb->dpy; 18070728a38Smrg size += xkmPutCARD16(file, info->bound_vmods); 18170728a38Smrg size += xkmPutCARD16(file, info->named_vmods); 18270728a38Smrg for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 18370728a38Smrg if (info->bound_vmods & bit) 18470728a38Smrg size += xkmPutCARD8(file, xkb->server->vmods[i]); 1858c9fbc29Smrg } 18670728a38Smrg if ((i = XkbPaddedSize(info->num_bound) - info->num_bound) > 0) 18770728a38Smrg size += xkmPutPadding(file, i); 18870728a38Smrg for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 18970728a38Smrg if (info->named_vmods & bit) { 19070728a38Smrg register char *name; 19170728a38Smrg 19270728a38Smrg name = XkbAtomGetString(dpy, xkb->names->vmods[i]); 19370728a38Smrg size += xkmPutCountedString(file, name); 19470728a38Smrg } 1958c9fbc29Smrg } 1968c9fbc29Smrg return size; 1978c9fbc29Smrg} 1988c9fbc29Smrg 1998c9fbc29Smrg/***====================================================================***/ 2008c9fbc29Smrg 2018c9fbc29Smrgstatic unsigned 20270728a38SmrgSizeXKMKeycodes(XkbFileInfo *result, xkmSectionInfo *toc, int *offset_inout) 2038c9fbc29Smrg{ 20470728a38Smrg XkbDescPtr xkb; 20570728a38Smrg Atom kcName; 20670728a38Smrg int size = 0; 20770728a38Smrg Display *dpy; 20870728a38Smrg 20970728a38Smrg xkb = result->xkb; 21070728a38Smrg if ((!xkb) || (!xkb->names) || (!xkb->names->keys)) { 21170728a38Smrg _XkbLibError(_XkbErrMissingNames, "SizeXKMKeycodes", 0); 21270728a38Smrg return 0; 2138c9fbc29Smrg } 21470728a38Smrg dpy = xkb->dpy; 21570728a38Smrg kcName = xkb->names->keycodes; 21670728a38Smrg size += 4; /* min and max keycode */ 21770728a38Smrg size += xkmSizeCountedAtomString(dpy, kcName); 21870728a38Smrg size += XkbNumKeys(xkb) * sizeof(XkbKeyNameRec); 21970728a38Smrg if (xkb->names->num_key_aliases > 0) { 22070728a38Smrg if (xkb->names->key_aliases != NULL) 22170728a38Smrg size += xkb->names->num_key_aliases * sizeof(XkbKeyAliasRec); 22270728a38Smrg else 22370728a38Smrg xkb->names->num_key_aliases = 0; 2248c9fbc29Smrg } 22570728a38Smrg toc->type = XkmKeyNamesIndex; 22670728a38Smrg toc->format = MSBFirst; 22770728a38Smrg toc->size = size + SIZEOF(xkmSectionInfo); 22870728a38Smrg toc->offset = (*offset_inout); 22970728a38Smrg (*offset_inout) += toc->size; 2308c9fbc29Smrg return 1; 2318c9fbc29Smrg} 2328c9fbc29Smrg 2338c9fbc29Smrgstatic unsigned 23470728a38SmrgWriteXKMKeycodes(FILE *file, XkbFileInfo *result) 2358c9fbc29Smrg{ 23670728a38Smrg XkbDescPtr xkb; 23770728a38Smrg Atom kcName; 23870728a38Smrg char *start; 23970728a38Smrg Display *dpy; 24070728a38Smrg unsigned tmp, size = 0; 24170728a38Smrg 24270728a38Smrg xkb = result->xkb; 24370728a38Smrg dpy = xkb->dpy; 24470728a38Smrg kcName = xkb->names->keycodes; 24570728a38Smrg start = xkb->names->keys[xkb->min_key_code].name; 24670728a38Smrg 24770728a38Smrg size += xkmPutCountedString(file, XkbAtomGetString(dpy, kcName)); 24870728a38Smrg size += xkmPutCARD8(file, xkb->min_key_code); 24970728a38Smrg size += xkmPutCARD8(file, xkb->max_key_code); 25070728a38Smrg size += xkmPutCARD8(file, xkb->names->num_key_aliases); 25170728a38Smrg size += xkmPutPadding(file, 1); 25270728a38Smrg tmp = fwrite(start, sizeof(XkbKeyNameRec), XkbNumKeys(xkb), file); 25370728a38Smrg size += tmp * sizeof(XkbKeyNameRec); 25470728a38Smrg if (xkb->names->num_key_aliases > 0) { 25570728a38Smrg tmp = fwrite((char *) xkb->names->key_aliases, 25670728a38Smrg sizeof(XkbKeyAliasRec), xkb->names->num_key_aliases, file); 25770728a38Smrg size += tmp * sizeof(XkbKeyAliasRec); 2588c9fbc29Smrg } 2598c9fbc29Smrg return size; 2608c9fbc29Smrg} 2618c9fbc29Smrg 2628c9fbc29Smrg/***====================================================================***/ 2638c9fbc29Smrg 2648c9fbc29Smrgstatic unsigned 26570728a38SmrgSizeXKMKeyTypes(XkbFileInfo *result, xkmSectionInfo *toc, int *offset_inout) 2668c9fbc29Smrg{ 26770728a38Smrg register unsigned i, n, size; 26870728a38Smrg XkbKeyTypePtr type; 26970728a38Smrg XkbDescPtr xkb; 27070728a38Smrg Display *dpy; 27170728a38Smrg char *name; 27270728a38Smrg 27370728a38Smrg xkb = result->xkb; 27470728a38Smrg if ((!xkb) || (!xkb->map) || (!xkb->map->types)) { 27570728a38Smrg _XkbLibError(_XkbErrMissingTypes, "SizeXKBKeyTypes", 0); 27670728a38Smrg return 0; 2778c9fbc29Smrg } 27870728a38Smrg dpy = xkb->dpy; 27970728a38Smrg if (xkb->map->num_types < XkbNumRequiredTypes) { 28070728a38Smrg _XkbLibError(_XkbErrMissingReqTypes, "SizeXKBKeyTypes", 0); 28170728a38Smrg return 0; 2828c9fbc29Smrg } 28370728a38Smrg if (xkb->names) 28470728a38Smrg name = XkbAtomGetString(dpy, xkb->names->types); 28570728a38Smrg else 28670728a38Smrg name = NULL; 28770728a38Smrg size = xkmSizeCountedString(name); 28870728a38Smrg size += 4; /* room for # of key types + padding */ 28970728a38Smrg for (i = 0, type = xkb->map->types; i < xkb->map->num_types; i++, type++) { 29070728a38Smrg size += SIZEOF(xkmKeyTypeDesc); 29170728a38Smrg size += SIZEOF(xkmKTMapEntryDesc) * type->map_count; 29270728a38Smrg size += xkmSizeCountedAtomString(dpy, type->name); 29370728a38Smrg if (type->preserve) 29470728a38Smrg size += SIZEOF(xkmModsDesc) * type->map_count; 29570728a38Smrg if (type->level_names) { 29670728a38Smrg Atom *names; 29770728a38Smrg 29870728a38Smrg names = type->level_names; 29970728a38Smrg for (n = 0; n < (unsigned) type->num_levels; n++) { 30070728a38Smrg size += xkmSizeCountedAtomString(dpy, names[n]); 30170728a38Smrg } 30270728a38Smrg } 3038c9fbc29Smrg } 30470728a38Smrg toc->type = XkmTypesIndex; 30570728a38Smrg toc->format = MSBFirst; 30670728a38Smrg toc->size = size + SIZEOF(xkmSectionInfo); 30770728a38Smrg toc->offset = (*offset_inout); 30870728a38Smrg (*offset_inout) += toc->size; 3098c9fbc29Smrg return 1; 3108c9fbc29Smrg} 3118c9fbc29Smrg 3128c9fbc29Smrgstatic unsigned 31370728a38SmrgWriteXKMKeyTypes(FILE *file, XkbFileInfo *result) 3148c9fbc29Smrg{ 31570728a38Smrg register unsigned i, n; 31670728a38Smrg XkbDescPtr xkb; 31770728a38Smrg XkbKeyTypePtr type; 31870728a38Smrg xkmKeyTypeDesc wire; 31970728a38Smrg XkbKTMapEntryPtr entry; 32070728a38Smrg xkmKTMapEntryDesc wire_entry; 32170728a38Smrg Atom *names; 32270728a38Smrg Display *dpy; 32370728a38Smrg unsigned tmp, size = 0; 32470728a38Smrg char *name; 32570728a38Smrg 32670728a38Smrg xkb = result->xkb; 32770728a38Smrg dpy = xkb->dpy; 32870728a38Smrg if (xkb->names) 32970728a38Smrg name = XkbAtomGetString(dpy, xkb->names->types); 33070728a38Smrg else 33170728a38Smrg name = NULL; 33270728a38Smrg size += xkmPutCountedString(file, name); 33370728a38Smrg size += xkmPutCARD16(file, xkb->map->num_types); 33470728a38Smrg size += xkmPutPadding(file, 2); 33570728a38Smrg type = xkb->map->types; 33670728a38Smrg for (i = 0; i < xkb->map->num_types; i++, type++) { 33770728a38Smrg wire.realMods = type->mods.real_mods; 33870728a38Smrg wire.virtualMods = type->mods.vmods; 33970728a38Smrg wire.numLevels = type->num_levels; 34070728a38Smrg wire.nMapEntries = type->map_count; 34170728a38Smrg wire.preserve = (type->preserve != NULL); 34270728a38Smrg if (type->level_names != NULL) 34370728a38Smrg wire.nLevelNames = type->num_levels; 34470728a38Smrg else 34570728a38Smrg wire.nLevelNames = 0; 34670728a38Smrg tmp = fwrite(&wire, SIZEOF(xkmKeyTypeDesc), 1, file); 34770728a38Smrg size += tmp * SIZEOF(xkmKeyTypeDesc); 34870728a38Smrg for (n = 0, entry = type->map; n < type->map_count; n++, entry++) { 34970728a38Smrg wire_entry.level = entry->level; 35070728a38Smrg wire_entry.realMods = entry->mods.real_mods; 35170728a38Smrg wire_entry.virtualMods = entry->mods.vmods; 35270728a38Smrg tmp = fwrite(&wire_entry, SIZEOF(xkmKTMapEntryDesc), 1, file); 35370728a38Smrg size += tmp * SIZEOF(xkmKTMapEntryDesc); 35470728a38Smrg } 35570728a38Smrg size += xkmPutCountedString(file, XkbAtomGetString(dpy, type->name)); 35670728a38Smrg if (type->preserve) { 35770728a38Smrg xkmModsDesc p_entry; 35870728a38Smrg 35970728a38Smrg XkbModsPtr pre; 36070728a38Smrg 36170728a38Smrg for (n = 0, pre = type->preserve; n < type->map_count; n++, pre++) { 36270728a38Smrg p_entry.realMods = pre->real_mods; 36370728a38Smrg p_entry.virtualMods = pre->vmods; 36470728a38Smrg tmp = fwrite(&p_entry, SIZEOF(xkmModsDesc), 1, file); 36570728a38Smrg size += tmp * SIZEOF(xkmModsDesc); 36670728a38Smrg } 36770728a38Smrg } 36870728a38Smrg if (type->level_names != NULL) { 36970728a38Smrg names = type->level_names; 37070728a38Smrg for (n = 0; n < wire.nLevelNames; n++) { 37170728a38Smrg size += 37270728a38Smrg xkmPutCountedString(file, XkbAtomGetString(dpy, names[n])); 37370728a38Smrg } 37470728a38Smrg } 3758c9fbc29Smrg } 3768c9fbc29Smrg return size; 3778c9fbc29Smrg} 3788c9fbc29Smrg 3798c9fbc29Smrg/***====================================================================***/ 3808c9fbc29Smrg 3818c9fbc29Smrgstatic unsigned 38270728a38SmrgSizeXKMCompatMap(XkbFileInfo *result, XkmInfo *info, 38370728a38Smrg xkmSectionInfo *toc, int *offset_inout) 3848c9fbc29Smrg{ 38570728a38Smrg XkbDescPtr xkb; 38670728a38Smrg char *name; 38770728a38Smrg int size; 38870728a38Smrg register int i; 38970728a38Smrg unsigned groups, nGroups; 39070728a38Smrg Display *dpy; 39170728a38Smrg 39270728a38Smrg xkb = result->xkb; 39370728a38Smrg if ((!xkb) || (!xkb->compat) || (!xkb->compat->sym_interpret)) { 39470728a38Smrg _XkbLibError(_XkbErrMissingCompatMap, "SizeXKMCompatMap", 0); 39570728a38Smrg return 0; 3968c9fbc29Smrg } 39770728a38Smrg dpy = xkb->dpy; 39870728a38Smrg if (xkb->names) 39970728a38Smrg name = XkbAtomGetString(dpy, xkb->names->compat); 40070728a38Smrg else 40170728a38Smrg name = NULL; 40270728a38Smrg 40370728a38Smrg for (i = groups = nGroups = 0; i < XkbNumKbdGroups; i++) { 40470728a38Smrg if ((xkb->compat->groups[i].real_mods != 0) || 40570728a38Smrg (xkb->compat->groups[i].vmods != 0)) { 40670728a38Smrg groups |= (1 << i); 40770728a38Smrg nGroups++; 40870728a38Smrg } 4098c9fbc29Smrg } 41070728a38Smrg info->group_compat = groups; 41170728a38Smrg info->num_group_compat = nGroups; 41270728a38Smrg size = 4; /* room for num_si and group_compat mask */ 41370728a38Smrg size += xkmSizeCountedString(name); 41470728a38Smrg size += (SIZEOF(xkmSymInterpretDesc) * xkb->compat->num_si); 41570728a38Smrg size += (SIZEOF(xkmModsDesc) * nGroups); 41670728a38Smrg toc->type = XkmCompatMapIndex; 41770728a38Smrg toc->format = MSBFirst; 41870728a38Smrg toc->size = size + SIZEOF(xkmSectionInfo); 41970728a38Smrg toc->offset = (*offset_inout); 42070728a38Smrg (*offset_inout) += toc->size; 4218c9fbc29Smrg return 1; 4228c9fbc29Smrg} 4238c9fbc29Smrg 4248c9fbc29Smrgstatic unsigned 42570728a38SmrgWriteXKMCompatMap(FILE *file, XkbFileInfo *result, XkmInfo *info) 4268c9fbc29Smrg{ 42770728a38Smrg register unsigned i; 42870728a38Smrg char *name; 42970728a38Smrg XkbDescPtr xkb; 43070728a38Smrg XkbSymInterpretPtr interp; 43170728a38Smrg xkmSymInterpretDesc wire; 43270728a38Smrg Display *dpy; 43370728a38Smrg unsigned tmp, size = 0; 43470728a38Smrg 43570728a38Smrg xkb = result->xkb; 43670728a38Smrg dpy = xkb->dpy; 43770728a38Smrg if (xkb->names) 43870728a38Smrg name = XkbAtomGetString(dpy, xkb->names->compat); 43970728a38Smrg else 44070728a38Smrg name = NULL; 44170728a38Smrg size += xkmPutCountedString(file, name); 44270728a38Smrg size += xkmPutCARD16(file, xkb->compat->num_si); 44370728a38Smrg size += xkmPutCARD8(file, info->group_compat); 44470728a38Smrg size += xkmPutPadding(file, 1); 44570728a38Smrg interp = xkb->compat->sym_interpret; 44670728a38Smrg for (i = 0; i < xkb->compat->num_si; i++, interp++) { 44770728a38Smrg wire.sym = interp->sym; 44870728a38Smrg wire.mods = interp->mods; 44970728a38Smrg wire.match = interp->match; 45070728a38Smrg wire.virtualMod = interp->virtual_mod; 45170728a38Smrg wire.flags = interp->flags; 45270728a38Smrg wire.actionType = interp->act.type; 45370728a38Smrg wire.actionData[0] = interp->act.data[0]; 45470728a38Smrg wire.actionData[1] = interp->act.data[1]; 45570728a38Smrg wire.actionData[2] = interp->act.data[2]; 45670728a38Smrg wire.actionData[3] = interp->act.data[3]; 45770728a38Smrg wire.actionData[4] = interp->act.data[4]; 45870728a38Smrg wire.actionData[5] = interp->act.data[5]; 45970728a38Smrg wire.actionData[6] = interp->act.data[6]; 46070728a38Smrg tmp = fwrite(&wire, SIZEOF(xkmSymInterpretDesc), 1, file); 46170728a38Smrg size += tmp * SIZEOF(xkmSymInterpretDesc); 4628c9fbc29Smrg } 4638c9fbc29Smrg if (info->group_compat) { 46470728a38Smrg register unsigned bit; 46570728a38Smrg 46670728a38Smrg xkmModsDesc modsWire; 46770728a38Smrg 46870728a38Smrg for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { 46970728a38Smrg if (info->group_compat & bit) { 47070728a38Smrg modsWire.realMods = xkb->compat->groups[i].real_mods; 47170728a38Smrg modsWire.virtualMods = xkb->compat->groups[i].vmods; 47270728a38Smrg fwrite(&modsWire, SIZEOF(xkmModsDesc), 1, file); 47370728a38Smrg size += SIZEOF(xkmModsDesc); 47470728a38Smrg } 47570728a38Smrg } 4768c9fbc29Smrg } 4778c9fbc29Smrg return size; 4788c9fbc29Smrg} 4798c9fbc29Smrg 4808c9fbc29Smrg/***====================================================================***/ 4818c9fbc29Smrg 4828c9fbc29Smrgstatic unsigned 48370728a38SmrgSizeXKMSymbols(XkbFileInfo *result, XkmInfo *info, 48470728a38Smrg xkmSectionInfo *toc, int *offset_inout) 4858c9fbc29Smrg{ 48670728a38Smrg Display *dpy; 48770728a38Smrg XkbDescPtr xkb; 48870728a38Smrg unsigned size; 48970728a38Smrg register int i, nSyms; 49070728a38Smrg char *name; 49170728a38Smrg 49270728a38Smrg xkb = result->xkb; 49370728a38Smrg if ((!xkb) || (!xkb->map) || ((!xkb->map->syms))) { 49470728a38Smrg _XkbLibError(_XkbErrMissingSymbols, "SizeXKMSymbols", 0); 49570728a38Smrg return 0; 4968c9fbc29Smrg } 49770728a38Smrg dpy = xkb->dpy; 49870728a38Smrg if (xkb->names && (xkb->names->symbols != None)) 49970728a38Smrg name = XkbAtomGetString(dpy, xkb->names->symbols); 50070728a38Smrg else 50170728a38Smrg name = NULL; 50270728a38Smrg size = xkmSizeCountedString(name); 50370728a38Smrg size += 4; /* min and max keycode, group names mask */ 50470728a38Smrg for (i = 0; i < XkbNumKbdGroups; i++) { 50570728a38Smrg if (xkb->names->groups[i] != None) 50670728a38Smrg size += xkmSizeCountedAtomString(dpy, xkb->names->groups[i]); 5078c9fbc29Smrg } 50870728a38Smrg info->total_vmodmaps = 0; 50970728a38Smrg for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { 51070728a38Smrg nSyms = XkbKeyNumSyms(xkb, i); 51170728a38Smrg size += SIZEOF(xkmKeySymMapDesc) + (nSyms * 4); 51270728a38Smrg if (xkb->server) { 51370728a38Smrg if (xkb->server->explicit[i] & XkbExplicitKeyTypesMask) { 51470728a38Smrg register int g; 51570728a38Smrg 51670728a38Smrg for (g = XkbKeyNumGroups(xkb, i) - 1; g >= 0; g--) { 51770728a38Smrg if (xkb->server->explicit[i] & (1 << g)) { 51870728a38Smrg XkbKeyTypePtr type; 51970728a38Smrg char *name; 52070728a38Smrg 52170728a38Smrg type = XkbKeyKeyType(xkb, i, g); 52270728a38Smrg name = XkbAtomGetString(dpy, type->name); 52370728a38Smrg if (name != NULL) 52470728a38Smrg size += xkmSizeCountedString(name); 52570728a38Smrg } 52670728a38Smrg } 52770728a38Smrg } 52870728a38Smrg if (XkbKeyHasActions(xkb, i)) 52970728a38Smrg size += nSyms * SIZEOF(xkmActionDesc); 53070728a38Smrg if (xkb->server->behaviors[i].type != XkbKB_Default) 53170728a38Smrg size += SIZEOF(xkmBehaviorDesc); 53270728a38Smrg if (xkb->server->vmodmap && (xkb->server->vmodmap[i] != 0)) 53370728a38Smrg info->total_vmodmaps++; 53470728a38Smrg } 5358c9fbc29Smrg } 53670728a38Smrg size += info->total_vmodmaps * SIZEOF(xkmVModMapDesc); 53770728a38Smrg toc->type = XkmSymbolsIndex; 53870728a38Smrg toc->format = MSBFirst; 53970728a38Smrg toc->size = size + SIZEOF(xkmSectionInfo); 54070728a38Smrg toc->offset = (*offset_inout); 54170728a38Smrg (*offset_inout) += toc->size; 5428c9fbc29Smrg return 1; 5438c9fbc29Smrg} 5448c9fbc29Smrg 5458c9fbc29Smrgstatic unsigned 54670728a38SmrgWriteXKMSymbols(FILE *file, XkbFileInfo *result, XkmInfo *info) 5478c9fbc29Smrg{ 54870728a38Smrg Display *dpy; 54970728a38Smrg XkbDescPtr xkb; 55070728a38Smrg register int i, n; 55170728a38Smrg xkmKeySymMapDesc wireMap; 55270728a38Smrg char *name; 55370728a38Smrg unsigned tmp, size = 0; 55470728a38Smrg 55570728a38Smrg xkb = result->xkb; 55670728a38Smrg dpy = xkb->dpy; 55770728a38Smrg if (xkb->names && (xkb->names->symbols != None)) 55870728a38Smrg name = XkbAtomGetString(dpy, xkb->names->symbols); 55970728a38Smrg else 56070728a38Smrg name = NULL; 56170728a38Smrg size += xkmPutCountedString(file, name); 56270728a38Smrg for (tmp = i = 0; i < XkbNumKbdGroups; i++) { 56370728a38Smrg if (xkb->names->groups[i] != None) 56470728a38Smrg tmp |= (1 << i); 5658c9fbc29Smrg } 56670728a38Smrg size += xkmPutCARD8(file, xkb->min_key_code); 56770728a38Smrg size += xkmPutCARD8(file, xkb->max_key_code); 56870728a38Smrg size += xkmPutCARD8(file, tmp); 56970728a38Smrg size += xkmPutCARD8(file, info->total_vmodmaps); 57070728a38Smrg for (i = 0, n = 1; i < XkbNumKbdGroups; i++, n <<= 1) { 57170728a38Smrg if ((tmp & n) == 0) 57270728a38Smrg continue; 57370728a38Smrg size += xkmPutCountedAtomString(dpy, file, xkb->names->groups[i]); 5748c9fbc29Smrg } 57570728a38Smrg for (i = xkb->min_key_code; i <= (int) xkb->max_key_code; i++) { 57670728a38Smrg char *typeName[XkbNumKbdGroups]; 57770728a38Smrg 57870728a38Smrg wireMap.width = XkbKeyGroupsWidth(xkb, i); 57970728a38Smrg wireMap.num_groups = XkbKeyGroupInfo(xkb, i); 58070728a38Smrg if (xkb->map && xkb->map->modmap) 58170728a38Smrg wireMap.modifier_map = xkb->map->modmap[i]; 58270728a38Smrg else 58370728a38Smrg wireMap.modifier_map = 0; 58470728a38Smrg wireMap.flags = 0; 58570728a38Smrg bzero((char *) typeName, XkbNumKbdGroups * sizeof(char *)); 58670728a38Smrg if (xkb->server) { 58770728a38Smrg if (xkb->server->explicit[i] & XkbExplicitKeyTypesMask) { 58870728a38Smrg register int g; 58970728a38Smrg 59070728a38Smrg for (g = 0; g < XkbKeyNumGroups(xkb, i); g++) { 59170728a38Smrg if (xkb->server->explicit[i] & (1 << g)) { 59270728a38Smrg XkbKeyTypePtr type; 59370728a38Smrg 59470728a38Smrg type = XkbKeyKeyType(xkb, i, g); 59570728a38Smrg typeName[g] = XkbAtomGetString(dpy, type->name); 59670728a38Smrg if (typeName[g] != NULL) 59770728a38Smrg wireMap.flags |= (1 << g); 59870728a38Smrg } 59970728a38Smrg } 60070728a38Smrg } 60170728a38Smrg if (XkbKeyHasActions(xkb, i)) 60270728a38Smrg wireMap.flags |= XkmKeyHasActions; 60370728a38Smrg if (xkb->server->behaviors[i].type != XkbKB_Default) 60470728a38Smrg wireMap.flags |= XkmKeyHasBehavior; 60570728a38Smrg if ((xkb->server->explicit[i] & XkbExplicitAutoRepeatMask) && 60670728a38Smrg (xkb->ctrls != NULL)) { 60770728a38Smrg if (xkb->ctrls->per_key_repeat[(i / 8)] & (1 << (i % 8))) 60870728a38Smrg wireMap.flags |= XkmRepeatingKey; 60970728a38Smrg else 61070728a38Smrg wireMap.flags |= XkmNonRepeatingKey; 61170728a38Smrg } 61270728a38Smrg } 61370728a38Smrg tmp = fwrite(&wireMap, SIZEOF(xkmKeySymMapDesc), 1, file); 61470728a38Smrg size += tmp * SIZEOF(xkmKeySymMapDesc); 61570728a38Smrg if (xkb->server->explicit[i] & XkbExplicitKeyTypesMask) { 61670728a38Smrg register int g; 61770728a38Smrg 61870728a38Smrg for (g = 0; g < XkbNumKbdGroups; g++) { 61970728a38Smrg if (typeName[g] != NULL) 62070728a38Smrg size += xkmPutCountedString(file, typeName[g]); 62170728a38Smrg } 62270728a38Smrg } 62370728a38Smrg if (XkbNumGroups(wireMap.num_groups) > 0) { 62470728a38Smrg KeySym *sym; 62570728a38Smrg 62670728a38Smrg sym = XkbKeySymsPtr(xkb, i); 62770728a38Smrg for (n = XkbKeyNumSyms(xkb, i); n > 0; n--, sym++) { 62870728a38Smrg size += xkmPutCARD32(file, (CARD32) *sym); 62970728a38Smrg } 63070728a38Smrg if (wireMap.flags & XkmKeyHasActions) { 63170728a38Smrg XkbAction *act; 63270728a38Smrg 63370728a38Smrg act = XkbKeyActionsPtr(xkb, i); 63470728a38Smrg for (n = XkbKeyNumActions(xkb, i); n > 0; n--, act++) { 63570728a38Smrg tmp = fwrite(act, SIZEOF(xkmActionDesc), 1, file); 63670728a38Smrg size += tmp * SIZEOF(xkmActionDesc); 63770728a38Smrg } 63870728a38Smrg } 63970728a38Smrg } 64070728a38Smrg if (wireMap.flags & XkmKeyHasBehavior) { 64170728a38Smrg xkmBehaviorDesc b; 64270728a38Smrg 64370728a38Smrg b.type = xkb->server->behaviors[i].type; 64470728a38Smrg b.data = xkb->server->behaviors[i].data; 64570728a38Smrg tmp = fwrite(&b, SIZEOF(xkmBehaviorDesc), 1, file); 64670728a38Smrg size += tmp * SIZEOF(xkmBehaviorDesc); 64770728a38Smrg } 6488c9fbc29Smrg } 64970728a38Smrg if (info->total_vmodmaps > 0) { 65070728a38Smrg xkmVModMapDesc v; 65170728a38Smrg 65270728a38Smrg for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 65370728a38Smrg if (xkb->server->vmodmap[i] != 0) { 65470728a38Smrg v.key = i; 65570728a38Smrg v.vmods = xkb->server->vmodmap[i]; 65670728a38Smrg tmp = fwrite(&v, SIZEOF(xkmVModMapDesc), 1, file); 65770728a38Smrg size += tmp * SIZEOF(xkmVModMapDesc); 65870728a38Smrg } 65970728a38Smrg } 6608c9fbc29Smrg } 6618c9fbc29Smrg return size; 6628c9fbc29Smrg} 6638c9fbc29Smrg 6648c9fbc29Smrg/***====================================================================***/ 6658c9fbc29Smrg 6668c9fbc29Smrgstatic unsigned 66770728a38SmrgSizeXKMIndicators(XkbFileInfo *result, XkmInfo *info, 66870728a38Smrg xkmSectionInfo *toc, int *offset_inout) 6698c9fbc29Smrg{ 67070728a38Smrg Display *dpy; 67170728a38Smrg XkbDescPtr xkb; 67270728a38Smrg unsigned size; 67370728a38Smrg register unsigned i, nLEDs; 67470728a38Smrg 67570728a38Smrg xkb = result->xkb; 67670728a38Smrg if ((xkb == NULL) || (xkb->indicators == NULL)) { 6778c9fbc29Smrg/* _XkbLibError(_XkbErrMissingIndicators,"SizeXKMIndicators",0);*/ 67870728a38Smrg return 0; 6798c9fbc29Smrg } 68070728a38Smrg dpy = xkb->dpy; 68170728a38Smrg nLEDs = 0; 68270728a38Smrg size = 8; /* number of indicator maps/physical indicators */ 68370728a38Smrg if (xkb->indicators != NULL) { 68470728a38Smrg for (i = 0; i < XkbNumIndicators; i++) { 68570728a38Smrg XkbIndicatorMapPtr map = &xkb->indicators->maps[i]; 68670728a38Smrg 68770728a38Smrg if ((map->flags != 0) || (map->which_groups != 0) || 68870728a38Smrg (map->groups != 0) || (map->which_mods != 0) || 68970728a38Smrg (map->mods.real_mods != 0) || (map->mods.vmods != 0) || 69070728a38Smrg (map->ctrls != 0) || 69170728a38Smrg (xkb->names && (xkb->names->indicators[i] != None))) { 69270728a38Smrg char *name; 69370728a38Smrg 69470728a38Smrg if (xkb->names && xkb->names->indicators[i] != None) { 69570728a38Smrg name = XkbAtomGetString(dpy, xkb->names->indicators[i]); 69670728a38Smrg } 69770728a38Smrg else 69870728a38Smrg name = NULL; 69970728a38Smrg size += xkmSizeCountedString(name); 70070728a38Smrg size += SIZEOF(xkmIndicatorMapDesc); 70170728a38Smrg nLEDs++; 70270728a38Smrg } 70370728a38Smrg } 7048c9fbc29Smrg } 70570728a38Smrg info->num_leds = nLEDs; 70670728a38Smrg toc->type = XkmIndicatorsIndex; 70770728a38Smrg toc->format = MSBFirst; 70870728a38Smrg toc->size = size + SIZEOF(xkmSectionInfo); 70970728a38Smrg toc->offset = (*offset_inout); 71070728a38Smrg (*offset_inout) += toc->size; 7118c9fbc29Smrg return 1; 7128c9fbc29Smrg} 7138c9fbc29Smrg 7148c9fbc29Smrgstatic unsigned 71570728a38SmrgWriteXKMIndicators(FILE *file, XkbFileInfo *result, XkmInfo *info) 7168c9fbc29Smrg{ 71770728a38Smrg Display *dpy; 71870728a38Smrg XkbDescPtr xkb; 71970728a38Smrg register unsigned i; 72070728a38Smrg xkmIndicatorMapDesc wire; 72170728a38Smrg unsigned tmp, size = 0; 72270728a38Smrg 72370728a38Smrg xkb = result->xkb; 72470728a38Smrg dpy = xkb->dpy; 72570728a38Smrg size += xkmPutCARD8(file, info->num_leds); 72670728a38Smrg size += xkmPutPadding(file, 3); 72770728a38Smrg size += xkmPutCARD32(file, xkb->indicators->phys_indicators); 72870728a38Smrg if (xkb->indicators != NULL) { 72970728a38Smrg for (i = 0; i < XkbNumIndicators; i++) { 73070728a38Smrg XkbIndicatorMapPtr map = &xkb->indicators->maps[i]; 73170728a38Smrg 73270728a38Smrg if ((map->flags != 0) || (map->which_groups != 0) || 73370728a38Smrg (map->groups != 0) || (map->which_mods != 0) || 73470728a38Smrg (map->mods.real_mods != 0) || (map->mods.vmods != 0) || 73570728a38Smrg (map->ctrls != 0) || (xkb->names && 73670728a38Smrg (xkb->names->indicators[i] != None))) { 73770728a38Smrg char *name; 73870728a38Smrg 73970728a38Smrg if (xkb->names && xkb->names->indicators[i] != None) { 74070728a38Smrg name = XkbAtomGetString(dpy, xkb->names->indicators[i]); 74170728a38Smrg } 74270728a38Smrg else 74370728a38Smrg name = NULL; 74470728a38Smrg size += xkmPutCountedString(file, name); 74570728a38Smrg wire.indicator = i + 1; 74670728a38Smrg wire.flags = map->flags; 74770728a38Smrg wire.which_mods = map->which_mods; 74870728a38Smrg wire.real_mods = map->mods.real_mods; 74970728a38Smrg wire.vmods = map->mods.vmods; 75070728a38Smrg wire.which_groups = map->which_groups; 75170728a38Smrg wire.groups = map->groups; 75270728a38Smrg wire.ctrls = map->ctrls; 75370728a38Smrg tmp = fwrite(&wire, SIZEOF(xkmIndicatorMapDesc), 1, file); 75470728a38Smrg size += tmp * SIZEOF(xkmIndicatorMapDesc); 75570728a38Smrg } 75670728a38Smrg } 7578c9fbc29Smrg } 7588c9fbc29Smrg return size; 7598c9fbc29Smrg} 7608c9fbc29Smrg 7618c9fbc29Smrg/***====================================================================***/ 7628c9fbc29Smrg 7638c9fbc29Smrgstatic unsigned 76470728a38SmrgSizeXKMGeomDoodad(XkbFileInfo *result, XkbDoodadPtr doodad) 7658c9fbc29Smrg{ 76670728a38Smrg unsigned size; 7678c9fbc29Smrg 76870728a38Smrg size = SIZEOF(xkmAnyDoodadDesc); 76970728a38Smrg size += xkmSizeCountedAtomString(result->xkb->dpy, doodad->any.name); 77070728a38Smrg if (doodad->any.type == XkbTextDoodad) { 77170728a38Smrg size += xkmSizeCountedString(doodad->text.text); 77270728a38Smrg size += xkmSizeCountedString(doodad->text.font); 7738c9fbc29Smrg } 77470728a38Smrg else if (doodad->any.type == XkbLogoDoodad) { 77570728a38Smrg size += xkmSizeCountedString(doodad->logo.logo_name); 7768c9fbc29Smrg } 7778c9fbc29Smrg return size; 7788c9fbc29Smrg} 7798c9fbc29Smrg 7808c9fbc29Smrgstatic unsigned 78170728a38SmrgSizeXKMGeomSection(XkbFileInfo *result, XkbSectionPtr section) 7828c9fbc29Smrg{ 78370728a38Smrg register int i; 78470728a38Smrg unsigned size; 7858c9fbc29Smrg 78670728a38Smrg size = SIZEOF(xkmSectionDesc); 78770728a38Smrg size += xkmSizeCountedAtomString(result->xkb->dpy, section->name); 7888c9fbc29Smrg if (section->rows) { 78970728a38Smrg XkbRowPtr row; 79070728a38Smrg 79170728a38Smrg for (row = section->rows, i = 0; i < section->num_rows; i++, row++) { 79270728a38Smrg size += SIZEOF(xkmRowDesc); 79370728a38Smrg size += row->num_keys * SIZEOF(xkmKeyDesc); 79470728a38Smrg } 7958c9fbc29Smrg } 7968c9fbc29Smrg if (section->doodads) { 79770728a38Smrg XkbDoodadPtr doodad; 79870728a38Smrg 79970728a38Smrg for (doodad = section->doodads, i = 0; i < section->num_doodads; 80070728a38Smrg i++, doodad++) { 80170728a38Smrg size += SizeXKMGeomDoodad(result, doodad); 80270728a38Smrg } 8038c9fbc29Smrg } 8048c9fbc29Smrg if (section->overlays) { 80570728a38Smrg XkbOverlayPtr ol; 80670728a38Smrg 80770728a38Smrg for (ol = section->overlays, i = 0; i < section->num_overlays; 80870728a38Smrg i++, ol++) { 80970728a38Smrg register int r; 81070728a38Smrg XkbOverlayRowPtr row; 81170728a38Smrg 81270728a38Smrg size += xkmSizeCountedAtomString(result->xkb->dpy, ol->name); 81370728a38Smrg size += SIZEOF(xkmOverlayDesc); 81470728a38Smrg for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { 81570728a38Smrg size += SIZEOF(xkmOverlayRowDesc); 81670728a38Smrg size += row->num_keys * SIZEOF(xkmOverlayKeyDesc); 81770728a38Smrg } 81870728a38Smrg } 8198c9fbc29Smrg } 8208c9fbc29Smrg return size; 8218c9fbc29Smrg} 8228c9fbc29Smrg 8238c9fbc29Smrgstatic unsigned 82470728a38SmrgSizeXKMGeometry(XkbFileInfo *result, xkmSectionInfo *toc, int *offset_inout) 8258c9fbc29Smrg{ 82670728a38Smrg register int i; 82770728a38Smrg Display *dpy; 82870728a38Smrg XkbDescPtr xkb; 82970728a38Smrg XkbGeometryPtr geom; 83070728a38Smrg unsigned size; 83170728a38Smrg 83270728a38Smrg xkb = result->xkb; 83370728a38Smrg if ((!xkb) || (!xkb->geom)) 83470728a38Smrg return 0; 83570728a38Smrg dpy = xkb->dpy; 83670728a38Smrg geom = xkb->geom; 83770728a38Smrg size = xkmSizeCountedAtomString(dpy, geom->name); 83870728a38Smrg size += SIZEOF(xkmGeometryDesc); 83970728a38Smrg size += xkmSizeCountedString(geom->label_font); 8408c9fbc29Smrg if (geom->properties) { 84170728a38Smrg XkbPropertyPtr prop; 84270728a38Smrg 84370728a38Smrg for (i = 0, prop = geom->properties; i < geom->num_properties; 84470728a38Smrg i++, prop++) { 84570728a38Smrg size += xkmSizeCountedString(prop->name); 84670728a38Smrg size += xkmSizeCountedString(prop->value); 84770728a38Smrg } 8488c9fbc29Smrg } 8498c9fbc29Smrg if (geom->colors) { 85070728a38Smrg XkbColorPtr color; 85170728a38Smrg 85270728a38Smrg for (i = 0, color = geom->colors; i < geom->num_colors; i++, color++) { 85370728a38Smrg size += xkmSizeCountedString(color->spec); 85470728a38Smrg } 8558c9fbc29Smrg } 8568c9fbc29Smrg if (geom->shapes) { 85770728a38Smrg XkbShapePtr shape; 85870728a38Smrg 85970728a38Smrg for (i = 0, shape = geom->shapes; i < geom->num_shapes; i++, shape++) { 86070728a38Smrg register int n; 86170728a38Smrg register XkbOutlinePtr ol; 86270728a38Smrg 86370728a38Smrg size += xkmSizeCountedAtomString(dpy, shape->name); 86470728a38Smrg size += SIZEOF(xkmShapeDesc); 86570728a38Smrg for (n = 0, ol = shape->outlines; n < shape->num_outlines; 86670728a38Smrg n++, ol++) { 86770728a38Smrg size += SIZEOF(xkmOutlineDesc); 86870728a38Smrg size += ol->num_points * SIZEOF(xkmPointDesc); 86970728a38Smrg } 87070728a38Smrg } 8718c9fbc29Smrg } 8728c9fbc29Smrg if (geom->sections) { 87370728a38Smrg XkbSectionPtr section; 87470728a38Smrg 87570728a38Smrg for (i = 0, section = geom->sections; i < geom->num_sections; 87670728a38Smrg i++, section++) { 87770728a38Smrg size += SizeXKMGeomSection(result, section); 87870728a38Smrg } 8798c9fbc29Smrg } 88070728a38Smrg if (geom->doodads) { 88170728a38Smrg XkbDoodadPtr doodad; 88270728a38Smrg 88370728a38Smrg for (i = 0, doodad = geom->doodads; i < geom->num_doodads; 88470728a38Smrg i++, doodad++) { 88570728a38Smrg size += SizeXKMGeomDoodad(result, doodad); 88670728a38Smrg } 8878c9fbc29Smrg } 8888c9fbc29Smrg if (geom->key_aliases) { 88970728a38Smrg size += geom->num_key_aliases * (XkbKeyNameLength * 2); 8908c9fbc29Smrg } 89170728a38Smrg toc->type = XkmGeometryIndex; 89270728a38Smrg toc->format = MSBFirst; 89370728a38Smrg toc->size = size + SIZEOF(xkmSectionInfo); 89470728a38Smrg toc->offset = (*offset_inout); 89570728a38Smrg (*offset_inout) += toc->size; 8968c9fbc29Smrg return 1; 8978c9fbc29Smrg} 8988c9fbc29Smrg 8998c9fbc29Smrgstatic unsigned 90070728a38SmrgWriteXKMGeomDoodad(FILE *file, XkbFileInfo *result, XkbDoodadPtr doodad) 9018c9fbc29Smrg{ 90270728a38Smrg Display *dpy; 90370728a38Smrg XkbDescPtr xkb; 90470728a38Smrg xkmDoodadDesc doodadWire; 90570728a38Smrg unsigned tmp, size = 0; 90670728a38Smrg 90770728a38Smrg xkb = result->xkb; 90870728a38Smrg dpy = xkb->dpy; 90970728a38Smrg bzero((char *) &doodadWire, sizeof(doodadWire)); 91070728a38Smrg doodadWire.any.type = doodad->any.type; 91170728a38Smrg doodadWire.any.priority = doodad->any.priority; 91270728a38Smrg doodadWire.any.top = doodad->any.top; 91370728a38Smrg doodadWire.any.left = doodad->any.left; 9148c9fbc29Smrg switch (doodad->any.type) { 91570728a38Smrg case XkbOutlineDoodad: 91670728a38Smrg case XkbSolidDoodad: 91770728a38Smrg doodadWire.shape.angle = doodad->shape.angle; 91870728a38Smrg doodadWire.shape.color_ndx = doodad->shape.color_ndx; 91970728a38Smrg doodadWire.shape.shape_ndx = doodad->shape.shape_ndx; 92070728a38Smrg break; 92170728a38Smrg case XkbTextDoodad: 92270728a38Smrg doodadWire.text.angle = doodad->text.angle; 92370728a38Smrg doodadWire.text.width = doodad->text.width; 92470728a38Smrg doodadWire.text.height = doodad->text.height; 92570728a38Smrg doodadWire.text.color_ndx = doodad->text.color_ndx; 92670728a38Smrg break; 92770728a38Smrg case XkbIndicatorDoodad: 92870728a38Smrg doodadWire.indicator.shape_ndx = doodad->indicator.shape_ndx; 92970728a38Smrg doodadWire.indicator.on_color_ndx = doodad->indicator.on_color_ndx; 93070728a38Smrg doodadWire.indicator.off_color_ndx = doodad->indicator.off_color_ndx; 93170728a38Smrg break; 93270728a38Smrg case XkbLogoDoodad: 93370728a38Smrg doodadWire.logo.angle = doodad->logo.angle; 93470728a38Smrg doodadWire.logo.color_ndx = doodad->logo.color_ndx; 93570728a38Smrg doodadWire.logo.shape_ndx = doodad->logo.shape_ndx; 93670728a38Smrg break; 93770728a38Smrg default: 93870728a38Smrg _XkbLibError(_XkbErrIllegalDoodad, "WriteXKMGeomDoodad", 93970728a38Smrg doodad->any.type); 94070728a38Smrg return 0; 9418c9fbc29Smrg } 94270728a38Smrg size += xkmPutCountedAtomString(dpy, file, doodad->any.name); 94370728a38Smrg tmp = fwrite(&doodadWire, SIZEOF(xkmDoodadDesc), 1, file); 94470728a38Smrg size += tmp * SIZEOF(xkmDoodadDesc); 94570728a38Smrg if (doodad->any.type == XkbTextDoodad) { 94670728a38Smrg size += xkmPutCountedString(file, doodad->text.text); 94770728a38Smrg size += xkmPutCountedString(file, doodad->text.font); 9488c9fbc29Smrg } 94970728a38Smrg else if (doodad->any.type == XkbLogoDoodad) { 95070728a38Smrg size += xkmPutCountedString(file, doodad->logo.logo_name); 9518c9fbc29Smrg } 9528c9fbc29Smrg return size; 9538c9fbc29Smrg} 9548c9fbc29Smrg 9558c9fbc29Smrgstatic unsigned 95670728a38SmrgWriteXKMGeomOverlay(FILE *file, XkbFileInfo *result, XkbOverlayPtr ol) 9578c9fbc29Smrg{ 95870728a38Smrg register int r, k; 95970728a38Smrg Display *dpy; 96070728a38Smrg XkbDescPtr xkb; 96170728a38Smrg XkbOverlayRowPtr row; 96270728a38Smrg xkmOverlayDesc olWire; 96370728a38Smrg xkmOverlayRowDesc rowWire; 96470728a38Smrg xkmOverlayKeyDesc keyWire; 96570728a38Smrg unsigned tmp, size = 0; 96670728a38Smrg 96770728a38Smrg xkb = result->xkb; 96870728a38Smrg dpy = xkb->dpy; 96970728a38Smrg bzero((char *) &olWire, sizeof(olWire)); 97070728a38Smrg bzero((char *) &rowWire, sizeof(rowWire)); 97170728a38Smrg bzero((char *) &keyWire, sizeof(keyWire)); 97270728a38Smrg size += xkmPutCountedAtomString(dpy, file, ol->name); 97370728a38Smrg olWire.num_rows = ol->num_rows; 97470728a38Smrg tmp = fwrite(&olWire, SIZEOF(xkmOverlayDesc), 1, file); 97570728a38Smrg size += tmp * SIZEOF(xkmOverlayDesc); 97670728a38Smrg for (r = 0, row = ol->rows; r < ol->num_rows; r++, row++) { 97770728a38Smrg XkbOverlayKeyPtr key; 97870728a38Smrg 97970728a38Smrg rowWire.row_under = row->row_under; 98070728a38Smrg rowWire.num_keys = row->num_keys; 98170728a38Smrg tmp = fwrite(&rowWire, SIZEOF(xkmOverlayRowDesc), 1, file); 98270728a38Smrg size += tmp * SIZEOF(xkmOverlayRowDesc); 98370728a38Smrg for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 98470728a38Smrg memcpy(keyWire.over, key->over.name, XkbKeyNameLength); 98570728a38Smrg memcpy(keyWire.under, key->under.name, XkbKeyNameLength); 98670728a38Smrg tmp = fwrite(&keyWire, SIZEOF(xkmOverlayKeyDesc), 1, file); 98770728a38Smrg size += tmp * SIZEOF(xkmOverlayKeyDesc); 98870728a38Smrg } 9898c9fbc29Smrg } 9904cd6a3aeSmrg return size; 9918c9fbc29Smrg} 9928c9fbc29Smrg 9938c9fbc29Smrgstatic unsigned 99470728a38SmrgWriteXKMGeomSection(FILE *file, XkbFileInfo *result, XkbSectionPtr section) 9958c9fbc29Smrg{ 99670728a38Smrg register int i; 99770728a38Smrg Display *dpy; 99870728a38Smrg XkbDescPtr xkb; 99970728a38Smrg xkmSectionDesc sectionWire; 100070728a38Smrg unsigned tmp, size = 0; 100170728a38Smrg 100270728a38Smrg xkb = result->xkb; 100370728a38Smrg dpy = xkb->dpy; 100470728a38Smrg size += xkmPutCountedAtomString(dpy, file, section->name); 100570728a38Smrg sectionWire.top = section->top; 100670728a38Smrg sectionWire.left = section->left; 100770728a38Smrg sectionWire.width = section->width; 100870728a38Smrg sectionWire.height = section->height; 100970728a38Smrg sectionWire.angle = section->angle; 101070728a38Smrg sectionWire.priority = section->priority; 101170728a38Smrg sectionWire.num_rows = section->num_rows; 101270728a38Smrg sectionWire.num_doodads = section->num_doodads; 101370728a38Smrg sectionWire.num_overlays = section->num_overlays; 101470728a38Smrg tmp = fwrite(§ionWire, SIZEOF(xkmSectionDesc), 1, file); 101570728a38Smrg size += tmp * SIZEOF(xkmSectionDesc); 10168c9fbc29Smrg if (section->rows) { 101770728a38Smrg register unsigned k; 101870728a38Smrg XkbRowPtr row; 101970728a38Smrg xkmRowDesc rowWire; 102070728a38Smrg XkbKeyPtr key; 102170728a38Smrg xkmKeyDesc keyWire; 102270728a38Smrg 102370728a38Smrg for (i = 0, row = section->rows; i < section->num_rows; i++, row++) { 102470728a38Smrg rowWire.top = row->top; 102570728a38Smrg rowWire.left = row->left; 102670728a38Smrg rowWire.num_keys = row->num_keys; 102770728a38Smrg rowWire.vertical = row->vertical; 102870728a38Smrg tmp = fwrite(&rowWire, SIZEOF(xkmRowDesc), 1, file); 102970728a38Smrg size += tmp * SIZEOF(xkmRowDesc); 103070728a38Smrg for (k = 0, key = row->keys; k < row->num_keys; k++, key++) { 103170728a38Smrg memcpy(keyWire.name, key->name.name, XkbKeyNameLength); 103270728a38Smrg keyWire.gap = key->gap; 103370728a38Smrg keyWire.shape_ndx = key->shape_ndx; 103470728a38Smrg keyWire.color_ndx = key->color_ndx; 103570728a38Smrg tmp = fwrite(&keyWire, SIZEOF(xkmKeyDesc), 1, file); 103670728a38Smrg size += tmp * SIZEOF(xkmKeyDesc); 103770728a38Smrg } 103870728a38Smrg } 10398c9fbc29Smrg } 10408c9fbc29Smrg if (section->doodads) { 104170728a38Smrg XkbDoodadPtr doodad; 104270728a38Smrg 104370728a38Smrg for (i = 0, doodad = section->doodads; i < section->num_doodads; 104470728a38Smrg i++, doodad++) { 104570728a38Smrg size += WriteXKMGeomDoodad(file, result, doodad); 104670728a38Smrg } 10478c9fbc29Smrg } 10488c9fbc29Smrg if (section->overlays) { 104970728a38Smrg XkbOverlayPtr ol; 105070728a38Smrg 105170728a38Smrg for (i = 0, ol = section->overlays; i < section->num_overlays; 105270728a38Smrg i++, ol++) { 105370728a38Smrg size += WriteXKMGeomOverlay(file, result, ol); 105470728a38Smrg } 10558c9fbc29Smrg } 10568c9fbc29Smrg return size; 10578c9fbc29Smrg} 10588c9fbc29Smrg 10598c9fbc29Smrgstatic unsigned 106070728a38SmrgWriteXKMGeometry(FILE *file, XkbFileInfo *result) 10618c9fbc29Smrg{ 106270728a38Smrg register int i; 106370728a38Smrg Display *dpy; 106470728a38Smrg XkbDescPtr xkb; 106570728a38Smrg XkbGeometryPtr geom; 106670728a38Smrg xkmGeometryDesc wire; 106770728a38Smrg unsigned tmp, size = 0; 106870728a38Smrg 106970728a38Smrg xkb = result->xkb; 107070728a38Smrg if ((!xkb) || (!xkb->geom)) 107170728a38Smrg return 0; 107270728a38Smrg dpy = xkb->dpy; 107370728a38Smrg geom = xkb->geom; 107470728a38Smrg wire.width_mm = geom->width_mm; 107570728a38Smrg wire.height_mm = geom->height_mm; 107670728a38Smrg wire.base_color_ndx = XkbGeomColorIndex(geom, geom->base_color); 107770728a38Smrg wire.label_color_ndx = XkbGeomColorIndex(geom, geom->label_color); 107870728a38Smrg wire.num_properties = geom->num_properties; 107970728a38Smrg wire.num_colors = geom->num_colors; 108070728a38Smrg wire.num_shapes = geom->num_shapes; 108170728a38Smrg wire.num_sections = geom->num_sections; 108270728a38Smrg wire.num_doodads = geom->num_doodads; 108370728a38Smrg wire.num_key_aliases = geom->num_key_aliases; 108470728a38Smrg size += xkmPutCountedAtomString(dpy, file, geom->name); 108570728a38Smrg tmp = fwrite(&wire, SIZEOF(xkmGeometryDesc), 1, file); 108670728a38Smrg size += tmp * SIZEOF(xkmGeometryDesc); 108770728a38Smrg size += xkmPutCountedString(file, geom->label_font); 10888c9fbc29Smrg if (geom->properties) { 108970728a38Smrg XkbPropertyPtr prop; 109070728a38Smrg 109170728a38Smrg for (i = 0, prop = geom->properties; i < geom->num_properties; 109270728a38Smrg i++, prop++) { 109370728a38Smrg size += xkmPutCountedString(file, prop->name); 109470728a38Smrg size += xkmPutCountedString(file, prop->value); 109570728a38Smrg } 10968c9fbc29Smrg } 10978c9fbc29Smrg if (geom->colors) { 109870728a38Smrg XkbColorPtr color; 109970728a38Smrg 110070728a38Smrg for (i = 0, color = geom->colors; i < geom->num_colors; i++, color++) { 110170728a38Smrg size += xkmPutCountedString(file, color->spec); 110270728a38Smrg } 11038c9fbc29Smrg } 11048c9fbc29Smrg if (geom->shapes) { 110570728a38Smrg XkbShapePtr shape; 110670728a38Smrg xkmShapeDesc shapeWire; 110770728a38Smrg 110870728a38Smrg for (i = 0, shape = geom->shapes; i < geom->num_shapes; i++, shape++) { 110970728a38Smrg register int n; 111070728a38Smrg XkbOutlinePtr ol; 111170728a38Smrg xkmOutlineDesc olWire; 111270728a38Smrg 111370728a38Smrg bzero((char *) &shapeWire, sizeof(xkmShapeDesc)); 111470728a38Smrg size += xkmPutCountedAtomString(dpy, file, shape->name); 111570728a38Smrg shapeWire.num_outlines = shape->num_outlines; 111670728a38Smrg if (shape->primary != NULL) 111770728a38Smrg shapeWire.primary_ndx = XkbOutlineIndex(shape, shape->primary); 111870728a38Smrg else 111970728a38Smrg shapeWire.primary_ndx = XkbNoShape; 112070728a38Smrg if (shape->approx != NULL) 112170728a38Smrg shapeWire.approx_ndx = XkbOutlineIndex(shape, shape->approx); 112270728a38Smrg else 112370728a38Smrg shapeWire.approx_ndx = XkbNoShape; 112470728a38Smrg tmp = fwrite(&shapeWire, SIZEOF(xkmShapeDesc), 1, file); 112570728a38Smrg size += tmp * SIZEOF(xkmShapeDesc); 112670728a38Smrg for (n = 0, ol = shape->outlines; n < shape->num_outlines; 112770728a38Smrg n++, ol++) { 112870728a38Smrg register int p; 112970728a38Smrg XkbPointPtr pt; 113070728a38Smrg xkmPointDesc ptWire; 113170728a38Smrg 113270728a38Smrg olWire.num_points = ol->num_points; 113370728a38Smrg olWire.corner_radius = ol->corner_radius; 113470728a38Smrg tmp = fwrite(&olWire, SIZEOF(xkmOutlineDesc), 1, file); 113570728a38Smrg size += tmp * SIZEOF(xkmOutlineDesc); 113670728a38Smrg for (p = 0, pt = ol->points; p < ol->num_points; p++, pt++) { 113770728a38Smrg ptWire.x = pt->x; 113870728a38Smrg ptWire.y = pt->y; 113970728a38Smrg tmp = fwrite(&ptWire, SIZEOF(xkmPointDesc), 1, file); 114070728a38Smrg size += tmp * SIZEOF(xkmPointDesc); 114170728a38Smrg } 114270728a38Smrg } 114370728a38Smrg } 11448c9fbc29Smrg } 11458c9fbc29Smrg if (geom->sections) { 114670728a38Smrg XkbSectionPtr section; 114770728a38Smrg 114870728a38Smrg for (i = 0, section = geom->sections; i < geom->num_sections; 114970728a38Smrg i++, section++) { 115070728a38Smrg size += WriteXKMGeomSection(file, result, section); 115170728a38Smrg } 11528c9fbc29Smrg } 11538c9fbc29Smrg if (geom->doodads) { 115470728a38Smrg XkbDoodadPtr doodad; 115570728a38Smrg 115670728a38Smrg for (i = 0, doodad = geom->doodads; i < geom->num_doodads; 115770728a38Smrg i++, doodad++) { 115870728a38Smrg size += WriteXKMGeomDoodad(file, result, doodad); 115970728a38Smrg } 11608c9fbc29Smrg } 11618c9fbc29Smrg if (geom->key_aliases) { 116270728a38Smrg tmp = 116370728a38Smrg fwrite(geom->key_aliases, 2 * XkbKeyNameLength, 116470728a38Smrg geom->num_key_aliases, file); 116570728a38Smrg size += tmp * (2 * XkbKeyNameLength); 11668c9fbc29Smrg } 11678c9fbc29Smrg return size; 11688c9fbc29Smrg} 11698c9fbc29Smrg 11708c9fbc29Smrg/***====================================================================***/ 11718c9fbc29Smrg 11728c9fbc29Smrg/*ARGSUSED*/ 11738c9fbc29Smrgstatic int 117470728a38SmrgGetXKMKeyNamesTOC(XkbFileInfo *result, XkmInfo *info, 117570728a38Smrg int max_toc, xkmSectionInfo *toc_rtrn) 11768c9fbc29Smrg{ 117770728a38Smrg int num_toc; 117870728a38Smrg int total_size; 117970728a38Smrg 118070728a38Smrg total_size = num_toc = 0; 118170728a38Smrg if (SizeXKMKeycodes(result, &toc_rtrn[num_toc], &total_size)) 118270728a38Smrg num_toc++; 118370728a38Smrg if (SizeXKMIndicators(result, info, &toc_rtrn[num_toc], &total_size)) 118470728a38Smrg num_toc++; 11858c9fbc29Smrg return num_toc; 11868c9fbc29Smrg} 11878c9fbc29Smrg 11888c9fbc29Smrg/*ARGSUSED*/ 11898c9fbc29Smrgstatic int 119070728a38SmrgGetXKMTypesTOC(XkbFileInfo *result, XkmInfo *info, 119170728a38Smrg int max_toc, xkmSectionInfo *toc_rtrn) 11928c9fbc29Smrg{ 119370728a38Smrg int num_toc; 119470728a38Smrg int total_size; 119570728a38Smrg 119670728a38Smrg total_size = num_toc = 0; 119770728a38Smrg if (SizeXKMVirtualMods(result, info, &toc_rtrn[num_toc], &total_size)) 119870728a38Smrg num_toc++; 119970728a38Smrg if (SizeXKMKeyTypes(result, &toc_rtrn[num_toc], &total_size)) 120070728a38Smrg num_toc++; 12018c9fbc29Smrg return num_toc; 12028c9fbc29Smrg} 12038c9fbc29Smrg 12048c9fbc29Smrg/*ARGSUSED*/ 12058c9fbc29Smrgstatic int 120670728a38SmrgGetXKMCompatMapTOC(XkbFileInfo *result, XkmInfo *info, 120770728a38Smrg int max_toc, xkmSectionInfo *toc_rtrn) 12088c9fbc29Smrg{ 120970728a38Smrg int num_toc; 121070728a38Smrg int total_size; 121170728a38Smrg 121270728a38Smrg total_size = num_toc = 0; 121370728a38Smrg if (SizeXKMVirtualMods(result, info, &toc_rtrn[num_toc], &total_size)) 121470728a38Smrg num_toc++; 121570728a38Smrg if (SizeXKMCompatMap(result, info, &toc_rtrn[num_toc], &total_size)) 121670728a38Smrg num_toc++; 121770728a38Smrg if (SizeXKMIndicators(result, info, &toc_rtrn[num_toc], &total_size)) 121870728a38Smrg num_toc++; 12198c9fbc29Smrg return num_toc; 12208c9fbc29Smrg} 12218c9fbc29Smrg 12228c9fbc29Smrg/*ARGSUSED*/ 12238c9fbc29Smrgstatic int 122470728a38SmrgGetXKMSemanticsTOC(XkbFileInfo *result, XkmInfo *info, 122570728a38Smrg int max_toc, xkmSectionInfo *toc_rtrn) 12268c9fbc29Smrg{ 122770728a38Smrg int num_toc; 122870728a38Smrg int total_size; 122970728a38Smrg 123070728a38Smrg total_size = num_toc = 0; 123170728a38Smrg if (SizeXKMVirtualMods(result, info, &toc_rtrn[num_toc], &total_size)) 123270728a38Smrg num_toc++; 123370728a38Smrg if (SizeXKMKeyTypes(result, &toc_rtrn[num_toc], &total_size)) 123470728a38Smrg num_toc++; 123570728a38Smrg if (SizeXKMCompatMap(result, info, &toc_rtrn[num_toc], &total_size)) 123670728a38Smrg num_toc++; 123770728a38Smrg if (SizeXKMIndicators(result, info, &toc_rtrn[num_toc], &total_size)) 123870728a38Smrg num_toc++; 12398c9fbc29Smrg return num_toc; 12408c9fbc29Smrg} 12418c9fbc29Smrg 12428c9fbc29Smrg/*ARGSUSED*/ 12438c9fbc29Smrgstatic int 124470728a38SmrgGetXKMLayoutTOC(XkbFileInfo *result, XkmInfo *info, 124570728a38Smrg int max_toc, xkmSectionInfo *toc_rtrn) 12468c9fbc29Smrg{ 124770728a38Smrg int num_toc; 124870728a38Smrg int total_size; 124970728a38Smrg 125070728a38Smrg total_size = num_toc = 0; 125170728a38Smrg if (SizeXKMVirtualMods(result, info, &toc_rtrn[num_toc], &total_size)) 125270728a38Smrg num_toc++; 125370728a38Smrg if (SizeXKMKeycodes(result, &toc_rtrn[num_toc], &total_size)) 125470728a38Smrg num_toc++; 125570728a38Smrg if (SizeXKMKeyTypes(result, &toc_rtrn[num_toc], &total_size)) 125670728a38Smrg num_toc++; 125770728a38Smrg if (SizeXKMSymbols(result, info, &toc_rtrn[num_toc], &total_size)) 125870728a38Smrg num_toc++; 125970728a38Smrg if (SizeXKMIndicators(result, info, &toc_rtrn[num_toc], &total_size)) 126070728a38Smrg num_toc++; 126170728a38Smrg if (SizeXKMGeometry(result, &toc_rtrn[num_toc], &total_size)) 126270728a38Smrg num_toc++; 12638c9fbc29Smrg return num_toc; 12648c9fbc29Smrg} 12658c9fbc29Smrg 12668c9fbc29Smrg/*ARGSUSED*/ 12678c9fbc29Smrgstatic int 126870728a38SmrgGetXKMKeymapTOC(XkbFileInfo *result, XkmInfo *info, 126970728a38Smrg int max_toc, xkmSectionInfo *toc_rtrn) 12708c9fbc29Smrg{ 127170728a38Smrg int num_toc; 127270728a38Smrg int total_size; 127370728a38Smrg 127470728a38Smrg total_size = num_toc = 0; 127570728a38Smrg if (SizeXKMVirtualMods(result, info, &toc_rtrn[num_toc], &total_size)) 127670728a38Smrg num_toc++; 127770728a38Smrg if (SizeXKMKeycodes(result, &toc_rtrn[num_toc], &total_size)) 127870728a38Smrg num_toc++; 127970728a38Smrg if (SizeXKMKeyTypes(result, &toc_rtrn[num_toc], &total_size)) 128070728a38Smrg num_toc++; 128170728a38Smrg if (SizeXKMCompatMap(result, info, &toc_rtrn[num_toc], &total_size)) 128270728a38Smrg num_toc++; 128370728a38Smrg if (SizeXKMSymbols(result, info, &toc_rtrn[num_toc], &total_size)) 128470728a38Smrg num_toc++; 128570728a38Smrg if (SizeXKMIndicators(result, info, &toc_rtrn[num_toc], &total_size)) 128670728a38Smrg num_toc++; 128770728a38Smrg if (SizeXKMGeometry(result, &toc_rtrn[num_toc], &total_size)) 128870728a38Smrg num_toc++; 12898c9fbc29Smrg return num_toc; 12908c9fbc29Smrg} 12918c9fbc29Smrg 12928c9fbc29Smrg/*ARGSUSED*/ 12938c9fbc29Smrgstatic int 129470728a38SmrgGetXKMGeometryTOC(XkbFileInfo *result, XkmInfo *info, 129570728a38Smrg int max_toc, xkmSectionInfo *toc_rtrn) 12968c9fbc29Smrg{ 129770728a38Smrg int num_toc; 129870728a38Smrg int total_size; 12998c9fbc29Smrg 130070728a38Smrg total_size = num_toc = 0; 130170728a38Smrg if (SizeXKMGeometry(result, &toc_rtrn[num_toc], &total_size)) 130270728a38Smrg num_toc++; 13038c9fbc29Smrg return num_toc; 13048c9fbc29Smrg} 13058c9fbc29Smrg 13068c9fbc29Smrgstatic Bool 130770728a38SmrgWriteXKMFile(FILE *file, XkbFileInfo *result, 130870728a38Smrg int num_toc, xkmSectionInfo *toc, XkmInfo *info) 13098c9fbc29Smrg{ 131070728a38Smrg register int i; 131170728a38Smrg unsigned tmp, size, total = 0; 131270728a38Smrg 131370728a38Smrg for (i = 0; i < num_toc; i++) { 131470728a38Smrg tmp = fwrite(&toc[i], SIZEOF(xkmSectionInfo), 1, file); 131570728a38Smrg total += tmp * SIZEOF(xkmSectionInfo); 131670728a38Smrg switch (toc[i].type) { 131770728a38Smrg case XkmTypesIndex: 131870728a38Smrg size = WriteXKMKeyTypes(file, result); 131970728a38Smrg break; 132070728a38Smrg case XkmCompatMapIndex: 132170728a38Smrg size = WriteXKMCompatMap(file, result, info); 132270728a38Smrg break; 132370728a38Smrg case XkmSymbolsIndex: 132470728a38Smrg size = WriteXKMSymbols(file, result, info); 132570728a38Smrg break; 132670728a38Smrg case XkmIndicatorsIndex: 132770728a38Smrg size = WriteXKMIndicators(file, result, info); 132870728a38Smrg break; 132970728a38Smrg case XkmKeyNamesIndex: 133070728a38Smrg size = WriteXKMKeycodes(file, result); 133170728a38Smrg break; 133270728a38Smrg case XkmGeometryIndex: 133370728a38Smrg size = WriteXKMGeometry(file, result); 133470728a38Smrg break; 133570728a38Smrg case XkmVirtualModsIndex: 133670728a38Smrg size = WriteXKMVirtualMods(file, result, info); 133770728a38Smrg break; 133870728a38Smrg default: 133970728a38Smrg _XkbLibError(_XkbErrIllegalTOCType, "WriteXKMFile", toc[i].type); 134070728a38Smrg return False; 134170728a38Smrg } 134270728a38Smrg size += SIZEOF(xkmSectionInfo); 134370728a38Smrg if (size != toc[i].size) { 134470728a38Smrg _XkbLibError(_XkbErrBadLength, 134570728a38Smrg XkbConfigText(toc[i].type, XkbMessage), 134670728a38Smrg size - toc[i].size); 134770728a38Smrg return False; 134870728a38Smrg } 13498c9fbc29Smrg } 13508c9fbc29Smrg return True; 13518c9fbc29Smrg} 13528c9fbc29Smrg 13538c9fbc29Smrg 13548c9fbc29Smrg#define MAX_TOC 16 13558c9fbc29Smrg 13568c9fbc29SmrgBool 135770728a38SmrgXkbWriteXKMFile(FILE *out, XkbFileInfo *result) 13588c9fbc29Smrg{ 135970728a38Smrg Bool ok; 136070728a38Smrg XkbDescPtr xkb; 136170728a38Smrg XkmInfo info; 136270728a38Smrg int size_toc, i; 136370728a38Smrg unsigned hdr, present; 136470728a38Smrg xkmFileInfo fileInfo; 136570728a38Smrg xkmSectionInfo toc[MAX_TOC]; 136670728a38Smrg 136770728a38Smrg int (*getTOC) (XkbFileInfo * /* result */ , 136870728a38Smrg XkmInfo * /* info */ , 136970728a38Smrg int /* max_to */ , 137070728a38Smrg xkmSectionInfo * /* toc_rtrn */ 137170728a38Smrg ); 13728c9fbc29Smrg 13738c9fbc29Smrg switch (result->type) { 137470728a38Smrg case XkmKeyNamesIndex: 137570728a38Smrg getTOC = GetXKMKeyNamesTOC; 137670728a38Smrg break; 137770728a38Smrg case XkmTypesIndex: 137870728a38Smrg getTOC = GetXKMTypesTOC; 137970728a38Smrg break; 138070728a38Smrg case XkmCompatMapIndex: 138170728a38Smrg getTOC = GetXKMCompatMapTOC; 138270728a38Smrg break; 138370728a38Smrg case XkmSemanticsFile: 138470728a38Smrg getTOC = GetXKMSemanticsTOC; 138570728a38Smrg break; 138670728a38Smrg case XkmLayoutFile: 138770728a38Smrg getTOC = GetXKMLayoutTOC; 138870728a38Smrg break; 138970728a38Smrg case XkmKeymapFile: 139070728a38Smrg getTOC = GetXKMKeymapTOC; 139170728a38Smrg break; 139270728a38Smrg case XkmGeometryFile: 139370728a38Smrg case XkmGeometryIndex: 139470728a38Smrg getTOC = GetXKMGeometryTOC; 139570728a38Smrg break; 139670728a38Smrg default: 139770728a38Smrg _XkbLibError(_XkbErrIllegalContents, 139870728a38Smrg XkbConfigText(result->type, XkbMessage), 0); 139970728a38Smrg return False; 14008c9fbc29Smrg } 140170728a38Smrg xkb = result->xkb; 14028c9fbc29Smrg 140370728a38Smrg bzero((char *) &info, sizeof(XkmInfo)); 140470728a38Smrg size_toc = (*getTOC) (result, &info, MAX_TOC, toc); 140570728a38Smrg if (size_toc < 1) { 140670728a38Smrg _XkbLibError(_XkbErrEmptyFile, "XkbWriteXKMFile", 0); 140770728a38Smrg return False; 14088c9fbc29Smrg } 140970728a38Smrg if (out == NULL) { 141070728a38Smrg _XkbLibError(_XkbErrFileCannotOpen, "XkbWriteXKMFile", 0); 141170728a38Smrg return False; 14128c9fbc29Smrg } 141370728a38Smrg for (i = present = 0; i < size_toc; i++) { 141470728a38Smrg toc[i].offset += 4 + SIZEOF(xkmFileInfo); 141570728a38Smrg toc[i].offset += (size_toc * SIZEOF(xkmSectionInfo)); 141670728a38Smrg if (toc[i].type <= XkmLastIndex) { 141770728a38Smrg present |= (1 << toc[i].type); 141870728a38Smrg } 14198c9fbc29Smrg#ifdef DEBUG 142070728a38Smrg else { 142170728a38Smrg fprintf(stderr, "Illegal section type %d\n", toc[i].type); 142270728a38Smrg fprintf(stderr, "Ignored\n"); 142370728a38Smrg } 14248c9fbc29Smrg#endif 14258c9fbc29Smrg } 142670728a38Smrg hdr = (('x' << 24) | ('k' << 16) | ('m' << 8) | XkmFileVersion); 142770728a38Smrg xkmPutCARD32(out, (unsigned long) hdr); 142870728a38Smrg fileInfo.type = result->type; 142970728a38Smrg fileInfo.min_kc = xkb->min_key_code; 143070728a38Smrg fileInfo.max_kc = xkb->max_key_code; 143170728a38Smrg fileInfo.num_toc = size_toc; 143270728a38Smrg fileInfo.present = present; 143370728a38Smrg fileInfo.pad = 0; 143470728a38Smrg fwrite(&fileInfo, SIZEOF(xkmFileInfo), 1, out); 143570728a38Smrg fwrite(toc, SIZEOF(xkmSectionInfo), size_toc, out); 143670728a38Smrg ok = WriteXKMFile(out, result, size_toc, toc, &info); 14378c9fbc29Smrg return ok; 14388c9fbc29Smrg} 1439