[comp.os.vms] An xgranite Client SOURCE!

jym@berkeley.edu (Jym Dyer) (01/11/91)

___
__  Eons ago I asked about a client that would put a granite
_   pattern on an root (X) window.  Somebody sent me one.  I
    enhanced it a tad and ported it to VMS.  The source below
    will run on Un*x and VMS.
___
__  The source is in Un*x "ar" format, which I chose because
_   I don't have "shar" or VMS_SHARE or anything, and because
    the "ar" archive can be all text.  The files are between
    headers that end with a backquote, and the headers contain
    the names of the files.  At any rate, just save it into a
    file called xgranite.ar and run "ar" or your favorite
    editor on it to get these files:

	0-README-0.txt
	xgranite.c
	xgranite.man
	xgranite.opt
___
__  If anyone wants to repackage this with VMS_SHARE and post
_   it to vmsnet.sources, be my guest.
    <_Jym_>
-------------8<--------------Cut-Here--------------8<-------------
!<arch>
0-README-0.txt  663548381   201   10    100644  792       `
These are the source files for xgranite, a client to generate a
granite pattern for the background (root) window.

These sources will work on a Un*x or VMS system.  The Un*x command
to build xgranite is generally this:

	cc -o xgranite -lX11 xgranite.c

On VMS, you must first have the X11 logical name defined to include
the DECW$INCLUDE path.  One way to do that is with this command:

	define X11 'f$trnlnm("DECW$INCLUDE")'

The program is then built with these two commands:

	cc xgranite
	link/notrace xgranite/opt

The author of xgranite is listed in the xgranite.man file.  The -bg
and -fg options and the VMS port were done by Jym Dyer.  Kudos to
the kind soul who provided the find_root() function (whose name I
unfortunately lost).
		-- Jym Dyer (jym@mica.berkeley.edu) 10-Jan-1991
xgranite.c      663546866   201   10    100644  5670      `
# include <X11/Xlib.h>
# include <stdio.h>

#ifdef VMS
#define random rand
#endif

#define Dynamic 1

Display	*dpy;
int	scr;
Window	root;
char	*prog_name;

unsigned long NameToPixel();
#ifdef VMS
static Window find_root();
#endif

main(argc, argv)
	char		**argv;
{
	extern Pixmap	mkrand();
	char		*display_name = NULL;
	int		i;
	int		width, height;
	char		*fore_color = NULL;
	char		*back_color = NULL;

	int		dark;

	prog_name = argv[0];
	width = 0;
	height = 0;
	dark = 0;

	for (i = 1; i < argc; i++) {
		if (!strcmp ("-display", argv[i])) {
			if (++i >= argc)
				usage(1);
			display_name = argv[i];
			continue;
		}

		if (!strcmp("-width", argv[i])) {
			if (++i >= argc)
				usage(1);
			width = atoi(argv[i]);
			continue;
		}

		if (!strcmp("-height", argv[i])) {
			if (++i >= argc)
				usage(1);
			height = atoi(argv[i]);
			continue;
		}

		if (!strcmp("-fg",argv[i]) || !strcmp("-foreground",argv[i])) {
			if (++i>=argc)
				usage(1);
			fore_color = argv[i];
			continue;
		}

		if (!strcmp("-bg",argv[i]) || !strcmp("-background",argv[i])) {
			if (++i>=argc)
				usage(1);
			back_color = argv[i];
			continue;
		}

		if (!strcmp("-darkness", argv[i])) {
			if (++i >= argc)
				usage(1);
			dark = atoi(argv[i]);
			continue;
		}

		if (!strcmp("-help", argv[i])) {
			usage(0);
		}

		usage(1);
	}

	dpy = XOpenDisplay(display_name);
	if (!dpy) {
		fprintf(stderr, "%s:  unable to open display '%s'\n",
			prog_name, XDisplayName(display_name));
		usage(1);
	}
	scr = DefaultScreen(dpy);

	root = RootWindow(dpy, scr);
#ifdef VMS
	root = find_root(dpy, root);
#endif

	if (width <= 0) {
		if (width < 0)
			fprintf(stderr, "%s: invalid width, using default.\n",
				prog_name);
		width = DisplayWidth(dpy, scr);
	}
	if (height <= 0) {
		if (height < 0)
			fprintf(stderr, "%s: invalid height, using default.\n",
				prog_name);
		height = DisplayHeight(dpy, scr);
	}
	if (dark < 0)
		dark = 0;
	if (dark > 15)
		dark = 15;

	background(mkrand(dark, width, height), width, height,
		   fore_color, back_color);

	XCloseDisplay(dpy);
	exit(0);
}

usage(status) {
	fprintf(stderr, "usage: %s [options]\n", prog_name);
	fprintf(stderr, "\twhere options are:\n");
	fprintf(stderr, "\t-display <display>\n");
	fprintf(stderr, "\t-width <N>\n");
	fprintf(stderr, "\t-height <N>\n");
	fprintf(stderr, "\t-fg <color>   or   -foreground <color>\n");
	fprintf(stderr, "\t-bg <color>   or   -background <color>\n");
	fprintf(stderr, "\t-darkness <N>\n");
	fprintf(stderr, "\t-help\n");
	exit(status);
}

