XKBGAlloc.c revision 5afda2e6
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 _XkbFree(color->spec); 181 return; 182} 183 184void 185XkbFreeGeomColors(XkbGeometryPtr geom, int first, int count, Bool freeAll) 186{ 187 _XkbFreeGeomNonLeafElems(freeAll, first, count, 188 &geom->num_colors, &geom->sz_colors, 189 (char **) &geom->colors, 190 sizeof(XkbColorRec), _XkbClearColor); 191 return; 192} 193 194/***====================================================================***/ 195 196void 197XkbFreeGeomPoints(XkbOutlinePtr outline, int first, int count, Bool freeAll) 198{ 199 _XkbFreeGeomLeafElems(freeAll, first, count, 200 &outline->num_points, &outline->sz_points, 201 (char **) &outline->points, 202 sizeof(XkbPointRec)); 203 return; 204} 205 206/***====================================================================***/ 207 208static void 209_XkbClearOutline(char *outline_in) 210{ 211 XkbOutlinePtr outline = (XkbOutlinePtr) outline_in; 212 213 if (outline->points != NULL) 214 XkbFreeGeomPoints(outline, 0, outline->num_points, True); 215 return; 216} 217 218void 219XkbFreeGeomOutlines(XkbShapePtr shape, int first, int count, Bool freeAll) 220{ 221 _XkbFreeGeomNonLeafElems(freeAll, first, count, 222 &shape->num_outlines, &shape->sz_outlines, 223 (char **) &shape->outlines, 224 sizeof(XkbOutlineRec), _XkbClearOutline); 225 226 return; 227} 228 229/***====================================================================***/ 230 231static void 232_XkbClearShape(char *shape_in) 233{ 234 XkbShapePtr shape = (XkbShapePtr) shape_in; 235 236 if (shape->outlines) 237 XkbFreeGeomOutlines(shape, 0, shape->num_outlines, True); 238 return; 239} 240 241void 242XkbFreeGeomShapes(XkbGeometryPtr geom, int first, int count, Bool freeAll) 243{ 244 _XkbFreeGeomNonLeafElems(freeAll, first, count, 245 &geom->num_shapes, &geom->sz_shapes, 246 (char **) &geom->shapes, 247 sizeof(XkbShapeRec), _XkbClearShape); 248 return; 249} 250 251/***====================================================================***/ 252 253void 254XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row, int first, int count, Bool freeAll) 255{ 256 _XkbFreeGeomLeafElems(freeAll, first, count, 257 &row->num_keys, &row->sz_keys, 258 (char **) &row->keys, 259 sizeof(XkbOverlayKeyRec)); 260 return; 261} 262 263/***====================================================================***/ 264 265static void 266_XkbClearOverlayRow(char *row_in) 267{ 268 XkbOverlayRowPtr row = (XkbOverlayRowPtr) row_in; 269 270 if (row->keys != NULL) 271 XkbFreeGeomOverlayKeys(row, 0, row->num_keys, True); 272 return; 273} 274 275void 276XkbFreeGeomOverlayRows(XkbOverlayPtr overlay, int first, int count, 277 Bool freeAll) 278{ 279 _XkbFreeGeomNonLeafElems(freeAll, first, count, 280 &overlay->num_rows, &overlay->sz_rows, 281 (char **) &overlay->rows, 282 sizeof(XkbOverlayRowRec), _XkbClearOverlayRow); 283 return; 284} 285 286/***====================================================================***/ 287 288static void 289_XkbClearOverlay(char *overlay_in) 290{ 291 XkbOverlayPtr overlay = (XkbOverlayPtr) overlay_in; 292 293 if (overlay->rows != NULL) 294 XkbFreeGeomOverlayRows(overlay, 0, overlay->num_rows, True); 295 return; 296} 297 298void 299XkbFreeGeomOverlays(XkbSectionPtr section, int first, int count, Bool freeAll) 300{ 301 _XkbFreeGeomNonLeafElems(freeAll, first, count, 302 §ion->num_overlays, §ion->sz_overlays, 303 (char **) §ion->overlays, 304 sizeof(XkbOverlayRec), _XkbClearOverlay); 305 return; 306} 307 308/***====================================================================***/ 309 310void 311XkbFreeGeomKeys(XkbRowPtr row, int first, int count, Bool freeAll) 312{ 313 _XkbFreeGeomLeafElems(freeAll, first, count, 314 &row->num_keys, &row->sz_keys, 315 (char **) &row->keys, 316 sizeof(XkbKeyRec)); 317 return; 318} 319 320/***====================================================================***/ 321 322static void 323_XkbClearRow(char *row_in) 324{ 325 XkbRowPtr row = (XkbRowPtr) row_in; 326 327 if (row->keys != NULL) 328 XkbFreeGeomKeys(row, 0, row->num_keys, True); 329 return; 330} 331 332void 333XkbFreeGeomRows(XkbSectionPtr section, int first, int count, Bool freeAll) 334{ 335 _XkbFreeGeomNonLeafElems(freeAll, first, count, 336 §ion->num_rows, §ion->sz_rows, 337 (char **) §ion->rows, 338 sizeof(XkbRowRec), _XkbClearRow); 339} 340 341/***====================================================================***/ 342 343static void 344_XkbClearSection(char *section_in) 345{ 346 XkbSectionPtr section = (XkbSectionPtr) section_in; 347 348 if (section->rows != NULL) 349 XkbFreeGeomRows(section, 0, section->num_rows, True); 350 if (section->doodads != NULL) { 351 XkbFreeGeomDoodads(section->doodads, section->num_doodads, True); 352 section->doodads = NULL; 353 } 354 return; 355} 356 357void 358XkbFreeGeomSections(XkbGeometryPtr geom, int first, int count, Bool freeAll) 359{ 360 _XkbFreeGeomNonLeafElems(freeAll, first, count, 361 &geom->num_sections, &geom->sz_sections, 362 (char **) &geom->sections, 363 sizeof(XkbSectionRec), _XkbClearSection); 364 return; 365} 366 367/***====================================================================***/ 368 369static void 370_XkbClearDoodad(char *doodad_in) 371{ 372 XkbDoodadPtr doodad = (XkbDoodadPtr) doodad_in; 373 374 switch (doodad->any.type) { 375 case XkbTextDoodad: 376 { 377 if (doodad->text.text != NULL) { 378 _XkbFree(doodad->text.text); 379 doodad->text.text = NULL; 380 } 381 if (doodad->text.font != NULL) { 382 _XkbFree(doodad->text.font); 383 doodad->text.font = NULL; 384 } 385 } 386 break; 387 case XkbLogoDoodad: 388 { 389 if (doodad->logo.logo_name != NULL) { 390 _XkbFree(doodad->logo.logo_name); 391 doodad->logo.logo_name = NULL; 392 } 393 } 394 break; 395 } 396 return; 397} 398 399void 400XkbFreeGeomDoodads(XkbDoodadPtr doodads, int nDoodads, Bool freeAll) 401{ 402 register int i; 403 register XkbDoodadPtr doodad; 404 405 if (doodads) { 406 for (i = 0, doodad = doodads; i < nDoodads; i++, doodad++) { 407 _XkbClearDoodad((char *) doodad); 408 } 409 if (freeAll) 410 _XkbFree(doodads); 411 } 412 return; 413} 414 415void 416XkbFreeGeometry(XkbGeometryPtr geom, unsigned which, Bool freeMap) 417{ 418 if (geom == NULL) 419 return; 420 if (freeMap) 421 which = XkbGeomAllMask; 422 if ((which & XkbGeomPropertiesMask) && (geom->properties != NULL)) 423 XkbFreeGeomProperties(geom, 0, geom->num_properties, True); 424 if ((which & XkbGeomColorsMask) && (geom->colors != NULL)) 425 XkbFreeGeomColors(geom, 0, geom->num_colors, True); 426 if ((which & XkbGeomShapesMask) && (geom->shapes != NULL)) 427 XkbFreeGeomShapes(geom, 0, geom->num_shapes, True); 428 if ((which & XkbGeomSectionsMask) && (geom->sections != NULL)) 429 XkbFreeGeomSections(geom, 0, geom->num_sections, True); 430 if ((which & XkbGeomDoodadsMask) && (geom->doodads != NULL)) { 431 XkbFreeGeomDoodads(geom->doodads, geom->num_doodads, True); 432 geom->doodads = NULL; 433 geom->num_doodads = geom->sz_doodads = 0; 434 } 435 if ((which & XkbGeomKeyAliasesMask) && (geom->key_aliases != NULL)) 436 XkbFreeGeomKeyAliases(geom, 0, geom->num_key_aliases, True); 437 if (freeMap) { 438 if (geom->label_font != NULL) { 439 _XkbFree(geom->label_font); 440 geom->label_font = NULL; 441 } 442 _XkbFree(geom); 443 } 444 return; 445} 446 447/***====================================================================***/ 448 449static Status 450_XkbGeomAlloc(XPointer *old, 451 unsigned short *num, 452 unsigned short *total, 453 int num_new, 454 size_t sz_elem) 455{ 456 if (num_new < 1) 457 return Success; 458 if ((*old) == NULL) 459 *num = *total = 0; 460 461 if ((*num) + num_new <= (*total)) 462 return Success; 463 464 *total = (*num) + num_new; 465 if ((*old) != NULL) 466 (*old) = (XPointer) _XkbRealloc((*old), (*total) * sz_elem); 467 else 468 (*old) = (XPointer) _XkbCalloc((*total), sz_elem); 469 if ((*old) == NULL) { 470 *total = *num = 0; 471 return BadAlloc; 472 } 473 474 if (*num > 0) { 475 char *tmp = (char *) (*old); 476 bzero(&tmp[sz_elem * (*num)], (num_new * sz_elem)); 477 } 478 return Success; 479} 480 481#define _XkbAllocProps(g, n) _XkbGeomAlloc((XPointer *)&(g)->properties, \ 482 &(g)->num_properties, &(g)->sz_properties, \ 483 (n), sizeof(XkbPropertyRec)) 484#define _XkbAllocColors(g, n) _XkbGeomAlloc((XPointer *)&(g)->colors, \ 485 &(g)->num_colors, &(g)->sz_colors, \ 486 (n), sizeof(XkbColorRec)) 487#define _XkbAllocShapes(g, n) _XkbGeomAlloc((XPointer *)&(g)->shapes, \ 488 &(g)->num_shapes, &(g)->sz_shapes, \ 489 (n), sizeof(XkbShapeRec)) 490#define _XkbAllocSections(g, n) _XkbGeomAlloc((XPointer *)&(g)->sections, \ 491 &(g)->num_sections, &(g)->sz_sections, \ 492 (n), sizeof(XkbSectionRec)) 493#define _XkbAllocDoodads(g, n) _XkbGeomAlloc((XPointer *)&(g)->doodads, \ 494 &(g)->num_doodads, &(g)->sz_doodads, \ 495 (n), sizeof(XkbDoodadRec)) 496#define _XkbAllocKeyAliases(g, n) _XkbGeomAlloc((XPointer *)&(g)->key_aliases, \ 497 &(g)->num_key_aliases, &(g)->sz_key_aliases, \ 498 (n), sizeof(XkbKeyAliasRec)) 499 500#define _XkbAllocOutlines(s, n) _XkbGeomAlloc((XPointer *)&(s)->outlines, \ 501 &(s)->num_outlines, &(s)->sz_outlines, \ 502 (n), sizeof(XkbOutlineRec)) 503#define _XkbAllocRows(s, n) _XkbGeomAlloc((XPointer *)&(s)->rows, \ 504 &(s)->num_rows, &(s)->sz_rows, \ 505 (n), sizeof(XkbRowRec)) 506#define _XkbAllocPoints(o, n) _XkbGeomAlloc((XPointer *)&(o)->points, \ 507 &(o)->num_points, &(o)->sz_points, \ 508 (n), sizeof(XkbPointRec)) 509#define _XkbAllocKeys(r, n) _XkbGeomAlloc((XPointer *)&(r)->keys, \ 510 &(r)->num_keys, &(r)->sz_keys, \ 511 (n), sizeof(XkbKeyRec)) 512#define _XkbAllocOverlays(s, n) _XkbGeomAlloc((XPointer *)&(s)->overlays, \ 513 &(s)->num_overlays, &(s)->sz_overlays, \ 514 (n), sizeof(XkbOverlayRec)) 515#define _XkbAllocOverlayRows(o, n) _XkbGeomAlloc((XPointer *)&(o)->rows, \ 516 &(o)->num_rows, &(o)->sz_rows, \ 517 (n), sizeof(XkbOverlayRowRec)) 518#define _XkbAllocOverlayKeys(r, n) _XkbGeomAlloc((XPointer *)&(r)->keys, \ 519 &(r)->num_keys, &(r)->sz_keys, \ 520 (n), sizeof(XkbOverlayKeyRec)) 521 522Status 523XkbAllocGeomProps(XkbGeometryPtr geom, int nProps) 524{ 525 return _XkbAllocProps(geom, nProps); 526} 527 528Status 529XkbAllocGeomColors(XkbGeometryPtr geom, int nColors) 530{ 531 return _XkbAllocColors(geom, nColors); 532} 533 534Status 535XkbAllocGeomKeyAliases(XkbGeometryPtr geom, int nKeyAliases) 536{ 537 return _XkbAllocKeyAliases(geom, nKeyAliases); 538} 539 540Status 541XkbAllocGeomShapes(XkbGeometryPtr geom, int nShapes) 542{ 543 return _XkbAllocShapes(geom, nShapes); 544} 545 546Status 547XkbAllocGeomSections(XkbGeometryPtr geom, int nSections) 548{ 549 return _XkbAllocSections(geom, nSections); 550} 551 552Status 553XkbAllocGeomOverlays(XkbSectionPtr section, int nOverlays) 554{ 555 return _XkbAllocOverlays(section, nOverlays); 556} 557 558Status 559XkbAllocGeomOverlayRows(XkbOverlayPtr overlay, int nRows) 560{ 561 return _XkbAllocOverlayRows(overlay, nRows); 562} 563 564Status 565XkbAllocGeomOverlayKeys(XkbOverlayRowPtr row, int nKeys) 566{ 567 return _XkbAllocOverlayKeys(row, nKeys); 568} 569 570Status 571XkbAllocGeomDoodads(XkbGeometryPtr geom, int nDoodads) 572{ 573 return _XkbAllocDoodads(geom, nDoodads); 574} 575 576Status 577XkbAllocGeomSectionDoodads(XkbSectionPtr section, int nDoodads) 578{ 579 return _XkbAllocDoodads(section, nDoodads); 580} 581 582Status 583XkbAllocGeomOutlines(XkbShapePtr shape, int nOL) 584{ 585 return _XkbAllocOutlines(shape, nOL); 586} 587 588Status 589XkbAllocGeomRows(XkbSectionPtr section, int nRows) 590{ 591 return _XkbAllocRows(section, nRows); 592} 593 594Status 595XkbAllocGeomPoints(XkbOutlinePtr ol, int nPts) 596{ 597 return _XkbAllocPoints(ol, nPts); 598} 599 600Status 601XkbAllocGeomKeys(XkbRowPtr row, int nKeys) 602{ 603 return _XkbAllocKeys(row, nKeys); 604} 605 606Status 607XkbAllocGeometry(XkbDescPtr xkb, XkbGeometrySizesPtr sizes) 608{ 609 XkbGeometryPtr geom; 610 Status rtrn; 611 612 if (xkb->geom == NULL) { 613 xkb->geom = _XkbTypedCalloc(1, XkbGeometryRec); 614 if (!xkb->geom) 615 return BadAlloc; 616 } 617 geom = xkb->geom; 618 if ((sizes->which & XkbGeomPropertiesMask) && 619 ((rtrn = _XkbAllocProps(geom, sizes->num_properties)) != Success)) { 620 goto BAIL; 621 } 622 if ((sizes->which & XkbGeomColorsMask) && 623 ((rtrn = _XkbAllocColors(geom, sizes->num_colors)) != Success)) { 624 goto BAIL; 625 } 626 if ((sizes->which & XkbGeomShapesMask) && 627 ((rtrn = _XkbAllocShapes(geom, sizes->num_shapes)) != Success)) { 628 goto BAIL; 629 } 630 if ((sizes->which & XkbGeomSectionsMask) && 631 ((rtrn = _XkbAllocSections(geom, sizes->num_sections)) != Success)) { 632 goto BAIL; 633 } 634 if ((sizes->which & XkbGeomDoodadsMask) && 635 ((rtrn = _XkbAllocDoodads(geom, sizes->num_doodads)) != Success)) { 636 goto BAIL; 637 } 638 if ((sizes->which & XkbGeomKeyAliasesMask) && 639 ((rtrn = _XkbAllocKeyAliases(geom, sizes->num_key_aliases)) 640 != Success)) { 641 goto BAIL; 642 } 643 return Success; 644 BAIL: 645 XkbFreeGeometry(geom, XkbGeomAllMask, True); 646 xkb->geom = NULL; 647 return rtrn; 648} 649 650/***====================================================================***/ 651 652XkbPropertyPtr 653XkbAddGeomProperty(XkbGeometryPtr geom, char *name, char *value) 654{ 655 register int i; 656 register XkbPropertyPtr prop; 657 658 if ((!geom) || (!name) || (!value)) 659 return NULL; 660 for (i = 0, prop = geom->properties; i < geom->num_properties; i++, prop++) { 661 if ((prop->name) && (strcmp(name, prop->name) == 0)) { 662 _XkbFree(prop->value); 663 prop->value = strdup(value); 664 return prop; 665 } 666 } 667 if ((geom->num_properties >= geom->sz_properties) && 668 (_XkbAllocProps(geom, 1) != Success)) { 669 return NULL; 670 } 671 prop = &geom->properties[geom->num_properties]; 672 prop->name = strdup(name); 673 if (!prop->name) 674 return NULL; 675 prop->value = strdup(value); 676 if (!prop->value) { 677 _XkbFree(prop->name); 678 prop->name = NULL; 679 return NULL; 680 } 681 geom->num_properties++; 682 return prop; 683} 684 685XkbKeyAliasPtr 686XkbAddGeomKeyAlias(XkbGeometryPtr geom, char *aliasStr, char *realStr) 687{ 688 register int i; 689 register XkbKeyAliasPtr alias; 690 691 if ((!geom) || (!aliasStr) || (!realStr) || (!aliasStr[0]) || (!realStr[0])) 692 return NULL; 693 for (i = 0, alias = geom->key_aliases; i < geom->num_key_aliases; 694 i++, alias++) { 695 if (strncmp(alias->alias, aliasStr, XkbKeyNameLength) == 0) { 696 bzero(alias->real, XkbKeyNameLength); 697 strncpy(alias->real, realStr, XkbKeyNameLength); 698 return alias; 699 } 700 } 701 if ((geom->num_key_aliases >= geom->sz_key_aliases) && 702 (_XkbAllocKeyAliases(geom, 1) != Success)) { 703 return NULL; 704 } 705 alias = &geom->key_aliases[geom->num_key_aliases]; 706 bzero(alias, sizeof(XkbKeyAliasRec)); 707 strncpy(alias->alias, aliasStr, XkbKeyNameLength); 708 strncpy(alias->real, realStr, XkbKeyNameLength); 709 geom->num_key_aliases++; 710 return alias; 711} 712 713XkbColorPtr 714XkbAddGeomColor(XkbGeometryPtr geom, char *spec, unsigned int pixel) 715{ 716 register int i; 717 register XkbColorPtr color; 718 719 if ((!geom) || (!spec)) 720 return NULL; 721 for (i = 0, color = geom->colors; i < geom->num_colors; i++, color++) { 722 if ((color->spec) && (strcmp(color->spec, spec) == 0)) { 723 color->pixel = pixel; 724 return color; 725 } 726 } 727 if ((geom->num_colors >= geom->sz_colors) && 728 (_XkbAllocColors(geom, 1) != Success)) { 729 return NULL; 730 } 731 color = &geom->colors[geom->num_colors]; 732 color->pixel = pixel; 733 color->spec = strdup(spec); 734 if (!color->spec) 735 return NULL; 736 geom->num_colors++; 737 return color; 738} 739 740XkbOutlinePtr 741XkbAddGeomOutline(XkbShapePtr shape, int sz_points) 742{ 743 XkbOutlinePtr outline; 744 745 if ((!shape) || (sz_points < 0)) 746 return NULL; 747 if ((shape->num_outlines >= shape->sz_outlines) && 748 (_XkbAllocOutlines(shape, 1) != Success)) { 749 return NULL; 750 } 751 outline = &shape->outlines[shape->num_outlines]; 752 bzero(outline, sizeof(XkbOutlineRec)); 753 if ((sz_points > 0) && (_XkbAllocPoints(outline, sz_points) != Success)) 754 return NULL; 755 shape->num_outlines++; 756 return outline; 757} 758 759XkbShapePtr 760XkbAddGeomShape(XkbGeometryPtr geom, Atom name, int sz_outlines) 761{ 762 XkbShapePtr shape; 763 register int i; 764 765 if ((!geom) || (!name) || (sz_outlines < 0)) 766 return NULL; 767 if (geom->num_shapes > 0) { 768 for (shape = geom->shapes, i = 0; i < geom->num_shapes; i++, shape++) { 769 if (name == shape->name) 770 return shape; 771 } 772 } 773 if ((geom->num_shapes >= geom->sz_shapes) && 774 (_XkbAllocShapes(geom, 1) != Success)) 775 return NULL; 776 shape = &geom->shapes[geom->num_shapes]; 777 bzero(shape, sizeof(XkbShapeRec)); 778 if ((sz_outlines > 0) && (_XkbAllocOutlines(shape, sz_outlines) != Success)) 779 return NULL; 780 shape->name = name; 781 shape->primary = shape->approx = NULL; 782 geom->num_shapes++; 783 return shape; 784} 785 786XkbKeyPtr 787XkbAddGeomKey(XkbRowPtr row) 788{ 789 XkbKeyPtr key; 790 791 if (!row) 792 return NULL; 793 if ((row->num_keys >= row->sz_keys) && (_XkbAllocKeys(row, 1) != Success)) 794 return NULL; 795 key = &row->keys[row->num_keys++]; 796 bzero(key, sizeof(XkbKeyRec)); 797 return key; 798} 799 800XkbRowPtr 801XkbAddGeomRow(XkbSectionPtr section, int sz_keys) 802{ 803 XkbRowPtr row; 804 805 if ((!section) || (sz_keys < 0)) 806 return NULL; 807 if ((section->num_rows >= section->sz_rows) && 808 (_XkbAllocRows(section, 1) != Success)) 809 return NULL; 810 row = §ion->rows[section->num_rows]; 811 bzero(row, sizeof(XkbRowRec)); 812 if ((sz_keys > 0) && (_XkbAllocKeys(row, sz_keys) != Success)) 813 return NULL; 814 section->num_rows++; 815 return row; 816} 817 818XkbSectionPtr 819XkbAddGeomSection(XkbGeometryPtr geom, 820 Atom name, 821 int sz_rows, 822 int sz_doodads, 823 int sz_over) 824{ 825 register int i; 826 XkbSectionPtr section; 827 828 if ((!geom) || (name == None) || (sz_rows < 0)) 829 return NULL; 830 for (i = 0, section = geom->sections; i < geom->num_sections; 831 i++, section++) { 832 if (section->name != name) 833 continue; 834 if (((sz_rows > 0) && (_XkbAllocRows(section, sz_rows) != Success)) || 835 ((sz_doodads > 0) && 836 (_XkbAllocDoodads(section, sz_doodads) != Success)) || 837 ((sz_over > 0) && (_XkbAllocOverlays(section, sz_over) != Success))) 838 return NULL; 839 return section; 840 } 841 if ((geom->num_sections >= geom->sz_sections) && 842 (_XkbAllocSections(geom, 1) != Success)) 843 return NULL; 844 section = &geom->sections[geom->num_sections]; 845 if ((sz_rows > 0) && (_XkbAllocRows(section, sz_rows) != Success)) 846 return NULL; 847 if ((sz_doodads > 0) && (_XkbAllocDoodads(section, sz_doodads) != Success)) { 848 if (section->rows) { 849 _XkbFree(section->rows); 850 section->rows = NULL; 851 section->sz_rows = section->num_rows = 0; 852 } 853 return NULL; 854 } 855 section->name = name; 856 geom->num_sections++; 857 return section; 858} 859 860XkbDoodadPtr 861XkbAddGeomDoodad(XkbGeometryPtr geom, XkbSectionPtr section, Atom name) 862{ 863 XkbDoodadPtr old, doodad; 864 register int i, nDoodads; 865 866 if ((!geom) || (name == None)) 867 return NULL; 868 if ((section != NULL) && (section->num_doodads > 0)) { 869 old = section->doodads; 870 nDoodads = section->num_doodads; 871 } 872 else { 873 old = geom->doodads; 874 nDoodads = geom->num_doodads; 875 } 876 for (i = 0, doodad = old; i < nDoodads; i++, doodad++) { 877 if (doodad->any.name == name) 878 return doodad; 879 } 880 if (section) { 881 if ((section->num_doodads >= geom->sz_doodads) && 882 (_XkbAllocDoodads(section, 1) != Success)) { 883 return NULL; 884 } 885 doodad = §ion->doodads[section->num_doodads++]; 886 } 887 else { 888 if ((geom->num_doodads >= geom->sz_doodads) && 889 (_XkbAllocDoodads(geom, 1) != Success)) 890 return NULL; 891 doodad = &geom->doodads[geom->num_doodads++]; 892 } 893 bzero(doodad, sizeof(XkbDoodadRec)); 894 doodad->any.name = name; 895 return doodad; 896} 897 898XkbOverlayKeyPtr 899XkbAddGeomOverlayKey(XkbOverlayPtr overlay, 900 XkbOverlayRowPtr row, 901 char *over, 902 char *under) 903{ 904 register int i; 905 XkbOverlayKeyPtr key; 906 XkbSectionPtr section; 907 XkbRowPtr row_under; 908 Bool found; 909 910 if ((!overlay) || (!row) || (!over) || (!under)) 911 return NULL; 912 section = overlay->section_under; 913 if (row->row_under >= section->num_rows) 914 return NULL; 915 row_under = §ion->rows[row->row_under]; 916 for (i = 0, found = False; i < row_under->num_keys; i++) { 917 if (strncmp(under, row_under->keys[i].name.name, XkbKeyNameLength) == 0) { 918 found = True; 919 break; 920 } 921 } 922 if (!found) 923 return NULL; 924 if ((row->num_keys >= row->sz_keys) && 925 (_XkbAllocOverlayKeys(row, 1) != Success)) 926 return NULL; 927 key = &row->keys[row->num_keys]; 928 strncpy(key->under.name, under, XkbKeyNameLength); 929 strncpy(key->over.name, over, XkbKeyNameLength); 930 row->num_keys++; 931 return key; 932} 933 934XkbOverlayRowPtr 935XkbAddGeomOverlayRow(XkbOverlayPtr overlay, int row_under, int sz_keys) 936{ 937 register int i; 938 XkbOverlayRowPtr row; 939 940 if ((!overlay) || (sz_keys < 0)) 941 return NULL; 942 if (row_under >= overlay->section_under->num_rows) 943 return NULL; 944 for (i = 0; i < overlay->num_rows; i++) { 945 if (overlay->rows[i].row_under == row_under) { 946 row = &overlay->rows[i]; 947 if ((row->sz_keys < sz_keys) && 948 (_XkbAllocOverlayKeys(row, sz_keys) != Success)) { 949 return NULL; 950 } 951 return &overlay->rows[i]; 952 } 953 } 954 if ((overlay->num_rows >= overlay->sz_rows) && 955 (_XkbAllocOverlayRows(overlay, 1) != Success)) 956 return NULL; 957 row = &overlay->rows[overlay->num_rows]; 958 bzero(row, sizeof(XkbOverlayRowRec)); 959 if ((sz_keys > 0) && (_XkbAllocOverlayKeys(row, sz_keys) != Success)) 960 return NULL; 961 row->row_under = row_under; 962 overlay->num_rows++; 963 return row; 964} 965 966XkbOverlayPtr 967XkbAddGeomOverlay(XkbSectionPtr section, Atom name, int sz_rows) 968{ 969 register int i; 970 XkbOverlayPtr overlay; 971 972 if ((!section) || (name == None) || (sz_rows == 0)) 973 return NULL; 974 975 for (i = 0, overlay = section->overlays; i < section->num_overlays; 976 i++, overlay++) { 977 if (overlay->name == name) { 978 if ((sz_rows > 0) && 979 (_XkbAllocOverlayRows(overlay, sz_rows) != Success)) 980 return NULL; 981 return overlay; 982 } 983 } 984 if ((section->num_overlays >= section->sz_overlays) && 985 (_XkbAllocOverlays(section, 1) != Success)) 986 return NULL; 987 overlay = §ion->overlays[section->num_overlays]; 988 if ((sz_rows > 0) && (_XkbAllocOverlayRows(overlay, sz_rows) != Success)) 989 return NULL; 990 overlay->name = name; 991 overlay->section_under = section; 992 section->num_overlays++; 993 return overlay; 994} 995