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