11ab64890Smrg/************************************************************
21ab64890SmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
31ab64890Smrg
41ab64890SmrgPermission to use, copy, modify, and distribute this
51ab64890Smrgsoftware and its documentation for any purpose and without
61ab64890Smrgfee is hereby granted, provided that the above copyright
71ab64890Smrgnotice appear in all copies and that both that copyright
81ab64890Smrgnotice and this permission notice appear in supporting
961b2299dSmrgdocumentation, and that the name of Silicon Graphics not be
1061b2299dSmrgused in advertising or publicity pertaining to distribution
111ab64890Smrgof the software without specific prior written permission.
1261b2299dSmrgSilicon Graphics makes no representation about the suitability
131ab64890Smrgof this software for any purpose. It is provided "as is"
141ab64890Smrgwithout any express or implied warranty.
151ab64890Smrg
1661b2299dSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
1761b2299dSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
181ab64890SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
1961b2299dSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
2061b2299dSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
2161b2299dSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
221ab64890SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
231ab64890SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE.
241ab64890Smrg
251ab64890Smrg********************************************************/
261ab64890Smrg
27818534a1Smrg#ifdef HAVE_CONFIG_H
281ab64890Smrg#include <config.h>
291ab64890Smrg#endif
301ab64890Smrg
311ab64890Smrg
321ab64890Smrg#include <stdio.h>
331ab64890Smrg#include "Xlibint.h"
341ab64890Smrg#include "XKBlibint.h"
355afda2e6Smrg#include "X11/extensions/XKBgeom.h"
361ab64890Smrg#include <X11/extensions/XKBproto.h>
371ab64890Smrg
381ab64890Smrg/***====================================================================***/
391ab64890Smrg
4061b2299dSmrgstatic void
41818534a1Smrg_XkbFreeGeomLeafElems(Bool freeAll,
42818534a1Smrg                      int first,
43818534a1Smrg                      int count,
44818534a1Smrg                      unsigned short *num_inout,
45818534a1Smrg                      unsigned short *sz_inout,
46818534a1Smrg                      char **elems,
47818534a1Smrg                      unsigned int elem_sz)
48818534a1Smrg{
49818534a1Smrg    if ((freeAll) || (*elems == NULL)) {
50818534a1Smrg        *num_inout = *sz_inout = 0;
51818534a1Smrg        if (*elems != NULL) {
52818534a1Smrg            _XkbFree(*elems);
53818534a1Smrg            *elems = NULL;
54818534a1Smrg        }
55818534a1Smrg        return;
56818534a1Smrg    }
57818534a1Smrg
58818534a1Smrg    if ((first >= (*num_inout)) || (first < 0) || (count < 1))
59818534a1Smrg        return;
60818534a1Smrg
61818534a1Smrg    if (first + count >= (*num_inout)) {
62818534a1Smrg        /* truncating the array is easy */
63818534a1Smrg        (*num_inout) = first;
641ab64890Smrg    }
651ab64890Smrg    else {
66818534a1Smrg        char *ptr;
67818534a1Smrg        int extra;
68818534a1Smrg
69818534a1Smrg        ptr = *elems;
70818534a1Smrg        extra = ((*num_inout) - (first + count)) * elem_sz;
71818534a1Smrg        if (extra > 0)
729c019ec5Smaya            memmove(&ptr[(unsigned) first * elem_sz], &ptr[(unsigned)(first + count) * elem_sz],
739c019ec5Smaya                    (size_t) extra);
74818534a1Smrg        (*num_inout) -= count;
751ab64890Smrg    }
761ab64890Smrg    return;
771ab64890Smrg}
781ab64890Smrg
79818534a1Smrgtypedef void (*ContentsClearFunc) (
80818534a1Smrg    char *       /* priv */
811ab64890Smrg);
821ab64890Smrg
8361b2299dSmrgstatic void
84818534a1Smrg_XkbFreeGeomNonLeafElems(Bool freeAll,
85818534a1Smrg                         int first,
86818534a1Smrg                         int count,
87818534a1Smrg                         unsigned short *num_inout,
88818534a1Smrg                         unsigned short *sz_inout,
89818534a1Smrg                         char **elems,
90818534a1Smrg                         unsigned int elem_sz,
91818534a1Smrg                         ContentsClearFunc freeFunc)
92818534a1Smrg{
93818534a1Smrg    register int i;
94818534a1Smrg    register char *ptr;
951ab64890Smrg
961ab64890Smrg    if (freeAll) {
97818534a1Smrg        first = 0;
98818534a1Smrg        count = (*num_inout);
991ab64890Smrg    }
100818534a1Smrg    else if ((first >= (*num_inout)) || (first < 0) || (count < 1))
101818534a1Smrg        return;
102818534a1Smrg    else if (first + count > (*num_inout))
103818534a1Smrg        count = (*num_inout) - first;
104818534a1Smrg    if (*elems == NULL)
105818534a1Smrg        return;
1061ab64890Smrg
1071ab64890Smrg    if (freeFunc) {
108818534a1Smrg        ptr = *elems;
109818534a1Smrg        ptr += first * elem_sz;
110818534a1Smrg        for (i = 0; i < count; i++) {
111818534a1Smrg            (*freeFunc) (ptr);
112818534a1Smrg            ptr += elem_sz;
113818534a1Smrg        }
1141ab64890Smrg    }
1151ab64890Smrg    if (freeAll) {
116818534a1Smrg        (*num_inout) = (*sz_inout) = 0;
117818534a1Smrg        if (*elems) {
118818534a1Smrg            _XkbFree(*elems);
119818534a1Smrg            *elems = NULL;
120818534a1Smrg        }
121818534a1Smrg    }
122818534a1Smrg    else if (first + count >= (*num_inout))
123818534a1Smrg        *num_inout = first;
1241ab64890Smrg    else {
125818534a1Smrg        i = ((*num_inout) - (first + count)) * elem_sz;
126818534a1Smrg        ptr = *elems;
1279c019ec5Smaya        memmove(&ptr[(unsigned) first * elem_sz], &ptr[(unsigned)(first + count) * elem_sz], (size_t) i);
128818534a1Smrg        (*num_inout) -= count;
1291ab64890Smrg    }
1301ab64890Smrg    return;
1311ab64890Smrg}
1321ab64890Smrg
1331ab64890Smrg/***====================================================================***/
1341ab64890Smrg
1351ab64890Smrgstatic void
1361ab64890Smrg_XkbClearProperty(char *prop_in)
1371ab64890Smrg{
138818534a1Smrg    XkbPropertyPtr prop = (XkbPropertyPtr) prop_in;
1391ab64890Smrg
1401ab64890Smrg    if (prop->name) {
141818534a1Smrg        _XkbFree(prop->name);
142818534a1Smrg        prop->name = NULL;
1431ab64890Smrg    }
1441ab64890Smrg    if (prop->value) {
145818534a1Smrg        _XkbFree(prop->value);
146818534a1Smrg        prop->value = NULL;
1471ab64890Smrg    }
1481ab64890Smrg    return;
1491ab64890Smrg}
1501ab64890Smrg
1511ab64890Smrgvoid
152818534a1SmrgXkbFreeGeomProperties(XkbGeometryPtr geom, int first, int count, Bool freeAll)
153818534a1Smrg{
154818534a1Smrg    _XkbFreeGeomNonLeafElems(freeAll, first, count,
155818534a1Smrg                             &geom->num_properties, &geom->sz_properties,
156818534a1Smrg                             (char **) &geom->properties,
157818534a1Smrg                             sizeof(XkbPropertyRec), _XkbClearProperty);
1581ab64890Smrg    return;
1591ab64890Smrg}
1601ab64890Smrg
1611ab64890Smrg/***====================================================================***/
1621ab64890Smrg
1631ab64890Smrgvoid
164818534a1SmrgXkbFreeGeomKeyAliases(XkbGeometryPtr geom, int first, int count, Bool freeAll)
165818534a1Smrg{
166818534a1Smrg    _XkbFreeGeomLeafElems(freeAll, first, count,
167818534a1Smrg                          &geom->num_key_aliases, &geom->sz_key_aliases,
168818534a1Smrg                          (char **) &geom->key_aliases,
169818534a1Smrg                          sizeof(XkbKeyAliasRec));
1701ab64890Smrg    return;
1711ab64890Smrg}
1721ab64890Smrg
1731ab64890Smrg/***====================================================================***/
1741ab64890Smrg
1751ab64890Smrgstatic void
1761ab64890Smrg_XkbClearColor(char *color_in)
1771ab64890Smrg{
178818534a1Smrg    XkbColorPtr color = (XkbColorPtr) color_in;
1791ab64890Smrg
1800f8248bfSmrg    _XkbFree(color->spec);
1811ab64890Smrg    return;
1821ab64890Smrg}
1831ab64890Smrg
1841ab64890Smrgvoid
185818534a1SmrgXkbFreeGeomColors(XkbGeometryPtr geom, int first, int count, Bool freeAll)
1861ab64890Smrg{
187818534a1Smrg    _XkbFreeGeomNonLeafElems(freeAll, first, count,
188818534a1Smrg                             &geom->num_colors, &geom->sz_colors,
189818534a1Smrg                             (char **) &geom->colors,
190818534a1Smrg                             sizeof(XkbColorRec), _XkbClearColor);
1911ab64890Smrg    return;
1921ab64890Smrg}
1931ab64890Smrg
1941ab64890Smrg/***====================================================================***/
1951ab64890Smrg
1961ab64890Smrgvoid
197818534a1SmrgXkbFreeGeomPoints(XkbOutlinePtr outline, int first, int count, Bool freeAll)
1981ab64890Smrg{
199818534a1Smrg    _XkbFreeGeomLeafElems(freeAll, first, count,
200818534a1Smrg                          &outline->num_points, &outline->sz_points,
201818534a1Smrg                          (char **) &outline->points,
202818534a1Smrg                          sizeof(XkbPointRec));
2031ab64890Smrg    return;
2041ab64890Smrg}
2051ab64890Smrg
2061ab64890Smrg/***====================================================================***/
2071ab64890Smrg
2081ab64890Smrgstatic void
2091ab64890Smrg_XkbClearOutline(char *outline_in)
2101ab64890Smrg{
211818534a1Smrg    XkbOutlinePtr outline = (XkbOutlinePtr) outline_in;
2121ab64890Smrg
213818534a1Smrg    if (outline->points != NULL)
214818534a1Smrg        XkbFreeGeomPoints(outline, 0, outline->num_points, True);
2151ab64890Smrg    return;
2161ab64890Smrg}
2171ab64890Smrg
2181ab64890Smrgvoid
219818534a1SmrgXkbFreeGeomOutlines(XkbShapePtr shape, int first, int count, Bool freeAll)
2201ab64890Smrg{
221818534a1Smrg    _XkbFreeGeomNonLeafElems(freeAll, first, count,
222818534a1Smrg                             &shape->num_outlines, &shape->sz_outlines,
223818534a1Smrg                             (char **) &shape->outlines,
224818534a1Smrg                             sizeof(XkbOutlineRec), _XkbClearOutline);
22561b2299dSmrg
2261ab64890Smrg    return;
2271ab64890Smrg}
2281ab64890Smrg
2291ab64890Smrg/***====================================================================***/
2301ab64890Smrg
2311ab64890Smrgstatic void
2321ab64890Smrg_XkbClearShape(char *shape_in)
2331ab64890Smrg{
234818534a1Smrg    XkbShapePtr shape = (XkbShapePtr) shape_in;
2351ab64890Smrg
2361ab64890Smrg    if (shape->outlines)
237818534a1Smrg        XkbFreeGeomOutlines(shape, 0, shape->num_outlines, True);
2381ab64890Smrg    return;
2391ab64890Smrg}
2401ab64890Smrg
2411ab64890Smrgvoid
242818534a1SmrgXkbFreeGeomShapes(XkbGeometryPtr geom, int first, int count, Bool freeAll)
2431ab64890Smrg{
244818534a1Smrg    _XkbFreeGeomNonLeafElems(freeAll, first, count,
245818534a1Smrg                             &geom->num_shapes, &geom->sz_shapes,
246818534a1Smrg                             (char **) &geom->shapes,
247818534a1Smrg                             sizeof(XkbShapeRec), _XkbClearShape);
2481ab64890Smrg    return;
2491ab64890Smrg}
2501ab64890Smrg
2511ab64890Smrg/***====================================================================***/
2521ab64890Smrg
25361b2299dSmrgvoid
254818534a1SmrgXkbFreeGeomOverlayKeys(XkbOverlayRowPtr row, int first, int count, Bool freeAll)
2551ab64890Smrg{
256818534a1Smrg    _XkbFreeGeomLeafElems(freeAll, first, count,
257818534a1Smrg                          &row->num_keys, &row->sz_keys,
258818534a1Smrg                          (char **) &row->keys,
259818534a1Smrg                          sizeof(XkbOverlayKeyRec));
2601ab64890Smrg    return;
2611ab64890Smrg}
2621ab64890Smrg
2631ab64890Smrg/***====================================================================***/
2641ab64890Smrg
2651ab64890Smrgstatic void
2661ab64890Smrg_XkbClearOverlayRow(char *row_in)
2671ab64890Smrg{
268818534a1Smrg    XkbOverlayRowPtr row = (XkbOverlayRowPtr) row_in;
2691ab64890Smrg
270818534a1Smrg    if (row->keys != NULL)
271818534a1Smrg        XkbFreeGeomOverlayKeys(row, 0, row->num_keys, True);
2721ab64890Smrg    return;
2731ab64890Smrg}
2741ab64890Smrg
2751ab64890Smrgvoid
276818534a1SmrgXkbFreeGeomOverlayRows(XkbOverlayPtr overlay, int first, int count,
277818534a1Smrg                       Bool freeAll)
2781ab64890Smrg{
279818534a1Smrg    _XkbFreeGeomNonLeafElems(freeAll, first, count,
280818534a1Smrg                             &overlay->num_rows, &overlay->sz_rows,
281818534a1Smrg                             (char **) &overlay->rows,
282818534a1Smrg                             sizeof(XkbOverlayRowRec), _XkbClearOverlayRow);
2831ab64890Smrg    return;
2841ab64890Smrg}
2851ab64890Smrg
2861ab64890Smrg/***====================================================================***/
2871ab64890Smrg
2881ab64890Smrgstatic void
2891ab64890Smrg_XkbClearOverlay(char *overlay_in)
2901ab64890Smrg{
291818534a1Smrg    XkbOverlayPtr overlay = (XkbOverlayPtr) overlay_in;
2921ab64890Smrg
293818534a1Smrg    if (overlay->rows != NULL)
294818534a1Smrg        XkbFreeGeomOverlayRows(overlay, 0, overlay->num_rows, True);
2951ab64890Smrg    return;
2961ab64890Smrg}
2971ab64890Smrg
2981ab64890Smrgvoid
299818534a1SmrgXkbFreeGeomOverlays(XkbSectionPtr section, int first, int count, Bool freeAll)
3001ab64890Smrg{
301818534a1Smrg    _XkbFreeGeomNonLeafElems(freeAll, first, count,
302818534a1Smrg                             &section->num_overlays, &section->sz_overlays,
303818534a1Smrg                             (char **) &section->overlays,
304818534a1Smrg                             sizeof(XkbOverlayRec), _XkbClearOverlay);
3051ab64890Smrg    return;
3061ab64890Smrg}
3071ab64890Smrg
3081ab64890Smrg/***====================================================================***/
3091ab64890Smrg
3101ab64890Smrgvoid
311818534a1SmrgXkbFreeGeomKeys(XkbRowPtr row, int first, int count, Bool freeAll)
3121ab64890Smrg{
313818534a1Smrg    _XkbFreeGeomLeafElems(freeAll, first, count,
314818534a1Smrg                          &row->num_keys, &row->sz_keys,
315818534a1Smrg                          (char **) &row->keys,
316818534a1Smrg                          sizeof(XkbKeyRec));
3171ab64890Smrg    return;
3181ab64890Smrg}
3191ab64890Smrg
3201ab64890Smrg/***====================================================================***/
3211ab64890Smrg
3221ab64890Smrgstatic void
3231ab64890Smrg_XkbClearRow(char *row_in)
3241ab64890Smrg{
325818534a1Smrg    XkbRowPtr row = (XkbRowPtr) row_in;
3261ab64890Smrg
327818534a1Smrg    if (row->keys != NULL)
328818534a1Smrg        XkbFreeGeomKeys(row, 0, row->num_keys, True);
3291ab64890Smrg    return;
3301ab64890Smrg}
3311ab64890Smrg
3321ab64890Smrgvoid
333818534a1SmrgXkbFreeGeomRows(XkbSectionPtr section, int first, int count, Bool freeAll)
3341ab64890Smrg{
335818534a1Smrg    _XkbFreeGeomNonLeafElems(freeAll, first, count,
336818534a1Smrg                             &section->num_rows, &section->sz_rows,
337818534a1Smrg                             (char **) &section->rows,
338818534a1Smrg                             sizeof(XkbRowRec), _XkbClearRow);
3391ab64890Smrg}
3401ab64890Smrg
3411ab64890Smrg/***====================================================================***/
3421ab64890Smrg
3431ab64890Smrgstatic void
3441ab64890Smrg_XkbClearSection(char *section_in)
3451ab64890Smrg{
346818534a1Smrg    XkbSectionPtr section = (XkbSectionPtr) section_in;
3471ab64890Smrg
348818534a1Smrg    if (section->rows != NULL)
349818534a1Smrg        XkbFreeGeomRows(section, 0, section->num_rows, True);
350818534a1Smrg    if (section->doodads != NULL) {
351818534a1Smrg        XkbFreeGeomDoodads(section->doodads, section->num_doodads, True);
352818534a1Smrg        section->doodads = NULL;
3531ab64890Smrg    }
3541ab64890Smrg    return;
3551ab64890Smrg}
3561ab64890Smrg
3571ab64890Smrgvoid
358818534a1SmrgXkbFreeGeomSections(XkbGeometryPtr geom, int first, int count, Bool freeAll)
3591ab64890Smrg{
360818534a1Smrg    _XkbFreeGeomNonLeafElems(freeAll, first, count,
361818534a1Smrg                             &geom->num_sections, &geom->sz_sections,
362818534a1Smrg                             (char **) &geom->sections,
363818534a1Smrg                             sizeof(XkbSectionRec), _XkbClearSection);
3641ab64890Smrg    return;
3651ab64890Smrg}
3661ab64890Smrg
3671ab64890Smrg/***====================================================================***/
3681ab64890Smrg
3691ab64890Smrgstatic void
3701ab64890Smrg_XkbClearDoodad(char *doodad_in)
3711ab64890Smrg{
372818534a1Smrg    XkbDoodadPtr doodad = (XkbDoodadPtr) doodad_in;
3731ab64890Smrg
3741ab64890Smrg    switch (doodad->any.type) {
375818534a1Smrg    case XkbTextDoodad:
376818534a1Smrg    {
377818534a1Smrg        if (doodad->text.text != NULL) {
378818534a1Smrg            _XkbFree(doodad->text.text);
379818534a1Smrg            doodad->text.text = NULL;
380818534a1Smrg        }
381818534a1Smrg        if (doodad->text.font != NULL) {
382818534a1Smrg            _XkbFree(doodad->text.font);
383818534a1Smrg            doodad->text.font = NULL;
384818534a1Smrg        }
385818534a1Smrg    }
386818534a1Smrg        break;
387818534a1Smrg    case XkbLogoDoodad:
388818534a1Smrg    {
389818534a1Smrg        if (doodad->logo.logo_name != NULL) {
390818534a1Smrg            _XkbFree(doodad->logo.logo_name);
391818534a1Smrg            doodad->logo.logo_name = NULL;
392818534a1Smrg        }
393818534a1Smrg    }
394818534a1Smrg        break;
3951ab64890Smrg    }
3961ab64890Smrg    return;
3971ab64890Smrg}
3981ab64890Smrg
3991ab64890Smrgvoid
400818534a1SmrgXkbFreeGeomDoodads(XkbDoodadPtr doodads, int nDoodads, Bool freeAll)
4011ab64890Smrg{
402818534a1Smrg    register int i;
403818534a1Smrg    register XkbDoodadPtr doodad;
4041ab64890Smrg
4051ab64890Smrg    if (doodads) {
406818534a1Smrg        for (i = 0, doodad = doodads; i < nDoodads; i++, doodad++) {
407818534a1Smrg            _XkbClearDoodad((char *) doodad);
408818534a1Smrg        }
409818534a1Smrg        if (freeAll)
410818534a1Smrg            _XkbFree(doodads);
4111ab64890Smrg    }
4121ab64890Smrg    return;
4131ab64890Smrg}
4141ab64890Smrg
4151ab64890Smrgvoid
416818534a1SmrgXkbFreeGeometry(XkbGeometryPtr geom, unsigned which, Bool freeMap)
4171ab64890Smrg{
418818534a1Smrg    if (geom == NULL)
419818534a1Smrg        return;
4201ab64890Smrg    if (freeMap)
421818534a1Smrg        which = XkbGeomAllMask;
422818534a1Smrg    if ((which & XkbGeomPropertiesMask) && (geom->properties != NULL))
423818534a1Smrg        XkbFreeGeomProperties(geom, 0, geom->num_properties, True);
424818534a1Smrg    if ((which & XkbGeomColorsMask) && (geom->colors != NULL))
425818534a1Smrg        XkbFreeGeomColors(geom, 0, geom->num_colors, True);
426818534a1Smrg    if ((which & XkbGeomShapesMask) && (geom->shapes != NULL))
427818534a1Smrg        XkbFreeGeomShapes(geom, 0, geom->num_shapes, True);
428818534a1Smrg    if ((which & XkbGeomSectionsMask) && (geom->sections != NULL))
429818534a1Smrg        XkbFreeGeomSections(geom, 0, geom->num_sections, True);
430818534a1Smrg    if ((which & XkbGeomDoodadsMask) && (geom->doodads != NULL)) {
431818534a1Smrg        XkbFreeGeomDoodads(geom->doodads, geom->num_doodads, True);
432818534a1Smrg        geom->doodads = NULL;
433818534a1Smrg        geom->num_doodads = geom->sz_doodads = 0;
434818534a1Smrg    }
435818534a1Smrg    if ((which & XkbGeomKeyAliasesMask) && (geom->key_aliases != NULL))
436818534a1Smrg        XkbFreeGeomKeyAliases(geom, 0, geom->num_key_aliases, True);
4371ab64890Smrg    if (freeMap) {
438818534a1Smrg        if (geom->label_font != NULL) {
439818534a1Smrg            _XkbFree(geom->label_font);
440818534a1Smrg            geom->label_font = NULL;
441818534a1Smrg        }
442818534a1Smrg        _XkbFree(geom);
4431ab64890Smrg    }
4441ab64890Smrg    return;
4451ab64890Smrg}
4461ab64890Smrg
4471ab64890Smrg/***====================================================================***/
4481ab64890Smrg
4491ab64890Smrgstatic Status
450818534a1Smrg_XkbGeomAlloc(XPointer *old,
451818534a1Smrg              unsigned short *num,
452818534a1Smrg              unsigned short *total,
453818534a1Smrg              int num_new,
454818534a1Smrg              size_t sz_elem)
455818534a1Smrg{
456818534a1Smrg    if (num_new < 1)
457818534a1Smrg        return Success;
458818534a1Smrg    if ((*old) == NULL)
459818534a1Smrg        *num = *total = 0;
460818534a1Smrg
461818534a1Smrg    if ((*num) + num_new <= (*total))
462818534a1Smrg        return Success;
463818534a1Smrg
464818534a1Smrg    *total = (*num) + num_new;
465818534a1Smrg    if ((*old) != NULL)
466818534a1Smrg        (*old) = (XPointer) _XkbRealloc((*old), (*total) * sz_elem);
467818534a1Smrg    else
468818534a1Smrg        (*old) = (XPointer) _XkbCalloc((*total), sz_elem);
469818534a1Smrg    if ((*old) == NULL) {
470818534a1Smrg        *total = *num = 0;
471818534a1Smrg        return BadAlloc;
472818534a1Smrg    }
473818534a1Smrg
474818534a1Smrg    if (*num > 0) {
475818534a1Smrg        char *tmp = (char *) (*old);
476818534a1Smrg        bzero(&tmp[sz_elem * (*num)], (num_new * sz_elem));
4771ab64890Smrg    }
4781ab64890Smrg    return Success;
4791ab64890Smrg}
4801ab64890Smrg
481818534a1Smrg#define _XkbAllocProps(g, n) _XkbGeomAlloc((XPointer *)&(g)->properties, \
482818534a1Smrg                                &(g)->num_properties, &(g)->sz_properties, \
483818534a1Smrg                                (n), sizeof(XkbPropertyRec))
484818534a1Smrg#define _XkbAllocColors(g, n) _XkbGeomAlloc((XPointer *)&(g)->colors, \
485818534a1Smrg                                &(g)->num_colors, &(g)->sz_colors, \
486818534a1Smrg                                (n), sizeof(XkbColorRec))
487818534a1Smrg#define _XkbAllocShapes(g, n) _XkbGeomAlloc((XPointer *)&(g)->shapes, \
488818534a1Smrg                                &(g)->num_shapes, &(g)->sz_shapes, \
489818534a1Smrg                                (n), sizeof(XkbShapeRec))
490818534a1Smrg#define _XkbAllocSections(g, n) _XkbGeomAlloc((XPointer *)&(g)->sections, \
491818534a1Smrg                                &(g)->num_sections, &(g)->sz_sections, \
492818534a1Smrg                                (n), sizeof(XkbSectionRec))
493818534a1Smrg#define _XkbAllocDoodads(g, n) _XkbGeomAlloc((XPointer *)&(g)->doodads, \
494818534a1Smrg                                &(g)->num_doodads, &(g)->sz_doodads, \
495818534a1Smrg                                (n), sizeof(XkbDoodadRec))
496818534a1Smrg#define _XkbAllocKeyAliases(g, n) _XkbGeomAlloc((XPointer *)&(g)->key_aliases, \
497818534a1Smrg                                &(g)->num_key_aliases, &(g)->sz_key_aliases, \
498818534a1Smrg                                (n), sizeof(XkbKeyAliasRec))
499818534a1Smrg
500818534a1Smrg#define _XkbAllocOutlines(s, n) _XkbGeomAlloc((XPointer *)&(s)->outlines, \
501818534a1Smrg                                &(s)->num_outlines, &(s)->sz_outlines, \
502818534a1Smrg                                (n), sizeof(XkbOutlineRec))
503818534a1Smrg#define _XkbAllocRows(s, n) _XkbGeomAlloc((XPointer *)&(s)->rows, \
504818534a1Smrg                                &(s)->num_rows, &(s)->sz_rows, \
505818534a1Smrg                                (n), sizeof(XkbRowRec))
506818534a1Smrg#define _XkbAllocPoints(o, n) _XkbGeomAlloc((XPointer *)&(o)->points, \
507818534a1Smrg                                &(o)->num_points, &(o)->sz_points, \
508818534a1Smrg                                (n), sizeof(XkbPointRec))
509818534a1Smrg#define _XkbAllocKeys(r, n) _XkbGeomAlloc((XPointer *)&(r)->keys, \
510818534a1Smrg                                &(r)->num_keys, &(r)->sz_keys, \
511818534a1Smrg                                (n), sizeof(XkbKeyRec))
512818534a1Smrg#define _XkbAllocOverlays(s, n) _XkbGeomAlloc((XPointer *)&(s)->overlays, \
513818534a1Smrg                                &(s)->num_overlays, &(s)->sz_overlays, \
514818534a1Smrg                                (n), sizeof(XkbOverlayRec))
515818534a1Smrg#define _XkbAllocOverlayRows(o, n) _XkbGeomAlloc((XPointer *)&(o)->rows, \
516818534a1Smrg                                &(o)->num_rows, &(o)->sz_rows, \
517818534a1Smrg                                (n), sizeof(XkbOverlayRowRec))
518818534a1Smrg#define _XkbAllocOverlayKeys(r, n) _XkbGeomAlloc((XPointer *)&(r)->keys, \
519818534a1Smrg                                &(r)->num_keys, &(r)->sz_keys, \
520818534a1Smrg                                (n), sizeof(XkbOverlayKeyRec))
52161b2299dSmrg
5221ab64890SmrgStatus
523818534a1SmrgXkbAllocGeomProps(XkbGeometryPtr geom, int nProps)
5241ab64890Smrg{
525818534a1Smrg    return _XkbAllocProps(geom, nProps);
5261ab64890Smrg}
5271ab64890Smrg
5281ab64890SmrgStatus
529818534a1SmrgXkbAllocGeomColors(XkbGeometryPtr geom, int nColors)
5301ab64890Smrg{
531818534a1Smrg    return _XkbAllocColors(geom, nColors);
5321ab64890Smrg}
5331ab64890Smrg
5341ab64890SmrgStatus
535818534a1SmrgXkbAllocGeomKeyAliases(XkbGeometryPtr geom, int nKeyAliases)
5361ab64890Smrg{
537818534a1Smrg    return _XkbAllocKeyAliases(geom, nKeyAliases);
5381ab64890Smrg}
5391ab64890Smrg
5401ab64890SmrgStatus
541818534a1SmrgXkbAllocGeomShapes(XkbGeometryPtr geom, int nShapes)
5421ab64890Smrg{
543818534a1Smrg    return _XkbAllocShapes(geom, nShapes);
5441ab64890Smrg}
5451ab64890Smrg
5461ab64890SmrgStatus
547818534a1SmrgXkbAllocGeomSections(XkbGeometryPtr geom, int nSections)
5481ab64890Smrg{
549818534a1Smrg    return _XkbAllocSections(geom, nSections);
5501ab64890Smrg}
5511ab64890Smrg
5521ab64890SmrgStatus
553818534a1SmrgXkbAllocGeomOverlays(XkbSectionPtr section, int nOverlays)
5541ab64890Smrg{
555818534a1Smrg    return _XkbAllocOverlays(section, nOverlays);
5561ab64890Smrg}
5571ab64890Smrg
5581ab64890SmrgStatus
559818534a1SmrgXkbAllocGeomOverlayRows(XkbOverlayPtr overlay, int nRows)
5601ab64890Smrg{
561818534a1Smrg    return _XkbAllocOverlayRows(overlay, nRows);
5621ab64890Smrg}
5631ab64890Smrg
5641ab64890SmrgStatus
565818534a1SmrgXkbAllocGeomOverlayKeys(XkbOverlayRowPtr row, int nKeys)
5661ab64890Smrg{
567818534a1Smrg    return _XkbAllocOverlayKeys(row, nKeys);
5681ab64890Smrg}
5691ab64890Smrg
5701ab64890SmrgStatus
571818534a1SmrgXkbAllocGeomDoodads(XkbGeometryPtr geom, int nDoodads)
5721ab64890Smrg{
573818534a1Smrg    return _XkbAllocDoodads(geom, nDoodads);
5741ab64890Smrg}
5751ab64890Smrg
5761ab64890SmrgStatus
577818534a1SmrgXkbAllocGeomSectionDoodads(XkbSectionPtr section, int nDoodads)
5781ab64890Smrg{
579818534a1Smrg    return _XkbAllocDoodads(section, nDoodads);
5801ab64890Smrg}
5811ab64890Smrg
5821ab64890SmrgStatus
583818534a1SmrgXkbAllocGeomOutlines(XkbShapePtr shape, int nOL)
5841ab64890Smrg{
585818534a1Smrg    return _XkbAllocOutlines(shape, nOL);
5861ab64890Smrg}
5871ab64890Smrg
5881ab64890SmrgStatus
589818534a1SmrgXkbAllocGeomRows(XkbSectionPtr section, int nRows)
5901ab64890Smrg{
591818534a1Smrg    return _XkbAllocRows(section, nRows);
5921ab64890Smrg}
5931ab64890Smrg
5941ab64890SmrgStatus
595818534a1SmrgXkbAllocGeomPoints(XkbOutlinePtr ol, int nPts)
5961ab64890Smrg{
597818534a1Smrg    return _XkbAllocPoints(ol, nPts);
5981ab64890Smrg}
5991ab64890Smrg
6001ab64890SmrgStatus
601818534a1SmrgXkbAllocGeomKeys(XkbRowPtr row, int nKeys)
6021ab64890Smrg{
603818534a1Smrg    return _XkbAllocKeys(row, nKeys);
6041ab64890Smrg}
6051ab64890Smrg
6061ab64890SmrgStatus
607818534a1SmrgXkbAllocGeometry(XkbDescPtr xkb, XkbGeometrySizesPtr sizes)
6081ab64890Smrg{
609818534a1Smrg    XkbGeometryPtr geom;
610818534a1Smrg    Status rtrn;
6111ab64890Smrg
612818534a1Smrg    if (xkb->geom == NULL) {
613818534a1Smrg        xkb->geom = _XkbTypedCalloc(1, XkbGeometryRec);
614818534a1Smrg        if (!xkb->geom)
615818534a1Smrg            return BadAlloc;
6161ab64890Smrg    }
617818534a1Smrg    geom = xkb->geom;
618818534a1Smrg    if ((sizes->which & XkbGeomPropertiesMask) &&
619818534a1Smrg        ((rtrn = _XkbAllocProps(geom, sizes->num_properties)) != Success)) {
620818534a1Smrg        goto BAIL;
6211ab64890Smrg    }
622818534a1Smrg    if ((sizes->which & XkbGeomColorsMask) &&
623818534a1Smrg        ((rtrn = _XkbAllocColors(geom, sizes->num_colors)) != Success)) {
624818534a1Smrg        goto BAIL;
6251ab64890Smrg    }
626818534a1Smrg    if ((sizes->which & XkbGeomShapesMask) &&
627818534a1Smrg        ((rtrn = _XkbAllocShapes(geom, sizes->num_shapes)) != Success)) {
628818534a1Smrg        goto BAIL;
6291ab64890Smrg    }
630818534a1Smrg    if ((sizes->which & XkbGeomSectionsMask) &&
631818534a1Smrg        ((rtrn = _XkbAllocSections(geom, sizes->num_sections)) != Success)) {
632818534a1Smrg        goto BAIL;
6331ab64890Smrg    }
634818534a1Smrg    if ((sizes->which & XkbGeomDoodadsMask) &&
635818534a1Smrg        ((rtrn = _XkbAllocDoodads(geom, sizes->num_doodads)) != Success)) {
636818534a1Smrg        goto BAIL;
6371ab64890Smrg    }
638818534a1Smrg    if ((sizes->which & XkbGeomKeyAliasesMask) &&
639818534a1Smrg        ((rtrn = _XkbAllocKeyAliases(geom, sizes->num_key_aliases))
640818534a1Smrg         != Success)) {
641818534a1Smrg        goto BAIL;
6421ab64890Smrg    }
6431ab64890Smrg    return Success;
644818534a1Smrg BAIL:
645818534a1Smrg    XkbFreeGeometry(geom, XkbGeomAllMask, True);
646818534a1Smrg    xkb->geom = NULL;
6471ab64890Smrg    return rtrn;
6481ab64890Smrg}
6491ab64890Smrg
6501ab64890Smrg/***====================================================================***/
6511ab64890Smrg
6521ab64890SmrgXkbPropertyPtr
653e9628295SmrgXkbAddGeomProperty(XkbGeometryPtr geom, _Xconst char *name, _Xconst char *value)
654818534a1Smrg{
655818534a1Smrg    register int i;
656818534a1Smrg    register XkbPropertyPtr prop;
657818534a1Smrg
658818534a1Smrg    if ((!geom) || (!name) || (!value))
659818534a1Smrg        return NULL;
660818534a1Smrg    for (i = 0, prop = geom->properties; i < geom->num_properties; i++, prop++) {
661818534a1Smrg        if ((prop->name) && (strcmp(name, prop->name) == 0)) {
6620f8248bfSmrg            _XkbFree(prop->value);
663818534a1Smrg            prop->value = strdup(value);
664818534a1Smrg            return prop;
665818534a1Smrg        }
666818534a1Smrg    }
667818534a1Smrg    if ((geom->num_properties >= geom->sz_properties) &&
668818534a1Smrg        (_XkbAllocProps(geom, 1) != Success)) {
669818534a1Smrg        return NULL;
670818534a1Smrg    }
671818534a1Smrg    prop = &geom->properties[geom->num_properties];
672818534a1Smrg    prop->name = strdup(name);
67357f47464Smrg    if (!prop->name)
674818534a1Smrg        return NULL;
675818534a1Smrg    prop->value = strdup(value);
67657f47464Smrg    if (!prop->value) {
677818534a1Smrg        _XkbFree(prop->name);
678818534a1Smrg        prop->name = NULL;
679818534a1Smrg        return NULL;
6801ab64890Smrg    }
6811ab64890Smrg    geom->num_properties++;
6821ab64890Smrg    return prop;
6831ab64890Smrg}
6841ab64890Smrg
6851ab64890SmrgXkbKeyAliasPtr
686e9628295SmrgXkbAddGeomKeyAlias(XkbGeometryPtr geom, _Xconst char *aliasStr,
687e9628295Smrg                   _Xconst char *realStr)
688818534a1Smrg{
689818534a1Smrg    register int i;
690818534a1Smrg    register XkbKeyAliasPtr alias;
691818534a1Smrg
692818534a1Smrg    if ((!geom) || (!aliasStr) || (!realStr) || (!aliasStr[0]) || (!realStr[0]))
693818534a1Smrg        return NULL;
694818534a1Smrg    for (i = 0, alias = geom->key_aliases; i < geom->num_key_aliases;
695818534a1Smrg         i++, alias++) {
696818534a1Smrg        if (strncmp(alias->alias, aliasStr, XkbKeyNameLength) == 0) {
697818534a1Smrg            bzero(alias->real, XkbKeyNameLength);
698818534a1Smrg            strncpy(alias->real, realStr, XkbKeyNameLength);
699818534a1Smrg            return alias;
700818534a1Smrg        }
701818534a1Smrg    }
702818534a1Smrg    if ((geom->num_key_aliases >= geom->sz_key_aliases) &&
703818534a1Smrg        (_XkbAllocKeyAliases(geom, 1) != Success)) {
704818534a1Smrg        return NULL;
705818534a1Smrg    }
706818534a1Smrg    alias = &geom->key_aliases[geom->num_key_aliases];
707818534a1Smrg    bzero(alias, sizeof(XkbKeyAliasRec));
708818534a1Smrg    strncpy(alias->alias, aliasStr, XkbKeyNameLength);
709818534a1Smrg    strncpy(alias->real, realStr, XkbKeyNameLength);
7101ab64890Smrg    geom->num_key_aliases++;
7111ab64890Smrg    return alias;
7121ab64890Smrg}
7131ab64890Smrg
7141ab64890SmrgXkbColorPtr
715e9628295SmrgXkbAddGeomColor(XkbGeometryPtr geom, _Xconst char *spec, unsigned int pixel)
716818534a1Smrg{
717818534a1Smrg    register int i;
718818534a1Smrg    register XkbColorPtr color;
719818534a1Smrg
720818534a1Smrg    if ((!geom) || (!spec))
721818534a1Smrg        return NULL;
722818534a1Smrg    for (i = 0, color = geom->colors; i < geom->num_colors; i++, color++) {
723818534a1Smrg        if ((color->spec) && (strcmp(color->spec, spec) == 0)) {
724818534a1Smrg            color->pixel = pixel;
725818534a1Smrg            return color;
726818534a1Smrg        }
727818534a1Smrg    }
728818534a1Smrg    if ((geom->num_colors >= geom->sz_colors) &&
729818534a1Smrg        (_XkbAllocColors(geom, 1) != Success)) {
730818534a1Smrg        return NULL;
731818534a1Smrg    }
732818534a1Smrg    color = &geom->colors[geom->num_colors];
733818534a1Smrg    color->pixel = pixel;
734818534a1Smrg    color->spec = strdup(spec);
7351ab64890Smrg    if (!color->spec)
736818534a1Smrg        return NULL;
7371ab64890Smrg    geom->num_colors++;
7381ab64890Smrg    return color;
7391ab64890Smrg}
7401ab64890Smrg
7411ab64890SmrgXkbOutlinePtr
742818534a1SmrgXkbAddGeomOutline(XkbShapePtr shape, int sz_points)
7431ab64890Smrg{
744818534a1Smrg    XkbOutlinePtr outline;
7451ab64890Smrg
746818534a1Smrg    if ((!shape) || (sz_points < 0))
747818534a1Smrg        return NULL;
748818534a1Smrg    if ((shape->num_outlines >= shape->sz_outlines) &&
749818534a1Smrg        (_XkbAllocOutlines(shape, 1) != Success)) {
750818534a1Smrg        return NULL;
7511ab64890Smrg    }
752818534a1Smrg    outline = &shape->outlines[shape->num_outlines];
753818534a1Smrg    bzero(outline, sizeof(XkbOutlineRec));
754818534a1Smrg    if ((sz_points > 0) && (_XkbAllocPoints(outline, sz_points) != Success))
755818534a1Smrg        return NULL;
7561ab64890Smrg    shape->num_outlines++;
7571ab64890Smrg    return outline;
7581ab64890Smrg}
7591ab64890Smrg
7601ab64890SmrgXkbShapePtr
761818534a1SmrgXkbAddGeomShape(XkbGeometryPtr geom, Atom name, int sz_outlines)
762818534a1Smrg{
763818534a1Smrg    XkbShapePtr shape;
764818534a1Smrg    register int i;
765818534a1Smrg
766818534a1Smrg    if ((!geom) || (!name) || (sz_outlines < 0))
767818534a1Smrg        return NULL;
768818534a1Smrg    if (geom->num_shapes > 0) {
769818534a1Smrg        for (shape = geom->shapes, i = 0; i < geom->num_shapes; i++, shape++) {
770818534a1Smrg            if (name == shape->name)
771818534a1Smrg                return shape;
772818534a1Smrg        }
773818534a1Smrg    }
774818534a1Smrg    if ((geom->num_shapes >= geom->sz_shapes) &&
775818534a1Smrg        (_XkbAllocShapes(geom, 1) != Success))
776818534a1Smrg        return NULL;
777818534a1Smrg    shape = &geom->shapes[geom->num_shapes];
778818534a1Smrg    bzero(shape, sizeof(XkbShapeRec));
779818534a1Smrg    if ((sz_outlines > 0) && (_XkbAllocOutlines(shape, sz_outlines) != Success))
780818534a1Smrg        return NULL;
781818534a1Smrg    shape->name = name;
782818534a1Smrg    shape->primary = shape->approx = NULL;
7831ab64890Smrg    geom->num_shapes++;
7841ab64890Smrg    return shape;
7851ab64890Smrg}
7861ab64890Smrg
7871ab64890SmrgXkbKeyPtr
7881ab64890SmrgXkbAddGeomKey(XkbRowPtr row)
7891ab64890Smrg{
790818534a1Smrg    XkbKeyPtr key;
791818534a1Smrg
7921ab64890Smrg    if (!row)
793818534a1Smrg        return NULL;
794818534a1Smrg    if ((row->num_keys >= row->sz_keys) && (_XkbAllocKeys(row, 1) != Success))
795818534a1Smrg        return NULL;
796818534a1Smrg    key = &row->keys[row->num_keys++];
797818534a1Smrg    bzero(key, sizeof(XkbKeyRec));
7981ab64890Smrg    return key;
7991ab64890Smrg}
8001ab64890Smrg
8011ab64890SmrgXkbRowPtr
802818534a1SmrgXkbAddGeomRow(XkbSectionPtr section, int sz_keys)
803818534a1Smrg{
804818534a1Smrg    XkbRowPtr row;
805818534a1Smrg
806818534a1Smrg    if ((!section) || (sz_keys < 0))
807818534a1Smrg        return NULL;
808818534a1Smrg    if ((section->num_rows >= section->sz_rows) &&
809818534a1Smrg        (_XkbAllocRows(section, 1) != Success))
810818534a1Smrg        return NULL;
811818534a1Smrg    row = &section->rows[section->num_rows];
812818534a1Smrg    bzero(row, sizeof(XkbRowRec));
813818534a1Smrg    if ((sz_keys > 0) && (_XkbAllocKeys(row, sz_keys) != Success))
814818534a1Smrg        return NULL;
8151ab64890Smrg    section->num_rows++;
8161ab64890Smrg    return row;
8171ab64890Smrg}
8181ab64890Smrg
8191ab64890SmrgXkbSectionPtr
820818534a1SmrgXkbAddGeomSection(XkbGeometryPtr geom,
821818534a1Smrg                  Atom name,
822818534a1Smrg                  int sz_rows,
823818534a1Smrg                  int sz_doodads,
824818534a1Smrg                  int sz_over)
825818534a1Smrg{
826818534a1Smrg    register int i;
827818534a1Smrg    XkbSectionPtr section;
828818534a1Smrg
829818534a1Smrg    if ((!geom) || (name == None) || (sz_rows < 0))
830818534a1Smrg        return NULL;
831818534a1Smrg    for (i = 0, section = geom->sections; i < geom->num_sections;
832818534a1Smrg         i++, section++) {
833818534a1Smrg        if (section->name != name)
834818534a1Smrg            continue;
835818534a1Smrg        if (((sz_rows > 0) && (_XkbAllocRows(section, sz_rows) != Success)) ||
836818534a1Smrg            ((sz_doodads > 0) &&
837818534a1Smrg             (_XkbAllocDoodads(section, sz_doodads) != Success)) ||
838818534a1Smrg            ((sz_over > 0) && (_XkbAllocOverlays(section, sz_over) != Success)))
839818534a1Smrg            return NULL;
840818534a1Smrg        return section;
841818534a1Smrg    }
842818534a1Smrg    if ((geom->num_sections >= geom->sz_sections) &&
843818534a1Smrg        (_XkbAllocSections(geom, 1) != Success))
844818534a1Smrg        return NULL;
845818534a1Smrg    section = &geom->sections[geom->num_sections];
846818534a1Smrg    if ((sz_rows > 0) && (_XkbAllocRows(section, sz_rows) != Success))
847818534a1Smrg        return NULL;
848818534a1Smrg    if ((sz_doodads > 0) && (_XkbAllocDoodads(section, sz_doodads) != Success)) {
849818534a1Smrg        if (section->rows) {
850818534a1Smrg            _XkbFree(section->rows);
851818534a1Smrg            section->rows = NULL;
852818534a1Smrg            section->sz_rows = section->num_rows = 0;
853818534a1Smrg        }
854818534a1Smrg        return NULL;
855818534a1Smrg    }
856818534a1Smrg    section->name = name;
8571ab64890Smrg    geom->num_sections++;
8581ab64890Smrg    return section;
8591ab64890Smrg}
8601ab64890Smrg
8611ab64890SmrgXkbDoodadPtr
862818534a1SmrgXkbAddGeomDoodad(XkbGeometryPtr geom, XkbSectionPtr section, Atom name)
8631ab64890Smrg{
864818534a1Smrg    XkbDoodadPtr old, doodad;
865818534a1Smrg    register int i, nDoodads;
8661ab64890Smrg
867818534a1Smrg    if ((!geom) || (name == None))
868818534a1Smrg        return NULL;
869818534a1Smrg    if ((section != NULL) && (section->num_doodads > 0)) {
870818534a1Smrg        old = section->doodads;
871818534a1Smrg        nDoodads = section->num_doodads;
8721ab64890Smrg    }
8731ab64890Smrg    else {
874818534a1Smrg        old = geom->doodads;
875818534a1Smrg        nDoodads = geom->num_doodads;
8761ab64890Smrg    }
877818534a1Smrg    for (i = 0, doodad = old; i < nDoodads; i++, doodad++) {
878818534a1Smrg        if (doodad->any.name == name)
879818534a1Smrg            return doodad;
8801ab64890Smrg    }
8811ab64890Smrg    if (section) {
882818534a1Smrg        if ((section->num_doodads >= geom->sz_doodads) &&
883818534a1Smrg            (_XkbAllocDoodads(section, 1) != Success)) {
884818534a1Smrg            return NULL;
885818534a1Smrg        }
886818534a1Smrg        doodad = &section->doodads[section->num_doodads++];
8871ab64890Smrg    }
8881ab64890Smrg    else {
889818534a1Smrg        if ((geom->num_doodads >= geom->sz_doodads) &&
890818534a1Smrg            (_XkbAllocDoodads(geom, 1) != Success))
891818534a1Smrg            return NULL;
892818534a1Smrg        doodad = &geom->doodads[geom->num_doodads++];
8931ab64890Smrg    }
894818534a1Smrg    bzero(doodad, sizeof(XkbDoodadRec));
895818534a1Smrg    doodad->any.name = name;
8961ab64890Smrg    return doodad;
8971ab64890Smrg}
8981ab64890Smrg
8991ab64890SmrgXkbOverlayKeyPtr
900818534a1SmrgXkbAddGeomOverlayKey(XkbOverlayPtr overlay,
901818534a1Smrg                     XkbOverlayRowPtr row,
902e9628295Smrg                     _Xconst char *over,
903e9628295Smrg                     _Xconst char *under)
904818534a1Smrg{
905818534a1Smrg    register int i;
906818534a1Smrg    XkbOverlayKeyPtr key;
907818534a1Smrg    XkbSectionPtr section;
908818534a1Smrg    XkbRowPtr row_under;
909818534a1Smrg    Bool found;
910818534a1Smrg
911818534a1Smrg    if ((!overlay) || (!row) || (!over) || (!under))
912818534a1Smrg        return NULL;
913818534a1Smrg    section = overlay->section_under;
914818534a1Smrg    if (row->row_under >= section->num_rows)
915818534a1Smrg        return NULL;
916818534a1Smrg    row_under = &section->rows[row->row_under];
917818534a1Smrg    for (i = 0, found = False; i < row_under->num_keys; i++) {
918818534a1Smrg        if (strncmp(under, row_under->keys[i].name.name, XkbKeyNameLength) == 0) {
919818534a1Smrg            found = True;
920818534a1Smrg            break;
921818534a1Smrg        }
9221ab64890Smrg    }
9231ab64890Smrg    if (!found)
924818534a1Smrg        return NULL;
925818534a1Smrg    if ((row->num_keys >= row->sz_keys) &&
926818534a1Smrg        (_XkbAllocOverlayKeys(row, 1) != Success))
927818534a1Smrg        return NULL;
928818534a1Smrg    key = &row->keys[row->num_keys];
929818534a1Smrg    strncpy(key->under.name, under, XkbKeyNameLength);
930818534a1Smrg    strncpy(key->over.name, over, XkbKeyNameLength);
9311ab64890Smrg    row->num_keys++;
9321ab64890Smrg    return key;
9331ab64890Smrg}
9341ab64890Smrg
9351ab64890SmrgXkbOverlayRowPtr
936818534a1SmrgXkbAddGeomOverlayRow(XkbOverlayPtr overlay, int row_under, int sz_keys)
937818534a1Smrg{
938818534a1Smrg    register int i;
939818534a1Smrg    XkbOverlayRowPtr row;
940818534a1Smrg
941818534a1Smrg    if ((!overlay) || (sz_keys < 0))
942818534a1Smrg        return NULL;
943818534a1Smrg    if (row_under >= overlay->section_under->num_rows)
944818534a1Smrg        return NULL;
945818534a1Smrg    for (i = 0; i < overlay->num_rows; i++) {
946818534a1Smrg        if (overlay->rows[i].row_under == row_under) {
947818534a1Smrg            row = &overlay->rows[i];
948818534a1Smrg            if ((row->sz_keys < sz_keys) &&
949818534a1Smrg                (_XkbAllocOverlayKeys(row, sz_keys) != Success)) {
950818534a1Smrg                return NULL;
951818534a1Smrg            }
952818534a1Smrg            return &overlay->rows[i];
953818534a1Smrg        }
954818534a1Smrg    }
955818534a1Smrg    if ((overlay->num_rows >= overlay->sz_rows) &&
956818534a1Smrg        (_XkbAllocOverlayRows(overlay, 1) != Success))
957818534a1Smrg        return NULL;
958818534a1Smrg    row = &overlay->rows[overlay->num_rows];
959818534a1Smrg    bzero(row, sizeof(XkbOverlayRowRec));
960818534a1Smrg    if ((sz_keys > 0) && (_XkbAllocOverlayKeys(row, sz_keys) != Success))
961818534a1Smrg        return NULL;
962818534a1Smrg    row->row_under = row_under;
9631ab64890Smrg    overlay->num_rows++;
9641ab64890Smrg    return row;
9651ab64890Smrg}
9661ab64890Smrg
9671ab64890SmrgXkbOverlayPtr
968818534a1SmrgXkbAddGeomOverlay(XkbSectionPtr section, Atom name, int sz_rows)
969818534a1Smrg{
970818534a1Smrg    register int i;
971818534a1Smrg    XkbOverlayPtr overlay;
972818534a1Smrg
973818534a1Smrg    if ((!section) || (name == None) || (sz_rows == 0))
974818534a1Smrg        return NULL;
975818534a1Smrg
976818534a1Smrg    for (i = 0, overlay = section->overlays; i < section->num_overlays;
977818534a1Smrg         i++, overlay++) {
978818534a1Smrg        if (overlay->name == name) {
979818534a1Smrg            if ((sz_rows > 0) &&
980818534a1Smrg                (_XkbAllocOverlayRows(overlay, sz_rows) != Success))
981818534a1Smrg                return NULL;
982818534a1Smrg            return overlay;
983818534a1Smrg        }
984818534a1Smrg    }
985818534a1Smrg    if ((section->num_overlays >= section->sz_overlays) &&
986818534a1Smrg        (_XkbAllocOverlays(section, 1) != Success))
987818534a1Smrg        return NULL;
988818534a1Smrg    overlay = &section->overlays[section->num_overlays];
989818534a1Smrg    if ((sz_rows > 0) && (_XkbAllocOverlayRows(overlay, sz_rows) != Success))
990818534a1Smrg        return NULL;
991818534a1Smrg    overlay->name = name;
992818534a1Smrg    overlay->section_under = section;
9931ab64890Smrg    section->num_overlays++;
9941ab64890Smrg    return overlay;
9951ab64890Smrg}
996