Pixmap
mkrand(dark, width, height) {
	extern long		random();
	extern long		time();
	extern char		*malloc();
	unsigned short		*data;
	register unsigned short	*pd;
	register unsigned short	*data_end;
	int			data_size;
	register int		j;
	register unsigned int	n;

	if ((data = (unsigned short *) malloc(256)) == NULL) {
		perror("malloc");
		exit(1);
	}
#ifndef VMS
	(void) initstate((unsigned int) time(0), (char *) data, 256);
#else
	(void) srand((unsigned int) time(0) + (unsigned int) data);
#endif
	free(data);

	data_size = ((width * height) / 8);
	if ((data = (unsigned short *) malloc(data_size)) == NULL) {
		perror("malloc");
		exit(1);
	}

	data_end = &data[data_size / sizeof(*data)];

	for (pd = data_end - 1; pd >= &data[0]; pd--)
		*pd = random() & 0xffff;

	if (dark > 0) {
		for (pd = data_end - 1; pd >= &data[0]; pd--) {
			n = random();
			n |= (n & 0x1) << 31; /* high bit = low bit */
			for (j = 0; j < 8; j++) {
				*pd |= ((n & 0x0f) < dark) << j;
				*pd |= ((n & 0x0f) < dark) << (j+8); /*hibyte*/
				n >>= 4;
			}
		}
	}

	return(XCreateBitmapFromData(dpy, root, (char *) data, width, height));
}

/* swiped from xsetroot */
background(bitmap, width, height, fore_color, back_color)
    Pixmap		bitmap;
    unsigned int	width, height;
{
	Pixmap		pix;
	GC		gc;
	XGCValues	gc_init;

	gc_init.foreground = NameToPixel(fore_color, BlackPixel(dpy, scr));
	gc_init.background = NameToPixel(back_color, WhitePixel(dpy, scr));

	gc = XCreateGC(dpy, root, GCForeground|GCBackground, &gc_init);
	pix = XCreatePixmap(dpy, root, width, height,
			    (unsigned int) DefaultDepth(dpy, scr));

	XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height, 0, 0,
		   (unsigned long) 1);
	XSetWindowBackgroundPixmap(dpy, root, pix);

	XFreeGC(dpy, gc);
	XFreePixmap(dpy, bitmap);
	XFreePixmap(dpy, pix);

	XClearWindow(dpy, root);
}

unsigned long NameToPixel(name, pixel)
    char *name;
    unsigned long pixel;
{
    XColor ecolor;

    if (!name || !*name)
	return pixel;
    if (!XParseColor(dpy,DefaultColormap(dpy,scr),name,&ecolor)) {
	fprintf(stderr,"%s:  unknown color \"%s\"\n",prog_name,name);
	exit(1);
	/*NOTREACHED*/
    }
    if (!XAllocColor(dpy, DefaultColormap(dpy, scr),&ecolor)) {
	fprintf(stderr, "%s:  unable to allocate color for \"%s\"\n",
		prog_name, name);
	exit(1);
	/*NOTREACHED*/
    }
    if ((ecolor.pixel != BlackPixel(dpy, scr)) &&
	(ecolor.pixel != WhitePixel(dpy, scr)) &&
	(DefaultVisual(dpy, scr)->class & Dynamic))
    return(ecolor.pixel);
}

#ifdef VMS
static Window find_root(dpy, pwin)
Display *dpy;
Window  pwin;
{
    XWindowAttributes pxwa,cxwa;
    Window  root,parent,*child;
    int     i,nchild;

    if (!XGetWindowAttributes(dpy,pwin,&pxwa))
	printf("find_root: fail to get window attributes\n");
    if (XQueryTree(dpy,pwin,&root,&parent,&child,&nchild)) {
	for (i = 0; i < nchild; i++) {
	    if (!XGetWindowAttributes(dpy,child[i],&cxwa))
		printf("find_root: fail to get window attributes\n");
	    if (pxwa.width == cxwa.width && pxwa.height == cxwa.height)
		return(find_root(dpy, child[i]));
	}
	return(pwin);
    }
    else printf("find_root: fail to get root window\n");
}
#endif /* VMS */
xgranite.man    663546870   201   10    100644  992       `
.TH XGRANITE 1 
.SH NAME
xgranite \- make a random background
.SH SYNOPSIS
.B xgranite
[-display \fIdisplay\fP] [-width \fIwidth\fP]
[-height \fIheight\fP] [-darkness \fIdarkness\fP]
.SH DESCRIPTION
.I xgranite
makes a random background that somewhat resembles granite.
.SH OPTIONS
.PP
The various options are as follows:
.IP "\fB-display\fP \fIdisplay\fP"
Specifies the server to connect to; see \fIX(1)\fP.
.IP "\fB-width\fP \fIwidth\fP"
Specifies the width of the random bitmap.  If no width is specified
the width of the screen is used.
.IP "\fB-height\fP \fIheight\fP"
Specifies the height of the random bitmap.  If no height is specified
the height of the screen is used.
.IP "\fB-darknes\fP \fIdarknes\fP"
Specifies how dark to make the random pattern.
.PP
For a completely random background don't use \fB-width\fP or
\fB-height\fP.
.SH "SEE ALSO"
X(1), xsetroot(1), xset(1), xrdb(1)
.SH AUTHOR
.ta 1.2i
Program:	Rusty C. Wright
.br
	rusty@cartan.berkeley.edu
.br
	ucbvax!cartan!rusty
xgranite.opt    663546874   201   10    100644  76        `
xgranite.obj
sys$share:decw$dwtlibshr.exe/share
sys$share:vaxcrtl.exe/share