Pixmap.c revision c889a3bf
1/* 2 * Copyright (c) 1998 by The XFree86 Project, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 * 22 * Except as contained in this notice, the name of the XFree86 Project shall 23 * not be used in advertising or otherwise to promote the sale, use or other 24 * dealings in this Software without prior written authorization from the 25 * XFree86 Project. 26 */ 27 28#ifdef HAVE_CONFIG_H 29#include <config.h> 30#endif 31#include <string.h> 32#include <stdio.h> 33#include <stdlib.h> 34#include <X11/IntrinsicP.h> 35#include <X11/Xmu/CharSet.h> 36#include <X11/Xfuncs.h> 37#include <X11/extensions/shape.h> 38#ifndef OLDXAW 39#include <X11/xpm.h> 40#endif 41#include "Private.h" 42 43 44#ifndef OLDXAW 45 46/* 47 * Types 48 */ 49typedef struct _XawCache { 50 long value; 51 XtPointer *elems; 52 unsigned int num_elems; 53} XawCache; 54 55typedef struct _XawPixmapLoaderInfo { 56 XawPixmapLoader loader; 57 String type; 58 String ext; 59} XawPixmapLoaderInfo; 60 61/* 62 * Private Methods 63 */ 64static Bool BitmapLoader(XawParams*, Screen*, Colormap, int, 65 Pixmap*, Pixmap*, Dimension*, Dimension*); 66static Bool GradientLoader(XawParams*, Screen*, Colormap, int, 67 Pixmap*, Pixmap*, Dimension*, Dimension*); 68static Bool XPixmapLoader(XawParams*, Screen*, Colormap, int, 69 Pixmap*, Pixmap*, Dimension*, Dimension*); 70static XawPixmap *_XawFindPixmap(String, Screen*, Colormap, int); 71static void _XawCachePixmap(XawPixmap*, Screen*, Colormap, int); 72static int _XawFindPixmapLoaderIndex(String, String); 73static int qcmp_long(register _Xconst void*, register _Xconst void *); 74static int bcmp_long(register _Xconst void*, register _Xconst void *); 75static int qcmp_string(register _Xconst void*, register _Xconst void *); 76static int bcmp_string(register _Xconst void*, register _Xconst void *); 77static void GetResourcePixmapPath(Display*); 78 79/* 80 * Initialization 81 */ 82static XawCache xaw_pixmaps; 83static XawCache x_pixmaps; /* for fast reverse search */ 84static XawPixmapLoaderInfo **loader_info; 85static Cardinal num_loader_info; 86 87/* 88 * Implementation 89 */ 90Bool 91XawPixmapsInitialize(void) 92{ 93 static Boolean first_time = True; 94 95 if (!first_time) 96 return (False); 97 98 (void)XawAddPixmapLoader(NULL, NULL, BitmapLoader); 99 (void)XawAddPixmapLoader("bitmap", NULL, BitmapLoader); 100 (void)XawAddPixmapLoader("gradient", NULL, GradientLoader); 101 (void)XawAddPixmapLoader("xpm", "xpm", XPixmapLoader); 102 103 return (True); 104} 105 106XawParams * 107XawParseParamsString(String name) 108{ 109 XawParams *xaw_params; 110 char *tok, *str, *type = NULL, *ext = NULL, *params = NULL; 111 112 if (!name) 113 return (NULL); 114 115 xaw_params = (XawParams *)XtMalloc(sizeof(XawParams)); 116 117 str = XtNewString(name); 118 119 /* Find type */ 120 tok = str; 121 while (tok = strchr(tok, ':'), tok) 122 { 123 if (tok == str || tok[-1] != '\\') 124 break; 125 memmove(&tok[-1], tok, strlen(tok) + 1); 126 } 127 if (tok) 128 { 129 *tok = '\0'; 130 if (strchr(str, '?')) 131 { 132 *tok = ':'; 133 } 134 else 135 { 136 ++tok; 137 type = XtNewString(str); 138 memmove(str, tok, strlen(tok) + 1); 139 } 140 } 141 142 /* Find params */ 143 tok = str; 144 while (tok = strchr(tok, '?'), tok) 145 { 146 if (tok == str || tok[-1] != '\\') 147 params = tok; 148 if (tok != str && tok[-1] == '\\') 149 memmove(&tok[-1], tok, strlen(tok) + 1); 150 else 151 break; 152 } 153 if (params) 154 { 155 *params = '\0'; 156 ++params; 157 } 158 159 /* Find ext */ 160 tok = str; 161 while (tok = strchr(tok, '.'), tok) 162 { 163 if (tok == str || tok[-1] != '\\') 164 ext = tok; 165 if (tok != str && tok[-1] == '\\') 166 memmove(&tok[-1], tok, strlen(tok) + 1); 167 else 168 break; 169 } 170 if (ext) 171 { 172 ++ext; 173 if (strchr(ext, '/')) 174 ext = NULL; 175 } 176 177 xaw_params->name = XtNewString(str); 178 xaw_params->type = type; 179 xaw_params->ext = ext ? XtNewString(ext) : ext; 180 xaw_params->args = NULL; 181 xaw_params->num_args = 0; 182 183 /* Parse params */ 184 if (params) 185 { 186 char *arg, *val; 187 XawArgVal *xaw_arg; 188 189 for (tok = strtok(params, "&"); tok; tok = strtok(NULL, "&")) 190 { 191 val = strchr(tok, '='); 192 if (val) 193 { 194 *val = '\0'; 195 ++val; 196 if (*val != '\0') 197 val = XtNewString(val); 198 else 199 val = NULL; 200 } 201 arg = XtNewString(tok); 202 xaw_arg = (XawArgVal *)XtMalloc(sizeof(XawArgVal)); 203 xaw_arg->name = arg; 204 xaw_arg->value = val; 205 if (!xaw_params->num_args) 206 { 207 xaw_params->num_args = 1; 208 xaw_params->args = (XawArgVal **) 209 XtMalloc(sizeof(XawArgVal*)); 210 } 211 else 212 { 213 ++xaw_params->num_args; 214 xaw_params->args = (XawArgVal **) 215 XtRealloc((char *)xaw_params->args, 216 sizeof(XawArgVal*) * xaw_params->num_args); 217 } 218 xaw_params->args[xaw_params->num_args - 1] = xaw_arg; 219 } 220 } 221 222 if (xaw_params->num_args > 1) 223 qsort(xaw_params->args, xaw_params->num_args, sizeof(XtPointer), 224 qcmp_string); 225 226 XtFree(str); 227 228 return (xaw_params); 229} 230 231void 232XawFreeParamsStruct(XawParams *params) 233{ 234 unsigned int i; 235 236 if (!params) 237 return; 238 239 for (i = 0; i < params->num_args; i++) 240 { 241 XtFree(params->args[i]->name); 242 if (params->args[i]->value) 243 XtFree(params->args[i]->value); 244 XtFree((char *)params->args[i]); 245 } 246 247 if (params->args) 248 XtFree((char *)params->args); 249 XtFree((char *)params); 250} 251 252XawArgVal * 253XawFindArgVal(XawParams *params, String name) 254{ 255 XawArgVal **arg_val; 256 257 if (!params->args) 258 return (NULL); 259 260 arg_val = (XawArgVal **)bsearch((void *)name, params->args, 261 params->num_args, sizeof(XtPointer*), 262 bcmp_string); 263 if (!arg_val) 264 return (NULL); 265 266 return (*arg_val); 267} 268 269XawPixmap * 270XawLoadPixmap(String name, Screen *screen, Colormap colormap, int depth) 271{ 272 int idx; 273 Bool success; 274 XawPixmap *xaw_pixmap; 275 Pixmap pixmap, mask; 276 Dimension width, height; 277 XawParams *xaw_params; 278 279 if (!name) 280 return (NULL); 281 282 xaw_pixmap = _XawFindPixmap(name, screen, colormap, depth); 283 284 if (xaw_pixmap) 285 return (xaw_pixmap); 286 287 if ((xaw_params = XawParseParamsString(name)) == NULL) 288 return (NULL); 289 290 idx = _XawFindPixmapLoaderIndex(xaw_params->type, xaw_params->ext); 291 if (idx < 0) 292 return (NULL); 293 294#ifdef DIAGNOSTIC 295 fprintf(stderr, "(*) Loading pixmap \"%s\": ", name); 296#endif 297 298 success = loader_info[idx]->loader(xaw_params, screen, colormap, depth, 299 &pixmap, &mask, &width, &height); 300 if (success) 301 { 302 xaw_pixmap = (XawPixmap *)XtMalloc(sizeof(XawPixmap)); 303 xaw_pixmap->name = XtNewString(name); 304 xaw_pixmap->pixmap = pixmap; 305 xaw_pixmap->mask = mask; 306 xaw_pixmap->width = width; 307 xaw_pixmap->height = height; 308 _XawCachePixmap(xaw_pixmap, screen, colormap, depth); 309 } 310 311 XawFreeParamsStruct(xaw_params); 312 313#ifdef DIAGNOSTIC 314 fprintf(stderr, "%s", success ? "success\n" : "failed\n"); 315#endif 316 317 return (success ? xaw_pixmap : NULL); 318} 319 320Bool 321XawAddPixmapLoader(String type, String ext, XawPixmapLoader loader) 322{ 323 XawPixmapLoaderInfo *info; 324 int i; 325 326 if (!loader) 327 return (False); 328 329 i = _XawFindPixmapLoaderIndex(type, ext); 330 331 if (i >= 0) 332 { 333 loader_info[i]->loader = loader; 334 if (loader_info[i]->type) 335 XtFree(loader_info[i]->type); 336 if (loader_info[i]->ext) 337 XtFree(loader_info[i]->ext); 338 loader_info[i]->type = type ? XtNewString(type) : NULL; 339 loader_info[i]->ext = ext ? XtNewString(ext) : NULL; 340 return (True); 341 } 342 343 if ((info = (XawPixmapLoaderInfo *)XtMalloc(sizeof(XawPixmapLoaderInfo))) 344 == NULL) 345 return (False); 346 347 info->loader = loader; 348 info->type = type ? XtNewString(type) : NULL; 349 info->ext = ext ? XtNewString(ext) : NULL; 350 351 if (!loader_info) 352 { 353 num_loader_info = 1; 354 loader_info = (XawPixmapLoaderInfo**) 355 XtMalloc(sizeof(XawPixmapLoaderInfo*)); 356 } 357 else 358 { 359 ++num_loader_info; 360 loader_info = (XawPixmapLoaderInfo**) 361 XtRealloc((char *)loader_info, 362 sizeof(XawPixmapLoaderInfo) * num_loader_info); 363 } 364 loader_info[num_loader_info - 1] = info; 365 366 return (True); 367} 368 369static int 370_XawFindPixmapLoaderIndex(String type, String ext) 371{ 372 Cardinal i; 373 374 if (!loader_info) 375 return (-1); 376 377 for (i = 0; i < num_loader_info; i++) 378 if ((type && loader_info[i]->type && strcmp(type, loader_info[i]->type) == 0) 379 || (ext && loader_info[i]->ext && strcmp(ext, loader_info[i]->ext) == 0)) 380 return ((int)i); 381 382 if (!type) 383 return (0); /* try a bitmap */ 384 385 return (-1); 386} 387 388static int 389qcmp_x_cache(register _Xconst void *left, register _Xconst void *right) 390{ 391 return ((int)((*(XawPixmap **)left)->pixmap) - 392 (int)((*(XawPixmap **)right)->pixmap)); 393} 394 395static int 396bcmp_x_cache(register _Xconst void *pixmap, register _Xconst void *xaw) 397{ 398 return (int)((long)pixmap - (long)((*(XawPixmap **)xaw)->pixmap)); 399} 400 401static int 402qcmp_long(register _Xconst void *left, register _Xconst void *right) 403{ 404 return ((long)((*(XawCache **)left)->value) - 405 (long)((*(XawCache **)right)->value)); 406} 407 408static int 409qcmp_string(register _Xconst void *left, register _Xconst void *right) 410{ 411 return (strcmp((String)((*(XawCache **)left)->value), 412 (String)((*(XawCache **)right)->value))); 413} 414 415static int 416bcmp_long(register _Xconst void *value, register _Xconst void *cache) 417{ 418 return ((long)value - (long)((*(XawCache **)cache)->value)); 419} 420 421static int 422bcmp_string(register _Xconst void *string, 423 register _Xconst void *cache) 424{ 425 return (strcmp((String)string, (String)((*(XawCache **)cache)->value))); 426} 427 428#define FIND_ALL 0 429#define FIND_SCREEN 1 430#define FIND_COLORMAP 2 431#define FIND_DEPTH 3 432static XawCache * 433_XawFindCache(XawCache *xaw, 434 Screen *screen, Colormap colormap, int depth, int flags) 435{ 436 XawCache **cache; 437 438 if (!xaw->num_elems) 439 return (NULL); 440 441 /* Screen */ 442 cache = (XawCache **)bsearch(screen, xaw->elems, 443 xaw->num_elems, sizeof(XtPointer), 444 bcmp_long); 445 if (!cache || !(*cache)->num_elems) 446 return (NULL); 447 if (flags == FIND_SCREEN) 448 return (*cache); 449 450 /* Colormap */ 451 cache = (XawCache **)bsearch((void *)colormap, (*cache)->elems, 452 (*cache)->num_elems, sizeof(XtPointer), 453 bcmp_long); 454 if (!cache || !(*cache)->num_elems) 455 return (NULL); 456 if (flags == FIND_COLORMAP) 457 return (*cache); 458 459 /* Depth */ 460 cache = (XawCache **)bsearch((void *)(long)depth, (*cache)->elems, 461 (*cache)->num_elems, sizeof(XtPointer), 462 bcmp_long); 463 464 if (!cache || !(*cache)->num_elems) 465 return (NULL); 466 return (*cache); 467} 468 469static XawCache * 470_XawGetCache(XawCache *xaw, Screen *screen, Colormap colormap, int depth) 471{ 472 XawCache *s_cache, *c_cache, *d_cache, *cache, *pcache; 473 474 cache = _XawFindCache(xaw, screen, colormap, depth, FIND_ALL); 475 476 if (!cache) 477 { 478 s_cache = _XawFindCache(xaw, 479 screen, colormap, depth, FIND_SCREEN); 480 if (!s_cache) 481 { 482 pcache = (XawCache *)XtMalloc(sizeof(XawCache)); 483 if (!xaw->num_elems) 484 { 485 xaw->num_elems = 1; 486 xaw->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); 487 } 488 else 489 { 490 ++xaw->num_elems; 491 xaw->elems = (XtPointer*) 492 XtRealloc((char *)xaw->elems, 493 sizeof(XtPointer) * xaw->num_elems); 494 } 495 pcache->value = (long)screen; 496 pcache->elems = NULL; 497 pcache->num_elems = 0; 498 xaw->elems[xaw->num_elems - 1] = (XtPointer)pcache; 499 s_cache = (XawCache *)xaw->elems[xaw->num_elems - 1]; 500 if (xaw->num_elems > 1) 501 qsort(xaw->elems, xaw->num_elems, sizeof(XtPointer), qcmp_long); 502 } 503 504 c_cache = _XawFindCache(xaw, 505 screen, colormap, depth, FIND_COLORMAP); 506 if (!c_cache) 507 { 508 pcache = (XawCache *)XtMalloc(sizeof(XawCache)); 509 if (!s_cache->num_elems) 510 { 511 s_cache->num_elems = 1; 512 s_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); 513 } 514 else 515 { 516 ++s_cache->num_elems; 517 s_cache->elems = (XtPointer*) 518 XtRealloc((char *)s_cache->elems, 519 sizeof(XtPointer) * s_cache->num_elems); 520 } 521 pcache->value = (long)colormap; 522 pcache->elems = NULL; 523 pcache->num_elems = 0; 524 s_cache->elems[s_cache->num_elems - 1] = (XtPointer)pcache; 525 c_cache = (XawCache *)s_cache->elems[s_cache->num_elems - 1]; 526 if (s_cache->num_elems > 1) 527 qsort(s_cache->elems, s_cache->num_elems, 528 sizeof(XtPointer), qcmp_long); 529 } 530 531 d_cache = _XawFindCache(xaw, 532 screen, colormap, depth, FIND_DEPTH); 533 if (!d_cache) 534 { 535 pcache = (XawCache *)XtMalloc(sizeof(XawCache)); 536 if (!c_cache->num_elems) 537 { 538 c_cache->num_elems = 1; 539 c_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); 540 } 541 else 542 { 543 ++c_cache->num_elems; 544 c_cache->elems = (XtPointer*) 545 XtRealloc((char *)c_cache->elems, 546 sizeof(XtPointer) * c_cache->num_elems); 547 } 548 pcache->value = (long)depth; 549 pcache->elems = NULL; 550 pcache->num_elems = 0; 551 c_cache->elems[c_cache->num_elems - 1] = (XtPointer)pcache; 552 d_cache = (XawCache *)c_cache->elems[c_cache->num_elems - 1]; 553 if (c_cache->num_elems > 1) 554 qsort(c_cache->elems, c_cache->num_elems, 555 sizeof(XtPointer), qcmp_long); 556 } 557 558 cache = d_cache; 559 } 560 561 return (cache); 562} 563 564static XawPixmap * 565_XawFindPixmap(String name, Screen *screen, Colormap colormap, int depth) 566{ 567 XawCache *cache; 568 XawPixmap **pixmap; 569 570 cache = _XawFindCache(&xaw_pixmaps, screen, colormap, depth, FIND_ALL); 571 572 if (!cache) 573 return (NULL); 574 575 /* Name */ 576 pixmap = (XawPixmap **)bsearch((void *)name, cache->elems, 577 cache->num_elems, sizeof(XtPointer), 578 bcmp_string); 579 if (!pixmap) 580 return (NULL); 581 582 return (*pixmap); 583} 584 585XawPixmap * 586XawPixmapFromXPixmap(Pixmap pixmap, 587 Screen *screen, Colormap colormap, int depth) 588{ 589 XawCache *cache; 590 XawPixmap **x_pixmap; 591 592 cache = _XawFindCache(&x_pixmaps, screen, colormap, depth, FIND_ALL); 593 594 if (!cache) 595 return (NULL); 596 597 /* Pixmap */ 598 x_pixmap = (XawPixmap **)bsearch((void *)pixmap, cache->elems, 599 cache->num_elems, sizeof(XtPointer), 600 bcmp_x_cache); 601 if (!x_pixmap) 602 return (NULL); 603 604 return (*x_pixmap); 605} 606 607static void 608_XawCachePixmap(XawPixmap *pixmap, 609 Screen *screen, Colormap colormap, int depth) 610{ 611 XawCache *xaw_cache, *x_cache; 612 613 xaw_cache = _XawGetCache(&xaw_pixmaps, screen, colormap, depth); 614 x_cache = _XawGetCache(&x_pixmaps, screen, colormap, depth); 615 616 if (!xaw_cache->num_elems) 617 { 618 xaw_cache->num_elems = 1; 619 xaw_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); 620 } 621 else 622 { 623 ++xaw_cache->num_elems; 624 xaw_cache->elems = (XtPointer*)XtRealloc((char *)xaw_cache->elems, 625 sizeof(XtPointer) * 626 xaw_cache->num_elems); 627 } 628 629 xaw_cache->elems[xaw_cache->num_elems - 1] = (XtPointer)pixmap; 630 if (xaw_cache->num_elems > 1) 631 qsort(xaw_cache->elems, xaw_cache->num_elems, 632 sizeof(XtPointer), qcmp_string); 633 634 635 if (!x_cache->num_elems) 636 { 637 x_cache->num_elems = 1; 638 x_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); 639 } 640 else 641 { 642 ++x_cache->num_elems; 643 x_cache->elems = (XtPointer*)XtRealloc((char *)x_cache->elems, 644 sizeof(XtPointer) * 645 x_cache->num_elems); 646 } 647 648 x_cache->elems[x_cache->num_elems - 1] = (XtPointer)pixmap; 649 if (x_cache->num_elems > 1) 650 qsort(x_cache->elems, x_cache->num_elems, sizeof(XtPointer), qcmp_x_cache); 651} 652 653#ifndef PROJECT_ROOT 654#define PROJECT_ROOT "/usr/X11R6" 655#endif 656 657static char *pixmap_path = NULL; 658 659static void 660GetResourcePixmapPath(Display *display) 661{ 662 XrmName xrm_name[2]; 663 XrmClass xrm_class[2]; 664 XrmRepresentation rep_type; 665 XrmValue value; 666 static char *default_path = 667 "%H/%T/%N:%P/include/X11/%T/%N:/usr/X11R6/include/X11/%T/%N:/usr/include/X11/%T/%N:%N"; 668 669 xrm_name[0] = XrmPermStringToQuark("pixmapFilePath"); 670 xrm_name[1] = NULLQUARK; 671 xrm_class[0] = XrmPermStringToQuark("PixmapFilePath"); 672 xrm_class[1] = NULLQUARK; 673 if (!XrmGetDatabase(display)) 674 (void) XGetDefault(display, "", ""); 675 if (XrmQGetResource(XrmGetDatabase(display), xrm_name, xrm_class, 676 &rep_type, &value) && 677 rep_type == XrmPermStringToQuark("String")) { 678 int length = 0; 679 char *tok, *buffer = XtNewString(value.addr); 680 681 for (tok = strtok(buffer, ":"); tok; tok = strtok(NULL, ":")) { 682 int toklen = strlen(tok); 683 684 if (toklen) { 685 pixmap_path = XtRealloc(pixmap_path, length + toklen + 5); 686 strcpy(pixmap_path + length, tok); 687 if (length) 688 pixmap_path[length++] = ':'; 689 sprintf(pixmap_path + length, "%s/%%N", tok); 690 length += strlen(tok) + 3; 691 } 692 } 693 pixmap_path = XtRealloc(pixmap_path, length + strlen(default_path) + 2); 694 if (length) 695 pixmap_path[length++] = ':'; 696 strcpy(pixmap_path + length, default_path); 697 } 698 else 699 pixmap_path = default_path; 700} 701 702static Bool 703BitmapLoader(XawParams *params, Screen *screen, Colormap colormap, int depth, 704 Pixmap *pixmap_return, Pixmap *mask_return, 705 Dimension *width_return, Dimension *height_return) 706{ 707 Pixel fg, bg; 708 XColor color, exact; 709 Pixmap pixmap; 710 unsigned int width, height; 711 unsigned char *data = NULL; 712 int hotX, hotY; 713 XawArgVal *argval; 714 Bool retval = False; 715 static SubstitutionRec sub[] = { 716 {'H', NULL}, 717 {'N', NULL}, 718 {'T', "bitmaps"}, 719 {'P', PROJECT_ROOT}, 720 }; 721 char *filename; 722 723 fg = BlackPixelOfScreen(screen); 724 bg = WhitePixelOfScreen(screen); 725 726 if ((argval = XawFindArgVal(params, "foreground")) != NULL 727 && argval->value) 728 { 729 if (XAllocNamedColor(DisplayOfScreen(screen), colormap, argval->value, 730 &color, &exact)) 731 fg = color.pixel; 732 else 733 return (False); 734 } 735 if ((argval = XawFindArgVal(params, "background")) != NULL 736 && argval->value) 737 { 738 if (XAllocNamedColor(DisplayOfScreen(screen), colormap, argval->value, 739 &color, &exact)) 740 bg = color.pixel; 741 else 742 return (False); 743 } 744 745 if (params->name[0] != '/' && params->name[0] != '.') 746 { 747 if (!sub[0].substitution) 748 sub[0].substitution = getenv("HOME"); 749 sub[1].substitution = params->name; 750 if (pixmap_path == NULL) 751 GetResourcePixmapPath(DisplayOfScreen(screen)); 752 filename = XtFindFile(pixmap_path, sub, XtNumber(sub), NULL); 753 if (!filename) 754 return (FALSE); 755 } 756 else 757 filename = params->name; 758 759 if (XReadBitmapFileData(filename, &width, &height, &data, 760 &hotX, &hotY) == BitmapSuccess) 761 { 762 pixmap = XCreatePixmapFromBitmapData(DisplayOfScreen(screen), 763 RootWindowOfScreen(screen), 764 (char *)data, 765 width, height, fg, bg, depth); 766 if (data) 767 XFree(data); 768 *pixmap_return = pixmap; 769 *mask_return = None; 770 *width_return = width; 771 *height_return = height; 772 773 retval = True; 774 } 775 776 if (filename != params->name) 777 XtFree(filename); 778 779 return (retval); 780} 781 782#define VERTICAL 1 783#define HORIZONTAL 2 784static Bool 785GradientLoader(XawParams *params, Screen *screen, Colormap colormap, int depth, 786 Pixmap *pixmap_return, Pixmap *mask_return, 787 Dimension *width_return, Dimension *height_return) 788{ 789 double ired, igreen, iblue, red, green, blue; 790 XColor start, end, color; 791 XGCValues values; 792 GC gc; 793 double i, inc, x, y, xend, yend; 794 Pixmap pixmap; 795 XawArgVal *argval; 796 int orientation, dimension, steps; 797 char *value; 798 799 if (XmuCompareISOLatin1(params->name, "vertical") == 0) 800 orientation = VERTICAL; 801 else if (XmuCompareISOLatin1(params->name, "horizontal") == 0) 802 orientation = HORIZONTAL; 803 else 804 return (False); 805 806 if ((argval = XawFindArgVal(params, "dimension")) != NULL 807 && argval->value) 808 { 809 dimension = atoi(argval->value); 810 if (dimension <= 0) 811 return (False); 812 } 813 else 814 dimension = 50; 815 816 if ((argval = XawFindArgVal(params, "steps")) != NULL 817 && argval->value) 818 { 819 steps = atoi(argval->value); 820 if (steps <= 0) 821 return (False); 822 } 823 else 824 steps = dimension; 825 826 steps = XawMin(steps, dimension); 827 828 value = NULL; 829 if ((argval = XawFindArgVal(params, "start")) != NULL) 830 value = argval->value; 831 if (value && !XAllocNamedColor(DisplayOfScreen(screen), colormap, value, 832 &start, &color)) 833 return (False); 834 else if (!value) 835 { 836 start.pixel = WhitePixelOfScreen(screen); 837 XQueryColor(DisplayOfScreen(screen), colormap, &start); 838 } 839 value = NULL; 840 if ((argval = XawFindArgVal(params, "end")) != NULL) 841 value = argval->value; 842 if (value && !XAllocNamedColor(DisplayOfScreen(screen), colormap, value, 843 &end, &color)) 844 return (False); 845 else if (!value) 846 { 847 end.pixel = BlackPixelOfScreen(screen); 848 XQueryColor(DisplayOfScreen(screen), colormap, &end); 849 } 850 851 if ((pixmap = XCreatePixmap(DisplayOfScreen(screen), 852 RootWindowOfScreen(screen), 853 orientation == VERTICAL ? 1 : dimension, 854 orientation == VERTICAL ? dimension : 1, depth)) 855 == 0) 856 return (False); 857 858 ired = (double)(end.red - start.red) / (double)steps; 859 igreen = (double)(end.green - start.green) / (double)steps; 860 iblue = (double)(end.blue - start.blue) / (double)steps; 861 862 red = color.red = start.red; 863 green = color.green = start.green; 864 blue = color.blue = start.blue; 865 866 inc = (double)dimension / (double)steps; 867 868 gc = XCreateGC(DisplayOfScreen(screen), pixmap, 0, &values); 869 870 x = y = 0.0; 871 if (orientation == VERTICAL) 872 { 873 xend = 1; 874 yend = 0; 875 } 876 else 877 { 878 xend = 0; 879 yend = 1; 880 } 881 882 color.flags = DoRed | DoGreen | DoBlue; 883 884 XSetForeground(DisplayOfScreen(screen), gc, start.pixel); 885 for (i = 0.0; i < dimension; i += inc) 886 { 887 if ((int)color.red != (int)red || (int)color.green != (int)green 888 || (int)color.blue != (int)blue) 889 { 890 XFillRectangle(DisplayOfScreen(screen), pixmap, gc, (int)x, (int)y, 891 (unsigned int)xend, (unsigned int)yend); 892 color.red = (unsigned short)red; 893 color.green = (unsigned short)green; 894 color.blue = (unsigned short)blue; 895 if (!XAllocColor(DisplayOfScreen(screen), colormap, &color)) 896 { 897 XFreePixmap(DisplayOfScreen(screen), pixmap); 898 return (False); 899 } 900 XSetForeground(DisplayOfScreen(screen), gc, color.pixel); 901 if (orientation == VERTICAL) 902 y = yend; 903 else 904 x = xend; 905 } 906 red += ired; 907 green += igreen; 908 blue += iblue; 909 if (orientation == VERTICAL) 910 yend += inc; 911 else 912 xend += inc; 913 } 914 XFillRectangle(DisplayOfScreen(screen), pixmap, gc, (int)x, (int)y, 915 (unsigned int)xend, (unsigned int)yend); 916 917 *pixmap_return = pixmap; 918 *mask_return = None; 919 *width_return = orientation == VERTICAL ? 1 : dimension; 920 *height_return = orientation == VERTICAL ? dimension : 1; 921 922 XFreeGC(DisplayOfScreen(screen), gc); 923 924 return (True); 925} 926 927static Bool 928XPixmapLoader(XawParams *params, Screen *screen, Colormap colormap, int depth, 929 Pixmap *pixmap_return, Pixmap *mask_return, 930 Dimension *width_return, Dimension *height_return) 931{ 932 XpmAttributes xpm_attributes; 933 XawArgVal *argval; 934 unsigned int closeness = 4000; 935 static SubstitutionRec sub[] = { 936 {'H', NULL}, 937 {'N', NULL}, 938 {'T', "pixmaps"}, 939 {'P', PROJECT_ROOT}, 940 }; 941 char *filename; 942 943 if ((argval = XawFindArgVal(params, "closeness")) != NULL 944 && argval->value) 945 closeness = atoi(argval->value); 946 947 if (params->name[0] != '/' && params->name[0] != '.') 948 { 949 if (!sub[0].substitution) 950 sub[0].substitution = getenv("HOME"); 951 sub[1].substitution = params->name; 952 if (pixmap_path == NULL) 953 GetResourcePixmapPath(DisplayOfScreen(screen)); 954 filename = XtFindFile(pixmap_path, sub, XtNumber(sub), NULL); 955 if (!filename) 956 return (False); 957 } 958 else 959 filename = params->name; 960 961 xpm_attributes.colormap = colormap; 962 xpm_attributes.closeness = closeness; 963 xpm_attributes.valuemask = XpmSize | XpmColormap | XpmCloseness; 964 if (XpmReadFileToPixmap(DisplayOfScreen(screen), 965 RootWindowOfScreen(screen), filename, pixmap_return, 966 mask_return, &xpm_attributes) == XpmSuccess) 967 { 968 *width_return = xpm_attributes.width; 969 *height_return = xpm_attributes.height; 970 971 return (True); 972 } 973 974 return (False); 975} 976 977void 978XawReshapeWidget(Widget w, XawPixmap *pixmap) 979{ 980 if (!pixmap || pixmap->mask == None) 981 XShapeCombineMask(XtDisplay(w), XtWindow(w), ShapeBounding, 0, 0, 982 None, ShapeSet); 983 else 984 XShapeCombineMask(XtDisplay(w), XtWindow(w), ShapeBounding, 0, 0, 985 pixmap->mask, ShapeSet); 986} 987 988#endif /* OLDXAW */ 989