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