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