Pixmap.c revision 82d1c0e7
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 (Cardinal)(sizeof(XawArgVal*) * (size_t)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((char *)params->args[i]->name); 242 if (params->args[i]->value) 243 XtFree((char *)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((char *)loader_info[i]->type); 336 if (loader_info[i]->ext) 337 XtFree((char *)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 (Cardinal)(sizeof(XawPixmapLoaderInfo) * (size_t)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 (int)((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 (int)((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 *cache; 473 474 cache = _XawFindCache(xaw, screen, colormap, depth, FIND_ALL); 475 476 if (!cache) 477 { 478 XawCache *c_cache, *d_cache, *pcache; 479 XawCache *s_cache = _XawFindCache(xaw, 480 screen, colormap, depth, FIND_SCREEN); 481 if (!s_cache) 482 { 483 pcache = (XawCache *)XtMalloc(sizeof(XawCache)); 484 if (!xaw->num_elems) 485 { 486 xaw->num_elems = 1; 487 xaw->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); 488 } 489 else 490 { 491 ++xaw->num_elems; 492 xaw->elems = (XtPointer*) 493 XtRealloc((char *)xaw->elems, 494 (Cardinal)(sizeof(XtPointer) * (size_t)xaw->num_elems)); 495 } 496 pcache->value = (long)screen; 497 pcache->elems = NULL; 498 pcache->num_elems = 0; 499 xaw->elems[xaw->num_elems - 1] = (XtPointer)pcache; 500 s_cache = (XawCache *)xaw->elems[xaw->num_elems - 1]; 501 if (xaw->num_elems > 1) 502 qsort(xaw->elems, xaw->num_elems, sizeof(XtPointer), qcmp_long); 503 } 504 505 c_cache = _XawFindCache(xaw, 506 screen, colormap, depth, FIND_COLORMAP); 507 if (!c_cache) 508 { 509 pcache = (XawCache *)XtMalloc(sizeof(XawCache)); 510 if (!s_cache->num_elems) 511 { 512 s_cache->num_elems = 1; 513 s_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); 514 } 515 else 516 { 517 ++s_cache->num_elems; 518 s_cache->elems = (XtPointer*) 519 XtRealloc((char *)s_cache->elems, 520 (Cardinal)(sizeof(XtPointer) * s_cache->num_elems)); 521 } 522 pcache->value = (long)colormap; 523 pcache->elems = NULL; 524 pcache->num_elems = 0; 525 s_cache->elems[s_cache->num_elems - 1] = (XtPointer)pcache; 526 c_cache = (XawCache *)s_cache->elems[s_cache->num_elems - 1]; 527 if (s_cache->num_elems > 1) 528 qsort(s_cache->elems, s_cache->num_elems, 529 sizeof(XtPointer), qcmp_long); 530 } 531 532 d_cache = _XawFindCache(xaw, 533 screen, colormap, depth, FIND_DEPTH); 534 if (!d_cache) 535 { 536 pcache = (XawCache *)XtMalloc(sizeof(XawCache)); 537 if (!c_cache->num_elems) 538 { 539 c_cache->num_elems = 1; 540 c_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); 541 } 542 else 543 { 544 ++c_cache->num_elems; 545 c_cache->elems = (XtPointer*) 546 XtRealloc((char *)c_cache->elems, 547 (Cardinal)(sizeof(XtPointer) * c_cache->num_elems)); 548 } 549 pcache->value = (long)depth; 550 pcache->elems = NULL; 551 pcache->num_elems = 0; 552 c_cache->elems[c_cache->num_elems - 1] = (XtPointer)pcache; 553 d_cache = (XawCache *)c_cache->elems[c_cache->num_elems - 1]; 554 if (c_cache->num_elems > 1) 555 qsort(c_cache->elems, c_cache->num_elems, 556 sizeof(XtPointer), qcmp_long); 557 } 558 559 cache = d_cache; 560 } 561 562 return (cache); 563} 564 565static XawPixmap * 566_XawFindPixmap(String name, Screen *screen, Colormap colormap, int depth) 567{ 568 XawCache *cache; 569 XawPixmap **pixmap; 570 571 cache = _XawFindCache(&xaw_pixmaps, screen, colormap, depth, FIND_ALL); 572 573 if (!cache) 574 return (NULL); 575 576 /* Name */ 577 pixmap = (XawPixmap **)bsearch((void *)name, cache->elems, 578 cache->num_elems, sizeof(XtPointer), 579 bcmp_string); 580 if (!pixmap) 581 return (NULL); 582 583 return (*pixmap); 584} 585 586XawPixmap * 587XawPixmapFromXPixmap(Pixmap pixmap, 588 Screen *screen, Colormap colormap, int depth) 589{ 590 XawCache *cache; 591 XawPixmap **x_pixmap; 592 593 cache = _XawFindCache(&x_pixmaps, screen, colormap, depth, FIND_ALL); 594 595 if (!cache) 596 return (NULL); 597 598 /* Pixmap */ 599 x_pixmap = (XawPixmap **)bsearch((void *)pixmap, cache->elems, 600 cache->num_elems, sizeof(XtPointer), 601 bcmp_x_cache); 602 if (!x_pixmap) 603 return (NULL); 604 605 return (*x_pixmap); 606} 607 608static void 609_XawCachePixmap(XawPixmap *pixmap, 610 Screen *screen, Colormap colormap, int depth) 611{ 612 XawCache *xaw_cache, *x_cache; 613 614 xaw_cache = _XawGetCache(&xaw_pixmaps, screen, colormap, depth); 615 x_cache = _XawGetCache(&x_pixmaps, screen, colormap, depth); 616 617 if (!xaw_cache->num_elems) 618 { 619 xaw_cache->num_elems = 1; 620 xaw_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); 621 } 622 else 623 { 624 ++xaw_cache->num_elems; 625 xaw_cache->elems = (XtPointer*)XtRealloc((char *)xaw_cache->elems, 626 (Cardinal)(sizeof(XtPointer) * 627 xaw_cache->num_elems)); 628 } 629 630 xaw_cache->elems[xaw_cache->num_elems - 1] = (XtPointer)pixmap; 631 if (xaw_cache->num_elems > 1) 632 qsort(xaw_cache->elems, xaw_cache->num_elems, 633 sizeof(XtPointer), qcmp_string); 634 635 636 if (!x_cache->num_elems) 637 { 638 x_cache->num_elems = 1; 639 x_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer)); 640 } 641 else 642 { 643 ++x_cache->num_elems; 644 x_cache->elems = (XtPointer*)XtRealloc((char *)x_cache->elems, 645 (Cardinal)(sizeof(XtPointer) * 646 x_cache->num_elems)); 647 } 648 649 x_cache->elems[x_cache->num_elems - 1] = (XtPointer)pixmap; 650 if (x_cache->num_elems > 1) 651 qsort(x_cache->elems, x_cache->num_elems, sizeof(XtPointer), qcmp_x_cache); 652} 653 654#ifndef PROJECT_ROOT 655#define PROJECT_ROOT "/usr/X11R6" 656#endif 657 658static char *pixmap_path = NULL; 659 660static void 661GetResourcePixmapPath(Display *display) 662{ 663 XrmName xrm_name[2]; 664 XrmClass xrm_class[2]; 665 XrmRepresentation rep_type; 666 XrmValue value; 667 static char *default_path = 668 (char*)"%H/%T/%N:%P/include/X11/%T/%N:/usr/X11R6/include/X11/%T/%N:/usr/include/X11/%T/%N:%N"; 669 670 xrm_name[0] = XrmPermStringToQuark("pixmapFilePath"); 671 xrm_name[1] = NULLQUARK; 672 xrm_class[0] = XrmPermStringToQuark("PixmapFilePath"); 673 xrm_class[1] = NULLQUARK; 674 if (!XrmGetDatabase(display)) 675 (void) XGetDefault(display, "", ""); 676 if (XrmQGetResource(XrmGetDatabase(display), xrm_name, xrm_class, 677 &rep_type, &value) && 678 rep_type == XrmPermStringToQuark("String")) { 679 int length = 0; 680 char *tok, *buffer = XtNewString(value.addr); 681 682 for (tok = strtok(buffer, ":"); tok; tok = strtok(NULL, ":")) { 683 int toklen = (int)strlen(tok); 684 685 if (toklen) { 686 pixmap_path = XtRealloc(pixmap_path, (Cardinal)(length + toklen + 5)); 687 strcpy(pixmap_path + length, tok); 688 if (length) 689 pixmap_path[length++] = ':'; 690 sprintf(pixmap_path + length, "%s/%%N", tok); 691 length = (length + (int)strlen(tok) + 3); 692 } 693 } 694 XtFree(buffer); 695 pixmap_path = XtRealloc(pixmap_path, (Cardinal)((size_t)length + strlen(default_path) + 2)); 696 if (length) 697 pixmap_path[length++] = ':'; 698 strcpy(pixmap_path + length, default_path); 699 } 700 else 701 pixmap_path = default_path; 702} 703 704static const char * 705GetFileName(XawParams *params, Screen *screen) 706{ 707 static SubstitutionRec sub[] = { 708 {'H', NULL}, 709 {'N', NULL}, 710 {'T', "pixmaps"}, 711 {'P', PROJECT_ROOT}, 712 }; 713 if (params->name[0] != '/' && params->name[0] != '.') 714 { 715 if (!sub[0].substitution) 716 sub[0].substitution = getenv("HOME"); 717 sub[1].substitution = (_XtString)params->name; 718 if (pixmap_path == NULL) 719 GetResourcePixmapPath(DisplayOfScreen(screen)); 720 return XtFindFile(pixmap_path, sub, XtNumber(sub), NULL); 721 } 722 return params->name; 723} 724 725static Bool 726BitmapLoader(XawParams *params, Screen *screen, Colormap colormap, int depth, 727 Pixmap *pixmap_return, Pixmap *mask_return, 728 Dimension *width_return, Dimension *height_return) 729{ 730 Pixel fg, bg; 731 XColor color, exact; 732 unsigned int width, height; 733 unsigned char *data = NULL; 734 int hotX, hotY; 735 XawArgVal *argval; 736 Bool retval = False; 737 const char *filename; 738 739 fg = BlackPixelOfScreen(screen); 740 bg = WhitePixelOfScreen(screen); 741 742 if ((argval = XawFindArgVal(params, "foreground")) != NULL 743 && argval->value) 744 { 745 if (XAllocNamedColor(DisplayOfScreen(screen), colormap, argval->value, 746 &color, &exact)) 747 fg = color.pixel; 748 else 749 return (False); 750 } 751 if ((argval = XawFindArgVal(params, "background")) != NULL 752 && argval->value) 753 { 754 if (XAllocNamedColor(DisplayOfScreen(screen), colormap, argval->value, 755 &color, &exact)) 756 bg = color.pixel; 757 else 758 return (False); 759 } 760 761 filename = GetFileName(params, screen); 762 if (!filename) 763 return (FALSE); 764 765 if (XReadBitmapFileData(filename, &width, &height, &data, 766 &hotX, &hotY) == BitmapSuccess) 767 { 768 Pixmap pixmap = 769 XCreatePixmapFromBitmapData(DisplayOfScreen(screen), 770 RootWindowOfScreen(screen), 771 (char *)data, 772 width, height, fg, bg, (unsigned)depth); 773 if (data) 774 XFree(data); 775 *pixmap_return = pixmap; 776 *mask_return = None; 777 *width_return = (Dimension)width; 778 *height_return = (Dimension)height; 779 780 retval = True; 781 } 782 783 if (filename != params->name) 784 XtFree((char *)filename); 785 786 return (retval); 787} 788 789#define VERTICAL 1 790#define HORIZONTAL 2 791static Bool 792GradientLoader(XawParams *params, Screen *screen, Colormap colormap, int depth, 793 Pixmap *pixmap_return, Pixmap *mask_return, 794 Dimension *width_return, Dimension *height_return) 795{ 796 double ired, igreen, iblue, red, green, blue; 797 XColor start, end, color; 798 XGCValues values; 799 GC gc; 800 double i, inc, x, y, xend, yend; 801 Pixmap pixmap; 802 XawArgVal *argval; 803 int orientation, dimension, steps; 804 char *value; 805 806 if (XmuCompareISOLatin1(params->name, "vertical") == 0) 807 orientation = VERTICAL; 808 else if (XmuCompareISOLatin1(params->name, "horizontal") == 0) 809 orientation = HORIZONTAL; 810 else 811 return (False); 812 813 if ((argval = XawFindArgVal(params, "dimension")) != NULL 814 && argval->value) 815 { 816 dimension = atoi(argval->value); 817 if (dimension <= 0) 818 return (False); 819 } 820 else 821 dimension = 50; 822 823 if ((argval = XawFindArgVal(params, "steps")) != NULL 824 && argval->value) 825 { 826 steps = atoi(argval->value); 827 if (steps <= 0) 828 return (False); 829 } 830 else 831 steps = dimension; 832 833 steps = XawMin(steps, dimension); 834 835 value = NULL; 836 if ((argval = XawFindArgVal(params, "start")) != NULL) 837 value = (char*)argval->value; 838 if (value && !XAllocNamedColor(DisplayOfScreen(screen), colormap, value, 839 &start, &color)) 840 return (False); 841 else if (!value) 842 { 843 start.pixel = WhitePixelOfScreen(screen); 844 XQueryColor(DisplayOfScreen(screen), colormap, &start); 845 } 846 value = NULL; 847 if ((argval = XawFindArgVal(params, "end")) != NULL) 848 value = (char*)argval->value; 849 if (value && !XAllocNamedColor(DisplayOfScreen(screen), colormap, value, 850 &end, &color)) 851 return (False); 852 else if (!value) 853 { 854 end.pixel = BlackPixelOfScreen(screen); 855 XQueryColor(DisplayOfScreen(screen), colormap, &end); 856 } 857 858 if ((pixmap = XCreatePixmap(DisplayOfScreen(screen), 859 RootWindowOfScreen(screen), 860 (unsigned)(orientation == VERTICAL ? 1 : dimension), 861 (unsigned)(orientation == VERTICAL ? dimension : 1), (unsigned)depth)) 862 == 0) 863 return (False); 864 865 ired = (double)(end.red - start.red) / (double)steps; 866 igreen = (double)(end.green - start.green) / (double)steps; 867 iblue = (double)(end.blue - start.blue) / (double)steps; 868 869 red = color.red = start.red; 870 green = color.green = start.green; 871 blue = color.blue = start.blue; 872 873 inc = (double)dimension / (double)steps; 874 875 gc = XCreateGC(DisplayOfScreen(screen), pixmap, 0, &values); 876 877 x = y = 0.0; 878 if (orientation == VERTICAL) 879 { 880 xend = 1; 881 yend = 0; 882 } 883 else 884 { 885 xend = 0; 886 yend = 1; 887 } 888 889 color.flags = DoRed | DoGreen | DoBlue; 890 891 XSetForeground(DisplayOfScreen(screen), gc, start.pixel); 892 for (i = 0.0; i < dimension; i += inc) 893 { 894 if ((int)color.red != (int)red || (int)color.green != (int)green 895 || (int)color.blue != (int)blue) 896 { 897 XFillRectangle(DisplayOfScreen(screen), pixmap, gc, (int)x, (int)y, 898 (unsigned int)xend, (unsigned int)yend); 899 color.red = (unsigned short)red; 900 color.green = (unsigned short)green; 901 color.blue = (unsigned short)blue; 902 if (!XAllocColor(DisplayOfScreen(screen), colormap, &color)) 903 { 904 XFreePixmap(DisplayOfScreen(screen), pixmap); 905 return (False); 906 } 907 XSetForeground(DisplayOfScreen(screen), gc, color.pixel); 908 if (orientation == VERTICAL) 909 y = yend; 910 else 911 x = xend; 912 } 913 red += ired; 914 green += igreen; 915 blue += iblue; 916 if (orientation == VERTICAL) 917 yend += inc; 918 else 919 xend += inc; 920 } 921 XFillRectangle(DisplayOfScreen(screen), pixmap, gc, (int)x, (int)y, 922 (unsigned int)xend, (unsigned int)yend); 923 924 *pixmap_return = pixmap; 925 *mask_return = None; 926 *width_return = (Dimension)(orientation == VERTICAL ? 1 : dimension); 927 *height_return = (Dimension)(orientation == VERTICAL ? dimension : 1); 928 929 XFreeGC(DisplayOfScreen(screen), gc); 930 931 return (True); 932} 933 934static Bool 935XPixmapLoader(XawParams *params, Screen *screen, Colormap colormap, int depth _X_UNUSED, 936 Pixmap *pixmap_return, Pixmap *mask_return, 937 Dimension *width_return, Dimension *height_return) 938{ 939 XpmAttributes xpm_attributes; 940 XawArgVal *argval; 941 unsigned int closeness = 4000; 942 Bool retval = False; 943 const char *filename; 944 945 if ((argval = XawFindArgVal(params, "closeness")) != NULL 946 && argval->value) 947 closeness = (unsigned)atoi(argval->value); 948 949 filename = GetFileName(params, screen); 950 if (!filename) 951 return (FALSE); 952 953 xpm_attributes.colormap = colormap; 954 xpm_attributes.closeness = closeness; 955 xpm_attributes.valuemask = XpmSize | XpmColormap | XpmCloseness; 956 if (XpmReadFileToPixmap(DisplayOfScreen(screen), 957 RootWindowOfScreen(screen), filename, pixmap_return, 958 mask_return, &xpm_attributes) == XpmSuccess) 959 { 960 *width_return = (Dimension)xpm_attributes.width; 961 *height_return = (Dimension)xpm_attributes.height; 962 963 retval = True; 964 } 965 966 if (filename != params->name) 967 XtFree((char *)filename); 968 return (retval); 969} 970 971void 972XawReshapeWidget(Widget w, XawPixmap *pixmap) 973{ 974 if (!pixmap || pixmap->mask == None) 975 XShapeCombineMask(XtDisplay(w), XtWindow(w), ShapeBounding, 0, 0, 976 None, ShapeSet); 977 else 978 XShapeCombineMask(XtDisplay(w), XtWindow(w), ShapeBounding, 0, 0, 979 pixmap->mask, ShapeSet); 980} 981 982#endif /* OLDXAW */ 983