First import
[xorg_rtime.git] / xorg-server-1.4 / xkb / XKBGAlloc.c
blob815cc95f5c58c1350c826bd1e2d6ab4f24359d85
1 /************************************************************
2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
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.
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.
25 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
29 #endif
31 #define NEED_EVENTS
32 #define NEED_REPLIES
34 #include <stdio.h>
35 #include <X11/X.h>
36 #include <X11/Xproto.h>
37 #include "misc.h"
38 #include "inputstr.h"
39 #include <xkbsrv.h>
40 #include <X11/extensions/XKBgeom.h>
42 #ifdef X_NOT_POSIX
43 #define Size_t unsigned int
44 #else
45 #define Size_t size_t
46 #endif
48 /***====================================================================***/
50 static void
51 _XkbFreeGeomLeafElems( Bool freeAll,
52 int first,
53 int count,
54 unsigned short * num_inout,
55 unsigned short * sz_inout,
56 char ** elems,
57 unsigned int elem_sz)
59 if ((freeAll)||(*elems==NULL)) {
60 *num_inout= *sz_inout= 0;
61 if (*elems!=NULL) {
62 _XkbFree(*elems);
63 *elems= NULL;
65 return;
68 if ((first>=(*num_inout))||(first<0)||(count<1))
69 return;
71 if (first+count>=(*num_inout)) {
72 /* truncating the array is easy */
73 (*num_inout)= first;
75 else {
76 char * ptr;
77 int extra;
78 ptr= *elems;
79 extra= ((*num_inout)-(first+count))*elem_sz;
80 if (extra>0)
81 memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],extra);
82 (*num_inout)-= count;
84 return;
87 typedef void (*ContentsClearFunc)(
88 char * /* priv */
91 static void
92 _XkbFreeGeomNonLeafElems( Bool freeAll,
93 int first,
94 int count,
95 unsigned short * num_inout,
96 unsigned short * sz_inout,
97 char ** elems,
98 unsigned int elem_sz,
99 ContentsClearFunc freeFunc)
101 register int i;
102 register char *ptr;
104 if (freeAll) {
105 first= 0;
106 count= (*num_inout);
108 else if ((first>=(*num_inout))||(first<0)||(count<1))
109 return;
110 else if (first+count>(*num_inout))
111 count= (*num_inout)-first;
112 if (*elems==NULL)
113 return;
115 if (freeFunc) {
116 ptr= *elems;
117 ptr+= first*elem_sz;
118 for (i=0;i<count;i++) {
119 (*freeFunc)(ptr);
120 ptr+= elem_sz;
123 if (freeAll) {
124 (*num_inout)= (*sz_inout)= 0;
125 if (*elems) {
126 _XkbFree(*elems);
127 *elems= NULL;
130 else if (first+count>=(*num_inout))
131 *num_inout= first;
132 else {
133 i= ((*num_inout)-(first+count))*elem_sz;
134 ptr= *elems;
135 memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],i);
136 (*num_inout)-= count;
138 return;
141 /***====================================================================***/
143 static void
144 _XkbClearProperty(char *prop_in)
146 XkbPropertyPtr prop= (XkbPropertyPtr)prop_in;
148 if (prop->name) {
149 _XkbFree(prop->name);
150 prop->name= NULL;
152 if (prop->value) {
153 _XkbFree(prop->value);
154 prop->value= NULL;
156 return;
159 void
160 XkbFreeGeomProperties( XkbGeometryPtr geom,
161 int first,
162 int count,
163 Bool freeAll)
165 _XkbFreeGeomNonLeafElems(freeAll,first,count,
166 &geom->num_properties,&geom->sz_properties,
167 (char **)&geom->properties,
168 sizeof(XkbPropertyRec),_XkbClearProperty);
169 return;
172 /***====================================================================***/
174 void
175 XkbFreeGeomKeyAliases( XkbGeometryPtr geom,
176 int first,
177 int count,
178 Bool freeAll)
180 _XkbFreeGeomLeafElems(freeAll,first,count,
181 &geom->num_key_aliases,&geom->sz_key_aliases,
182 (char **)&geom->key_aliases,
183 sizeof(XkbKeyAliasRec));
184 return;
187 /***====================================================================***/
189 static void
190 _XkbClearColor(char *color_in)
192 XkbColorPtr color= (XkbColorPtr)color_in;
194 if (color->spec)
195 _XkbFree(color->spec);
196 return;
199 void
200 XkbFreeGeomColors(XkbGeometryPtr geom,int first,int count,Bool freeAll)
202 _XkbFreeGeomNonLeafElems(freeAll,first,count,
203 &geom->num_colors,&geom->sz_colors,
204 (char **)&geom->colors,
205 sizeof(XkbColorRec),_XkbClearColor);
206 return;
209 /***====================================================================***/
211 void
212 XkbFreeGeomPoints(XkbOutlinePtr outline,int first,int count,Bool freeAll)
214 _XkbFreeGeomLeafElems(freeAll,first,count,
215 &outline->num_points,&outline->sz_points,
216 (char **)&outline->points,
217 sizeof(XkbPointRec));
218 return;
221 /***====================================================================***/
223 static void
224 _XkbClearOutline(char *outline_in)
226 XkbOutlinePtr outline= (XkbOutlinePtr)outline_in;
228 if (outline->points!=NULL)
229 XkbFreeGeomPoints(outline,0,outline->num_points,True);
230 return;
233 void
234 XkbFreeGeomOutlines(XkbShapePtr shape,int first,int count,Bool freeAll)
236 _XkbFreeGeomNonLeafElems(freeAll,first,count,
237 &shape->num_outlines,&shape->sz_outlines,
238 (char **)&shape->outlines,
239 sizeof(XkbOutlineRec),_XkbClearOutline);
241 return;
244 /***====================================================================***/
246 static void
247 _XkbClearShape(char *shape_in)
249 XkbShapePtr shape= (XkbShapePtr)shape_in;
251 if (shape->outlines)
252 XkbFreeGeomOutlines(shape,0,shape->num_outlines,True);
253 return;
256 void
257 XkbFreeGeomShapes(XkbGeometryPtr geom,int first,int count,Bool freeAll)
259 _XkbFreeGeomNonLeafElems(freeAll,first,count,
260 &geom->num_shapes,&geom->sz_shapes,
261 (char **)&geom->shapes,
262 sizeof(XkbShapeRec),_XkbClearShape);
263 return;
266 /***====================================================================***/
268 void
269 XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row,int first,int count,Bool freeAll)
271 _XkbFreeGeomLeafElems(freeAll,first,count,
272 &row->num_keys,&row->sz_keys,
273 (char **)&row->keys,
274 sizeof(XkbOverlayKeyRec));
275 return;
278 /***====================================================================***/
280 static void
281 _XkbClearOverlayRow(char *row_in)
283 XkbOverlayRowPtr row= (XkbOverlayRowPtr)row_in;
285 if (row->keys!=NULL)
286 XkbFreeGeomOverlayKeys(row,0,row->num_keys,True);
287 return;
290 void
291 XkbFreeGeomOverlayRows(XkbOverlayPtr overlay,int first,int count,Bool freeAll)
293 _XkbFreeGeomNonLeafElems(freeAll,first,count,
294 &overlay->num_rows,&overlay->sz_rows,
295 (char **)&overlay->rows,
296 sizeof(XkbOverlayRowRec),_XkbClearOverlayRow);
297 return;
300 /***====================================================================***/
302 static void
303 _XkbClearOverlay(char *overlay_in)
305 XkbOverlayPtr overlay= (XkbOverlayPtr)overlay_in;
307 if (overlay->rows!=NULL)
308 XkbFreeGeomOverlayRows(overlay,0,overlay->num_rows,True);
309 return;
312 void
313 XkbFreeGeomOverlays(XkbSectionPtr section,int first,int count,Bool freeAll)
315 _XkbFreeGeomNonLeafElems(freeAll,first,count,
316 &section->num_overlays,&section->sz_overlays,
317 (char **)&section->overlays,
318 sizeof(XkbOverlayRec),_XkbClearOverlay);
319 return;
322 /***====================================================================***/
324 void
325 XkbFreeGeomKeys(XkbRowPtr row,int first,int count,Bool freeAll)
327 _XkbFreeGeomLeafElems(freeAll,first,count,
328 &row->num_keys,&row->sz_keys,
329 (char **)&row->keys,
330 sizeof(XkbKeyRec));
331 return;
334 /***====================================================================***/
336 static void
337 _XkbClearRow(char *row_in)
339 XkbRowPtr row= (XkbRowPtr)row_in;
341 if (row->keys!=NULL)
342 XkbFreeGeomKeys(row,0,row->num_keys,True);
343 return;
346 void
347 XkbFreeGeomRows(XkbSectionPtr section,int first,int count,Bool freeAll)
349 _XkbFreeGeomNonLeafElems(freeAll,first,count,
350 &section->num_rows,&section->sz_rows,
351 (char **)&section->rows,
352 sizeof(XkbRowRec),_XkbClearRow);
355 /***====================================================================***/
357 static void
358 _XkbClearSection(char *section_in)
360 XkbSectionPtr section= (XkbSectionPtr)section_in;
362 if (section->rows!=NULL)
363 XkbFreeGeomRows(section,0,section->num_rows,True);
364 if (section->doodads!=NULL) {
365 XkbFreeGeomDoodads(section->doodads,section->num_doodads,True);
366 section->doodads= NULL;
368 return;
371 void
372 XkbFreeGeomSections(XkbGeometryPtr geom,int first,int count,Bool freeAll)
374 _XkbFreeGeomNonLeafElems(freeAll,first,count,
375 &geom->num_sections,&geom->sz_sections,
376 (char **)&geom->sections,
377 sizeof(XkbSectionRec),_XkbClearSection);
378 return;
381 /***====================================================================***/
383 static void
384 _XkbClearDoodad(char *doodad_in)
386 XkbDoodadPtr doodad= (XkbDoodadPtr)doodad_in;
388 switch (doodad->any.type) {
389 case XkbTextDoodad:
391 if (doodad->text.text!=NULL) {
392 _XkbFree(doodad->text.text);
393 doodad->text.text= NULL;
395 if (doodad->text.font!=NULL) {
396 _XkbFree(doodad->text.font);
397 doodad->text.font= NULL;
400 break;
401 case XkbLogoDoodad:
403 if (doodad->logo.logo_name!=NULL) {
404 _XkbFree(doodad->logo.logo_name);
405 doodad->logo.logo_name= NULL;
408 break;
410 return;
413 void
414 XkbFreeGeomDoodads(XkbDoodadPtr doodads,int nDoodads,Bool freeAll)
416 register int i;
417 register XkbDoodadPtr doodad;
419 if (doodads) {
420 for (i=0,doodad= doodads;i<nDoodads;i++,doodad++) {
421 _XkbClearDoodad((char *)doodad);
423 if (freeAll)
424 _XkbFree(doodads);
426 return;
429 void
430 XkbFreeGeometry(XkbGeometryPtr geom,unsigned which,Bool freeMap)
432 if (geom==NULL)
433 return;
434 if (freeMap)
435 which= XkbGeomAllMask;
436 if ((which&XkbGeomPropertiesMask)&&(geom->properties!=NULL))
437 XkbFreeGeomProperties(geom,0,geom->num_properties,True);
438 if ((which&XkbGeomColorsMask)&&(geom->colors!=NULL))
439 XkbFreeGeomColors(geom,0,geom->num_colors,True);
440 if ((which&XkbGeomShapesMask)&&(geom->shapes!=NULL))
441 XkbFreeGeomShapes(geom,0,geom->num_shapes,True);
442 if ((which&XkbGeomSectionsMask)&&(geom->sections!=NULL))
443 XkbFreeGeomSections(geom,0,geom->num_sections,True);
444 if ((which&XkbGeomDoodadsMask)&&(geom->doodads!= NULL)) {
445 XkbFreeGeomDoodads(geom->doodads,geom->num_doodads,True);
446 geom->doodads= NULL;
447 geom->num_doodads= geom->sz_doodads= 0;
449 if ((which&XkbGeomKeyAliasesMask)&&(geom->key_aliases!=NULL))
450 XkbFreeGeomKeyAliases(geom,0,geom->num_key_aliases,True);
451 if (freeMap) {
452 if (geom->label_font!=NULL) {
453 _XkbFree(geom->label_font);
454 geom->label_font= NULL;
456 _XkbFree(geom);
458 return;
461 /***====================================================================***/
463 static Status
464 _XkbGeomAlloc( XPointer * old,
465 unsigned short * num,
466 unsigned short * total,
467 int num_new,
468 Size_t sz_elem)
470 if (num_new<1)
471 return Success;
472 if ((*old)==NULL)
473 *num= *total= 0;
475 if ((*num)+num_new<=(*total))
476 return Success;
478 *total= (*num)+num_new;
479 if ((*old)!=NULL)
480 (*old)= (XPointer)_XkbRealloc((*old),(*total)*sz_elem);
481 else (*old)= (XPointer)_XkbCalloc((*total),sz_elem);
482 if ((*old)==NULL) {
483 *total= *num= 0;
484 return BadAlloc;
487 if (*num>0) {
488 char *tmp= (char *)(*old);
489 bzero(&tmp[sz_elem*(*num)],(num_new*sz_elem));
491 return Success;
494 #define _XkbAllocProps(g,n) _XkbGeomAlloc((XPointer *)&(g)->properties,\
495 &(g)->num_properties,&(g)->sz_properties,\
496 (n),sizeof(XkbPropertyRec))
497 #define _XkbAllocColors(g,n) _XkbGeomAlloc((XPointer *)&(g)->colors,\
498 &(g)->num_colors,&(g)->sz_colors,\
499 (n),sizeof(XkbColorRec))
500 #define _XkbAllocShapes(g,n) _XkbGeomAlloc((XPointer *)&(g)->shapes,\
501 &(g)->num_shapes,&(g)->sz_shapes,\
502 (n),sizeof(XkbShapeRec))
503 #define _XkbAllocSections(g,n) _XkbGeomAlloc((XPointer *)&(g)->sections,\
504 &(g)->num_sections,&(g)->sz_sections,\
505 (n),sizeof(XkbSectionRec))
506 #define _XkbAllocDoodads(g,n) _XkbGeomAlloc((XPointer *)&(g)->doodads,\
507 &(g)->num_doodads,&(g)->sz_doodads,\
508 (n),sizeof(XkbDoodadRec))
509 #define _XkbAllocKeyAliases(g,n) _XkbGeomAlloc((XPointer *)&(g)->key_aliases,\
510 &(g)->num_key_aliases,&(g)->sz_key_aliases,\
511 (n),sizeof(XkbKeyAliasRec))
513 #define _XkbAllocOutlines(s,n) _XkbGeomAlloc((XPointer *)&(s)->outlines,\
514 &(s)->num_outlines,&(s)->sz_outlines,\
515 (n),sizeof(XkbOutlineRec))
516 #define _XkbAllocRows(s,n) _XkbGeomAlloc((XPointer *)&(s)->rows,\
517 &(s)->num_rows,&(s)->sz_rows,\
518 (n),sizeof(XkbRowRec))
519 #define _XkbAllocPoints(o,n) _XkbGeomAlloc((XPointer *)&(o)->points,\
520 &(o)->num_points,&(o)->sz_points,\
521 (n),sizeof(XkbPointRec))
522 #define _XkbAllocKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\
523 &(r)->num_keys,&(r)->sz_keys,\
524 (n),sizeof(XkbKeyRec))
525 #define _XkbAllocOverlays(s,n) _XkbGeomAlloc((XPointer *)&(s)->overlays,\
526 &(s)->num_overlays,&(s)->sz_overlays,\
527 (n),sizeof(XkbOverlayRec))
528 #define _XkbAllocOverlayRows(o,n) _XkbGeomAlloc((XPointer *)&(o)->rows,\
529 &(o)->num_rows,&(o)->sz_rows,\
530 (n),sizeof(XkbOverlayRowRec))
531 #define _XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\
532 &(r)->num_keys,&(r)->sz_keys,\
533 (n),sizeof(XkbOverlayKeyRec))
535 Status
536 XkbAllocGeomProps(XkbGeometryPtr geom,int nProps)
538 return _XkbAllocProps(geom,nProps);
541 Status
542 XkbAllocGeomColors(XkbGeometryPtr geom,int nColors)
544 return _XkbAllocColors(geom,nColors);
547 Status
548 XkbAllocGeomKeyAliases(XkbGeometryPtr geom,int nKeyAliases)
550 return _XkbAllocKeyAliases(geom,nKeyAliases);
553 Status
554 XkbAllocGeomShapes(XkbGeometryPtr geom,int nShapes)
556 return _XkbAllocShapes(geom,nShapes);
559 Status
560 XkbAllocGeomSections(XkbGeometryPtr geom,int nSections)
562 return _XkbAllocSections(geom,nSections);
565 Status
566 XkbAllocGeomOverlays(XkbSectionPtr section,int nOverlays)
568 return _XkbAllocOverlays(section,nOverlays);
571 Status
572 XkbAllocGeomOverlayRows(XkbOverlayPtr overlay,int nRows)
574 return _XkbAllocOverlayRows(overlay,nRows);
577 Status
578 XkbAllocGeomOverlayKeys(XkbOverlayRowPtr row,int nKeys)
580 return _XkbAllocOverlayKeys(row,nKeys);
583 Status
584 XkbAllocGeomDoodads(XkbGeometryPtr geom,int nDoodads)
586 return _XkbAllocDoodads(geom,nDoodads);
589 Status
590 XkbAllocGeomSectionDoodads(XkbSectionPtr section,int nDoodads)
592 return _XkbAllocDoodads(section,nDoodads);
595 Status
596 XkbAllocGeomOutlines(XkbShapePtr shape,int nOL)
598 return _XkbAllocOutlines(shape,nOL);
601 Status
602 XkbAllocGeomRows(XkbSectionPtr section,int nRows)
604 return _XkbAllocRows(section,nRows);
607 Status
608 XkbAllocGeomPoints(XkbOutlinePtr ol,int nPts)
610 return _XkbAllocPoints(ol,nPts);
613 Status
614 XkbAllocGeomKeys(XkbRowPtr row,int nKeys)
616 return _XkbAllocKeys(row,nKeys);
619 Status
620 XkbAllocGeometry(XkbDescPtr xkb,XkbGeometrySizesPtr sizes)
622 XkbGeometryPtr geom;
623 Status rtrn;
625 if (xkb->geom==NULL) {
626 xkb->geom= _XkbTypedCalloc(1,XkbGeometryRec);
627 if (!xkb->geom)
628 return BadAlloc;
630 geom= xkb->geom;
631 if ((sizes->which&XkbGeomPropertiesMask)&&
632 ((rtrn=_XkbAllocProps(geom,sizes->num_properties))!=Success)) {
633 goto BAIL;
635 if ((sizes->which&XkbGeomColorsMask)&&
636 ((rtrn=_XkbAllocColors(geom,sizes->num_colors))!=Success)) {
637 goto BAIL;
639 if ((sizes->which&XkbGeomShapesMask)&&
640 ((rtrn=_XkbAllocShapes(geom,sizes->num_shapes))!=Success)) {
641 goto BAIL;
643 if ((sizes->which&XkbGeomSectionsMask)&&
644 ((rtrn=_XkbAllocSections(geom,sizes->num_sections))!=Success)) {
645 goto BAIL;
647 if ((sizes->which&XkbGeomDoodadsMask)&&
648 ((rtrn=_XkbAllocDoodads(geom,sizes->num_doodads))!=Success)) {
649 goto BAIL;
651 if ((sizes->which&XkbGeomKeyAliasesMask)&&
652 ((rtrn=_XkbAllocKeyAliases(geom,sizes->num_key_aliases))!=Success)) {
653 goto BAIL;
655 return Success;
656 BAIL:
657 XkbFreeGeometry(geom,XkbGeomAllMask,True);
658 xkb->geom= NULL;
659 return rtrn;
662 /***====================================================================***/
664 XkbPropertyPtr
665 XkbAddGeomProperty(XkbGeometryPtr geom,char *name,char *value)
667 register int i;
668 register XkbPropertyPtr prop;
670 if ((!geom)||(!name)||(!value))
671 return NULL;
672 for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
673 if ((prop->name)&&(strcmp(name,prop->name)==0)) {
674 if (prop->value)
675 _XkbFree(prop->value);
676 prop->value= (char *)_XkbAlloc(strlen(value)+1);
677 if (prop->value)
678 strcpy(prop->value,value);
679 return prop;
682 if ((geom->num_properties>=geom->sz_properties)&&
683 (_XkbAllocProps(geom,1)!=Success)) {
684 return NULL;
686 prop= &geom->properties[geom->num_properties];
687 prop->name= (char *)_XkbAlloc(strlen(name)+1);
688 if (!name)
689 return NULL;
690 strcpy(prop->name,name);
691 prop->value= (char *)_XkbAlloc(strlen(value)+1);
692 if (!value) {
693 _XkbFree(prop->name);
694 prop->name= NULL;
695 return NULL;
697 strcpy(prop->value,value);
698 geom->num_properties++;
699 return prop;
702 XkbKeyAliasPtr
703 XkbAddGeomKeyAlias(XkbGeometryPtr geom,char *aliasStr,char *realStr)
705 register int i;
706 register XkbKeyAliasPtr alias;
708 if ((!geom)||(!aliasStr)||(!realStr)||(!aliasStr[0])||(!realStr[0]))
709 return NULL;
710 for (i=0,alias=geom->key_aliases;i<geom->num_key_aliases;i++,alias++) {
711 if (strncmp(alias->alias,aliasStr,XkbKeyNameLength)==0) {
712 bzero(alias->real,XkbKeyNameLength);
713 strncpy(alias->real,realStr,XkbKeyNameLength);
714 return alias;
717 if ((geom->num_key_aliases>=geom->sz_key_aliases)&&
718 (_XkbAllocKeyAliases(geom,1)!=Success)) {
719 return NULL;
721 alias= &geom->key_aliases[geom->num_key_aliases];
722 bzero(alias,sizeof(XkbKeyAliasRec));
723 strncpy(alias->alias,aliasStr,XkbKeyNameLength);
724 strncpy(alias->real,realStr,XkbKeyNameLength);
725 geom->num_key_aliases++;
726 return alias;
729 XkbColorPtr
730 XkbAddGeomColor(XkbGeometryPtr geom,char *spec,unsigned int pixel)
732 register int i;
733 register XkbColorPtr color;
735 if ((!geom)||(!spec))
736 return NULL;
737 for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
738 if ((color->spec)&&(strcmp(color->spec,spec)==0)) {
739 color->pixel= pixel;
740 return color;
743 if ((geom->num_colors>=geom->sz_colors)&&
744 (_XkbAllocColors(geom,1)!=Success)) {
745 return NULL;
747 color= &geom->colors[geom->num_colors];
748 color->pixel= pixel;
749 color->spec= (char *)_XkbAlloc(strlen(spec)+1);
750 if (!color->spec)
751 return NULL;
752 strcpy(color->spec,spec);
753 geom->num_colors++;
754 return color;
757 XkbOutlinePtr
758 XkbAddGeomOutline(XkbShapePtr shape,int sz_points)
760 XkbOutlinePtr outline;
762 if ((!shape)||(sz_points<0))
763 return NULL;
764 if ((shape->num_outlines>=shape->sz_outlines)&&
765 (_XkbAllocOutlines(shape,1)!=Success)) {
766 return NULL;
768 outline= &shape->outlines[shape->num_outlines];
769 bzero(outline,sizeof(XkbOutlineRec));
770 if ((sz_points>0)&&(_XkbAllocPoints(outline,sz_points)!=Success))
771 return NULL;
772 shape->num_outlines++;
773 return outline;
776 XkbShapePtr
777 XkbAddGeomShape(XkbGeometryPtr geom,Atom name,int sz_outlines)
779 XkbShapePtr shape;
780 register int i;
782 if ((!geom)||(!name)||(sz_outlines<0))
783 return NULL;
784 if (geom->num_shapes>0) {
785 for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) {
786 if (name==shape->name)
787 return shape;
790 if ((geom->num_shapes>=geom->sz_shapes)&&
791 (_XkbAllocShapes(geom,1)!=Success))
792 return NULL;
793 shape= &geom->shapes[geom->num_shapes];
794 bzero(shape,sizeof(XkbShapeRec));
795 if ((sz_outlines>0)&&(_XkbAllocOutlines(shape,sz_outlines)!=Success))
796 return NULL;
797 shape->name= name;
798 shape->primary= shape->approx= NULL;
799 geom->num_shapes++;
800 return shape;
803 XkbKeyPtr
804 XkbAddGeomKey(XkbRowPtr row)
806 XkbKeyPtr key;
807 if (!row)
808 return NULL;
809 if ((row->num_keys>=row->sz_keys)&&(_XkbAllocKeys(row,1)!=Success))
810 return NULL;
811 key= &row->keys[row->num_keys++];
812 bzero(key,sizeof(XkbKeyRec));
813 return key;
816 XkbRowPtr
817 XkbAddGeomRow(XkbSectionPtr section,int sz_keys)
819 XkbRowPtr row;
821 if ((!section)||(sz_keys<0))
822 return NULL;
823 if ((section->num_rows>=section->sz_rows)&&
824 (_XkbAllocRows(section,1)!=Success))
825 return NULL;
826 row= &section->rows[section->num_rows];
827 bzero(row,sizeof(XkbRowRec));
828 if ((sz_keys>0)&&(_XkbAllocKeys(row,sz_keys)!=Success))
829 return NULL;
830 section->num_rows++;
831 return row;
834 XkbSectionPtr
835 XkbAddGeomSection( XkbGeometryPtr geom,
836 Atom name,
837 int sz_rows,
838 int sz_doodads,
839 int sz_over)
841 register int i;
842 XkbSectionPtr section;
844 if ((!geom)||(name==None)||(sz_rows<0))
845 return NULL;
846 for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
847 if (section->name!=name)
848 continue;
849 if (((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))||
850 ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success))||
851 ((sz_over>0)&&(_XkbAllocOverlays(section,sz_over)!=Success)))
852 return NULL;
853 return section;
855 if ((geom->num_sections>=geom->sz_sections)&&
856 (_XkbAllocSections(geom,1)!=Success))
857 return NULL;
858 section= &geom->sections[geom->num_sections];
859 if ((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))
860 return NULL;
861 if ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success)) {
862 if (section->rows) {
863 _XkbFree(section->rows);
864 section->rows= NULL;
865 section->sz_rows= section->num_rows= 0;
867 return NULL;
869 section->name= name;
870 geom->num_sections++;
871 return section;
874 XkbDoodadPtr
875 XkbAddGeomDoodad(XkbGeometryPtr geom,XkbSectionPtr section,Atom name)
877 XkbDoodadPtr old,doodad;
878 register int i,nDoodads;
880 if ((!geom)||(name==None))
881 return NULL;
882 if ((section!=NULL)&&(section->num_doodads>0)) {
883 old= section->doodads;
884 nDoodads= section->num_doodads;
886 else {
887 old= geom->doodads;
888 nDoodads= geom->num_doodads;
890 for (i=0,doodad=old;i<nDoodads;i++,doodad++) {
891 if (doodad->any.name==name)
892 return doodad;
894 if (section) {
895 if ((section->num_doodads>=geom->sz_doodads)&&
896 (_XkbAllocDoodads(section,1)!=Success)) {
897 return NULL;
899 doodad= &section->doodads[section->num_doodads++];
901 else {
902 if ((geom->num_doodads>=geom->sz_doodads)&&
903 (_XkbAllocDoodads(geom,1)!=Success))
904 return NULL;
905 doodad= &geom->doodads[geom->num_doodads++];
907 bzero(doodad,sizeof(XkbDoodadRec));
908 doodad->any.name= name;
909 return doodad;
912 XkbOverlayKeyPtr
913 XkbAddGeomOverlayKey( XkbOverlayPtr overlay,
914 XkbOverlayRowPtr row,
915 char * over,
916 char * under)
918 register int i;
919 XkbOverlayKeyPtr key;
920 XkbSectionPtr section;
921 XkbRowPtr row_under;
922 Bool found;
924 if ((!overlay)||(!row)||(!over)||(!under))
925 return NULL;
926 section= overlay->section_under;
927 if (row->row_under>=section->num_rows)
928 return NULL;
929 row_under= &section->rows[row->row_under];
930 for (i=0,found=False;i<row_under->num_keys;i++) {
931 if (strncmp(under,row_under->keys[i].name.name,XkbKeyNameLength)==0) {
932 found= True;
933 break;
936 if (!found)
937 return NULL;
938 if ((row->num_keys>=row->sz_keys)&&(_XkbAllocOverlayKeys(row,1)!=Success))
939 return NULL;
940 key= &row->keys[row->num_keys];
941 strncpy(key->under.name,under,XkbKeyNameLength);
942 strncpy(key->over.name,over,XkbKeyNameLength);
943 row->num_keys++;
944 return key;
947 XkbOverlayRowPtr
948 XkbAddGeomOverlayRow(XkbOverlayPtr overlay,int row_under,int sz_keys)
950 register int i;
951 XkbOverlayRowPtr row;
953 if ((!overlay)||(sz_keys<0))
954 return NULL;
955 if (row_under>=overlay->section_under->num_rows)
956 return NULL;
957 for (i=0;i<overlay->num_rows;i++) {
958 if (overlay->rows[i].row_under==row_under) {
959 row= &overlay->rows[i];
960 if ((row->sz_keys<sz_keys)&&
961 (_XkbAllocOverlayKeys(row,sz_keys)!=Success)) {
962 return NULL;
964 return &overlay->rows[i];
967 if ((overlay->num_rows>=overlay->sz_rows)&&
968 (_XkbAllocOverlayRows(overlay,1)!=Success))
969 return NULL;
970 row= &overlay->rows[overlay->num_rows];
971 bzero(row,sizeof(XkbOverlayRowRec));
972 if ((sz_keys>0)&&(_XkbAllocOverlayKeys(row,sz_keys)!=Success))
973 return NULL;
974 row->row_under= row_under;
975 overlay->num_rows++;
976 return row;
979 XkbOverlayPtr
980 XkbAddGeomOverlay(XkbSectionPtr section,Atom name,int sz_rows)
982 register int i;
983 XkbOverlayPtr overlay;
985 if ((!section)||(name==None)||(sz_rows==0))
986 return NULL;
988 for (i=0,overlay=section->overlays;i<section->num_overlays;i++,overlay++) {
989 if (overlay->name==name) {
990 if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
991 return NULL;
992 return overlay;
995 if ((section->num_overlays>=section->sz_overlays)&&
996 (_XkbAllocOverlays(section,1)!=Success))
997 return NULL;
998 overlay= &section->overlays[section->num_overlays];
999 if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
1000 return NULL;
1001 overlay->name= name;
1002 overlay->section_under= section;
1003 section->num_overlays++;
1004 return overlay;