earlybrowserreborn - Rev 1

Subversion Repositories:
Rev:
/* Copyright 1990,91 GROUPE BULL -- See licence conditions in file COPYRIGHT */
/*****************************************************************************\
* sxpm.c:                                                                     *
*                                                                             *
*  Show XPM File program                                                      *
*                                                                             *
*  Developed by Arnaud Le Hors                                                *
\*****************************************************************************/


#ifdef VMS
#include "decw$include:Xlib.h"
#include "decw$include:Intrinsic.h"
#include "decw$include:Shell.h"
#include "decw$include:shape.h"
#else
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <X11/extensions/shape.h>
#endif

#include "xpm.h"

/* XPM */
/* plaid pixmap */
static char *plaid[] =
{
/* width height ncolors chars_per_pixel */
 "22 22 4 2",
/* colors */
 "   c red      m white  s light_color",
 "Y  c green    m black  s lines_in_mix",
 "+  c yellow   m white  s lines_in_dark",
 "x             m black  s dark_color",
/* pixels */
 "x   x   x x x   x   x x x x x x + x x x x x ",
 "  x   x   x   x   x   x x x x x x x x x x x ",
 "x   x   x x x   x   x x x x x x + x x x x x ",
 "  x   x   x   x   x   x x x x x x x x x x x ",
 "x   x   x x x   x   x x x x x x + x x x x x ",
 "Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ",
 "x   x   x x x   x   x x x x x x + x x x x x ",
 "  x   x   x   x   x   x x x x x x x x x x x ",
 "x   x   x x x   x   x x x x x x + x x x x x ",
 "  x   x   x   x   x   x x x x x x x x x x x ",
 "x   x   x x x   x   x x x x x x + x x x x x ",
 "          x           x   x   x Y x   x   x ",
 "          x             x   x   Y   x   x   ",
 "          x           x   x   x Y x   x   x ",
 "          x             x   x   Y   x   x   ",
 "          x           x   x   x Y x   x   x ",
 "x x x x x x x x x x x x x x x x x x x x x x ",
 "          x           x   x   x Y x   x   x ",
 "          x             x   x   Y   x   x   ",
 "          x           x   x   x Y x   x   x ",
 "          x             x   x   Y   x   x   ",
 "          x           x   x   x Y x   x   x "
};

#define win XtWindow(topw)
#define dpy XtDisplay(topw)
#define screen XtScreen(topw)
#define colormap XDefaultColormapOfScreen(screen)
#define root XRootWindowOfScreen(screen)
#define xrdb XtDatabase(dpy)

void Usage();
void ErrorMessage();
void Punt();
void kinput();

#define IWIDTH      50
#define IHEIGHT     50

typedef struct _XpmIcon {
    Pixmap pixmap;
    Pixmap mask;
    XpmAttributes attributes;
}        XpmIcon;

static char **command;
static Widget topw;
static XpmIcon view, icon;
static XrmOptionDescRec options[] = {
                  {"-hints", ".hints", XrmoptionNoArg, (XtPointer) "True"},
                     {"-icon", ".icon", XrmoptionSepArg, (XtPointer) NULL},
};

