Tizen 2.1 base
[framework/uifw/xorg/lib/libx11.git] / src / xkb / XKBGAlloc.c
1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
3
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
15
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25 ********************************************************/
26
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
29 #elif defined(HAVE_CONFIG_H)
30 #include <config.h>
31 #endif
32
33 #ifndef XKB_IN_SERVER
34
35 #include <stdio.h>
36 #include "Xlibint.h"
37 #include "XKBlibint.h"
38 #include <X11/extensions/XKBgeom.h>
39 #include <X11/extensions/XKBproto.h>
40
41 #else
42
43 #include <stdio.h>
44 #include <X11/X.h>
45 #include <X11/Xproto.h>
46 #include "misc.h"
47 #include "inputstr.h"
48 #include <X11/extensions/XKBsrv.h>
49 #include <X11/extensions/XKBgeom.h>
50
51 #endif /* XKB_IN_SERVER */
52
53 #ifdef X_NOT_POSIX
54 #define Size_t unsigned int
55 #else
56 #define Size_t size_t
57 #endif
58
59 /***====================================================================***/
60
61 static void
62 _XkbFreeGeomLeafElems(  Bool                    freeAll,
63                         int                     first,
64                         int                     count,
65                         unsigned short *        num_inout,
66                         unsigned short *        sz_inout,
67                         char **                 elems,
68                         unsigned int            elem_sz)
69 {
70     if ((freeAll)||(*elems==NULL)) {
71         *num_inout= *sz_inout= 0;
72         if (*elems!=NULL) {
73             _XkbFree(*elems);
74             *elems= NULL;
75         }
76         return;
77     }
78
79     if ((first>=(*num_inout))||(first<0)||(count<1))
80         return;
81
82     if (first+count>=(*num_inout)) {
83         /* truncating the array is easy */
84         (*num_inout)= first;
85     }
86     else {
87         char *  ptr;
88         int     extra;
89         ptr= *elems;
90         extra= ((*num_inout)-(first+count))*elem_sz;
91         if (extra>0)
92             memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],extra);
93         (*num_inout)-= count;
94     }
95     return;
96 }
97
98 typedef void (*ContentsClearFunc)(
99                 char *          /* priv */
100 );
101
102 static void
103 _XkbFreeGeomNonLeafElems(       Bool                    freeAll,
104                                 int                     first,
105                                 int                     count,
106                                 unsigned short *        num_inout,
107                                 unsigned short *        sz_inout,
108                                 char **                 elems,
109                                 unsigned int            elem_sz,
110                                 ContentsClearFunc       freeFunc)
111 {
112 register int i;
113 register char *ptr;
114
115     if (freeAll) {
116         first= 0;
117         count= (*num_inout);
118     }
119     else if ((first>=(*num_inout))||(first<0)||(count<1))
120         return;
121     else if (first+count>(*num_inout))
122         count= (*num_inout)-first;
123     if (*elems==NULL)
124         return;
125
126     if (freeFunc) {
127         ptr= *elems;
128         ptr+= first*elem_sz;
129         for (i=0;i<count;i++) {
130             (*freeFunc)(ptr);
131             ptr+= elem_sz;
132         }
133     }
134     if (freeAll) {
135         (*num_inout)= (*sz_inout)= 0;
136         if (*elems) {
137             _XkbFree(*elems);
138             *elems= NULL;
139         }
140     }
141     else if (first+count>=(*num_inout))
142         *num_inout= first;
143     else {
144         i= ((*num_inout)-(first+count))*elem_sz;
145         ptr= *elems;
146         memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],i);
147         (*num_inout)-= count;
148     }
149     return;
150 }
151
152 /***====================================================================***/
153
154 static void
155 _XkbClearProperty(char *prop_in)
156 {
157 XkbPropertyPtr  prop= (XkbPropertyPtr)prop_in;
158
159     if (prop->name) {
160         _XkbFree(prop->name);
161         prop->name= NULL;
162     }
163     if (prop->value) {
164         _XkbFree(prop->value);
165         prop->value= NULL;
166     }
167     return;
168 }
169
170 void
171 XkbFreeGeomProperties(  XkbGeometryPtr  geom,
172                         int             first,
173                         int             count,
174                         Bool            freeAll)
175 {
176     _XkbFreeGeomNonLeafElems(freeAll,first,count,
177                                 &geom->num_properties,&geom->sz_properties,
178                                 (char **)&geom->properties,
179                                 sizeof(XkbPropertyRec),_XkbClearProperty);
180     return;
181 }
182
183 /***====================================================================***/
184
185 void
186 XkbFreeGeomKeyAliases(  XkbGeometryPtr  geom,
187                         int             first,
188                         int             count,
189                         Bool            freeAll)
190 {
191     _XkbFreeGeomLeafElems(freeAll,first,count,
192                                 &geom->num_key_aliases,&geom->sz_key_aliases,
193                                 (char **)&geom->key_aliases,
194                                 sizeof(XkbKeyAliasRec));
195     return;
196 }
197
198 /***====================================================================***/
199
200 static void
201 _XkbClearColor(char *color_in)
202 {
203 XkbColorPtr     color= (XkbColorPtr)color_in;
204
205     if (color->spec)
206         _XkbFree(color->spec);
207     return;
208 }
209
210 void
211 XkbFreeGeomColors(XkbGeometryPtr geom,int first,int count,Bool freeAll)
212 {
213     _XkbFreeGeomNonLeafElems(freeAll,first,count,
214                                 &geom->num_colors,&geom->sz_colors,
215                                 (char **)&geom->colors,
216                                 sizeof(XkbColorRec),_XkbClearColor);
217     return;
218 }
219
220 /***====================================================================***/
221
222 void
223 XkbFreeGeomPoints(XkbOutlinePtr outline,int first,int count,Bool freeAll)
224 {
225     _XkbFreeGeomLeafElems(freeAll,first,count,
226                                 &outline->num_points,&outline->sz_points,
227                                 (char **)&outline->points,
228                                 sizeof(XkbPointRec));
229     return;
230 }
231
232 /***====================================================================***/
233
234 static void
235 _XkbClearOutline(char *outline_in)
236 {
237 XkbOutlinePtr   outline= (XkbOutlinePtr)outline_in;
238
239     if (outline->points!=NULL)
240         XkbFreeGeomPoints(outline,0,outline->num_points,True);
241     return;
242 }
243
244 void
245 XkbFreeGeomOutlines(XkbShapePtr shape,int first,int count,Bool freeAll)
246 {
247     _XkbFreeGeomNonLeafElems(freeAll,first,count,
248                                 &shape->num_outlines,&shape->sz_outlines,
249                                 (char **)&shape->outlines,
250                                 sizeof(XkbOutlineRec),_XkbClearOutline);
251
252     return;
253 }
254
255 /***====================================================================***/
256
257 static void
258 _XkbClearShape(char *shape_in)
259 {
260 XkbShapePtr     shape= (XkbShapePtr)shape_in;
261
262     if (shape->outlines)
263         XkbFreeGeomOutlines(shape,0,shape->num_outlines,True);
264     return;
265 }
266
267 void
268 XkbFreeGeomShapes(XkbGeometryPtr geom,int first,int count,Bool freeAll)
269 {
270     _XkbFreeGeomNonLeafElems(freeAll,first,count,
271                                 &geom->num_shapes,&geom->sz_shapes,
272                                 (char **)&geom->shapes,
273                                 sizeof(XkbShapeRec),_XkbClearShape);
274     return;
275 }
276
277 /***====================================================================***/
278
279 void
280 XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row,int first,int count,Bool freeAll)
281 {
282     _XkbFreeGeomLeafElems(freeAll,first,count,
283                                 &row->num_keys,&row->sz_keys,
284                                 (char **)&row->keys,
285                                 sizeof(XkbOverlayKeyRec));
286     return;
287 }
288
289 /***====================================================================***/
290
291 static void
292 _XkbClearOverlayRow(char *row_in)
293 {
294 XkbOverlayRowPtr        row= (XkbOverlayRowPtr)row_in;
295
296     if (row->keys!=NULL)
297         XkbFreeGeomOverlayKeys(row,0,row->num_keys,True);
298     return;
299 }
300
301 void
302 XkbFreeGeomOverlayRows(XkbOverlayPtr overlay,int first,int count,Bool freeAll)
303 {
304     _XkbFreeGeomNonLeafElems(freeAll,first,count,
305                                 &overlay->num_rows,&overlay->sz_rows,
306                                 (char **)&overlay->rows,
307                                 sizeof(XkbOverlayRowRec),_XkbClearOverlayRow);
308     return;
309 }
310
311 /***====================================================================***/
312
313 static void
314 _XkbClearOverlay(char *overlay_in)
315 {
316 XkbOverlayPtr   overlay= (XkbOverlayPtr)overlay_in;
317
318     if (overlay->rows!=NULL)
319         XkbFreeGeomOverlayRows(overlay,0,overlay->num_rows,True);
320     return;
321 }
322
323 void
324 XkbFreeGeomOverlays(XkbSectionPtr section,int first,int count,Bool freeAll)
325 {
326     _XkbFreeGeomNonLeafElems(freeAll,first,count,
327                                 &section->num_overlays,&section->sz_overlays,
328                                 (char **)&section->overlays,
329                                 sizeof(XkbOverlayRec),_XkbClearOverlay);
330     return;
331 }
332
333 /***====================================================================***/
334
335 void
336 XkbFreeGeomKeys(XkbRowPtr row,int first,int count,Bool freeAll)
337 {
338     _XkbFreeGeomLeafElems(freeAll,first,count,
339                                 &row->num_keys,&row->sz_keys,
340                                 (char **)&row->keys,
341                                 sizeof(XkbKeyRec));
342     return;
343 }
344
345 /***====================================================================***/
346
347 static void
348 _XkbClearRow(char *row_in)
349 {
350 XkbRowPtr       row= (XkbRowPtr)row_in;
351
352     if (row->keys!=NULL)
353         XkbFreeGeomKeys(row,0,row->num_keys,True);
354     return;
355 }
356
357 void
358 XkbFreeGeomRows(XkbSectionPtr section,int first,int count,Bool freeAll)
359 {
360     _XkbFreeGeomNonLeafElems(freeAll,first,count,
361                                 &section->num_rows,&section->sz_rows,
362                                 (char **)&section->rows,
363                                 sizeof(XkbRowRec),_XkbClearRow);
364 }
365
366 /***====================================================================***/
367
368 static void
369 _XkbClearSection(char *section_in)
370 {
371 XkbSectionPtr   section= (XkbSectionPtr)section_in;
372
373     if (section->rows!=NULL)
374         XkbFreeGeomRows(section,0,section->num_rows,True);
375     if (section->doodads!=NULL) {
376         XkbFreeGeomDoodads(section->doodads,section->num_doodads,True);
377         section->doodads= NULL;
378     }
379     return;
380 }
381
382 void
383 XkbFreeGeomSections(XkbGeometryPtr geom,int first,int count,Bool freeAll)
384 {
385     _XkbFreeGeomNonLeafElems(freeAll,first,count,
386                                 &geom->num_sections,&geom->sz_sections,
387                                 (char **)&geom->sections,
388                                 sizeof(XkbSectionRec),_XkbClearSection);
389     return;
390 }
391
392 /***====================================================================***/
393
394 static void
395 _XkbClearDoodad(char *doodad_in)
396 {
397 XkbDoodadPtr    doodad= (XkbDoodadPtr)doodad_in;
398
399     switch (doodad->any.type) {
400         case XkbTextDoodad:
401             {
402                 if (doodad->text.text!=NULL) {
403                     _XkbFree(doodad->text.text);
404                     doodad->text.text= NULL;
405                 }
406                 if (doodad->text.font!=NULL) {
407                     _XkbFree(doodad->text.font);
408                     doodad->text.font= NULL;
409                 }
410             }
411             break;
412         case XkbLogoDoodad:
413             {
414                 if (doodad->logo.logo_name!=NULL) {
415                     _XkbFree(doodad->logo.logo_name);
416                     doodad->logo.logo_name= NULL;
417                 }
418             }
419             break;
420     }
421     return;
422 }
423
424 void
425 XkbFreeGeomDoodads(XkbDoodadPtr doodads,int nDoodads,Bool freeAll)
426 {
427 register int            i;
428 register XkbDoodadPtr   doodad;
429
430     if (doodads) {
431         for (i=0,doodad= doodads;i<nDoodads;i++,doodad++) {
432             _XkbClearDoodad((char *)doodad);
433         }
434         if (freeAll)
435             _XkbFree(doodads);
436     }
437     return;
438 }
439
440 void
441 XkbFreeGeometry(XkbGeometryPtr geom,unsigned which,Bool freeMap)
442 {
443     if (geom==NULL)
444         return;
445     if (freeMap)
446         which= XkbGeomAllMask;
447     if ((which&XkbGeomPropertiesMask)&&(geom->properties!=NULL))
448         XkbFreeGeomProperties(geom,0,geom->num_properties,True);
449     if ((which&XkbGeomColorsMask)&&(geom->colors!=NULL))
450         XkbFreeGeomColors(geom,0,geom->num_colors,True);
451     if ((which&XkbGeomShapesMask)&&(geom->shapes!=NULL))
452         XkbFreeGeomShapes(geom,0,geom->num_shapes,True);
453     if ((which&XkbGeomSectionsMask)&&(geom->sections!=NULL))
454         XkbFreeGeomSections(geom,0,geom->num_sections,True);
455     if ((which&XkbGeomDoodadsMask)&&(geom->doodads!= NULL)) {
456         XkbFreeGeomDoodads(geom->doodads,geom->num_doodads,True);
457         geom->doodads= NULL;
458         geom->num_doodads= geom->sz_doodads= 0;
459     }
460     if ((which&XkbGeomKeyAliasesMask)&&(geom->key_aliases!=NULL))
461         XkbFreeGeomKeyAliases(geom,0,geom->num_key_aliases,True);
462     if (freeMap) {
463         if (geom->label_font!=NULL) {
464             _XkbFree(geom->label_font);
465             geom->label_font= NULL;
466         }
467         _XkbFree(geom);
468     }
469     return;
470 }
471
472 /***====================================================================***/
473
474 static Status
475 _XkbGeomAlloc(  XPointer *              old,
476                 unsigned short *        num,
477                 unsigned short *        total,
478                 int                     num_new,
479                 Size_t                  sz_elem)
480 {
481     if (num_new<1)
482         return Success;
483     if ((*old)==NULL)
484         *num= *total= 0;
485
486     if ((*num)+num_new<=(*total))
487         return Success;
488
489     *total= (*num)+num_new;
490     if ((*old)!=NULL)
491          (*old)= (XPointer)_XkbRealloc((*old),(*total)*sz_elem);
492     else (*old)= (XPointer)_XkbCalloc((*total),sz_elem);
493     if ((*old)==NULL) {
494         *total= *num= 0;
495         return BadAlloc;
496     }
497
498     if (*num>0) {
499         char *tmp= (char *)(*old);
500         bzero(&tmp[sz_elem*(*num)],(num_new*sz_elem));
501     }
502     return Success;
503 }
504
505 #define _XkbAllocProps(g,n) _XkbGeomAlloc((XPointer *)&(g)->properties,\
506                                 &(g)->num_properties,&(g)->sz_properties,\
507                                 (n),sizeof(XkbPropertyRec))
508 #define _XkbAllocColors(g,n) _XkbGeomAlloc((XPointer *)&(g)->colors,\
509                                 &(g)->num_colors,&(g)->sz_colors,\
510                                 (n),sizeof(XkbColorRec))
511 #define _XkbAllocShapes(g,n) _XkbGeomAlloc((XPointer *)&(g)->shapes,\
512                                 &(g)->num_shapes,&(g)->sz_shapes,\
513                                 (n),sizeof(XkbShapeRec))
514 #define _XkbAllocSections(g,n) _XkbGeomAlloc((XPointer *)&(g)->sections,\
515                                 &(g)->num_sections,&(g)->sz_sections,\
516                                 (n),sizeof(XkbSectionRec))
517 #define _XkbAllocDoodads(g,n) _XkbGeomAlloc((XPointer *)&(g)->doodads,\
518                                 &(g)->num_doodads,&(g)->sz_doodads,\
519                                 (n),sizeof(XkbDoodadRec))
520 #define _XkbAllocKeyAliases(g,n) _XkbGeomAlloc((XPointer *)&(g)->key_aliases,\
521                                 &(g)->num_key_aliases,&(g)->sz_key_aliases,\
522                                 (n),sizeof(XkbKeyAliasRec))
523
524 #define _XkbAllocOutlines(s,n) _XkbGeomAlloc((XPointer *)&(s)->outlines,\
525                                 &(s)->num_outlines,&(s)->sz_outlines,\
526                                 (n),sizeof(XkbOutlineRec))
527 #define _XkbAllocRows(s,n) _XkbGeomAlloc((XPointer *)&(s)->rows,\
528                                 &(s)->num_rows,&(s)->sz_rows,\
529                                 (n),sizeof(XkbRowRec))
530 #define _XkbAllocPoints(o,n) _XkbGeomAlloc((XPointer *)&(o)->points,\
531                                 &(o)->num_points,&(o)->sz_points,\
532                                 (n),sizeof(XkbPointRec))
533 #define _XkbAllocKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\
534                                 &(r)->num_keys,&(r)->sz_keys,\
535                                 (n),sizeof(XkbKeyRec))
536 #define _XkbAllocOverlays(s,n) _XkbGeomAlloc((XPointer *)&(s)->overlays,\
537                                 &(s)->num_overlays,&(s)->sz_overlays,\
538                                 (n),sizeof(XkbOverlayRec))
539 #define _XkbAllocOverlayRows(o,n) _XkbGeomAlloc((XPointer *)&(o)->rows,\
540                                 &(o)->num_rows,&(o)->sz_rows,\
541                                 (n),sizeof(XkbOverlayRowRec))
542 #define _XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\
543                                 &(r)->num_keys,&(r)->sz_keys,\
544                                 (n),sizeof(XkbOverlayKeyRec))
545
546 Status
547 XkbAllocGeomProps(XkbGeometryPtr geom,int nProps)
548 {
549     return _XkbAllocProps(geom,nProps);
550 }
551
552 Status
553 XkbAllocGeomColors(XkbGeometryPtr geom,int nColors)
554 {
555     return _XkbAllocColors(geom,nColors);
556 }
557
558 Status
559 XkbAllocGeomKeyAliases(XkbGeometryPtr geom,int nKeyAliases)
560 {
561     return _XkbAllocKeyAliases(geom,nKeyAliases);
562 }
563
564 Status
565 XkbAllocGeomShapes(XkbGeometryPtr geom,int nShapes)
566 {
567     return _XkbAllocShapes(geom,nShapes);
568 }
569
570 Status
571 XkbAllocGeomSections(XkbGeometryPtr geom,int nSections)
572 {
573     return _XkbAllocSections(geom,nSections);
574 }
575
576 Status
577 XkbAllocGeomOverlays(XkbSectionPtr section,int nOverlays)
578 {
579     return _XkbAllocOverlays(section,nOverlays);
580 }
581
582 Status
583 XkbAllocGeomOverlayRows(XkbOverlayPtr overlay,int nRows)
584 {
585     return _XkbAllocOverlayRows(overlay,nRows);
586 }
587
588 Status
589 XkbAllocGeomOverlayKeys(XkbOverlayRowPtr row,int nKeys)
590 {
591     return _XkbAllocOverlayKeys(row,nKeys);
592 }
593
594 Status
595 XkbAllocGeomDoodads(XkbGeometryPtr geom,int nDoodads)
596 {
597     return _XkbAllocDoodads(geom,nDoodads);
598 }
599
600 Status
601 XkbAllocGeomSectionDoodads(XkbSectionPtr section,int nDoodads)
602 {
603     return _XkbAllocDoodads(section,nDoodads);
604 }
605
606 Status
607 XkbAllocGeomOutlines(XkbShapePtr shape,int nOL)
608 {
609     return _XkbAllocOutlines(shape,nOL);
610 }
611
612 Status
613 XkbAllocGeomRows(XkbSectionPtr section,int nRows)
614 {
615     return _XkbAllocRows(section,nRows);
616 }
617
618 Status
619 XkbAllocGeomPoints(XkbOutlinePtr ol,int nPts)
620 {
621     return _XkbAllocPoints(ol,nPts);
622 }
623
624 Status
625 XkbAllocGeomKeys(XkbRowPtr row,int nKeys)
626 {
627     return _XkbAllocKeys(row,nKeys);
628 }
629
630 Status
631 XkbAllocGeometry(XkbDescPtr xkb,XkbGeometrySizesPtr sizes)
632 {
633 XkbGeometryPtr  geom;
634 Status          rtrn;
635
636     if (xkb->geom==NULL) {
637         xkb->geom= _XkbTypedCalloc(1,XkbGeometryRec);
638         if (!xkb->geom)
639             return BadAlloc;
640     }
641     geom= xkb->geom;
642     if ((sizes->which&XkbGeomPropertiesMask)&&
643         ((rtrn=_XkbAllocProps(geom,sizes->num_properties))!=Success)) {
644         goto BAIL;
645     }
646     if ((sizes->which&XkbGeomColorsMask)&&
647         ((rtrn=_XkbAllocColors(geom,sizes->num_colors))!=Success)) {
648         goto BAIL;
649     }
650     if ((sizes->which&XkbGeomShapesMask)&&
651         ((rtrn=_XkbAllocShapes(geom,sizes->num_shapes))!=Success)) {
652         goto BAIL;
653     }
654     if ((sizes->which&XkbGeomSectionsMask)&&
655         ((rtrn=_XkbAllocSections(geom,sizes->num_sections))!=Success)) {
656         goto BAIL;
657     }
658     if ((sizes->which&XkbGeomDoodadsMask)&&
659         ((rtrn=_XkbAllocDoodads(geom,sizes->num_doodads))!=Success)) {
660         goto BAIL;
661     }
662     if ((sizes->which&XkbGeomKeyAliasesMask)&&
663         ((rtrn=_XkbAllocKeyAliases(geom,sizes->num_key_aliases))!=Success)) {
664         goto BAIL;
665     }
666     return Success;
667 BAIL:
668     XkbFreeGeometry(geom,XkbGeomAllMask,True);
669     xkb->geom= NULL;
670     return rtrn;
671 }
672
673 /***====================================================================***/
674
675 XkbPropertyPtr
676 XkbAddGeomProperty(XkbGeometryPtr geom,char *name,char *value)
677 {
678 register int i;
679 register XkbPropertyPtr prop;
680
681     if ((!geom)||(!name)||(!value))
682         return NULL;
683     for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
684         if ((prop->name)&&(strcmp(name,prop->name)==0)) {
685             if (prop->value)
686                 _XkbFree(prop->value);
687             prop->value= strdup(value);
688             return prop;
689         }
690     }
691     if ((geom->num_properties>=geom->sz_properties)&&
692                                         (_XkbAllocProps(geom,1)!=Success)) {
693         return NULL;
694     }
695     prop= &geom->properties[geom->num_properties];
696     prop->name= strdup(name);
697     if (!prop->name)
698         return NULL;
699     prop->value= strdup(value);
700     if (!prop->value) {
701         _XkbFree(prop->name);
702         prop->name= NULL;
703         return NULL;
704     }
705     geom->num_properties++;
706     return prop;
707 }
708
709 XkbKeyAliasPtr
710 XkbAddGeomKeyAlias(XkbGeometryPtr geom,char *aliasStr,char *realStr)
711 {
712 register int i;
713 register XkbKeyAliasPtr alias;
714
715     if ((!geom)||(!aliasStr)||(!realStr)||(!aliasStr[0])||(!realStr[0]))
716         return NULL;
717     for (i=0,alias=geom->key_aliases;i<geom->num_key_aliases;i++,alias++) {
718         if (strncmp(alias->alias,aliasStr,XkbKeyNameLength)==0) {
719             bzero(alias->real,XkbKeyNameLength);
720             strncpy(alias->real,realStr,XkbKeyNameLength);
721             return alias;
722         }
723     }
724     if ((geom->num_key_aliases>=geom->sz_key_aliases)&&
725                                 (_XkbAllocKeyAliases(geom,1)!=Success)) {
726         return NULL;
727     }
728     alias= &geom->key_aliases[geom->num_key_aliases];
729     bzero(alias,sizeof(XkbKeyAliasRec));
730     strncpy(alias->alias,aliasStr,XkbKeyNameLength);
731     strncpy(alias->real,realStr,XkbKeyNameLength);
732     geom->num_key_aliases++;
733     return alias;
734 }
735
736 XkbColorPtr
737 XkbAddGeomColor(XkbGeometryPtr geom,char *spec,unsigned int pixel)
738 {
739 register int i;
740 register XkbColorPtr color;
741
742     if ((!geom)||(!spec))
743         return NULL;
744     for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
745         if ((color->spec)&&(strcmp(color->spec,spec)==0)) {
746             color->pixel= pixel;
747             return color;
748         }
749     }
750     if ((geom->num_colors>=geom->sz_colors)&&
751                                         (_XkbAllocColors(geom,1)!=Success)) {
752         return NULL;
753     }
754     color= &geom->colors[geom->num_colors];
755     color->pixel= pixel;
756     color->spec= strdup(spec);
757     if (!color->spec)
758         return NULL;
759     geom->num_colors++;
760     return color;
761 }
762
763 XkbOutlinePtr
764 XkbAddGeomOutline(XkbShapePtr shape,int sz_points)
765 {
766 XkbOutlinePtr   outline;
767
768     if ((!shape)||(sz_points<0))
769         return NULL;
770     if ((shape->num_outlines>=shape->sz_outlines)&&
771                                         (_XkbAllocOutlines(shape,1)!=Success)) {
772         return NULL;
773     }
774     outline= &shape->outlines[shape->num_outlines];
775     bzero(outline,sizeof(XkbOutlineRec));
776     if ((sz_points>0)&&(_XkbAllocPoints(outline,sz_points)!=Success))
777         return NULL;
778     shape->num_outlines++;
779     return outline;
780 }
781
782 XkbShapePtr
783 XkbAddGeomShape(XkbGeometryPtr geom,Atom name,int sz_outlines)
784 {
785 XkbShapePtr     shape;
786 register int    i;
787
788     if ((!geom)||(!name)||(sz_outlines<0))
789         return NULL;
790     if (geom->num_shapes>0) {
791         for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) {
792             if (name==shape->name)
793                 return shape;
794         }
795     }
796     if ((geom->num_shapes>=geom->sz_shapes)&&
797                                         (_XkbAllocShapes(geom,1)!=Success))
798         return NULL;
799     shape= &geom->shapes[geom->num_shapes];
800     bzero(shape,sizeof(XkbShapeRec));
801     if ((sz_outlines>0)&&(_XkbAllocOutlines(shape,sz_outlines)!=Success))
802         return NULL;
803     shape->name= name;
804     shape->primary= shape->approx= NULL;
805     geom->num_shapes++;
806     return shape;
807 }
808
809 XkbKeyPtr
810 XkbAddGeomKey(XkbRowPtr row)
811 {
812 XkbKeyPtr       key;
813     if (!row)
814         return NULL;
815     if ((row->num_keys>=row->sz_keys)&&(_XkbAllocKeys(row,1)!=Success))
816         return NULL;
817     key= &row->keys[row->num_keys++];
818     bzero(key,sizeof(XkbKeyRec));
819     return key;
820 }
821
822 XkbRowPtr
823 XkbAddGeomRow(XkbSectionPtr section,int sz_keys)
824 {
825 XkbRowPtr       row;
826
827     if ((!section)||(sz_keys<0))
828         return NULL;
829     if ((section->num_rows>=section->sz_rows)&&
830                                         (_XkbAllocRows(section,1)!=Success))
831         return NULL;
832     row= &section->rows[section->num_rows];
833     bzero(row,sizeof(XkbRowRec));
834     if ((sz_keys>0)&&(_XkbAllocKeys(row,sz_keys)!=Success))
835         return NULL;
836     section->num_rows++;
837     return row;
838 }
839
840 XkbSectionPtr
841 XkbAddGeomSection(      XkbGeometryPtr  geom,
842                         Atom            name,
843                         int             sz_rows,
844                         int             sz_doodads,
845                         int             sz_over)
846 {
847 register int    i;
848 XkbSectionPtr   section;
849
850     if ((!geom)||(name==None)||(sz_rows<0))
851         return NULL;
852     for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
853         if (section->name!=name)
854             continue;
855         if (((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))||
856             ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success))||
857             ((sz_over>0)&&(_XkbAllocOverlays(section,sz_over)!=Success)))
858             return NULL;
859         return section;
860     }
861     if ((geom->num_sections>=geom->sz_sections)&&
862                                         (_XkbAllocSections(geom,1)!=Success))
863         return NULL;
864     section= &geom->sections[geom->num_sections];
865     if ((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))
866         return NULL;
867     if ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success)) {
868         if (section->rows) {
869             _XkbFree(section->rows);
870             section->rows= NULL;
871             section->sz_rows= section->num_rows= 0;
872         }
873         return NULL;
874     }
875     section->name= name;
876     geom->num_sections++;
877     return section;
878 }
879
880 XkbDoodadPtr
881 XkbAddGeomDoodad(XkbGeometryPtr geom,XkbSectionPtr section,Atom name)
882 {
883 XkbDoodadPtr    old,doodad;
884 register int    i,nDoodads;
885
886     if ((!geom)||(name==None))
887         return NULL;
888     if ((section!=NULL)&&(section->num_doodads>0)) {
889         old= section->doodads;
890         nDoodads= section->num_doodads;
891     }
892     else {
893         old= geom->doodads;
894         nDoodads= geom->num_doodads;
895     }
896     for (i=0,doodad=old;i<nDoodads;i++,doodad++) {
897         if (doodad->any.name==name)
898             return doodad;
899     }
900     if (section) {
901         if ((section->num_doodads>=geom->sz_doodads)&&
902             (_XkbAllocDoodads(section,1)!=Success)) {
903             return NULL;
904         }
905         doodad= &section->doodads[section->num_doodads++];
906     }
907     else {
908         if ((geom->num_doodads>=geom->sz_doodads)&&
909                                         (_XkbAllocDoodads(geom,1)!=Success))
910             return NULL;
911         doodad= &geom->doodads[geom->num_doodads++];
912     }
913     bzero(doodad,sizeof(XkbDoodadRec));
914     doodad->any.name= name;
915     return doodad;
916 }
917
918 XkbOverlayKeyPtr
919 XkbAddGeomOverlayKey(   XkbOverlayPtr           overlay,
920                         XkbOverlayRowPtr        row,
921                         char *                  over,
922                         char *                  under)
923 {
924 register int    i;
925 XkbOverlayKeyPtr key;
926 XkbSectionPtr   section;
927 XkbRowPtr       row_under;
928 Bool            found;
929
930     if ((!overlay)||(!row)||(!over)||(!under))
931         return NULL;
932     section= overlay->section_under;
933     if (row->row_under>=section->num_rows)
934         return NULL;
935     row_under= &section->rows[row->row_under];
936     for (i=0,found=False;i<row_under->num_keys;i++) {
937         if (strncmp(under,row_under->keys[i].name.name,XkbKeyNameLength)==0) {
938             found= True;
939             break;
940         }
941     }
942     if (!found)
943         return NULL;
944     if ((row->num_keys>=row->sz_keys)&&(_XkbAllocOverlayKeys(row,1)!=Success))
945         return NULL;
946     key= &row->keys[row->num_keys];
947     strncpy(key->under.name,under,XkbKeyNameLength);
948     strncpy(key->over.name,over,XkbKeyNameLength);
949     row->num_keys++;
950     return key;
951 }
952
953 XkbOverlayRowPtr
954 XkbAddGeomOverlayRow(XkbOverlayPtr overlay,int row_under,int sz_keys)
955 {
956 register int            i;
957 XkbOverlayRowPtr        row;
958
959     if ((!overlay)||(sz_keys<0))
960         return NULL;
961     if (row_under>=overlay->section_under->num_rows)
962         return NULL;
963     for (i=0;i<overlay->num_rows;i++) {
964         if (overlay->rows[i].row_under==row_under) {
965             row= &overlay->rows[i];
966             if ((row->sz_keys<sz_keys)&&
967                                 (_XkbAllocOverlayKeys(row,sz_keys)!=Success)) {
968                 return NULL;
969             }
970             return &overlay->rows[i];
971         }
972     }
973     if ((overlay->num_rows>=overlay->sz_rows)&&
974                                 (_XkbAllocOverlayRows(overlay,1)!=Success))
975         return NULL;
976     row= &overlay->rows[overlay->num_rows];
977     bzero(row,sizeof(XkbOverlayRowRec));
978     if ((sz_keys>0)&&(_XkbAllocOverlayKeys(row,sz_keys)!=Success))
979         return NULL;
980     row->row_under= row_under;
981     overlay->num_rows++;
982     return row;
983 }
984
985 XkbOverlayPtr
986 XkbAddGeomOverlay(XkbSectionPtr section,Atom name,int sz_rows)
987 {
988 register int    i;
989 XkbOverlayPtr   overlay;
990
991     if ((!section)||(name==None)||(sz_rows==0))
992         return NULL;
993
994     for (i=0,overlay=section->overlays;i<section->num_overlays;i++,overlay++) {
995         if (overlay->name==name) {
996             if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
997                 return NULL;
998             return overlay;
999         }
1000     }
1001     if ((section->num_overlays>=section->sz_overlays)&&
1002                                 (_XkbAllocOverlays(section,1)!=Success))
1003         return NULL;
1004     overlay= &section->overlays[section->num_overlays];
1005     if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
1006         return NULL;
1007     overlay->name= name;
1008     overlay->section_under= section;
1009     section->num_overlays++;
1010     return overlay;
1011 }