Rename headers to XKBcommon* and install in extensions directory
[platform/upstream/libxkbcommon.git] / src / galloc.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 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29 #include "X11/extensions/XKBcommon.h"
30 #include "XKBcommonint.h"
31 #include <X11/X.h>
32 #include <X11/Xdefs.h>
33 #include <X11/extensions/XKB.h>
34
35 static void
36 _XkbFreeGeomLeafElems(  Bool                    freeAll,
37                         int                     first,
38                         int                     count,
39                         unsigned short *        num_inout,
40                         unsigned short *        sz_inout,
41                         char **                 elems,
42                         unsigned int            elem_sz)
43 {
44     if ((freeAll)||(*elems==NULL)) {
45         *num_inout= *sz_inout= 0;
46         if (*elems!=NULL) {
47             _XkbFree(*elems);
48             *elems= NULL;
49         }
50         return;
51     }
52
53     if ((first>=(*num_inout))||(first<0)||(count<1))
54         return;
55
56     if (first+count>=(*num_inout)) {
57         /* truncating the array is easy */
58         (*num_inout)= first;
59     }
60     else {
61         char *  ptr;
62         int     extra;
63         ptr= *elems;
64         extra= ((*num_inout)-(first+count))*elem_sz;
65         if (extra>0)
66             memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],extra);
67         (*num_inout)-= count;
68     }
69     return;
70 }
71
72 typedef void (*ContentsClearFunc)(
73                 char *          /* priv */
74 );
75
76 static void
77 _XkbFreeGeomNonLeafElems(       Bool                    freeAll,
78                                 int                     first,
79                                 int                     count,
80                                 unsigned short *        num_inout,
81                                 unsigned short *        sz_inout,
82                                 char **                 elems,
83                                 unsigned int            elem_sz,
84                                 ContentsClearFunc       freeFunc)
85 {
86 register int i;
87 register char *ptr;
88
89     if (freeAll) {
90         first= 0;
91         count= (*num_inout);
92     }
93     else if ((first>=(*num_inout))||(first<0)||(count<1))
94         return;
95     else if (first+count>(*num_inout))
96         count= (*num_inout)-first;
97     if (*elems==NULL)
98         return;
99
100     if (freeFunc) {
101         ptr= *elems;
102         ptr+= first*elem_sz;
103         for (i=0;i<count;i++) {
104             (*freeFunc)(ptr);
105             ptr+= elem_sz;
106         }
107     }
108     if (freeAll) {
109         (*num_inout)= (*sz_inout)= 0;
110         if (*elems) {
111             _XkbFree(*elems);
112             *elems= NULL;
113         }
114     }
115     else if (first+count>=(*num_inout))
116         *num_inout= first;
117     else {
118         i= ((*num_inout)-(first+count))*elem_sz;
119         ptr= *elems;
120         memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],i);
121         (*num_inout)-= count;
122     }
123     return;
124 }
125
126 static void
127 _XkbClearProperty(char *prop_in)
128 {
129 XkbPropertyPtr  prop= (XkbPropertyPtr)prop_in;
130
131     if (prop->name) {
132         _XkbFree(prop->name);
133         prop->name= NULL;
134     }
135     if (prop->value) {
136         _XkbFree(prop->value);
137         prop->value= NULL;
138     }
139     return;
140 }
141
142 void
143 XkbcFreeGeomProperties( XkbGeometryPtr  geom,
144                         int             first,
145                         int             count,
146                         Bool            freeAll)
147 {
148     _XkbFreeGeomNonLeafElems(freeAll,first,count,
149                                 &geom->num_properties,&geom->sz_properties,
150                                 (char **)&geom->properties,
151                                 sizeof(XkbPropertyRec),_XkbClearProperty);
152     return;
153 }
154
155 void
156 XkbcFreeGeomKeyAliases( XkbGeometryPtr  geom,
157                         int             first,
158                         int             count,
159                         Bool            freeAll)
160 {
161     _XkbFreeGeomLeafElems(freeAll,first,count,
162                                 &geom->num_key_aliases,&geom->sz_key_aliases,
163                                 (char **)&geom->key_aliases,
164                                 sizeof(XkbKeyAliasRec));
165     return;
166 }
167
168 static void
169 _XkbClearColor(char *color_in)
170 {
171 XkbColorPtr     color= (XkbColorPtr)color_in;
172
173     if (color->spec)
174         _XkbFree(color->spec);
175     return;
176 }
177
178 void
179 XkbcFreeGeomColors(XkbGeometryPtr geom,int first,int count,Bool freeAll)
180 {
181     _XkbFreeGeomNonLeafElems(freeAll,first,count,
182                                 &geom->num_colors,&geom->sz_colors,
183                                 (char **)&geom->colors,
184                                 sizeof(XkbColorRec),_XkbClearColor);
185     return;
186 }
187
188 void
189 XkbcFreeGeomPoints(XkbOutlinePtr outline,int first,int count,Bool freeAll)
190 {
191     _XkbFreeGeomLeafElems(freeAll,first,count,
192                                 &outline->num_points,&outline->sz_points,
193                                 (char **)&outline->points,
194                                 sizeof(XkbPointRec));
195     return;
196 }
197
198 static void
199 _XkbClearOutline(char *outline_in)
200 {
201 XkbOutlinePtr   outline= (XkbOutlinePtr)outline_in;
202
203     if (outline->points!=NULL)
204         XkbcFreeGeomPoints(outline,0,outline->num_points,True);
205     return;
206 }
207
208 void
209 XkbcFreeGeomOutlines(XkbShapePtr        shape,int first,int count,Bool freeAll)
210 {
211     _XkbFreeGeomNonLeafElems(freeAll,first,count,
212                                 &shape->num_outlines,&shape->sz_outlines,
213                                 (char **)&shape->outlines,
214                                 sizeof(XkbOutlineRec),_XkbClearOutline);
215
216     return;
217 }
218
219 static void
220 _XkbClearShape(char *shape_in)
221 {
222 XkbShapePtr     shape= (XkbShapePtr)shape_in;
223
224     if (shape->outlines)
225         XkbcFreeGeomOutlines(shape,0,shape->num_outlines,True);
226     return;
227 }
228
229 void
230 XkbcFreeGeomShapes(XkbGeometryPtr geom,int first,int count,Bool freeAll)
231 {
232     _XkbFreeGeomNonLeafElems(freeAll,first,count,
233                                 &geom->num_shapes,&geom->sz_shapes,
234                                 (char **)&geom->shapes,
235                                 sizeof(XkbShapeRec),_XkbClearShape);
236     return;
237 }
238
239 void
240 XkbcFreeGeomOverlayKeys(XkbOverlayRowPtr row,int first,int count,Bool freeAll)
241 {
242     _XkbFreeGeomLeafElems(freeAll,first,count,
243                                 &row->num_keys,&row->sz_keys,
244                                 (char **)&row->keys,
245                                 sizeof(XkbOverlayKeyRec));
246     return;
247 }
248
249
250 static void
251 _XkbClearOverlayRow(char *row_in)
252 {
253 XkbOverlayRowPtr        row= (XkbOverlayRowPtr)row_in;
254
255     if (row->keys!=NULL)
256         XkbcFreeGeomOverlayKeys(row,0,row->num_keys,True);
257     return;
258 }
259
260 void
261 XkbcFreeGeomOverlayRows(XkbOverlayPtr overlay,int first,int count,Bool freeAll)
262 {
263     _XkbFreeGeomNonLeafElems(freeAll,first,count,
264                                 &overlay->num_rows,&overlay->sz_rows,
265                                 (char **)&overlay->rows,
266                                 sizeof(XkbOverlayRowRec),_XkbClearOverlayRow);
267     return;
268 }
269
270
271 static void
272 _XkbClearOverlay(char *overlay_in)
273 {
274 XkbOverlayPtr   overlay= (XkbOverlayPtr)overlay_in;
275
276     if (overlay->rows!=NULL)
277         XkbcFreeGeomOverlayRows(overlay,0,overlay->num_rows,True);
278     return;
279 }
280
281 void
282 XkbcFreeGeomOverlays(XkbSectionPtr section,int first,int        count,Bool freeAll)
283 {
284     _XkbFreeGeomNonLeafElems(freeAll,first,count,
285                                 &section->num_overlays,&section->sz_overlays,
286                                 (char **)&section->overlays,
287                                 sizeof(XkbOverlayRec),_XkbClearOverlay);
288     return;
289 }
290
291
292 void
293 XkbcFreeGeomKeys(XkbRowPtr row,int first,int count,Bool freeAll)
294 {
295     _XkbFreeGeomLeafElems(freeAll,first,count,
296                                 &row->num_keys,&row->sz_keys,
297                                 (char **)&row->keys,
298                                 sizeof(XkbKeyRec));
299     return;
300 }
301
302
303 static void
304 _XkbClearRow(char *row_in)
305 {
306 XkbRowPtr       row= (XkbRowPtr)row_in;
307
308     if (row->keys!=NULL)
309         XkbcFreeGeomKeys(row,0,row->num_keys,True);
310     return;
311 }
312
313 void
314 XkbcFreeGeomRows(XkbSectionPtr section,int first,int count,Bool freeAll)
315 {
316     _XkbFreeGeomNonLeafElems(freeAll,first,count,
317                                 &section->num_rows,&section->sz_rows,
318                                 (char **)&section->rows,
319                                 sizeof(XkbRowRec),_XkbClearRow);
320 }
321
322
323 static void
324 _XkbClearSection(char *section_in)
325 {
326 XkbSectionPtr   section= (XkbSectionPtr)section_in;
327
328     if (section->rows!=NULL)
329         XkbcFreeGeomRows(section,0,section->num_rows,True);
330     if (section->doodads!=NULL) {
331         XkbcFreeGeomDoodads(section->doodads,section->num_doodads,True);
332         section->doodads= NULL;
333     }
334     return;
335 }
336
337 void
338 XkbcFreeGeomSections(XkbGeometryPtr geom,int first,int count,Bool freeAll)
339 {
340     _XkbFreeGeomNonLeafElems(freeAll,first,count,
341                                 &geom->num_sections,&geom->sz_sections,
342                                 (char **)&geom->sections,
343                                 sizeof(XkbSectionRec),_XkbClearSection);
344     return;
345 }
346
347
348 static void
349 _XkbClearDoodad(char *doodad_in)
350 {
351 XkbDoodadPtr    doodad= (XkbDoodadPtr)doodad_in;
352
353     switch (doodad->any.type) {
354         case XkbTextDoodad:
355             {
356                 if (doodad->text.text!=NULL) {
357                     _XkbFree(doodad->text.text);
358                     doodad->text.text= NULL;
359                 }
360                 if (doodad->text.font!=NULL) {
361                     _XkbFree(doodad->text.font);
362                     doodad->text.font= NULL;
363                 }
364             }
365             break;
366         case XkbLogoDoodad:
367             {
368                 if (doodad->logo.logo_name!=NULL) {
369                     _XkbFree(doodad->logo.logo_name);
370                     doodad->logo.logo_name= NULL;
371                 }
372             }
373             break;
374     }
375     return;
376 }
377
378 void
379 XkbcFreeGeomDoodads(XkbDoodadPtr doodads,int nDoodads,Bool freeAll)
380 {
381 register int            i;
382 register XkbDoodadPtr   doodad;
383
384     if (doodads) {
385         for (i=0,doodad= doodads;i<nDoodads;i++,doodad++) {
386             _XkbClearDoodad((char *)doodad);
387         }
388         if (freeAll)
389             _XkbFree(doodads);
390     }
391     return;
392 }
393
394 void
395 XkbcFreeGeometry(XkbGeometryPtr geom,unsigned which,Bool freeMap)
396 {
397     if (geom==NULL)
398         return;
399     if (freeMap)
400         which= XkbGeomAllMask;
401     if ((which&XkbGeomPropertiesMask)&&(geom->properties!=NULL))
402         XkbcFreeGeomProperties(geom,0,geom->num_properties,True);
403     if ((which&XkbGeomColorsMask)&&(geom->colors!=NULL))
404         XkbcFreeGeomColors(geom,0,geom->num_colors,True);
405     if ((which&XkbGeomShapesMask)&&(geom->shapes!=NULL))
406         XkbcFreeGeomShapes(geom,0,geom->num_shapes,True);
407     if ((which&XkbGeomSectionsMask)&&(geom->sections!=NULL))
408         XkbcFreeGeomSections(geom,0,geom->num_sections,True);
409     if ((which&XkbGeomDoodadsMask)&&(geom->doodads!= NULL)) {
410         XkbcFreeGeomDoodads(geom->doodads,geom->num_doodads,True);
411         geom->doodads= NULL;
412         geom->num_doodads= geom->sz_doodads= 0;
413     }
414     if ((which&XkbGeomKeyAliasesMask)&&(geom->key_aliases!=NULL))
415         XkbcFreeGeomKeyAliases(geom,0,geom->num_key_aliases,True);
416     if (freeMap) {
417         if (geom->label_font!=NULL) {
418             _XkbFree(geom->label_font);
419             geom->label_font= NULL;
420         }
421         _XkbFree(geom);
422     }
423     return;
424 }
425
426 static int
427 _XkbGeomAlloc(  char **         old,
428                 unsigned short *        num,
429                 unsigned short *        total,
430                 int                     num_new,
431                 size_t                  sz_elem)
432 {
433     if (num_new<1)
434         return Success;
435     if ((*old)==NULL)
436         *num= *total= 0;
437
438     if ((*num)+num_new<=(*total))
439         return Success;
440
441     *total= (*num)+num_new;
442     if ((*old)!=NULL)
443          (*old)= (char *)_XkbRealloc((*old),(*total)*sz_elem);
444     else (*old)= (char *)_XkbCalloc((*total),sz_elem);
445     if ((*old)==NULL) {
446         *total= *num= 0;
447         return BadAlloc;
448     }
449
450     if (*num>0) {
451         char *tmp= (char *)(*old);
452         bzero(&tmp[sz_elem*(*num)],(num_new*sz_elem));
453     }
454     return Success;
455 }
456
457 #define _XkbAllocProps(g,n) _XkbGeomAlloc((char **)&(g)->properties,\
458                                 &(g)->num_properties,&(g)->sz_properties,\
459                                 (n),sizeof(XkbPropertyRec))
460 #define _XkbAllocColors(g,n) _XkbGeomAlloc((char **)&(g)->colors,\
461                                 &(g)->num_colors,&(g)->sz_colors,\
462                                 (n),sizeof(XkbColorRec))
463 #define _XkbAllocShapes(g,n) _XkbGeomAlloc((char **)&(g)->shapes,\
464                                 &(g)->num_shapes,&(g)->sz_shapes,\
465                                 (n),sizeof(XkbShapeRec))
466 #define _XkbAllocSections(g,n) _XkbGeomAlloc((char **)&(g)->sections,\
467                                 &(g)->num_sections,&(g)->sz_sections,\
468                                 (n),sizeof(XkbSectionRec))
469 #define _XkbAllocDoodads(g,n) _XkbGeomAlloc((char **)&(g)->doodads,\
470                                 &(g)->num_doodads,&(g)->sz_doodads,\
471                                 (n),sizeof(XkbDoodadRec))
472 #define _XkbAllocKeyAliases(g,n) _XkbGeomAlloc((char **)&(g)->key_aliases,\
473                                 &(g)->num_key_aliases,&(g)->sz_key_aliases,\
474                                 (n),sizeof(XkbKeyAliasRec))
475
476 #define _XkbAllocOutlines(s,n) _XkbGeomAlloc((char **)&(s)->outlines,\
477                                 &(s)->num_outlines,&(s)->sz_outlines,\
478                                 (n),sizeof(XkbOutlineRec))
479 #define _XkbAllocRows(s,n) _XkbGeomAlloc((char **)&(s)->rows,\
480                                 &(s)->num_rows,&(s)->sz_rows,\
481                                 (n),sizeof(XkbRowRec))
482 #define _XkbAllocPoints(o,n) _XkbGeomAlloc((char **)&(o)->points,\
483                                 &(o)->num_points,&(o)->sz_points,\
484                                 (n),sizeof(XkbPointRec))
485 #define _XkbAllocKeys(r,n) _XkbGeomAlloc((char **)&(r)->keys,\
486                                 &(r)->num_keys,&(r)->sz_keys,\
487                                 (n),sizeof(XkbKeyRec))
488 #define _XkbAllocOverlays(s,n) _XkbGeomAlloc((char **)&(s)->overlays,\
489                                 &(s)->num_overlays,&(s)->sz_overlays,\
490                                 (n),sizeof(XkbOverlayRec))
491 #define _XkbAllocOverlayRows(o,n) _XkbGeomAlloc((char **)&(o)->rows,\
492                                 &(o)->num_rows,&(o)->sz_rows,\
493                                 (n),sizeof(XkbOverlayRowRec))
494 #define _XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((char **)&(r)->keys,\
495                                 &(r)->num_keys,&(r)->sz_keys,\
496                                 (n),sizeof(XkbOverlayKeyRec))
497
498 int
499 XkbcAllocGeometry(XkbcDescPtr xkb,XkbGeometrySizesPtr sizes)
500 {
501 XkbGeometryPtr  geom;
502 int             rtrn;
503
504     if (xkb->geom==NULL) {
505         xkb->geom= _XkbTypedCalloc(1,XkbGeometryRec);
506         if (!xkb->geom)
507             return BadAlloc;
508     }
509     geom= xkb->geom;
510     if ((sizes->which&XkbGeomPropertiesMask)&&
511         ((rtrn=_XkbAllocProps(geom,sizes->num_properties))!=Success)) {
512         goto BAIL;
513     }
514     if ((sizes->which&XkbGeomColorsMask)&&
515         ((rtrn=_XkbAllocColors(geom,sizes->num_colors))!=Success)) {
516         goto BAIL;
517     }
518     if ((sizes->which&XkbGeomShapesMask)&&
519         ((rtrn=_XkbAllocShapes(geom,sizes->num_shapes))!=Success)) {
520         goto BAIL;
521     }
522     if ((sizes->which&XkbGeomSectionsMask)&&
523         ((rtrn=_XkbAllocSections(geom,sizes->num_sections))!=Success)) {
524         goto BAIL;
525     }
526     if ((sizes->which&XkbGeomDoodadsMask)&&
527         ((rtrn=_XkbAllocDoodads(geom,sizes->num_doodads))!=Success)) {
528         goto BAIL;
529     }
530     if ((sizes->which&XkbGeomKeyAliasesMask)&&
531         ((rtrn=_XkbAllocKeyAliases(geom,sizes->num_key_aliases))!=Success)) {
532         goto BAIL;
533     }
534     return Success;
535 BAIL:
536     XkbcFreeGeometry(geom,XkbGeomAllMask,True);
537     xkb->geom= NULL;
538     return rtrn;
539 }