main(argc, argv)
    unsigned int argc;
    char **argv;
{
    int ErrorStatus;
    unsigned int stdinf = 0;
    unsigned int stdoutf = 0;
    unsigned int nod = 0;
    unsigned int incResize = 0;
    unsigned int resize = 0;
    unsigned int w_rtn;
    unsigned int h_rtn;
    char *input = NULL;
    char *output = NULL;
    char *iconFile = NULL;
    unsigned int numsymbols = 0;
    XpmColorSymbol symbols[10];
    char *stype;
    XrmValue val;
    unsigned long valuemask = 0;
    int n;
    Arg args[3];

#ifdef Debug2
    char **data;

#endif

    topw = XtInitialize(argv[0], "Sxpm",
                        options, XtNumber(options), &argc, argv);

    if (!topw) {
        fprintf(stderr, "Sxpm Error... [ Undefined DISPLAY ]\n");
        exit(1);
    }

    /*
     * geometry management
     */


    if (XrmGetResource(xrdb, NULL, "sxpm.geometry", &stype, &val)
        || XrmGetResource(xrdb, NULL, "Sxpm.geometry", &stype, &val)) {

        int flags;
        int x_rtn;
        int y_rtn;
        char *geo = NULL;

        geo = (char *) val.addr;
        flags = XParseGeometry(geo, &x_rtn, &y_rtn,
                               (unsigned int *) &w_rtn,
                               (unsigned int *) &h_rtn);
        if (!((WidthValue & flags) && (HeightValue & flags)))
            resize = 1;
    } else
        resize = 1;

    n = 0;
    if (resize) {
        w_rtn = 0;
        h_rtn = 0;
        XtSetArg(args[n], XtNwidth, 1);
        n++;
        XtSetArg(args[n], XtNheight, 1);
        n++;
    }
    XtSetArg(args[n], XtNmappedWhenManaged, False);
    n++;
    XtSetValues(topw, args, n);

    if ((XrmGetResource(xrdb, "sxpm.hints", "", &stype, &val)
         || XrmGetResource(xrdb, "Sxpm.hints", "", &stype, &val))
        && !strcmp((char *) val.addr, "True")) {
        /* gotcha */
        incResize = 1;
        resize = 1;
    }

    /*
     * icon management
     */


    if (XrmGetResource(xrdb, "sxpm.icon", "", &stype, &val) ||
        XrmGetResource(xrdb, "Sxpm.icon", "", &stype, &val)) {
        iconFile = (char *) val.addr;
    }
    if (iconFile) {

        XColor color, junk;
        Pixel bpix;
        Window iconW;

        if (XAllocNamedColor(dpy, colormap, "black", &color, &junk))
            bpix = color.pixel;
        else
            bpix = XBlackPixelOfScreen(screen);

        iconW = XCreateSimpleWindow(dpy, root, 0, 0,
                                    IWIDTH, IHEIGHT, 1, bpix, bpix);

        icon.attributes.valuemask = XpmReturnPixels;
        ErrorStatus = XpmReadFileToPixmap(dpy, root, iconFile, &icon.pixmap,
                                          &icon.mask, &icon.attributes);
        ErrorMessage(ErrorStatus, "Icon");

        XSetWindowBackgroundPixmap(dpy, iconW, icon.pixmap);

        n = 0;
        XtSetArg(args[n], XtNbackground, bpix);
        n++;
        XtSetArg(args[n], XtNiconWindow, iconW);
        n++;
        XtSetValues(topw, args, n);
    }

    /*
     * arguments parsing
     */


    command = argv;
    if (argc < 2)
        Usage();
    for (n = 1; n < argc; n++) {
        if (strncmp(argv[n], "-plaid", 3) == 0) {
            continue;
        }
        if (strncmp(argv[n], "-in", 3) == 0) {
            input = argv[++n];
            continue;
        }
        if (strncmp(argv[n], "-out", 2) == 0) {
            output = argv[++n];
            continue;
        }
        if (strncmp(argv[n], "-stdin", 5) == 0) {
            stdinf = 1;
            continue;
        }
        if (strncmp(argv[n], "-stdout", 5) == 0) {
            stdoutf = 1;
            continue;
        }
        if (strncmp(argv[n], "-nod", 2) == 0) {
            nod = 1;
            continue;
        }
        if (strncmp(argv[n], "-s", 2) == 0) {
            if (n < argc - 2) {
                valuemask |= XpmColorSymbols;
                symbols[numsymbols].name = argv[++n];
                symbols[numsymbols++].value = argv[++n];
                continue;
            }
        }
        if (strncmp(argv[n], "-p", 2) == 0) {
            if (n < argc - 2) {
                valuemask |= XpmColorSymbols;
                symbols[numsymbols].name = argv[++n];
                symbols[numsymbols].value = NULL;
                symbols[numsymbols++].pixel = atol(argv[++n]);
                continue;
            }
        }
        if (strncmp(argv[n], "-rgb", 3) == 0) {
            if (n < argc - 1) {
                valuemask |= XpmRgbFilename;
                view.attributes.rgb_fname = argv[++n];
                continue;
            }
        }
        Usage();
    }

    XtRealizeWidget(topw);

    view.attributes.colorsymbols = symbols;
    view.attributes.numsymbols = numsymbols;
    view.attributes.valuemask = valuemask;

#ifdef Debug2
    /* this is just to test the XpmCreateDataFromPixmap function */

    view.attributes.valuemask |= XpmReturnPixels;
    ErrorStatus = XpmCreatePixmapFromData(dpy, win, plaid,
                                          &view.pixmap, &view.mask,
                                          &view.attributes);
    ErrorMessage(ErrorStatus, "Plaid");

    ErrorStatus = XpmCreateDataFromPixmap(dpy, &data, view.pixmap, view.mask,
                                          &view.attributes);
    ErrorMessage(ErrorStatus, "Data");

    XFreePixmap(dpy, view.pixmap);
    if (view.mask)
        XFreePixmap(dpy, view.mask);

    XFreeColors(dpy, colormap,
                view.attributes.pixels, view.attributes.npixels, 0);

    XpmFreeAttributes(&view.attributes);
    view.attributes.valuemask = valuemask;
#endif

    if (input || stdinf) {
        view.attributes.valuemask |= XpmReturnInfos;
        view.attributes.valuemask |= XpmReturnPixels;
        ErrorStatus = XpmReadFileToPixmap(dpy, win, input,
                                          &view.pixmap, &view.mask,
                                          &view.attributes);
        ErrorMessage(ErrorStatus, "Read");
    } else {

#ifdef Debug2
        ErrorStatus = XpmCreatePixmapFromData(dpy, win, data,
                                              &view.pixmap, &view.mask,
                                              &view.attributes);
#else
        ErrorStatus = XpmCreatePixmapFromData(dpy, win, plaid,
                                              &view.pixmap, &view.mask,
                                              &view.attributes);
#endif
        ErrorMessage(ErrorStatus, "Plaid");
    }

#ifdef Debug2
    free(data);
#endif

    if (output || stdoutf) {
        ErrorStatus = XpmWriteFileFromPixmap(dpy, output, view.pixmap,
                                             view.mask, &view.attributes);
        ErrorMessage(ErrorStatus, "Write");
    }
    if (!nod) {

        /*
         * manage display if requested
         */


        XSizeHints size_hints;
        char *xString = NULL;

        if (w_rtn && h_rtn
            && ((w_rtn < view.attributes.width)
                || h_rtn < view.attributes.height)) {
            resize = 1;
        }
        if (resize) {
            XtResizeWidget(topw,
                         view.attributes.width, view.attributes.height, 1);
        }
        if (incResize) {
            size_hints.flags = USSize | PMinSize | PResizeInc;
            size_hints.height = view.attributes.height;
            size_hints.width = view.attributes.width;
            size_hints.height_inc = view.attributes.height;
            size_hints.width_inc = view.attributes.width;
        } else
            size_hints.flags = PMinSize;

        size_hints.min_height = view.attributes.height;
        size_hints.min_width = view.attributes.width;
        XSetWMNormalHints(dpy, win, &size_hints);

        if (input) {
            xString = (char *) XtMalloc((sizeof(char) * strlen(input)) + 20);
            sprintf(xString, "Sxpm: %s\0", input);
            XStoreName(dpy, XtWindow(topw), xString);
            XSetIconName(dpy, XtWindow(topw), xString);
        } else if (stdinf) {
            XStoreName(dpy, XtWindow(topw), "Sxpm: stdin");
            XSetIconName(dpy, XtWindow(topw), "Sxpm: stdin");
        } else {
            XStoreName(dpy, XtWindow(topw), "Sxpm");
            XSetIconName(dpy, XtWindow(topw), "Sxpm");
        }

        XtAddEventHandler(topw, KeyPressMask, False,
                          (XtEventHandler) kinput, NULL);
        XSetWindowBackgroundPixmap(dpy, win, view.pixmap);

        if (view.mask)
            XShapeCombineMask(dpy, win, ShapeBounding, 0, 0,
                              view.mask, ShapeSet);

        XClearWindow(dpy, win);
        XMapWindow(dpy, win);
        if (xString)
            XtFree(xString);
        XtMainLoop();
    }
    Punt(0);
}

