/sxpm/sxpm.c
C | 750 lines | 583 code | 75 blank | 92 comment | 109 complexity | 399a8d29bc2d05aba001b0ec83cf7897 MD5 | raw file
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); 113void ErrorMessage(int ErrorStatus, const char *tag); 114void Punt(int i); 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 /* Muffle gcc */ 574 return 0; 575} 576 577void 578Usage(void) 579{ 580 /* L10N_Comments : Usage message (sxpm -h) in two parts. 581 In the first part %s is replaced by the command name. */ 582 fprintf(stderr, gettext("\nUsage: %s [options...]\n"), command[0]); 583 fprintf(stderr, gettext("Where options are:\n\ 584\n\ 585[-d host:display] Display to connect to.\n\ 586[-g geom] Geometry of window.\n\ 587[-hints] Set ResizeInc for window.\n\ 588[-icon filename] Set pixmap for iconWindow.\n\ 589[-plaid] Read the included plaid pixmap.\n\ 590[filename] Read from file 'filename', and from standard\n\ 591 input if 'filename' is '-'.\n\ 592[-o filename] Write to file 'filename', and to standard\n\ 593 output if 'filename' is '-'.\n\ 594[-pcmap] Use a private colormap.\n\ 595[-closecolors] Try to use `close' colors.\n\ 596[-nod] Don't display in window.\n\ 597[-nom] Don't use clip mask if any.\n\ 598[-mono] Use the colors specified for a monochrome visual.\n\ 599[-grey4] Use the colors specified for a 4 greyscale visual.\n\ 600[-grey] Use the colors specified for a greyscale visual.\n\ 601[-color] Use the colors specified for a color visual.\n\ 602[-sc symbol color] Override color defaults.\n\ 603[-sp symbol pixel] Override color defaults.\n\ 604[-cp color pixel] Override color defaults.\n\ 605[-rgb filename] Search color names in the rgb text file 'filename'.\n\ 606[-v] Verbose - print out extensions.\n\ 607[-version] Print out program's version number\n\ 608 and library's version number if different.\n\ 609if no input is specified sxpm reads from standard input.\n\ 610\n")); 611 exit(0); 612} 613 614 615void 616ErrorMessage( 617 int ErrorStatus, 618 const char *tag) 619{ 620 char *error = NULL; 621 char *warning = NULL; 622 623 switch (ErrorStatus) { 624 case XpmSuccess: 625 return; 626 case XpmColorError: 627/* L10N_Comments : The following set of messages are classified as 628 either errors or warnings. Based on the class of message, different 629 wrappers are selected at the end to state the message source & class. 630 631 L10N_Comments : WARNING produced when filename can be read, but 632 contains an invalid color specification (need to create test case)*/ 633 warning = gettext("Could not parse or alloc requested color"); 634 break; 635 case XpmOpenFailed: 636 /* L10N_Comments : ERROR produced when filename does not exist 637 or insufficient permissions to open (i.e. sxpm /no/such/file ) */ 638 error = gettext("Cannot open file"); 639 break; 640 case XpmFileInvalid: 641 /* L10N_Comments : ERROR produced when filename can be read, but 642 is not an XPM file (i.e. sxpm /dev/null ) */ 643 error = gettext("Invalid XPM file"); 644 break; 645 case XpmNoMemory: 646 /* L10N_Comments : ERROR produced when filename can be read, but 647 is too big for memory 648 (i.e. limit datasize 32 ; sxpm /usr/dt/backdrops/Crochet.pm ) */ 649 error = gettext("Not enough memory"); 650 break; 651 case XpmColorFailed: 652 /* L10N_Comments : ERROR produced when filename can be read, but 653 contains an invalid color specification (need to create test case)*/ 654 error = gettext("Failed to parse or alloc some color"); 655 break; 656 } 657 658 if (warning) 659 /* L10N_Comments : Wrapper around above WARNING messages. 660 First %s is the tag for the operation that produced the warning. 661 Second %s is the message selected from the above set. */ 662 fprintf(stderr, gettext("%s Xpm Warning: %s.\n"), tag, warning); 663 664 if (error) { 665 /* L10N_Comments : Wrapper around above ERROR messages. 666 First %s is the tag for the operation that produced the error. 667 Second %s is the message selected from the above set */ 668 fprintf(stderr, gettext("%s Xpm Error: %s.\n"), tag, error); 669 Punt(1); 670 } 671} 672 673void 674Punt(int i) 675{ 676 if (icon.pixmap) { 677 XFreePixmap(dpy, icon.pixmap); 678 if (icon.mask) 679 XFreePixmap(dpy, icon.mask); 680 681 XFreeColors(dpy, colormap, 682 icon.attributes.alloc_pixels, 683 icon.attributes.nalloc_pixels, 0); 684 685 XpmFreeAttributes(&icon.attributes); 686 } 687 if (view.pixmap) { 688 XFreePixmap(dpy, view.pixmap); 689 if (view.mask) 690 XFreePixmap(dpy, view.mask); 691 692 XFreeColors(dpy, colormap, 693 view.attributes.alloc_pixels, 694 view.attributes.nalloc_pixels, 0); 695 696 XpmFreeAttributes(&view.attributes); 697 } 698 exit(i); 699} 700 701void 702kinput( 703 Widget widget, 704 char *tag, 705 XEvent *xe, 706 Boolean *b) 707{ 708 char c = '\0'; 709 710 XLookupString(&(xe->xkey), &c, 1, NULL, NULL); 711 if (c == 'q' || c == 'Q') 712 Punt(0); 713} 714 715/* 716 * small function to extract various version numbers from the given global 717 * number (following the rule described in xpm.h). 718 */ 719void 720GetNumbers( 721 int num, 722 int *format_return, 723 int *libmajor_return, 724 char *libminor_return) 725{ 726 *format_return = num / 10000; 727 *libmajor_return = (num % 10000) / 100; 728 *libminor_return = 'a' + (num % 10000) % 100 - 1; 729} 730 731void 732VersionInfo(void) 733{ 734 int format, libmajor; 735 char libminor; 736 737 GetNumbers(XpmIncludeVersion, &format, &libmajor, &libminor); 738 /* L10N_Comments : sxpm -version output */ 739 fprintf(stderr, gettext("sxpm version: %d.%d%c\n"), 740 format, libmajor, libminor); 741 /* L10N_Comments : 742 * if we are linked to an XPM library different from the one we've been 743 * compiled with, print its own number too when sxpm -version is called. 744 */ 745 if (XpmIncludeVersion != XpmLibraryVersion()) { 746 GetNumbers(XpmLibraryVersion(), &format, &libmajor, &libminor); 747 fprintf(stderr, gettext("using the XPM library version: %d.%d%c\n"), 748 format, libmajor, libminor); 749 } 750}