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