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