/**********************************************************/ /* */ /* 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 #ifdef VMS #include "decw$include:Xlib.h" #include "decw$include:Intrinsic.h" #include "decw$include:Shell.h" #include "decw$include:shape.h" #else #include #include #include #include #include #endif #include 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); }