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