void
Usage()
{
    fprintf(stderr, "\nUsage:  %s [options...]\n", command[0]);
    fprintf(stderr, "%s\n", "Where options are:");
    fprintf(stderr, "%s\n",
            "[-d host:display]            Display to connect to.");
    fprintf(stderr, "%s\n",
            "[-g geom]                    Geometry of window.");
    fprintf(stderr, "%s\n",
            "[-hints]                     Set ResizeInc for window.");
    fprintf(stderr, "%s\n",
            "[-icon filename ]            Set pixmap for iconWindow.");
    fprintf(stderr, "%s\n",
            "[-s symbol_name color_name]  Overwrite color defaults.");
    fprintf(stderr, "%s\n",
            "[-p symbol_name pixel_value] Overwrite color defaults.");
    fprintf(stderr, "%s\n",
            "[-plaid]                     Read the included plaid pixmap.");
    fprintf(stderr, "%s\n",
          "[-in filename]               Read input from file `filename`.");
    fprintf(stderr, "%s\n",
            "[-stdin]                     Read input from stdin.");
    fprintf(stderr, "%s\n",
          "[-out filename]              Write output to file `filename`.");
    fprintf(stderr, "%s\n",
            "[-stdout]                    Write output to stdout.");
    fprintf(stderr, "%s\n",
            "[-nod]                       Don't display in window.");
    fprintf(stderr, "%s\n\n",
            "[-rgb filename]              Search color names in the \
rgb text file `filename`."
);
    exit(0);
}


