1/* 2 * Copyright (C) 1989-95 GROUPE BULL 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to 6 * deal in the Software without restriction, including without limitation the 7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 * sell copies of the Software, and to permit persons to whom the Software is 9 * 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 * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 * 21 * Except as contained in this notice, the name of GROUPE BULL shall not be 22 * used in advertising or otherwise to promote the sale, use or other dealings 23 * in this Software without prior written authorization from GROUPE BULL. 24 */ 25 26/*****************************************************************************\ 27* sxpm.c: * 28* * 29* Show XPM File program * 30* * 31* Developed by Arnaud Le Hors * 32\*****************************************************************************/ 33 34#ifdef HAVE_CONFIG_H 35#include <config.h> 36#endif 37 38#include <stdio.h> 39#include <stdlib.h> 40#include <X11/StringDefs.h> 41#include <X11/Intrinsic.h> 42#include <X11/IntrinsicP.h> 43#include <X11/Shell.h> 44 45#ifdef VMS 46#include <X11/shape.h> 47#else 48#include <X11/extensions/shape.h> 49#endif 50 51#include <X11/xpm.h> 52 53#ifdef USE_GETTEXT 54#include <locale.h> 55#include <libintl.h> 56#else 57#define gettext(a) (a) 58#endif 59 60/* XPM */ 61/* plaid pixmap */ 62static char *plaid[] = { 63 /* width height ncolors chars_per_pixel */ 64 "22 22 4 2 XPMEXT", 65 /* colors */ 66 " c red m white s light_color", 67 "Y c green m black s lines_in_mix", 68 "+ c yellow m white s lines_in_dark", 69 "x m black s dark_color", 70 /* pixels */ 71 "x x x x x x x x x x x x + x x x x x ", 72 " x x x x x x x x x x x x x x x x ", 73 "x x x x x x x x x x x x + x x x x x ", 74 " x x x x x x x x x x x x x x x x ", 75 "x x x x x x x x x x x x + x x x x x ", 76 "Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ", 77 "x x x x x x x x x x x x + x x x x x ", 78 " x x x x x x x x x x x x x x x x ", 79 "x x x x x x x x x x x x + x x x x x ", 80 " x x x x x x x x x x x x x x x x ", 81 "x x x x x x x x x x x x + x x x x x ", 82 " x x x x Y x x x ", 83 " x x x Y x x ", 84 " x x x x Y x x x ", 85 " x x x Y x x ", 86 " x x x x Y x x x ", 87 "x x x x x x x x x x x x x x x x x x x x x x ", 88 " x x x x Y x x x ", 89 " x x x Y x x ", 90 " x x x x Y x x x ", 91 " x x x Y x x ", 92 " x x x x Y x x x ", 93 "bullshit", 94 "XPMEXT ext1 data1", 95 "XPMEXT ext2", 96 "data2_1", 97 "data2_2", 98 "XPMEXT", 99 "foo", 100 "", 101 "XPMEXT ext3", 102 "data3", 103 "XPMENDEXT" 104}; 105 106#define win XtWindow(topw) 107#define dpy XtDisplay(topw) 108#define root XRootWindowOfScreen(XtScreen(topw)) 109#define xrdb XtDatabase(dpy) 110static Colormap colormap; 111 112void Usage(void) _X_NORETURN; 113void ErrorMessage(int ErrorStatus, const char *tag); 114void Punt(int i) _X_NORETURN; 115void VersionInfo(void); 116void kinput(Widget widget, char *tag, XEvent *xe, Boolean *b); 117void GetNumbers(int num, int *format_return, 118 int *libmajor_return, 119 char *libminor_return); 120 121#define IWIDTH 50 122#define IHEIGHT 50 123 124typedef struct _XpmIcon { 125 Pixmap pixmap; 126 Pixmap mask; 127 XpmAttributes attributes; 128} XpmIcon; 129 130static char **command; 131static Widget topw; 132static XpmIcon view, icon; 133static XrmOptionDescRec options[] = { 134 {"-hints", ".hints", XrmoptionNoArg, (XtPointer) "True"}, 135 {"-icon", ".icon", XrmoptionSepArg, (XtPointer) NULL}, 136}; 137 138int 139main( 140 int argc, 141 char **argv) 142{ 143 int ErrorStatus; 144 unsigned int verbose = 0; /* performs verbose output */ 145 unsigned int stdinf = 1; /* read from stdin */ 146 unsigned int stdoutf = 0; /* write to stdout */ 147 unsigned int nod = 0; /* no display */ 148 unsigned int nom = 0; /* no mask display */ 149 unsigned int incResize = 0; 150 unsigned int resize = 0; 151 unsigned int w_rtn; 152 unsigned int h_rtn; 153 char *input = NULL; 154 char *output = NULL; 155 char *iconFile = NULL; 156 unsigned int numsymbols = 0; 157 XpmColorSymbol symbols[10]; 158 char *stype; 159 XrmValue val; 160 unsigned long valuemask = 0; 161 int n; 162 Arg args[4]; 163 164#ifdef Debug 165 char **data; 166 char *buffer; 167#endif 168 169#ifdef USE_GETTEXT 170 XtSetLanguageProc(NULL,NULL,NULL); 171 bindtextdomain("sxpm",LOCALEDIR); 172 textdomain("sxpm"); 173#endif 174 175 topw = XtInitialize(argv[0], "Sxpm", 176 options, XtNumber(options), &argc, argv); 177 178 if (!topw) { 179 /* L10N_Comments : Error if no $DISPLAY or $DISPLAY can't be opened. 180 Not normally reached as Xt exits before we get here. */ 181 fprintf(stderr, gettext("Sxpm Error... [ Undefined DISPLAY ]\n")); 182 exit(1); 183 } 184 colormap = XDefaultColormapOfScreen(XtScreen(topw)); 185 186 /* 187 * geometry management 188 */ 189 190 if (XrmGetResource(xrdb, NULL, "sxpm.geometry", &stype, &val) 191 || XrmGetResource(xrdb, NULL, "Sxpm.geometry", &stype, &val)) { 192 193 int flags; 194 int x_rtn; 195 int y_rtn; 196 char *geo = NULL; 197 198 geo = (char *) val.addr; 199 flags = XParseGeometry(geo, &x_rtn, &y_rtn, 200 (unsigned int *) &w_rtn, 201 (unsigned int *) &h_rtn); 202 203 if (!((WidthValue & flags) && (HeightValue & flags))) 204 resize = 1; 205 206 } else 207 resize = 1; 208 209 n = 0; 210 if (resize) { 211 w_rtn = 0; 212 h_rtn = 0; 213 XtSetArg(args[n], XtNwidth, 1); 214 n++; 215 XtSetArg(args[n], XtNheight, 1); 216 n++; 217 } 218 XtSetArg(args[n], XtNmappedWhenManaged, False); 219 n++; 220 XtSetArg(args[n], XtNinput, True); 221 n++; 222 XtSetValues(topw, args, n); 223 224 if ((XrmGetResource(xrdb, "sxpm.hints", "", &stype, &val) 225 || XrmGetResource(xrdb, "Sxpm.hints", "", &stype, &val)) 226 && !strcmp((char *) val.addr, "True")) { 227 /* gotcha */ 228 incResize = 1; 229 resize = 1; 230 } 231 232 /* 233 * icon management 234 */ 235 236 if (XrmGetResource(xrdb, "sxpm.icon", "", &stype, &val) 237 || XrmGetResource(xrdb, "Sxpm.icon", "", &stype, &val)) { 238 iconFile = (char *) val.addr; 239 } 240 if (iconFile) { 241 242 XColor color, junk; 243 Pixel bpix; 244 Window iconW; 245 246 if (XAllocNamedColor(dpy, colormap, "black", &color, &junk)) 247 bpix = color.pixel; 248 else 249 bpix = XBlackPixelOfScreen(XtScreen(topw)); 250 251 iconW = XCreateSimpleWindow(dpy, root, 0, 0, 252 IWIDTH, IHEIGHT, 1, bpix, bpix); 253 254 icon.attributes.valuemask = XpmReturnAllocPixels; 255 ErrorStatus = XpmReadFileToPixmap(dpy, root, iconFile, &icon.pixmap, 256 &icon.mask, &icon.attributes); 257 ErrorMessage(ErrorStatus, "Icon"); 258 259 XSetWindowBackgroundPixmap(dpy, iconW, icon.pixmap); 260 261 n = 0; 262 XtSetArg(args[n], XtNbackground, bpix); 263 n++; 264 XtSetArg(args[n], XtNiconWindow, iconW); 265 n++; 266 XtSetValues(topw, args, n); 267 } 268 269 /* 270 * arguments parsing 271 */ 272 273 command = argv; 274 for (n = 1; n < argc; n++) { 275 if (strcmp(argv[n], "-plaid") == 0) { 276 stdinf = 0; 277 continue; 278 } 279 if (argv[n][0] != '-') { 280 stdinf = 0; 281 input = argv[n]; 282 continue; 283 } 284 if ((strlen(argv[n]) == 1) && (argv[n][0] == '-')) 285 /* stdin */ 286 continue; 287 if (strcmp(argv[n], "-o") == 0) { 288 if (n < argc - 1) { 289 if ((strlen(argv[n + 1]) == 1) && (argv[n + 1][0] == '-')) 290 stdoutf = 1; 291 else 292 output = argv[n + 1]; 293 n++; 294 continue; 295 } else 296 Usage(); 297 } 298 if (strcmp(argv[n], "-nod") == 0) { 299 nod = 1; 300 continue; 301 } 302 if (strcmp(argv[n], "-nom") == 0) { 303 nom = 1; 304 continue; 305 } 306 if (strcmp(argv[n], "-sc") == 0) { 307 if (n < argc - 2) { 308 valuemask |= XpmColorSymbols; 309 symbols[numsymbols].name = argv[++n]; 310 symbols[numsymbols++].value = argv[++n]; 311 continue; 312 } else 313 Usage(); 314 } 315 if (strcmp(argv[n], "-sp") == 0) { 316 if (n < argc - 2) { 317 valuemask |= XpmColorSymbols; 318 symbols[numsymbols].name = argv[++n]; 319 symbols[numsymbols].value = NULL; 320 symbols[numsymbols++].pixel = atol(argv[++n]); 321 continue; 322 } 323 } 324 if (strcmp(argv[n], "-cp") == 0) { 325 if (n < argc - 2) { 326 valuemask |= XpmColorSymbols; 327 symbols[numsymbols].name = NULL; 328 symbols[numsymbols].value = argv[++n]; 329 symbols[numsymbols++].pixel = atol(argv[++n]); 330 continue; 331 } 332 } 333 if (strcmp(argv[n], "-mono") == 0) { 334 valuemask |= XpmColorKey; 335 view.attributes.color_key = XPM_MONO; 336 continue; 337 } 338 if (strcmp(argv[n], "-gray4") == 0 || strcmp(argv[n], "-grey4") == 0) { 339 valuemask |= XpmColorKey; 340 view.attributes.color_key = XPM_GRAY4; 341 continue; 342 } 343 if (strcmp(argv[n], "-gray") == 0 || strcmp(argv[n], "-grey") == 0) { 344 valuemask |= XpmColorKey; 345 view.attributes.color_key = XPM_GRAY; 346 continue; 347 } 348 if (strcmp(argv[n], "-color") == 0) { 349 valuemask |= XpmColorKey; 350 view.attributes.color_key = XPM_COLOR; 351 continue; 352 } 353 if (strncmp(argv[n], "-closecolors", 6) == 0) { 354 valuemask |= XpmCloseness; 355 view.attributes.closeness = 40000; 356 continue; 357 } 358 if (strcmp(argv[n], "-rgb") == 0) { 359 if (n < argc - 1) { 360 valuemask |= XpmRgbFilename; 361 view.attributes.rgb_fname = argv[++n]; 362 continue; 363 } else 364 Usage(); 365 366 } 367 if (strncmp(argv[n], "-version", 4) == 0) { 368 VersionInfo(); 369 exit(0); 370 } 371 if (strcmp(argv[n], "-v") == 0) { 372 verbose = 1; 373 continue; 374 } 375 if (strcmp(argv[n], "-pcmap") == 0) { 376 valuemask |= XpmColormap; 377 continue; 378 } 379 Usage(); 380 } 381 382 XtRealizeWidget(topw); 383 if (valuemask & XpmColormap) { 384 colormap = XCreateColormap(dpy, win, 385 DefaultVisual(dpy, DefaultScreen(dpy)), 386 AllocNone); 387 view.attributes.colormap = colormap; 388 XSetWindowColormap(dpy, win, colormap); 389 } 390 view.attributes.colorsymbols = symbols; 391 view.attributes.numsymbols = numsymbols; 392 view.attributes.valuemask = valuemask; 393 394#ifdef Debug 395 /* this is just to test the XpmCreateDataFromPixmap function */ 396 397 view.attributes.valuemask |= XpmReturnAllocPixels; 398 view.attributes.valuemask |= XpmReturnExtensions; 399 ErrorStatus = XpmCreatePixmapFromData(dpy, win, plaid, 400 &view.pixmap, &view.mask, 401 &view.attributes); 402 ErrorMessage(ErrorStatus, "Plaid"); 403 404 ErrorStatus = XpmCreateDataFromPixmap(dpy, &data, view.pixmap, view.mask, 405 &view.attributes); 406 ErrorMessage(ErrorStatus, "Data"); 407 if (verbose && view.attributes.nextensions) { 408 unsigned int i, j; 409 410 for (i = 0; i < view.attributes.nextensions; i++) { 411 fprintf(stderr, "Xpm extension : %s\n", 412 view.attributes.extensions[i].name); 413 for (j = 0; j < view.attributes.extensions[i].nlines; j++) 414 fprintf(stderr, "\t\t%s\n", 415 view.attributes.extensions[i].lines[j]); 416 } 417 } 418 XFreePixmap(dpy, view.pixmap); 419 if (view.mask) 420 XFreePixmap(dpy, view.mask); 421 422 XFreeColors(dpy, colormap, 423 view.attributes.alloc_pixels, 424 view.attributes.nalloc_pixels, 0); 425 426 XpmFreeAttributes(&view.attributes); 427 view.attributes.valuemask = valuemask; 428#endif 429 430 if (input || stdinf) { 431 view.attributes.valuemask |= XpmReturnInfos; 432 view.attributes.valuemask |= XpmReturnAllocPixels; 433 view.attributes.valuemask |= XpmReturnExtensions; 434 435#ifdef Debug 436 XpmFree(data); 437 438 /* 439 * this is just to test the XpmCreatePixmapFromBuffer and 440 * XpmCreateBufferFromPixmap functions 441 */ 442 ErrorStatus = XpmReadFileToBuffer(input, &buffer); 443 ErrorMessage(ErrorStatus, "CreateBufferFromFile"); 444 445 ErrorStatus = XpmCreatePixmapFromBuffer(dpy, win, buffer, 446 &view.pixmap, &view.mask, 447 &view.attributes); 448 ErrorMessage(ErrorStatus, "CreatePixmapFromBuffer"); 449 XpmFree(buffer); 450 ErrorStatus = XpmCreateBufferFromPixmap(dpy, &buffer, 451 view.pixmap, view.mask, 452 &view.attributes); 453 ErrorMessage(ErrorStatus, "CreateBufferFromPixmap"); 454 ErrorStatus = XpmWriteFileFromBuffer("buffer_output", buffer); 455 ErrorMessage(ErrorStatus, "WriteFileFromBuffer"); 456 XpmFree(buffer); 457 if (view.pixmap) { 458 XFreePixmap(dpy, view.pixmap); 459 if (view.mask) 460 XFreePixmap(dpy, view.mask); 461 462 XFreeColors(dpy, colormap, view.attributes.alloc_pixels, 463 view.attributes.nalloc_pixels, 0); 464 465 XpmFreeAttributes(&view.attributes); 466 } 467 ErrorStatus = XpmReadFileToData(input, &data); 468 ErrorMessage(ErrorStatus, "ReadFileToData"); 469 ErrorStatus = XpmCreatePixmapFromData(dpy, win, data, 470 &view.pixmap, &view.mask, 471 &view.attributes); 472 ErrorMessage(ErrorStatus, "CreatePixmapFromData"); 473 ErrorStatus = XpmWriteFileFromData("sxpmout.xpm", data); 474 ErrorMessage(ErrorStatus, "WriteFileFromData"); 475 XpmFree(data); 476 XpmFreeAttributes(&view.attributes); 477#endif 478 ErrorStatus = XpmReadFileToPixmap(dpy, win, input, 479 &view.pixmap, &view.mask, 480 &view.attributes); 481 ErrorMessage(ErrorStatus, "Read"); 482 if (verbose && view.attributes.nextensions) { 483 unsigned int i, j; 484 485 for (i = 0; i < view.attributes.nextensions; i++) { 486 /* L10N_Comments : Output when -v & file has extensions 487 %s is replaced by extension name */ 488 fprintf(stderr, gettext("Xpm extension : %s\n"), 489 view.attributes.extensions[i].name); 490 for (j = 0; j < view.attributes.extensions[i].nlines; j++) 491 fprintf(stderr, "\t\t%s\n", 492 view.attributes.extensions[i].lines[j]); 493 } 494 } 495 } else { 496#ifdef Debug 497 ErrorStatus = XpmCreatePixmapFromData(dpy, win, data, 498 &view.pixmap, &view.mask, 499 &view.attributes); 500 XpmFree(data); 501#else 502 ErrorStatus = XpmCreatePixmapFromData(dpy, win, plaid, 503 &view.pixmap, &view.mask, 504 &view.attributes); 505#endif 506 ErrorMessage(ErrorStatus, "Plaid"); 507 } 508 if (output || stdoutf) { 509 ErrorStatus = XpmWriteFileFromPixmap(dpy, output, view.pixmap, 510 view.mask, &view.attributes); 511 ErrorMessage(ErrorStatus, "Write"); 512 } 513 if (!nod) { 514 515 /* 516 * manage display if requested 517 */ 518 519 XSizeHints size_hints; 520 char *xString = NULL; 521 522 if (w_rtn && h_rtn 523 && ((w_rtn < view.attributes.width) 524 || h_rtn < view.attributes.height)) { 525 resize = 1; 526 } 527 if (resize) { 528 XtResizeWidget(topw, 529 view.attributes.width, view.attributes.height, 1); 530 } 531 if (incResize) { 532 size_hints.flags = USSize | PMinSize | PResizeInc; 533 size_hints.height = view.attributes.height; 534 size_hints.width = view.attributes.width; 535 size_hints.height_inc = view.attributes.height; 536 size_hints.width_inc = view.attributes.width; 537 } else 538 size_hints.flags = PMinSize; 539 540 size_hints.min_height = view.attributes.height; 541 size_hints.min_width = view.attributes.width; 542 XSetWMNormalHints(dpy, win, &size_hints); 543 544 if (input) { 545 xString = (char *) XtMalloc((sizeof(char) * strlen(input)) + 20); 546 sprintf(xString, "Sxpm: %s", input); 547 XStoreName(dpy, win, xString); 548 XSetIconName(dpy, win, xString); 549 } else if (stdinf) { 550 XStoreName(dpy, win, "Sxpm: stdin"); 551 XSetIconName(dpy, win, "Sxpm: stdin"); 552 } else { 553 XStoreName(dpy, win, "Sxpm"); 554 XSetIconName(dpy, win, "Sxpm"); 555 } 556 557 XtAddEventHandler(topw, KeyPressMask, False, 558 (XtEventHandler) kinput, NULL); 559 XSetWindowBackgroundPixmap(dpy, win, view.pixmap); 560 561 if (view.mask && !nom) 562 XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, 563 view.mask, ShapeSet); 564 565 XClearWindow(dpy, win); 566 XtMapWidget(topw); 567 if (xString) 568 XtFree(xString); 569 XtMainLoop(); 570 } 571 Punt(0); 572} 573 574void 575Usage(void) 576{ 577 /* L10N_Comments : Usage message (sxpm -h) in two parts. 578 In the first part %s is replaced by the command name. */ 579 fprintf(stderr, gettext("\nUsage: %s [options...]\n"), command[0]); 580 fprintf(stderr, gettext("Where options are:\n\ 581\n\ 582[-d host:display] Display to connect to.\n\ 583[-g geom] Geometry of window.\n\ 584[-hints] Set ResizeInc for window.\n\ 585[-icon filename] Set pixmap for iconWindow.\n\ 586[-plaid] Read the included plaid pixmap.\n\ 587[filename] Read from file 'filename', and from standard\n\ 588 input if 'filename' is '-'.\n\ 589[-o filename] Write to file 'filename', and to standard\n\ 590 output if 'filename' is '-'.\n\ 591[-pcmap] Use a private colormap.\n\ 592[-closecolors] Try to use `close' colors.\n\ 593[-nod] Don't display in window.\n\ 594[-nom] Don't use clip mask if any.\n\ 595[-mono] Use the colors specified for a monochrome visual.\n\ 596[-grey4] Use the colors specified for a 4 greyscale visual.\n\ 597[-grey] Use the colors specified for a greyscale visual.\n\ 598[-color] Use the colors specified for a color visual.\n\ 599[-sc symbol color] Override color defaults.\n\ 600[-sp symbol pixel] Override color defaults.\n\ 601[-cp color pixel] Override color defaults.\n\ 602[-rgb filename] Search color names in the rgb text file 'filename'.\n\ 603[-v] Verbose - print out extensions.\n\ 604[-version] Print out program's version number\n\ 605 and library's version number if different.\n\ 606if no input is specified sxpm reads from standard input.\n\ 607\n")); 608 exit(0); 609} 610 611 612void 613ErrorMessage( 614 int ErrorStatus, 615 const char *tag) 616{ 617 char *error = NULL; 618 char *warning = NULL; 619 620 switch (ErrorStatus) { 621 case XpmSuccess: 622 return; 623 case XpmColorError: 624/* L10N_Comments : The following set of messages are classified as 625 either errors or warnings. Based on the class of message, different 626 wrappers are selected at the end to state the message source & class. 627 628 L10N_Comments : WARNING produced when filename can be read, but 629 contains an invalid color specification (need to create test case)*/ 630 warning = gettext("Could not parse or alloc requested color"); 631 break; 632 case XpmOpenFailed: 633 /* L10N_Comments : ERROR produced when filename does not exist 634 or insufficient permissions to open (i.e. sxpm /no/such/file ) */ 635 error = gettext("Cannot open file"); 636 break; 637 case XpmFileInvalid: 638 /* L10N_Comments : ERROR produced when filename can be read, but 639 is not an XPM file (i.e. sxpm /dev/null ) */ 640 error = gettext("Invalid XPM file"); 641 break; 642 case XpmNoMemory: 643 /* L10N_Comments : ERROR produced when filename can be read, but 644 is too big for memory 645 (i.e. limit datasize 32 ; sxpm /usr/dt/backdrops/Crochet.pm ) */ 646 error = gettext("Not enough memory"); 647 break; 648 case XpmColorFailed: 649 /* L10N_Comments : ERROR produced when filename can be read, but 650 contains an invalid color specification (need to create test case)*/ 651 error = gettext("Failed to parse or alloc some color"); 652 break; 653 } 654 655 if (warning) 656 /* L10N_Comments : Wrapper around above WARNING messages. 657 First %s is the tag for the operation that produced the warning. 658 Second %s is the message selected from the above set. */ 659 fprintf(stderr, gettext("%s Xpm Warning: %s.\n"), tag, warning); 660 661 if (error) { 662 /* L10N_Comments : Wrapper around above ERROR messages. 663 First %s is the tag for the operation that produced the error. 664 Second %s is the message selected from the above set */ 665 fprintf(stderr, gettext("%s Xpm Error: %s.\n"), tag, error); 666 Punt(1); 667 } 668} 669 670void 671Punt(int i) 672{ 673 if (icon.pixmap) { 674 XFreePixmap(dpy, icon.pixmap); 675 if (icon.mask) 676 XFreePixmap(dpy, icon.mask); 677 678 XFreeColors(dpy, colormap, 679 icon.attributes.alloc_pixels, 680 icon.attributes.nalloc_pixels, 0); 681 682 XpmFreeAttributes(&icon.attributes); 683 } 684 if (view.pixmap) { 685 XFreePixmap(dpy, view.pixmap); 686 if (view.mask) 687 XFreePixmap(dpy, view.mask); 688 689 XFreeColors(dpy, colormap, 690 view.attributes.alloc_pixels, 691 view.attributes.nalloc_pixels, 0); 692 693 XpmFreeAttributes(&view.attributes); 694 } 695 exit(i); 696} 697 698void 699kinput( 700 Widget widget, 701 char *tag, 702 XEvent *xe, 703 Boolean *b) 704{ 705 char c = '\0'; 706 707 XLookupString(&(xe->xkey), &c, 1, NULL, NULL); 708 if (c == 'q' || c == 'Q') 709 Punt(0); 710} 711 712/* 713 * small function to extract various version numbers from the given global 714 * number (following the rule described in xpm.h). 715 */ 716void 717GetNumbers( 718 int num, 719 int *format_return, 720 int *libmajor_return, 721 char *libminor_return) 722{ 723 *format_return = num / 10000; 724 *libmajor_return = (num % 10000) / 100; 725 *libminor_return = 'a' + (num % 10000) % 100 - 1; 726} 727 728void 729VersionInfo(void) 730{ 731 int format, libmajor; 732 char libminor; 733 734 GetNumbers(XpmIncludeVersion, &format, &libmajor, &libminor); 735 /* L10N_Comments : sxpm -version output */ 736 fprintf(stderr, gettext("sxpm version: %d.%d%c\n"), 737 format, libmajor, libminor); 738 /* L10N_Comments : 739 * if we are linked to an XPM library different from the one we've been 740 * compiled with, print its own number too when sxpm -version is called. 741 */ 742 if (XpmIncludeVersion != XpmLibraryVersion()) { 743 GetNumbers(XpmLibraryVersion(), &format, &libmajor, &libminor); 744 fprintf(stderr, gettext("using the XPM library version: %d.%d%c\n"), 745 format, libmajor, libminor); 746 } 747} 748