/**********************************************************/
/* */
/* pxpm.c: this is sxpm.c hacked by Ralph Betza so that */
/* it can be used to set a background picture for the */
/* vtwm panner window, */
/* */
/* Works for vtwm, not for tvtwm. */
/* */
/* And then also changed to set backgrounds for */
/* *any* window. */
/* Ralph Betza, June 1993 gnohmon@ssiny.com */
/**********************************************************/
/* Copyright 1990,91 GROUPE BULL -- See licence conditions in file COPYRIGHT */
/* Since most of the code is from sxpm.c, the above copyright should
** still apply.
*/
/*****************************************************************************\
* sxpm.c: *
* *
* Show XPM File program *
* *
* Developed by Arnaud Le Hors *
\*****************************************************************************/
#include <stdio.h>
#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>
#include <X11/cursorfont.h>
#endif
#include <X11/xpm.h>
Window window_by_name();
Window point_to_window();
/* 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) */
Window win;
Window Compensate();
#define dpy XtDisplay(topw)
#define screen XtScreen(topw)
#define colormap XDefaultColormapOfScreen(screen)
#define root XRootWindowOfScreen(screen)
#define xrdb XtDatabase(dpy)
int sDoByName;
int sDoByNumber;
char * pTargetWindowName;
void Usage();
void ErrorMessage();
void Punt();
#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;
char *point_txt[] = {
" ====> Please select the window",
" ====> whose background you wish to",
" ====> change by clicking the",
" ====> pointer in that window.",
0};
XColor NameToXColor();
unsigned long NameToPixel();
main(argc, argv)
unsigned int argc;
char **argv;
{
int ErrorStatus;
unsigned int stdinf = 0;
unsigned int sSolid = 0;
unsigned int w_rtn;
unsigned int h_rtn;
char *input = NULL;
unsigned int numsymbols = 0;
XpmColorSymbol symbols[10];
char *stype;
XrmValue val;
unsigned long valuemask = 0;
int n;
char *solid_color = NULL;
Arg args[3];
topw = XtInitialize(argv[0], "Nexpm",
(void*)0, 0, &argc, argv);
if (!topw) {
fprintf(stderr, "Nexpm Error... [ Undefined DISPLAY ]\n");
exit(1);
}
/*
* arguments parsing
*/
command = argv;
if (argc < 2)
Usage();
for (n = 1; n < argc; n++) {
if ( ! strcmp( argv[ n ], "-target" ))
{ sDoByName = 1;
pTargetWindowName = argv[++n];
continue;
}
if ( ! strcmp( argv[ n ], "-vtwm" ))
{ sDoByName = 1;
pTargetWindowName = "VTWM Desktop";
continue;
}
if ( ! strcmp( argv[ n ], "-id" ))
{ sDoByNumber = 1;
pTargetWindowName = argv[++n];
continue;
}
if (!strcmp("-solid", argv[n])) {
solid_color = argv[++n];
sSolid = 1;
continue;
}
if (strncmp(argv[n], "-plaid", 3) == 0) {
continue;
}
if (strncmp(argv[n], "-in", 3) == 0) {
input = argv[++n];
continue;
}
if (strncmp(argv[n], "-stdin", 5) == 0) {
stdinf = 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();
}
n = 0;
XtSetArg(args[n], XtNwidth, 1);
n++;
XtSetArg(args[n], XtNheight, 1);
n++;
XtSetArg(args[n], XtNmappedWhenManaged, False);
n++;
XtSetValues(topw, args, n);
XtRealizeWidget(topw);
view.attributes.colorsymbols = symbols;
view.attributes.numsymbols = numsymbols;
view.attributes.valuemask = valuemask;
if ( sDoByName )
{ win = window_by_name( root, pTargetWindowName );
win = Compensate( win );
}
else if ( sDoByNumber )
{
win = strtol( pTargetWindowName, (void *)0, 0 );
}
else
{ char ** ptr;
for (ptr = point_txt; *ptr; ptr++)
printf("%s\n",*ptr);
win = point_to_window(); /* use pointer to get window */
win = Compensate( win );
}
if ( ! sSolid )
{
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 {
ErrorStatus = XpmCreatePixmapFromData(dpy, win, plaid,
&view.pixmap, &view.mask,
&view.attributes);
ErrorMessage(ErrorStatus, "Plaid");
}
/* Now we are ready to display it... */
XSetWindowBackgroundPixmap(dpy, win, view.pixmap);
}
else
{
XSetWindowBackground(dpy, win, NameToPixel( solid_color,
0L ));
}
XClearWindow(dpy, win);
XFlush( dpy );
Punt(0);
}
void
Usage()
{
fprintf(stderr, "\nUsage: %s [options...]\n", command[0]);
fprintf(stderr, "%s\n", "Where options are:");
fprintf(stderr, "%s\n",
"[-vtwm] Target is the vtwm panner.");
fprintf(stderr, "%s\n",
"[-id window_id target Window's numeric ID.");
fprintf(stderr, "%s\n",
"[-target window_name] target Window's name.");
fprintf(stderr, "%s\n",
" (if none of the above specified, target is selected by mouse)");
fprintf(stderr, "%s\n",
"[-solid color_name] Ignore all pixmap parameters, set\
background color.");
fprintf(stderr, "%s\n",
"[-d host:display] Display to connect to.");
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\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 (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);
}
Window window_by_name(wdw,name)
Window wdw;
char *name;
{
/**********************************************************/
/* */
/* Copied from xcursor.c, who copied it from xwininfo. */
/* */
/**********************************************************/
Window *offspring; /* Any children */
Window junk; /* Just that */
Window w = 0; /* Found window */
int count; /* Number of kids */
int loop; /* Loop counter */
char *wdw_name; /* Returnewd name */
if (XFetchName(dpy,wdw,&wdw_name) && !strcmp(wdw_name,name))
return(wdw);
if (!XQueryTree(dpy,wdw,&junk,&junk,&offspring,&count))
return(0);
for (loop = 0; loop < count; loop++)
{
w = window_by_name(offspring[loop],name);
if (w)
break;
}
if (offspring)
XFree(offspring);
/* fprintf( stderr, "w=%x\n", w ); */
return(w);
}
Window point_to_window()
{ /* from xcursor.c, also from blast.c */
int status;
Cursor cursor;
XEvent event;
Window target_win = None;
int buttons = 0;
/* Make the target cursor */
cursor = XCreateFontCursor(dpy, XC_crosshair);
/* Grab the pointer using target cursor, letting it room all over */
status = XGrabPointer(dpy, root, False,
ButtonPressMask|ButtonReleaseMask, GrabModeSync,
GrabModeAsync, None, cursor, CurrentTime);
if (status != GrabSuccess)
{
fprintf(stderr,"Can't grab the mouse.");
exit(4);
}
/* Let the user select a window... */
while ((target_win == None) || (buttons != 0)) /* allow one more event */
{
XAllowEvents(dpy, SyncPointer, CurrentTime);
XWindowEvent(dpy, root,
ButtonPressMask|ButtonReleaseMask, &event);
switch (event.type)
{
case ButtonPress:
if (target_win == None)
{
/* window selected */
target_win = event.xbutton.subwindow;
if (target_win == None)
target_win = root;
}
buttons++;
break;
/* there may have been some down before we started */
case ButtonRelease:
if (buttons > 0)
buttons--;
break;
}
}
XUngrabPointer(dpy, CurrentTime); /* Done with pointer */
target_win = XmuClientWindow( dpy, target_win );
/* XmuClientWindow() is suggested by blast.c, but ifdeffed out.
** What happens is that blast gets the ID of the frame window,
** created by the window manager, not the ID of the window you
** really pointed to; but for blast it's OK: the shape *should* be
** given to the frame.
*/
return(target_win);
}
Window
Compensate( win )
Window win;
{
Window dummy;
Window dummy2;
Window * children;
unsigned int n;
if ( XQueryTree( dpy, win, &dummy, &dummy2, &children, &n ))
{
/* Test for children submitted by Steve Ratcliffe */
if (children)
{
win = *children;
XFree( children );
}
}
/**********************************************************/
/* */
/* It is possible that Compensate() is vtwm-specific. */
/* */
/* In any case, xlswins() reveals that the window ID we */
/* get from the pointer or from the name is always the */
/* *parent* of the window we really want, and since it */
/* is always at the bottom of the stacking order we */
/* know that it is the first window returned by */
/* XQueryTree. */
/* */
/**********************************************************/
return win;
}
unsigned long NameToPixel(name, pixel)
char *name;
unsigned long pixel;
{
XColor ecolor;
if (!name || !*name)
return pixel;
if (!XParseColor(dpy,colormap,name,&ecolor)) {
fprintf(stderr,"nexpm: unknown color \"%s\"\n",name);
exit(1);
/*NOTREACHED*/
}
if (!XAllocColor(dpy, colormap,&ecolor))
{
fprintf(stderr, "nexpm: unable to allocate color for \"%s\"\n",
name);
exit(1);
/*NOTREACHED*/
}
return(ecolor.pixel);
}
syntax highlighted by Code2HTML, v. 0.9.1