void
ErrorMessage(ErrorStatus, tag)
    int ErrorStatus;
    char *tag;
{
    char *error = NULL;
    char *warning = NULL;

    switch (ErrorStatus) {
    case XpmSuccess:
        return;
    case XpmColorError:
        warning = "Could not parse or alloc requested color";
        break;
    case XpmOpenFailed:
        error = "Cannot open file";
        break;
    case XpmFileInvalid:
        error = "invalid XPM file";
        break;
    case XpmNoMemory:
        error = "Not enough memory";
        break;
    case XpmColorFailed:
        error = "Color not found";
        break;
    }

    if (warning)
        printf("%s Xpm Warning: %s.\n", tag, warning);

    if (error) {
        printf("%s Xpm Error: %s.\n", tag, error);
        Punt(1);
    }
}

void
Punt(i)
    int i;
{
    if (icon.pixmap) {
        XFreePixmap(dpy, icon.pixmap);
        if (icon.mask)
            XFreePixmap(dpy, icon.mask);

        XFreeColors(dpy, colormap,
                    icon.attributes.pixels, icon.attributes.npixels, 0);

        XpmFreeAttributes(&icon.attributes);
    }
    if (view.pixmap) {
        XFreePixmap(dpy, view.pixmap);
        if (view.mask)
            XFreePixmap(dpy, view.mask);

        XFreeColors(dpy, colormap,
                    view.attributes.pixels, view.attributes.npixels, 0);

        XpmFreeAttributes(&view.attributes);
    }
    exit(i);
}

void
kinput(widget, tag, xe, b)
    Widget widget;
    char *tag;
    XEvent *xe;
    Boolean *b;
{
    char c;

    XLookupString(&(xe->xkey), &c, 1, NULL, NULL);
    if (c == 'q' || c == 'Q')
        Punt(0);
}