XKBGAlloc.c revision 61b2299d
11ab64890Smrg/* $Xorg: XKBGAlloc.c,v 1.3 2000/08/17 19:45:01 cpqbld Exp $ */
21ab64890Smrg/************************************************************
31ab64890SmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
41ab64890Smrg
51ab64890SmrgPermission to use, copy, modify, and distribute this
61ab64890Smrgsoftware and its documentation for any purpose and without
71ab64890Smrgfee is hereby granted, provided that the above copyright
81ab64890Smrgnotice appear in all copies and that both that copyright
91ab64890Smrgnotice and this permission notice appear in supporting
1061b2299dSmrgdocumentation, and that the name of Silicon Graphics not be
1161b2299dSmrgused in advertising or publicity pertaining to distribution
121ab64890Smrgof the software without specific prior written permission.
1361b2299dSmrgSilicon Graphics makes no representation about the suitability
141ab64890Smrgof this software for any purpose. It is provided "as is"
151ab64890Smrgwithout any express or implied warranty.
161ab64890Smrg
1761b2299dSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
1861b2299dSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
191ab64890SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
2061b2299dSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
2161b2299dSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
2261b2299dSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
231ab64890SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
241ab64890SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE.
251ab64890Smrg
261ab64890Smrg********************************************************/
271ab64890Smrg/* $XFree86: xc/lib/X11/XKBGAlloc.c,v 3.4 2001/01/17 19:41:48 dawes Exp $ */
281ab64890Smrg
291ab64890Smrg#ifdef HAVE_DIX_CONFIG_H
301ab64890Smrg#include <dix-config.h>
311ab64890Smrg#elif defined(HAVE_CONFIG_H)
321ab64890Smrg#include <config.h>
331ab64890Smrg#endif
341ab64890Smrg
351ab64890Smrg#define	NEED_EVENTS
361ab64890Smrg#define	NEED_REPLIES
371ab64890Smrg
381ab64890Smrg#ifndef XKB_IN_SERVER
391ab64890Smrg
401ab64890Smrg#include <stdio.h>
411ab64890Smrg#include "Xlibint.h"
421ab64890Smrg#include "XKBlibint.h"
431ab64890Smrg#include <X11/extensions/XKBgeom.h>
441ab64890Smrg#include <X11/extensions/XKBproto.h>
451ab64890Smrg
4661b2299dSmrg#else
471ab64890Smrg
481ab64890Smrg#include <stdio.h>
491ab64890Smrg#include <X11/X.h>
501ab64890Smrg#include <X11/Xproto.h>
511ab64890Smrg#include "misc.h"
521ab64890Smrg#include "inputstr.h"
531ab64890Smrg#include <X11/extensions/XKBsrv.h>
541ab64890Smrg#include <X11/extensions/XKBgeom.h>
551ab64890Smrg
561ab64890Smrg#endif /* XKB_IN_SERVER */
571ab64890Smrg
581ab64890Smrg#ifdef X_NOT_POSIX
591ab64890Smrg#define Size_t unsigned int
601ab64890Smrg#else
611ab64890Smrg#define Size_t size_t
621ab64890Smrg#endif
631ab64890Smrg
641ab64890Smrg/***====================================================================***/
651ab64890Smrg
6661b2299dSmrgstatic void
671ab64890Smrg_XkbFreeGeomLeafElems(	Bool			freeAll,
681ab64890Smrg			int			first,
691ab64890Smrg			int 			count,
701ab64890Smrg			unsigned short *	num_inout,
711ab64890Smrg			unsigned short *	sz_inout,
721ab64890Smrg			char **			elems,
731ab64890Smrg			unsigned int		elem_sz)
741ab64890Smrg{
751ab64890Smrg    if ((freeAll)||(*elems==NULL)) {
761ab64890Smrg	*num_inout= *sz_inout= 0;
771ab64890Smrg	if (*elems!=NULL) {
781ab64890Smrg	    _XkbFree(*elems);
791ab64890Smrg	    *elems= NULL;
8061b2299dSmrg	}
811ab64890Smrg	return;
821ab64890Smrg    }
831ab64890Smrg
841ab64890Smrg    if ((first>=(*num_inout))||(first<0)||(count<1))
851ab64890Smrg	return;
861ab64890Smrg
8761b2299dSmrg    if (first+count>=(*num_inout)) {
881ab64890Smrg	/* truncating the array is easy */
891ab64890Smrg	(*num_inout)= first;
901ab64890Smrg    }
911ab64890Smrg    else {
921ab64890Smrg	char *	ptr;
931ab64890Smrg	int 	extra;
941ab64890Smrg	ptr= *elems;
951ab64890Smrg	extra= ((*num_inout)-(first+count))*elem_sz;
961ab64890Smrg	if (extra>0)
971ab64890Smrg	    memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],extra);
981ab64890Smrg	(*num_inout)-= count;
991ab64890Smrg    }
1001ab64890Smrg    return;
1011ab64890Smrg}
1021ab64890Smrg
1031ab64890Smrgtypedef void (*ContentsClearFunc)(
1041ab64890Smrg		char *		/* priv */
1051ab64890Smrg);
1061ab64890Smrg
10761b2299dSmrgstatic void
1081ab64890Smrg_XkbFreeGeomNonLeafElems(	Bool			freeAll,
1091ab64890Smrg				int			first,
1101ab64890Smrg				int 			count,
1111ab64890Smrg				unsigned short *	num_inout,
1121ab64890Smrg				unsigned short *	sz_inout,
1131ab64890Smrg				char **			elems,
1141ab64890Smrg				unsigned int		elem_sz,
1151ab64890Smrg				ContentsClearFunc	freeFunc)
1161ab64890Smrg{
1171ab64890Smrgregister int i;
1181ab64890Smrgregister char *ptr;
1191ab64890Smrg
1201ab64890Smrg    if (freeAll) {
1211ab64890Smrg	first= 0;
1221ab64890Smrg	count= (*num_inout);
1231ab64890Smrg    }
1241ab64890Smrg    else if ((first>=(*num_inout))||(first<0)||(count<1))
1251ab64890Smrg	return;
1261ab64890Smrg    else if (first+count>(*num_inout))
1271ab64890Smrg	count= (*num_inout)-first;
1281ab64890Smrg    if (*elems==NULL)
1291ab64890Smrg	return;
1301ab64890Smrg
1311ab64890Smrg    if (freeFunc) {
1321ab64890Smrg	ptr= *elems;
1331ab64890Smrg	ptr+= first*elem_sz;
1341ab64890Smrg	for (i=0;i<count;i++) {
1351ab64890Smrg	    (*freeFunc)(ptr);
1361ab64890Smrg	    ptr+= elem_sz;
1371ab64890Smrg	}
1381ab64890Smrg    }
1391ab64890Smrg    if (freeAll) {
1401ab64890Smrg	(*num_inout)= (*sz_inout)= 0;
1411ab64890Smrg	if (*elems) {
1421ab64890Smrg	    _XkbFree(*elems);
1431ab64890Smrg	    *elems= NULL;
1441ab64890Smrg	}
1451ab64890Smrg    }
1461ab64890Smrg    else if (first+count>=(*num_inout))
1471ab64890Smrg	*num_inout= first;
1481ab64890Smrg    else {
1491ab64890Smrg	i= ((*num_inout)-(first+count))*elem_sz;
1501ab64890Smrg	ptr= *elems;
1511ab64890Smrg	memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],i);
1521ab64890Smrg	(*num_inout)-= count;
1531ab64890Smrg    }
1541ab64890Smrg    return;
1551ab64890Smrg}
1561ab64890Smrg
1571ab64890Smrg/***====================================================================***/
1581ab64890Smrg
1591ab64890Smrgstatic void
1601ab64890Smrg_XkbClearProperty(char *prop_in)
1611ab64890Smrg{
1621ab64890SmrgXkbPropertyPtr	prop= (XkbPropertyPtr)prop_in;
1631ab64890Smrg
1641ab64890Smrg    if (prop->name) {
1651ab64890Smrg	_XkbFree(prop->name);
1661ab64890Smrg	prop->name= NULL;
1671ab64890Smrg    }
1681ab64890Smrg    if (prop->value) {
1691ab64890Smrg	_XkbFree(prop->value);
1701ab64890Smrg	prop->value= NULL;
1711ab64890Smrg    }
1721ab64890Smrg    return;
1731ab64890Smrg}
1741ab64890Smrg
1751ab64890Smrgvoid
1761ab64890SmrgXkbFreeGeomProperties(	XkbGeometryPtr	geom,
1771ab64890Smrg			int		first,
1781ab64890Smrg			int		count,
1791ab64890Smrg			Bool		freeAll)
1801ab64890Smrg{
1811ab64890Smrg    _XkbFreeGeomNonLeafElems(freeAll,first,count,
1821ab64890Smrg				&geom->num_properties,&geom->sz_properties,
1831ab64890Smrg				(char **)&geom->properties,
1841ab64890Smrg				sizeof(XkbPropertyRec),_XkbClearProperty);
1851ab64890Smrg    return;
1861ab64890Smrg}
1871ab64890Smrg
1881ab64890Smrg/***====================================================================***/
1891ab64890Smrg
1901ab64890Smrgvoid
1911ab64890SmrgXkbFreeGeomKeyAliases(	XkbGeometryPtr	geom,
1921ab64890Smrg			int		first,
1931ab64890Smrg			int		count,
1941ab64890Smrg			Bool		freeAll)
19561b2299dSmrg{
1961ab64890Smrg    _XkbFreeGeomLeafElems(freeAll,first,count,
1971ab64890Smrg				&geom->num_key_aliases,&geom->sz_key_aliases,
1981ab64890Smrg				(char **)&geom->key_aliases,
1991ab64890Smrg				sizeof(XkbKeyAliasRec));
2001ab64890Smrg    return;
2011ab64890Smrg}
2021ab64890Smrg
2031ab64890Smrg/***====================================================================***/
2041ab64890Smrg
2051ab64890Smrgstatic void
2061ab64890Smrg_XkbClearColor(char *color_in)
2071ab64890Smrg{
2081ab64890SmrgXkbColorPtr	color= (XkbColorPtr)color_in;
2091ab64890Smrg
2101ab64890Smrg    if (color->spec)
2111ab64890Smrg	_XkbFree(color->spec);
2121ab64890Smrg    return;
2131ab64890Smrg}
2141ab64890Smrg
2151ab64890Smrgvoid
2161ab64890SmrgXkbFreeGeomColors(XkbGeometryPtr geom,int first,int count,Bool freeAll)
2171ab64890Smrg{
2181ab64890Smrg    _XkbFreeGeomNonLeafElems(freeAll,first,count,
2191ab64890Smrg				&geom->num_colors,&geom->sz_colors,
2201ab64890Smrg				(char **)&geom->colors,
2211ab64890Smrg				sizeof(XkbColorRec),_XkbClearColor);
2221ab64890Smrg    return;
2231ab64890Smrg}
2241ab64890Smrg
2251ab64890Smrg/***====================================================================***/
2261ab64890Smrg
2271ab64890Smrgvoid
2281ab64890SmrgXkbFreeGeomPoints(XkbOutlinePtr outline,int first,int count,Bool freeAll)
2291ab64890Smrg{
2301ab64890Smrg    _XkbFreeGeomLeafElems(freeAll,first,count,
2311ab64890Smrg				&outline->num_points,&outline->sz_points,
2321ab64890Smrg				(char **)&outline->points,
2331ab64890Smrg				sizeof(XkbPointRec));
2341ab64890Smrg    return;
2351ab64890Smrg}
2361ab64890Smrg
2371ab64890Smrg/***====================================================================***/
2381ab64890Smrg
2391ab64890Smrgstatic void
2401ab64890Smrg_XkbClearOutline(char *outline_in)
2411ab64890Smrg{
2421ab64890SmrgXkbOutlinePtr	outline= (XkbOutlinePtr)outline_in;
2431ab64890Smrg
2441ab64890Smrg    if (outline->points!=NULL)
2451ab64890Smrg	XkbFreeGeomPoints(outline,0,outline->num_points,True);
2461ab64890Smrg    return;
2471ab64890Smrg}
2481ab64890Smrg
2491ab64890Smrgvoid
2501ab64890SmrgXkbFreeGeomOutlines(XkbShapePtr	shape,int first,int count,Bool freeAll)
2511ab64890Smrg{
2521ab64890Smrg    _XkbFreeGeomNonLeafElems(freeAll,first,count,
2531ab64890Smrg				&shape->num_outlines,&shape->sz_outlines,
2541ab64890Smrg				(char **)&shape->outlines,
2551ab64890Smrg				sizeof(XkbOutlineRec),_XkbClearOutline);
25661b2299dSmrg
2571ab64890Smrg    return;
2581ab64890Smrg}
2591ab64890Smrg
2601ab64890Smrg/***====================================================================***/
2611ab64890Smrg
2621ab64890Smrgstatic void
2631ab64890Smrg_XkbClearShape(char *shape_in)
2641ab64890Smrg{
2651ab64890SmrgXkbShapePtr	shape= (XkbShapePtr)shape_in;
2661ab64890Smrg
2671ab64890Smrg    if (shape->outlines)
2681ab64890Smrg	XkbFreeGeomOutlines(shape,0,shape->num_outlines,True);
2691ab64890Smrg    return;
2701ab64890Smrg}
2711ab64890Smrg
2721ab64890Smrgvoid
2731ab64890SmrgXkbFreeGeomShapes(XkbGeometryPtr geom,int first,int count,Bool freeAll)
2741ab64890Smrg{
2751ab64890Smrg    _XkbFreeGeomNonLeafElems(freeAll,first,count,
2761ab64890Smrg				&geom->num_shapes,&geom->sz_shapes,
2771ab64890Smrg				(char **)&geom->shapes,
2781ab64890Smrg				sizeof(XkbShapeRec),_XkbClearShape);
2791ab64890Smrg    return;
2801ab64890Smrg}
2811ab64890Smrg
2821ab64890Smrg/***====================================================================***/
2831ab64890Smrg
28461b2299dSmrgvoid
2851ab64890SmrgXkbFreeGeomOverlayKeys(XkbOverlayRowPtr row,int first,int count,Bool freeAll)
2861ab64890Smrg{
2871ab64890Smrg    _XkbFreeGeomLeafElems(freeAll,first,count,
2881ab64890Smrg				&row->num_keys,&row->sz_keys,
2891ab64890Smrg				(char **)&row->keys,
2901ab64890Smrg				sizeof(XkbOverlayKeyRec));
2911ab64890Smrg    return;
2921ab64890Smrg}
2931ab64890Smrg
2941ab64890Smrg/***====================================================================***/
2951ab64890Smrg
2961ab64890Smrgstatic void
2971ab64890Smrg_XkbClearOverlayRow(char *row_in)
2981ab64890Smrg{
2991ab64890SmrgXkbOverlayRowPtr	row= (XkbOverlayRowPtr)row_in;
3001ab64890Smrg
3011ab64890Smrg    if (row->keys!=NULL)
3021ab64890Smrg	XkbFreeGeomOverlayKeys(row,0,row->num_keys,True);
3031ab64890Smrg    return;
3041ab64890Smrg}
3051ab64890Smrg
3061ab64890Smrgvoid
3071ab64890SmrgXkbFreeGeomOverlayRows(XkbOverlayPtr overlay,int first,int count,Bool freeAll)
3081ab64890Smrg{
3091ab64890Smrg    _XkbFreeGeomNonLeafElems(freeAll,first,count,
3101ab64890Smrg				&overlay->num_rows,&overlay->sz_rows,
3111ab64890Smrg				(char **)&overlay->rows,
3121ab64890Smrg				sizeof(XkbOverlayRowRec),_XkbClearOverlayRow);
3131ab64890Smrg    return;
3141ab64890Smrg}
3151ab64890Smrg
3161ab64890Smrg/***====================================================================***/
3171ab64890Smrg
3181ab64890Smrgstatic void
3191ab64890Smrg_XkbClearOverlay(char *overlay_in)
3201ab64890Smrg{
3211ab64890SmrgXkbOverlayPtr	overlay= (XkbOverlayPtr)overlay_in;
3221ab64890Smrg
3231ab64890Smrg    if (overlay->rows!=NULL)
3241ab64890Smrg	XkbFreeGeomOverlayRows(overlay,0,overlay->num_rows,True);
3251ab64890Smrg    return;
3261ab64890Smrg}
3271ab64890Smrg
3281ab64890Smrgvoid
3291ab64890SmrgXkbFreeGeomOverlays(XkbSectionPtr section,int first,int	count,Bool freeAll)
3301ab64890Smrg{
3311ab64890Smrg    _XkbFreeGeomNonLeafElems(freeAll,first,count,
3321ab64890Smrg				&section->num_overlays,&section->sz_overlays,
3331ab64890Smrg				(char **)&section->overlays,
3341ab64890Smrg				sizeof(XkbOverlayRec),_XkbClearOverlay);
3351ab64890Smrg    return;
3361ab64890Smrg}
3371ab64890Smrg
3381ab64890Smrg/***====================================================================***/
3391ab64890Smrg
3401ab64890Smrgvoid
3411ab64890SmrgXkbFreeGeomKeys(XkbRowPtr row,int first,int count,Bool freeAll)
3421ab64890Smrg{
3431ab64890Smrg    _XkbFreeGeomLeafElems(freeAll,first,count,
3441ab64890Smrg				&row->num_keys,&row->sz_keys,
3451ab64890Smrg				(char **)&row->keys,
3461ab64890Smrg				sizeof(XkbKeyRec));
3471ab64890Smrg    return;
3481ab64890Smrg}
3491ab64890Smrg
3501ab64890Smrg/***====================================================================***/
3511ab64890Smrg
3521ab64890Smrgstatic void
3531ab64890Smrg_XkbClearRow(char *row_in)
3541ab64890Smrg{
3551ab64890SmrgXkbRowPtr	row= (XkbRowPtr)row_in;
3561ab64890Smrg
3571ab64890Smrg    if (row->keys!=NULL)
3581ab64890Smrg	XkbFreeGeomKeys(row,0,row->num_keys,True);
3591ab64890Smrg    return;
3601ab64890Smrg}
3611ab64890Smrg
3621ab64890Smrgvoid
3631ab64890SmrgXkbFreeGeomRows(XkbSectionPtr section,int first,int count,Bool freeAll)
3641ab64890Smrg{
3651ab64890Smrg    _XkbFreeGeomNonLeafElems(freeAll,first,count,
3661ab64890Smrg				&section->num_rows,&section->sz_rows,
3671ab64890Smrg				(char **)&section->rows,
3681ab64890Smrg				sizeof(XkbRowRec),_XkbClearRow);
3691ab64890Smrg}
3701ab64890Smrg
3711ab64890Smrg/***====================================================================***/
3721ab64890Smrg
3731ab64890Smrgstatic void
3741ab64890Smrg_XkbClearSection(char *section_in)
3751ab64890Smrg{
3761ab64890SmrgXkbSectionPtr	section= (XkbSectionPtr)section_in;
3771ab64890Smrg
3781ab64890Smrg    if (section->rows!=NULL)
3791ab64890Smrg	XkbFreeGeomRows(section,0,section->num_rows,True);
3801ab64890Smrg    if (section->doodads!=NULL) {
3811ab64890Smrg	XkbFreeGeomDoodads(section->doodads,section->num_doodads,True);
3821ab64890Smrg	section->doodads= NULL;
3831ab64890Smrg    }
3841ab64890Smrg    return;
3851ab64890Smrg}
3861ab64890Smrg
3871ab64890Smrgvoid
3881ab64890SmrgXkbFreeGeomSections(XkbGeometryPtr geom,int first,int count,Bool freeAll)
3891ab64890Smrg{
3901ab64890Smrg    _XkbFreeGeomNonLeafElems(freeAll,first,count,
3911ab64890Smrg				&geom->num_sections,&geom->sz_sections,
3921ab64890Smrg				(char **)&geom->sections,
3931ab64890Smrg				sizeof(XkbSectionRec),_XkbClearSection);
3941ab64890Smrg    return;
3951ab64890Smrg}
3961ab64890Smrg
3971ab64890Smrg/***====================================================================***/
3981ab64890Smrg
3991ab64890Smrgstatic void
4001ab64890Smrg_XkbClearDoodad(char *doodad_in)
4011ab64890Smrg{
4021ab64890SmrgXkbDoodadPtr	doodad= (XkbDoodadPtr)doodad_in;
4031ab64890Smrg
4041ab64890Smrg    switch (doodad->any.type) {
40561b2299dSmrg   	case XkbTextDoodad:
4061ab64890Smrg	    {
4071ab64890Smrg		if (doodad->text.text!=NULL) {
4081ab64890Smrg		    _XkbFree(doodad->text.text);
4091ab64890Smrg		    doodad->text.text= NULL;
4101ab64890Smrg		}
4111ab64890Smrg		if (doodad->text.font!=NULL) {
4121ab64890Smrg		    _XkbFree(doodad->text.font);
4131ab64890Smrg		    doodad->text.font= NULL;
4141ab64890Smrg		}
4151ab64890Smrg	    }
4161ab64890Smrg	    break;
41761b2299dSmrg   	case XkbLogoDoodad:
4181ab64890Smrg	    {
4191ab64890Smrg		if (doodad->logo.logo_name!=NULL) {
4201ab64890Smrg		    _XkbFree(doodad->logo.logo_name);
4211ab64890Smrg		    doodad->logo.logo_name= NULL;
4221ab64890Smrg		}
4231ab64890Smrg	    }
4241ab64890Smrg	    break;
4251ab64890Smrg    }
4261ab64890Smrg    return;
4271ab64890Smrg}
4281ab64890Smrg
4291ab64890Smrgvoid
4301ab64890SmrgXkbFreeGeomDoodads(XkbDoodadPtr doodads,int nDoodads,Bool freeAll)
4311ab64890Smrg{
4321ab64890Smrgregister int 		i;
4331ab64890Smrgregister XkbDoodadPtr	doodad;
4341ab64890Smrg
4351ab64890Smrg    if (doodads) {
4361ab64890Smrg	for (i=0,doodad= doodads;i<nDoodads;i++,doodad++) {
4371ab64890Smrg	    _XkbClearDoodad((char *)doodad);
4381ab64890Smrg	}
4391ab64890Smrg	if (freeAll)
4401ab64890Smrg	    _XkbFree(doodads);
4411ab64890Smrg    }
4421ab64890Smrg    return;
4431ab64890Smrg}
4441ab64890Smrg
4451ab64890Smrgvoid
4461ab64890SmrgXkbFreeGeometry(XkbGeometryPtr geom,unsigned which,Bool freeMap)
4471ab64890Smrg{
4481ab64890Smrg    if (geom==NULL)
4491ab64890Smrg	return;
4501ab64890Smrg    if (freeMap)
4511ab64890Smrg	which= XkbGeomAllMask;
4521ab64890Smrg    if ((which&XkbGeomPropertiesMask)&&(geom->properties!=NULL))
4531ab64890Smrg	XkbFreeGeomProperties(geom,0,geom->num_properties,True);
4541ab64890Smrg    if ((which&XkbGeomColorsMask)&&(geom->colors!=NULL))
4551ab64890Smrg	XkbFreeGeomColors(geom,0,geom->num_colors,True);
4561ab64890Smrg    if ((which&XkbGeomShapesMask)&&(geom->shapes!=NULL))
4571ab64890Smrg	XkbFreeGeomShapes(geom,0,geom->num_shapes,True);
4581ab64890Smrg    if ((which&XkbGeomSectionsMask)&&(geom->sections!=NULL))
4591ab64890Smrg	XkbFreeGeomSections(geom,0,geom->num_sections,True);
4601ab64890Smrg    if ((which&XkbGeomDoodadsMask)&&(geom->doodads!= NULL)) {
4611ab64890Smrg	XkbFreeGeomDoodads(geom->doodads,geom->num_doodads,True);
4621ab64890Smrg	geom->doodads= NULL;
4631ab64890Smrg	geom->num_doodads= geom->sz_doodads= 0;
4641ab64890Smrg    }
4651ab64890Smrg    if ((which&XkbGeomKeyAliasesMask)&&(geom->key_aliases!=NULL))
4661ab64890Smrg	XkbFreeGeomKeyAliases(geom,0,geom->num_key_aliases,True);
4671ab64890Smrg    if (freeMap) {
4681ab64890Smrg	if (geom->label_font!=NULL) {
4691ab64890Smrg	    _XkbFree(geom->label_font);
4701ab64890Smrg	    geom->label_font= NULL;
4711ab64890Smrg	}
4721ab64890Smrg	_XkbFree(geom);
4731ab64890Smrg    }
4741ab64890Smrg    return;
4751ab64890Smrg}
4761ab64890Smrg
4771ab64890Smrg/***====================================================================***/
4781ab64890Smrg
4791ab64890Smrgstatic Status
4801ab64890Smrg_XkbGeomAlloc(	XPointer *		old,
4811ab64890Smrg		unsigned short *	num,
4821ab64890Smrg		unsigned short *	total,
4831ab64890Smrg		int			num_new,
4841ab64890Smrg		Size_t			sz_elem)
4851ab64890Smrg{
4861ab64890Smrg    if (num_new<1)
4871ab64890Smrg	return Success;
4881ab64890Smrg    if ((*old)==NULL)
4891ab64890Smrg	*num= *total= 0;
4901ab64890Smrg
4911ab64890Smrg    if ((*num)+num_new<=(*total))
4921ab64890Smrg	return Success;
4931ab64890Smrg
4941ab64890Smrg    *total= (*num)+num_new;
4951ab64890Smrg    if ((*old)!=NULL)
4961ab64890Smrg	 (*old)= (XPointer)_XkbRealloc((*old),(*total)*sz_elem);
4971ab64890Smrg    else (*old)= (XPointer)_XkbCalloc((*total),sz_elem);
4981ab64890Smrg    if ((*old)==NULL) {
4991ab64890Smrg	*total= *num= 0;
5001ab64890Smrg	return BadAlloc;
5011ab64890Smrg    }
5021ab64890Smrg
5031ab64890Smrg    if (*num>0) {
5041ab64890Smrg	char *tmp= (char *)(*old);
5051ab64890Smrg	bzero(&tmp[sz_elem*(*num)],(num_new*sz_elem));
5061ab64890Smrg    }
5071ab64890Smrg    return Success;
5081ab64890Smrg}
5091ab64890Smrg
5101ab64890Smrg#define	_XkbAllocProps(g,n) _XkbGeomAlloc((XPointer *)&(g)->properties,\
5111ab64890Smrg				&(g)->num_properties,&(g)->sz_properties,\
5121ab64890Smrg				(n),sizeof(XkbPropertyRec))
5131ab64890Smrg#define	_XkbAllocColors(g,n) _XkbGeomAlloc((XPointer *)&(g)->colors,\
5141ab64890Smrg				&(g)->num_colors,&(g)->sz_colors,\
5151ab64890Smrg				(n),sizeof(XkbColorRec))
5161ab64890Smrg#define	_XkbAllocShapes(g,n) _XkbGeomAlloc((XPointer *)&(g)->shapes,\
5171ab64890Smrg				&(g)->num_shapes,&(g)->sz_shapes,\
5181ab64890Smrg				(n),sizeof(XkbShapeRec))
5191ab64890Smrg#define	_XkbAllocSections(g,n) _XkbGeomAlloc((XPointer *)&(g)->sections,\
5201ab64890Smrg				&(g)->num_sections,&(g)->sz_sections,\
5211ab64890Smrg				(n),sizeof(XkbSectionRec))
5221ab64890Smrg#define	_XkbAllocDoodads(g,n) _XkbGeomAlloc((XPointer *)&(g)->doodads,\
5231ab64890Smrg				&(g)->num_doodads,&(g)->sz_doodads,\
5241ab64890Smrg				(n),sizeof(XkbDoodadRec))
5251ab64890Smrg#define	_XkbAllocKeyAliases(g,n) _XkbGeomAlloc((XPointer *)&(g)->key_aliases,\
5261ab64890Smrg				&(g)->num_key_aliases,&(g)->sz_key_aliases,\
5271ab64890Smrg				(n),sizeof(XkbKeyAliasRec))
5281ab64890Smrg
5291ab64890Smrg#define	_XkbAllocOutlines(s,n) _XkbGeomAlloc((XPointer *)&(s)->outlines,\
5301ab64890Smrg				&(s)->num_outlines,&(s)->sz_outlines,\
5311ab64890Smrg				(n),sizeof(XkbOutlineRec))
5321ab64890Smrg#define	_XkbAllocRows(s,n) _XkbGeomAlloc((XPointer *)&(s)->rows,\
5331ab64890Smrg				&(s)->num_rows,&(s)->sz_rows,\
5341ab64890Smrg				(n),sizeof(XkbRowRec))
5351ab64890Smrg#define	_XkbAllocPoints(o,n) _XkbGeomAlloc((XPointer *)&(o)->points,\
5361ab64890Smrg				&(o)->num_points,&(o)->sz_points,\
5371ab64890Smrg				(n),sizeof(XkbPointRec))
5381ab64890Smrg#define	_XkbAllocKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\
5391ab64890Smrg				&(r)->num_keys,&(r)->sz_keys,\
5401ab64890Smrg				(n),sizeof(XkbKeyRec))
5411ab64890Smrg#define	_XkbAllocOverlays(s,n) _XkbGeomAlloc((XPointer *)&(s)->overlays,\
5421ab64890Smrg				&(s)->num_overlays,&(s)->sz_overlays,\
5431ab64890Smrg				(n),sizeof(XkbOverlayRec))
5441ab64890Smrg#define	_XkbAllocOverlayRows(o,n) _XkbGeomAlloc((XPointer *)&(o)->rows,\
5451ab64890Smrg				&(o)->num_rows,&(o)->sz_rows,\
5461ab64890Smrg				(n),sizeof(XkbOverlayRowRec))
5471ab64890Smrg#define	_XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\
5481ab64890Smrg				&(r)->num_keys,&(r)->sz_keys,\
5491ab64890Smrg				(n),sizeof(XkbOverlayKeyRec))
55061b2299dSmrg
5511ab64890SmrgStatus
5521ab64890SmrgXkbAllocGeomProps(XkbGeometryPtr geom,int nProps)
5531ab64890Smrg{
5541ab64890Smrg    return _XkbAllocProps(geom,nProps);
5551ab64890Smrg}
5561ab64890Smrg
5571ab64890SmrgStatus
5581ab64890SmrgXkbAllocGeomColors(XkbGeometryPtr geom,int nColors)
5591ab64890Smrg{
5601ab64890Smrg    return _XkbAllocColors(geom,nColors);
5611ab64890Smrg}
5621ab64890Smrg
5631ab64890SmrgStatus
5641ab64890SmrgXkbAllocGeomKeyAliases(XkbGeometryPtr geom,int nKeyAliases)
5651ab64890Smrg{
5661ab64890Smrg    return _XkbAllocKeyAliases(geom,nKeyAliases);
5671ab64890Smrg}
5681ab64890Smrg
5691ab64890SmrgStatus
5701ab64890SmrgXkbAllocGeomShapes(XkbGeometryPtr geom,int nShapes)
5711ab64890Smrg{
5721ab64890Smrg    return _XkbAllocShapes(geom,nShapes);
5731ab64890Smrg}
5741ab64890Smrg
5751ab64890SmrgStatus
5761ab64890SmrgXkbAllocGeomSections(XkbGeometryPtr geom,int nSections)
5771ab64890Smrg{
5781ab64890Smrg    return _XkbAllocSections(geom,nSections);
5791ab64890Smrg}
5801ab64890Smrg
5811ab64890SmrgStatus
5821ab64890SmrgXkbAllocGeomOverlays(XkbSectionPtr section,int nOverlays)
5831ab64890Smrg{
5841ab64890Smrg    return _XkbAllocOverlays(section,nOverlays);
5851ab64890Smrg}
5861ab64890Smrg
5871ab64890SmrgStatus
5881ab64890SmrgXkbAllocGeomOverlayRows(XkbOverlayPtr overlay,int nRows)
5891ab64890Smrg{
5901ab64890Smrg    return _XkbAllocOverlayRows(overlay,nRows);
5911ab64890Smrg}
5921ab64890Smrg
5931ab64890SmrgStatus
5941ab64890SmrgXkbAllocGeomOverlayKeys(XkbOverlayRowPtr row,int nKeys)
5951ab64890Smrg{
5961ab64890Smrg    return _XkbAllocOverlayKeys(row,nKeys);
5971ab64890Smrg}
5981ab64890Smrg
5991ab64890SmrgStatus
6001ab64890SmrgXkbAllocGeomDoodads(XkbGeometryPtr geom,int nDoodads)
6011ab64890Smrg{
6021ab64890Smrg    return _XkbAllocDoodads(geom,nDoodads);
6031ab64890Smrg}
6041ab64890Smrg
6051ab64890SmrgStatus
6061ab64890SmrgXkbAllocGeomSectionDoodads(XkbSectionPtr section,int nDoodads)
6071ab64890Smrg{
6081ab64890Smrg    return _XkbAllocDoodads(section,nDoodads);
6091ab64890Smrg}
6101ab64890Smrg
6111ab64890SmrgStatus
6121ab64890SmrgXkbAllocGeomOutlines(XkbShapePtr shape,int nOL)
6131ab64890Smrg{
6141ab64890Smrg    return _XkbAllocOutlines(shape,nOL);
6151ab64890Smrg}
6161ab64890Smrg
6171ab64890SmrgStatus
6181ab64890SmrgXkbAllocGeomRows(XkbSectionPtr section,int nRows)
6191ab64890Smrg{
6201ab64890Smrg    return _XkbAllocRows(section,nRows);
6211ab64890Smrg}
6221ab64890Smrg
6231ab64890SmrgStatus
6241ab64890SmrgXkbAllocGeomPoints(XkbOutlinePtr ol,int nPts)
6251ab64890Smrg{
6261ab64890Smrg    return _XkbAllocPoints(ol,nPts);
6271ab64890Smrg}
6281ab64890Smrg
6291ab64890SmrgStatus
6301ab64890SmrgXkbAllocGeomKeys(XkbRowPtr row,int nKeys)
6311ab64890Smrg{
6321ab64890Smrg    return _XkbAllocKeys(row,nKeys);
6331ab64890Smrg}
6341ab64890Smrg
6351ab64890SmrgStatus
6361ab64890SmrgXkbAllocGeometry(XkbDescPtr xkb,XkbGeometrySizesPtr sizes)
6371ab64890Smrg{
6381ab64890SmrgXkbGeometryPtr	geom;
6391ab64890SmrgStatus		rtrn;
6401ab64890Smrg
6411ab64890Smrg    if (xkb->geom==NULL) {
6421ab64890Smrg	xkb->geom= _XkbTypedCalloc(1,XkbGeometryRec);
6431ab64890Smrg	if (!xkb->geom)
6441ab64890Smrg	    return BadAlloc;
6451ab64890Smrg    }
6461ab64890Smrg    geom= xkb->geom;
6471ab64890Smrg    if ((sizes->which&XkbGeomPropertiesMask)&&
6481ab64890Smrg	((rtrn=_XkbAllocProps(geom,sizes->num_properties))!=Success)) {
6491ab64890Smrg	goto BAIL;
6501ab64890Smrg    }
6511ab64890Smrg    if ((sizes->which&XkbGeomColorsMask)&&
6521ab64890Smrg	((rtrn=_XkbAllocColors(geom,sizes->num_colors))!=Success)) {
6531ab64890Smrg	goto BAIL;
6541ab64890Smrg    }
6551ab64890Smrg    if ((sizes->which&XkbGeomShapesMask)&&
6561ab64890Smrg	((rtrn=_XkbAllocShapes(geom,sizes->num_shapes))!=Success)) {
6571ab64890Smrg	goto BAIL;
6581ab64890Smrg    }
6591ab64890Smrg    if ((sizes->which&XkbGeomSectionsMask)&&
6601ab64890Smrg	((rtrn=_XkbAllocSections(geom,sizes->num_sections))!=Success)) {
6611ab64890Smrg	goto BAIL;
6621ab64890Smrg    }
6631ab64890Smrg    if ((sizes->which&XkbGeomDoodadsMask)&&
6641ab64890Smrg	((rtrn=_XkbAllocDoodads(geom,sizes->num_doodads))!=Success)) {
6651ab64890Smrg	goto BAIL;
6661ab64890Smrg    }
6671ab64890Smrg    if ((sizes->which&XkbGeomKeyAliasesMask)&&
6681ab64890Smrg	((rtrn=_XkbAllocKeyAliases(geom,sizes->num_key_aliases))!=Success)) {
6691ab64890Smrg	goto BAIL;
6701ab64890Smrg    }
6711ab64890Smrg    return Success;
6721ab64890SmrgBAIL:
6731ab64890Smrg    XkbFreeGeometry(geom,XkbGeomAllMask,True);
6741ab64890Smrg    xkb->geom= NULL;
6751ab64890Smrg    return rtrn;
6761ab64890Smrg}
6771ab64890Smrg
6781ab64890Smrg/***====================================================================***/
6791ab64890Smrg
6801ab64890SmrgXkbPropertyPtr
6811ab64890SmrgXkbAddGeomProperty(XkbGeometryPtr geom,char *name,char *value)
6821ab64890Smrg{
6831ab64890Smrgregister int i;
6841ab64890Smrgregister XkbPropertyPtr prop;
6851ab64890Smrg
6861ab64890Smrg    if ((!geom)||(!name)||(!value))
6871ab64890Smrg	return NULL;
6881ab64890Smrg    for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
6891ab64890Smrg	if ((prop->name)&&(strcmp(name,prop->name)==0)) {
6901ab64890Smrg	    if (prop->value)
6911ab64890Smrg		_XkbFree(prop->value);
6921ab64890Smrg	    prop->value= (char *)_XkbAlloc(strlen(value)+1);
6931ab64890Smrg	    if (prop->value)
6941ab64890Smrg		strcpy(prop->value,value);
6951ab64890Smrg	    return prop;
69661b2299dSmrg	}
6971ab64890Smrg    }
6981ab64890Smrg    if ((geom->num_properties>=geom->sz_properties)&&
6991ab64890Smrg					(_XkbAllocProps(geom,1)!=Success)) {
7001ab64890Smrg	return NULL;
7011ab64890Smrg    }
7021ab64890Smrg    prop= &geom->properties[geom->num_properties];
7031ab64890Smrg    prop->name= (char *)_XkbAlloc(strlen(name)+1);
7041ab64890Smrg    if (!name)
7051ab64890Smrg	return NULL;
7061ab64890Smrg    strcpy(prop->name,name);
7071ab64890Smrg    prop->value= (char *)_XkbAlloc(strlen(value)+1);
7081ab64890Smrg    if (!value) {
7091ab64890Smrg	_XkbFree(prop->name);
7101ab64890Smrg	prop->name= NULL;
7111ab64890Smrg	return NULL;
7121ab64890Smrg    }
7131ab64890Smrg    strcpy(prop->value,value);
7141ab64890Smrg    geom->num_properties++;
7151ab64890Smrg    return prop;
7161ab64890Smrg}
7171ab64890Smrg
7181ab64890SmrgXkbKeyAliasPtr
7191ab64890SmrgXkbAddGeomKeyAlias(XkbGeometryPtr geom,char *aliasStr,char *realStr)
7201ab64890Smrg{
7211ab64890Smrgregister int i;
7221ab64890Smrgregister XkbKeyAliasPtr alias;
7231ab64890Smrg
7241ab64890Smrg    if ((!geom)||(!aliasStr)||(!realStr)||(!aliasStr[0])||(!realStr[0]))
7251ab64890Smrg	return NULL;
7261ab64890Smrg    for (i=0,alias=geom->key_aliases;i<geom->num_key_aliases;i++,alias++) {
7271ab64890Smrg	if (strncmp(alias->alias,aliasStr,XkbKeyNameLength)==0) {
7281ab64890Smrg	    bzero(alias->real,XkbKeyNameLength);
7291ab64890Smrg	    strncpy(alias->real,realStr,XkbKeyNameLength);
7301ab64890Smrg	    return alias;
7311ab64890Smrg	}
7321ab64890Smrg    }
7331ab64890Smrg    if ((geom->num_key_aliases>=geom->sz_key_aliases)&&
7341ab64890Smrg				(_XkbAllocKeyAliases(geom,1)!=Success)) {
7351ab64890Smrg	return NULL;
7361ab64890Smrg    }
7371ab64890Smrg    alias= &geom->key_aliases[geom->num_key_aliases];
7381ab64890Smrg    bzero(alias,sizeof(XkbKeyAliasRec));
7391ab64890Smrg    strncpy(alias->alias,aliasStr,XkbKeyNameLength);
7401ab64890Smrg    strncpy(alias->real,realStr,XkbKeyNameLength);
7411ab64890Smrg    geom->num_key_aliases++;
7421ab64890Smrg    return alias;
7431ab64890Smrg}
7441ab64890Smrg
7451ab64890SmrgXkbColorPtr
7461ab64890SmrgXkbAddGeomColor(XkbGeometryPtr geom,char *spec,unsigned int pixel)
7471ab64890Smrg{
7481ab64890Smrgregister int i;
7491ab64890Smrgregister XkbColorPtr color;
7501ab64890Smrg
7511ab64890Smrg    if ((!geom)||(!spec))
7521ab64890Smrg	return NULL;
7531ab64890Smrg    for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
7541ab64890Smrg	if ((color->spec)&&(strcmp(color->spec,spec)==0)) {
7551ab64890Smrg	    color->pixel= pixel;
7561ab64890Smrg	    return color;
7571ab64890Smrg	}
7581ab64890Smrg    }
7591ab64890Smrg    if ((geom->num_colors>=geom->sz_colors)&&
7601ab64890Smrg					(_XkbAllocColors(geom,1)!=Success)) {
7611ab64890Smrg	return NULL;
7621ab64890Smrg    }
7631ab64890Smrg    color= &geom->colors[geom->num_colors];
7641ab64890Smrg    color->pixel= pixel;
7651ab64890Smrg    color->spec= (char *)_XkbAlloc(strlen(spec)+1);
7661ab64890Smrg    if (!color->spec)
7671ab64890Smrg	return NULL;
7681ab64890Smrg    strcpy(color->spec,spec);
7691ab64890Smrg    geom->num_colors++;
7701ab64890Smrg    return color;
7711ab64890Smrg}
7721ab64890Smrg
7731ab64890SmrgXkbOutlinePtr
7741ab64890SmrgXkbAddGeomOutline(XkbShapePtr shape,int sz_points)
7751ab64890Smrg{
7761ab64890SmrgXkbOutlinePtr	outline;
7771ab64890Smrg
7781ab64890Smrg    if ((!shape)||(sz_points<0))
7791ab64890Smrg	return NULL;
7801ab64890Smrg    if ((shape->num_outlines>=shape->sz_outlines)&&
7811ab64890Smrg					(_XkbAllocOutlines(shape,1)!=Success)) {
7821ab64890Smrg	return NULL;
7831ab64890Smrg    }
7841ab64890Smrg    outline= &shape->outlines[shape->num_outlines];
7851ab64890Smrg    bzero(outline,sizeof(XkbOutlineRec));
7861ab64890Smrg    if ((sz_points>0)&&(_XkbAllocPoints(outline,sz_points)!=Success))
7871ab64890Smrg	return NULL;
7881ab64890Smrg    shape->num_outlines++;
7891ab64890Smrg    return outline;
7901ab64890Smrg}
7911ab64890Smrg
7921ab64890SmrgXkbShapePtr
7931ab64890SmrgXkbAddGeomShape(XkbGeometryPtr geom,Atom name,int sz_outlines)
7941ab64890Smrg{
7951ab64890SmrgXkbShapePtr	shape;
7961ab64890Smrgregister int	i;
7971ab64890Smrg
7981ab64890Smrg    if ((!geom)||(!name)||(sz_outlines<0))
7991ab64890Smrg	return NULL;
8001ab64890Smrg    if (geom->num_shapes>0) {
8011ab64890Smrg	for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) {
8021ab64890Smrg	    if (name==shape->name)
8031ab64890Smrg		return shape;
8041ab64890Smrg	}
8051ab64890Smrg    }
8061ab64890Smrg    if ((geom->num_shapes>=geom->sz_shapes)&&
8071ab64890Smrg					(_XkbAllocShapes(geom,1)!=Success))
8081ab64890Smrg	return NULL;
8091ab64890Smrg    shape= &geom->shapes[geom->num_shapes];
8101ab64890Smrg    bzero(shape,sizeof(XkbShapeRec));
8111ab64890Smrg    if ((sz_outlines>0)&&(_XkbAllocOutlines(shape,sz_outlines)!=Success))
8121ab64890Smrg	return NULL;
8131ab64890Smrg    shape->name= name;
8141ab64890Smrg    shape->primary= shape->approx= NULL;
8151ab64890Smrg    geom->num_shapes++;
8161ab64890Smrg    return shape;
8171ab64890Smrg}
8181ab64890Smrg
8191ab64890SmrgXkbKeyPtr
8201ab64890SmrgXkbAddGeomKey(XkbRowPtr row)
8211ab64890Smrg{
8221ab64890SmrgXkbKeyPtr	key;
8231ab64890Smrg    if (!row)
8241ab64890Smrg	return NULL;
8251ab64890Smrg    if ((row->num_keys>=row->sz_keys)&&(_XkbAllocKeys(row,1)!=Success))
8261ab64890Smrg	return NULL;
8271ab64890Smrg    key= &row->keys[row->num_keys++];
8281ab64890Smrg    bzero(key,sizeof(XkbKeyRec));
8291ab64890Smrg    return key;
8301ab64890Smrg}
8311ab64890Smrg
8321ab64890SmrgXkbRowPtr
8331ab64890SmrgXkbAddGeomRow(XkbSectionPtr section,int sz_keys)
8341ab64890Smrg{
8351ab64890SmrgXkbRowPtr	row;
8361ab64890Smrg
8371ab64890Smrg    if ((!section)||(sz_keys<0))
8381ab64890Smrg	return NULL;
8391ab64890Smrg    if ((section->num_rows>=section->sz_rows)&&
8401ab64890Smrg    					(_XkbAllocRows(section,1)!=Success))
8411ab64890Smrg	return NULL;
8421ab64890Smrg    row= &section->rows[section->num_rows];
8431ab64890Smrg    bzero(row,sizeof(XkbRowRec));
8441ab64890Smrg    if ((sz_keys>0)&&(_XkbAllocKeys(row,sz_keys)!=Success))
8451ab64890Smrg	return NULL;
8461ab64890Smrg    section->num_rows++;
8471ab64890Smrg    return row;
8481ab64890Smrg}
8491ab64890Smrg
8501ab64890SmrgXkbSectionPtr
8511ab64890SmrgXkbAddGeomSection(	XkbGeometryPtr	geom,
8521ab64890Smrg			Atom		name,
8531ab64890Smrg			int		sz_rows,
8541ab64890Smrg			int		sz_doodads,
8551ab64890Smrg			int		sz_over)
8561ab64890Smrg{
8571ab64890Smrgregister int	i;
8581ab64890SmrgXkbSectionPtr	section;
8591ab64890Smrg
8601ab64890Smrg    if ((!geom)||(name==None)||(sz_rows<0))
8611ab64890Smrg	return NULL;
8621ab64890Smrg    for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
8631ab64890Smrg	if (section->name!=name)
8641ab64890Smrg	    continue;
8651ab64890Smrg	if (((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))||
8661ab64890Smrg	    ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success))||
8671ab64890Smrg	    ((sz_over>0)&&(_XkbAllocOverlays(section,sz_over)!=Success)))
8681ab64890Smrg	    return NULL;
8691ab64890Smrg	return section;
8701ab64890Smrg    }
8711ab64890Smrg    if ((geom->num_sections>=geom->sz_sections)&&
8721ab64890Smrg					(_XkbAllocSections(geom,1)!=Success))
8731ab64890Smrg	return NULL;
8741ab64890Smrg    section= &geom->sections[geom->num_sections];
8751ab64890Smrg    if ((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))
8761ab64890Smrg	return NULL;
8771ab64890Smrg    if ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success)) {
8781ab64890Smrg	if (section->rows) {
8791ab64890Smrg	    _XkbFree(section->rows);
8801ab64890Smrg	    section->rows= NULL;
8811ab64890Smrg	    section->sz_rows= section->num_rows= 0;
8821ab64890Smrg	}
8831ab64890Smrg	return NULL;
8841ab64890Smrg    }
8851ab64890Smrg    section->name= name;
8861ab64890Smrg    geom->num_sections++;
8871ab64890Smrg    return section;
8881ab64890Smrg}
8891ab64890Smrg
8901ab64890SmrgXkbDoodadPtr
8911ab64890SmrgXkbAddGeomDoodad(XkbGeometryPtr geom,XkbSectionPtr section,Atom name)
8921ab64890Smrg{
8931ab64890SmrgXkbDoodadPtr	old,doodad;
8941ab64890Smrgregister int	i,nDoodads;
8951ab64890Smrg
8961ab64890Smrg    if ((!geom)||(name==None))
8971ab64890Smrg	return NULL;
8981ab64890Smrg    if ((section!=NULL)&&(section->num_doodads>0)) {
8991ab64890Smrg	old= section->doodads;
9001ab64890Smrg	nDoodads= section->num_doodads;
9011ab64890Smrg    }
9021ab64890Smrg    else {
9031ab64890Smrg	old= geom->doodads;
9041ab64890Smrg	nDoodads= geom->num_doodads;
9051ab64890Smrg    }
9061ab64890Smrg    for (i=0,doodad=old;i<nDoodads;i++,doodad++) {
9071ab64890Smrg	if (doodad->any.name==name)
9081ab64890Smrg	    return doodad;
9091ab64890Smrg    }
9101ab64890Smrg    if (section) {
9111ab64890Smrg	if ((section->num_doodads>=geom->sz_doodads)&&
9121ab64890Smrg	    (_XkbAllocDoodads(section,1)!=Success)) {
9131ab64890Smrg	    return NULL;
9141ab64890Smrg	}
9151ab64890Smrg	doodad= &section->doodads[section->num_doodads++];
9161ab64890Smrg    }
9171ab64890Smrg    else {
9181ab64890Smrg	if ((geom->num_doodads>=geom->sz_doodads)&&
9191ab64890Smrg					(_XkbAllocDoodads(geom,1)!=Success))
9201ab64890Smrg	    return NULL;
9211ab64890Smrg	doodad= &geom->doodads[geom->num_doodads++];
9221ab64890Smrg    }
9231ab64890Smrg    bzero(doodad,sizeof(XkbDoodadRec));
9241ab64890Smrg    doodad->any.name= name;
9251ab64890Smrg    return doodad;
9261ab64890Smrg}
9271ab64890Smrg
9281ab64890SmrgXkbOverlayKeyPtr
9291ab64890SmrgXkbAddGeomOverlayKey(	XkbOverlayPtr		overlay,
9301ab64890Smrg			XkbOverlayRowPtr 	row,
9311ab64890Smrg			char *			over,
9321ab64890Smrg			char *			under)
9331ab64890Smrg{
9341ab64890Smrgregister int	i;
9351ab64890SmrgXkbOverlayKeyPtr key;
9361ab64890SmrgXkbSectionPtr	section;
9371ab64890SmrgXkbRowPtr	row_under;
9381ab64890SmrgBool		found;
9391ab64890Smrg
9401ab64890Smrg    if ((!overlay)||(!row)||(!over)||(!under))
9411ab64890Smrg	return NULL;
9421ab64890Smrg    section= overlay->section_under;
9431ab64890Smrg    if (row->row_under>=section->num_rows)
9441ab64890Smrg	return NULL;
9451ab64890Smrg    row_under= &section->rows[row->row_under];
9461ab64890Smrg    for (i=0,found=False;i<row_under->num_keys;i++) {
9471ab64890Smrg	if (strncmp(under,row_under->keys[i].name.name,XkbKeyNameLength)==0) {
9481ab64890Smrg	    found= True;
9491ab64890Smrg	    break;
9501ab64890Smrg	}
9511ab64890Smrg    }
9521ab64890Smrg    if (!found)
95361b2299dSmrg   	return NULL;
9541ab64890Smrg    if ((row->num_keys>=row->sz_keys)&&(_XkbAllocOverlayKeys(row,1)!=Success))
9551ab64890Smrg	return NULL;
9561ab64890Smrg    key= &row->keys[row->num_keys];
9571ab64890Smrg    strncpy(key->under.name,under,XkbKeyNameLength);
9581ab64890Smrg    strncpy(key->over.name,over,XkbKeyNameLength);
9591ab64890Smrg    row->num_keys++;
9601ab64890Smrg    return key;
9611ab64890Smrg}
9621ab64890Smrg
9631ab64890SmrgXkbOverlayRowPtr
9641ab64890SmrgXkbAddGeomOverlayRow(XkbOverlayPtr overlay,int row_under,int sz_keys)
9651ab64890Smrg{
9661ab64890Smrgregister int		i;
9671ab64890SmrgXkbOverlayRowPtr	row;
9681ab64890Smrg
9691ab64890Smrg    if ((!overlay)||(sz_keys<0))
9701ab64890Smrg	return NULL;
9711ab64890Smrg    if (row_under>=overlay->section_under->num_rows)
9721ab64890Smrg	return NULL;
9731ab64890Smrg    for (i=0;i<overlay->num_rows;i++) {
9741ab64890Smrg	if (overlay->rows[i].row_under==row_under) {
9751ab64890Smrg	    row= &overlay->rows[i];
9761ab64890Smrg	    if ((row->sz_keys<sz_keys)&&
9771ab64890Smrg				(_XkbAllocOverlayKeys(row,sz_keys)!=Success)) {
9781ab64890Smrg		return NULL;
9791ab64890Smrg	    }
9801ab64890Smrg	    return &overlay->rows[i];
9811ab64890Smrg	}
9821ab64890Smrg    }
9831ab64890Smrg    if ((overlay->num_rows>=overlay->sz_rows)&&
9841ab64890Smrg				(_XkbAllocOverlayRows(overlay,1)!=Success))
9851ab64890Smrg	return NULL;
9861ab64890Smrg    row= &overlay->rows[overlay->num_rows];
9871ab64890Smrg    bzero(row,sizeof(XkbOverlayRowRec));
9881ab64890Smrg    if ((sz_keys>0)&&(_XkbAllocOverlayKeys(row,sz_keys)!=Success))
9891ab64890Smrg	return NULL;
9901ab64890Smrg    row->row_under= row_under;
9911ab64890Smrg    overlay->num_rows++;
9921ab64890Smrg    return row;
9931ab64890Smrg}
9941ab64890Smrg
9951ab64890SmrgXkbOverlayPtr
9961ab64890SmrgXkbAddGeomOverlay(XkbSectionPtr section,Atom name,int sz_rows)
9971ab64890Smrg{
9981ab64890Smrgregister int	i;
9991ab64890SmrgXkbOverlayPtr	overlay;
10001ab64890Smrg
10011ab64890Smrg    if ((!section)||(name==None)||(sz_rows==0))
10021ab64890Smrg	return NULL;
10031ab64890Smrg
10041ab64890Smrg    for (i=0,overlay=section->overlays;i<section->num_overlays;i++,overlay++) {
10051ab64890Smrg	if (overlay->name==name) {
10061ab64890Smrg	    if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
10071ab64890Smrg		return NULL;
10081ab64890Smrg	    return overlay;
10091ab64890Smrg	}
10101ab64890Smrg    }
10111ab64890Smrg    if ((section->num_overlays>=section->sz_overlays)&&
10121ab64890Smrg				(_XkbAllocOverlays(section,1)!=Success))
10131ab64890Smrg	return NULL;
10141ab64890Smrg    overlay= &section->overlays[section->num_overlays];
10151ab64890Smrg    if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
10161ab64890Smrg	return NULL;
10171ab64890Smrg    overlay->name= name;
10181ab64890Smrg    overlay->section_under= section;
10191ab64890Smrg    section->num_overlays++;
10201ab64890Smrg    return overlay;
10211ab64890Smrg}
1022