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.
30 #include "xkbcommon/xkbcommon.h"
31 #include "XKBcommonint.h"
32 #include <X11/extensions/XKB.h>
34 typedef void (*ContentsClearFunc)(void *priv);
37 _XkbFreeGeomNonLeafElems(unsigned short *num_inout, unsigned short *sz_inout,
38 void *elems, size_t elem_sz,
39 ContentsClearFunc freeFunc)
47 start = *(char **)elems;
52 for (i = 0; i < *num_inout; i++) {
57 *num_inout = *sz_inout = 0;
62 _XkbClearProperty(void *prop_in)
64 struct xkb_property * prop = prop_in;
73 XkbcFreeGeomProperties(struct xkb_geometry * geom)
75 _XkbFreeGeomNonLeafElems(&geom->num_properties, &geom->sz_properties,
76 &geom->properties, sizeof(struct xkb_property),
81 _XkbClearColor(void *color_in)
83 struct xkb_color * color = color_in;
89 XkbcFreeGeomColors(struct xkb_geometry * geom)
91 _XkbFreeGeomNonLeafElems(&geom->num_colors, &geom->sz_colors,
92 &geom->colors, sizeof(struct xkb_color),
97 _XkbClearOutline(void *outline_in)
99 struct xkb_outline * outline = outline_in;
101 free(outline->points);
105 XkbcFreeGeomOutlines(struct xkb_shape * shape)
107 _XkbFreeGeomNonLeafElems(&shape->num_outlines, &shape->sz_outlines,
108 &shape->outlines, sizeof(struct xkb_outline),
113 _XkbClearShape(void *shape_in)
115 struct xkb_shape * shape = shape_in;
117 XkbcFreeGeomOutlines(shape);
121 XkbcFreeGeomShapes(struct xkb_geometry * geom)
123 _XkbFreeGeomNonLeafElems(&geom->num_shapes, &geom->sz_shapes,
124 &geom->shapes, sizeof(struct xkb_shape),
129 _XkbClearRow(void *row_in)
131 struct xkb_row * row = row_in;
137 XkbcFreeGeomRows(struct xkb_section * section)
139 _XkbFreeGeomNonLeafElems(§ion->num_rows, §ion->sz_rows,
140 §ion->rows, sizeof(struct xkb_row),
145 _XkbClearDoodad(union xkb_doodad *doodad)
147 switch (doodad->any.type) {
149 free(doodad->text.text);
150 doodad->text.text = NULL;
151 free(doodad->text.font);
152 doodad->text.font = NULL;
156 free(doodad->logo.logo_name);
157 doodad->logo.logo_name = NULL;
163 XkbcFreeGeomDoodads(union xkb_doodad * doodads, int nDoodads)
166 union xkb_doodad * doodad;
168 for (i = 0, doodad = doodads; i < nDoodads && doodad; i++, doodad++)
169 _XkbClearDoodad(doodad);
174 _XkbClearSection(void *section_in)
176 struct xkb_section * section = section_in;
178 XkbcFreeGeomRows(section);
179 XkbcFreeGeomDoodads(section->doodads, section->num_doodads);
180 section->doodads = NULL;
184 XkbcFreeGeomSections(struct xkb_geometry * geom)
186 _XkbFreeGeomNonLeafElems(&geom->num_sections, &geom->sz_sections,
187 &geom->sections, sizeof(struct xkb_section),
192 XkbcFreeGeometry(struct xkb_desc * xkb)
194 struct xkb_geometry *geom;
196 if (!xkb || !xkb->geom)
201 XkbcFreeGeomProperties(geom);
202 XkbcFreeGeomColors(geom);
203 XkbcFreeGeomShapes(geom);
204 XkbcFreeGeomSections(geom);
205 XkbcFreeGeomDoodads(geom->doodads, geom->num_doodads);
206 free(geom->key_aliases);
207 free(geom->label_font);
212 _XkbGeomAlloc(char **old, unsigned short *num, unsigned short *total,
213 int num_new, size_t sz_elem)
221 if ((*num) + num_new <= (*total))
224 *total = (*num) + num_new;
227 *old = realloc(*old, (*total) * sz_elem);
229 *old = calloc(*total, sz_elem);
237 memset(&tmp[sz_elem * (*num)], 0, num_new * sz_elem);
243 #define _XkbAllocProps(g, n) _XkbGeomAlloc((char **)&(g)->properties, \
244 &(g)->num_properties, \
245 &(g)->sz_properties, \
246 (n), sizeof(struct xkb_property))
247 #define _XkbAllocColors(g, n) _XkbGeomAlloc((char **)&(g)->colors, \
250 (n), sizeof(struct xkb_color))
251 #define _XkbAllocShapes(g, n) _XkbGeomAlloc((char **)&(g)->shapes, \
254 (n), sizeof(struct xkb_shape))
255 #define _XkbAllocSections(g, n) _XkbGeomAlloc((char **)&(g)->sections, \
256 &(g)->num_sections, \
258 (n), sizeof(struct xkb_section))
259 #define _XkbAllocDoodads(g, n) _XkbGeomAlloc((char **)&(g)->doodads, \
262 (n), sizeof(union xkb_doodad))
263 #define _XkbAllocKeyAliases(g, n) _XkbGeomAlloc((char **)&(g)->key_aliases, \
264 &(g)->num_key_aliases, \
265 &(g)->sz_key_aliases, \
266 (n), sizeof(struct xkb_key_alias))
268 #define _XkbAllocOutlines(s, n) _XkbGeomAlloc((char **)&(s)->outlines, \
269 &(s)->num_outlines, \
271 (n), sizeof(struct xkb_outline))
272 #define _XkbAllocRows(s, n) _XkbGeomAlloc((char **)&(s)->rows, \
275 (n), sizeof(struct xkb_row))
276 #define _XkbAllocPoints(o, n) _XkbGeomAlloc((char **)&(o)->points, \
279 (n), sizeof(struct xkb_point))
280 #define _XkbAllocKeys(r, n) _XkbGeomAlloc((char **)&(r)->keys, \
283 (n), sizeof(struct xkb_key))
284 #define _XkbAllocOverlays(s, n) _XkbGeomAlloc((char **)&(s)->overlays, \
285 &(s)->num_overlays, \
287 (n), sizeof(struct xkb_overlay))
288 #define _XkbAllocOverlayRows(o, n) _XkbGeomAlloc((char **)&(o)->rows, \
291 (n), sizeof(struct xkb_overlay_row))
292 #define _XkbAllocOverlayKeys(r, n) _XkbGeomAlloc((char **)&(r)->keys, \
295 (n), sizeof(struct xkb_overlay_key))
298 XkbcAllocGeomKeyAliases(struct xkb_geometry * geom, int nKeyAliases)
300 return _XkbAllocKeyAliases(geom, nKeyAliases);
304 XkbcAllocGeometry(struct xkb_desc * xkb, struct xkb_geometry_sizes * sizes)
306 struct xkb_geometry * geom;
310 xkb->geom = _XkbTypedCalloc(1, struct xkb_geometry);
316 if ((sizes->which & XkbGeomPropertiesMask) &&
317 ((rtrn = _XkbAllocProps(geom, sizes->num_properties)) != Success))
320 if ((sizes->which & XkbGeomColorsMask) &&
321 ((rtrn = _XkbAllocColors(geom, sizes->num_colors)) != Success))
324 if ((sizes->which & XkbGeomShapesMask) &&
325 ((rtrn = _XkbAllocShapes(geom, sizes->num_shapes)) != Success))
328 if ((sizes->which & XkbGeomSectionsMask) &&
329 ((rtrn = _XkbAllocSections(geom, sizes->num_sections)) != Success))
332 if ((sizes->which & XkbGeomDoodadsMask) &&
333 ((rtrn = _XkbAllocDoodads(geom, sizes->num_doodads)) != Success))
336 if ((sizes->which & XkbGeomKeyAliasesMask) &&
337 ((rtrn = _XkbAllocKeyAliases(geom, sizes->num_key_aliases)) != Success))
342 XkbcFreeGeometry(xkb);
347 struct xkb_property *
348 XkbcAddGeomProperty(struct xkb_geometry * geom,const char *name,const char *value)
351 struct xkb_property * prop;
353 if ((!geom)||(!name)||(!value))
355 for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
356 if ((prop->name)&&(strcmp(name,prop->name)==0)) {
358 prop->value = strdup(value);
362 if ((geom->num_properties>=geom->sz_properties)&&
363 (_XkbAllocProps(geom,1)!=Success)) {
366 prop= &geom->properties[geom->num_properties];
367 prop->name = strdup(name);
370 prop->value = strdup(value);
376 geom->num_properties++;
381 XkbcAddGeomColor(struct xkb_geometry * geom,const char *spec,unsigned int pixel)
384 struct xkb_color * color;
386 if ((!geom)||(!spec))
388 for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
389 if ((color->spec)&&(strcmp(color->spec,spec)==0)) {
394 if ((geom->num_colors>=geom->sz_colors)&&
395 (_XkbAllocColors(geom,1)!=Success)) {
398 color= &geom->colors[geom->num_colors];
400 color->spec = strdup(spec);
408 XkbcAddGeomOutline(struct xkb_shape * shape,int sz_points)
410 struct xkb_outline * outline;
412 if ((!shape)||(sz_points<0))
414 if ((shape->num_outlines>=shape->sz_outlines)&&
415 (_XkbAllocOutlines(shape,1)!=Success)) {
418 outline= &shape->outlines[shape->num_outlines];
419 memset(outline, 0, sizeof(struct xkb_outline));
420 if ((sz_points>0)&&(_XkbAllocPoints(outline,sz_points)!=Success))
422 shape->num_outlines++;
427 XkbcAddGeomShape(struct xkb_geometry * geom,uint32_t name,int sz_outlines)
429 struct xkb_shape *shape;
432 if ((!geom)||(!name)||(sz_outlines<0))
434 if (geom->num_shapes>0) {
435 for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) {
436 if (name==shape->name)
440 if ((geom->num_shapes>=geom->sz_shapes)&&
441 (_XkbAllocShapes(geom,1)!=Success))
443 shape= &geom->shapes[geom->num_shapes];
444 memset(shape, 0, sizeof(struct xkb_shape));
445 if ((sz_outlines>0)&&(_XkbAllocOutlines(shape,sz_outlines)!=Success))
448 shape->primary= shape->approx= NULL;
454 XkbcAddGeomKey(struct xkb_row * row)
456 struct xkb_key * key;
459 if ((row->num_keys>=row->sz_keys)&&(_XkbAllocKeys(row,1)!=Success))
461 key= &row->keys[row->num_keys++];
462 memset(key, 0, sizeof(struct xkb_key));
467 XkbcAddGeomRow(struct xkb_section * section,int sz_keys)
469 struct xkb_row * row;
471 if ((!section)||(sz_keys<0))
473 if ((section->num_rows>=section->sz_rows)&&
474 (_XkbAllocRows(section,1)!=Success))
476 row= §ion->rows[section->num_rows];
477 memset(row, 0, sizeof(struct xkb_row));
478 if ((sz_keys>0)&&(_XkbAllocKeys(row,sz_keys)!=Success))
485 XkbcAddGeomSection( struct xkb_geometry * geom,
492 struct xkb_section * section;
494 if ((!geom)||(name==None)||(sz_rows<0))
496 for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
497 if (section->name!=name)
499 if (((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))||
500 ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success))||
501 ((sz_over>0)&&(_XkbAllocOverlays(section,sz_over)!=Success)))
505 if ((geom->num_sections>=geom->sz_sections)&&
506 (_XkbAllocSections(geom,1)!=Success))
508 section= &geom->sections[geom->num_sections];
509 if ((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))
511 if ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success)) {
514 section->sz_rows= section->num_rows= 0;
518 geom->num_sections++;
523 XkbcAddGeomDoodad(struct xkb_geometry * geom,struct xkb_section * section,uint32_t name)
525 union xkb_doodad *old, *doodad;
528 if ((!geom)||(name==None))
530 if ((section!=NULL)&&(section->num_doodads>0)) {
531 old= section->doodads;
532 nDoodads= section->num_doodads;
536 nDoodads= geom->num_doodads;
538 for (i=0,doodad=old;i<nDoodads;i++,doodad++) {
539 if (doodad->any.name==name)
543 if ((section->num_doodads>=geom->sz_doodads)&&
544 (_XkbAllocDoodads(section,1)!=Success)) {
547 doodad= §ion->doodads[section->num_doodads++];
550 if ((geom->num_doodads>=geom->sz_doodads)&&
551 (_XkbAllocDoodads(geom,1)!=Success))
553 doodad= &geom->doodads[geom->num_doodads++];
555 memset(doodad, 0, sizeof(union xkb_doodad));
556 doodad->any.name= name;
560 struct xkb_overlay_row *
561 XkbcAddGeomOverlayRow(struct xkb_overlay * overlay,int row_under,int sz_keys)
564 struct xkb_overlay_row *row;
566 if ((!overlay)||(sz_keys<0))
568 if (row_under>=overlay->section_under->num_rows)
570 for (i=0;i<overlay->num_rows;i++) {
571 if (overlay->rows[i].row_under==row_under) {
572 row= &overlay->rows[i];
573 if ((row->sz_keys<sz_keys)&&
574 (_XkbAllocOverlayKeys(row,sz_keys)!=Success)) {
577 return &overlay->rows[i];
580 if ((overlay->num_rows>=overlay->sz_rows)&&
581 (_XkbAllocOverlayRows(overlay,1)!=Success))
583 row= &overlay->rows[overlay->num_rows];
584 memset(row, 0, sizeof(struct xkb_overlay_row));
585 if ((sz_keys>0)&&(_XkbAllocOverlayKeys(row,sz_keys)!=Success))
587 row->row_under= row_under;
593 XkbcAddGeomOverlay(struct xkb_section * section,uint32_t name,int sz_rows)
596 struct xkb_overlay *overlay;
598 if ((!section)||(name==None)||(sz_rows==0))
601 for (i=0,overlay=section->overlays;i<section->num_overlays;i++,overlay++) {
602 if (overlay->name==name) {
603 if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
608 if ((section->num_overlays>=section->sz_overlays)&&
609 (_XkbAllocOverlays(section,1)!=Success))
611 overlay= §ion->overlays[section->num_overlays];
612 if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
615 overlay->section_under= section;
616 section->num_overlays++;