xsetroot.c revision d80571a9
1c95b42baSmrg/*
2c95b42baSmrg *
3c95b42baSmrgCopyright 1987, 1998  The Open Group
4c95b42baSmrg
5c95b42baSmrgPermission to use, copy, modify, distribute, and sell this software and its
6c95b42baSmrgdocumentation for any purpose is hereby granted without fee, provided that
7c95b42baSmrgthe above copyright notice appear in all copies and that both that
8c95b42baSmrgcopyright notice and this permission notice appear in supporting
9c95b42baSmrgdocumentation.
10c95b42baSmrg
11c95b42baSmrgThe above copyright notice and this permission notice shall be included in
12c95b42baSmrgall copies or substantial portions of the Software.
13c95b42baSmrg
14c95b42baSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15c95b42baSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16c95b42baSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17c95b42baSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18c95b42baSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19c95b42baSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20c95b42baSmrg
21c95b42baSmrgExcept as contained in this notice, the name of The Open Group shall not be
22c95b42baSmrgused in advertising or otherwise to promote the sale, use or other dealings
23c95b42baSmrgin this Software without prior written authorization from The Open Group.
24c95b42baSmrg */
25c95b42baSmrg
26c95b42baSmrg/*
27c95b42baSmrg * xsetroot.c 	MIT Project Athena, X Window System root window
28c95b42baSmrg *		parameter setting utility.  This program will set
29c95b42baSmrg *		various parameters of the X root window.
30c95b42baSmrg *
31c95b42baSmrg *  Author:	Mark Lillibridge, MIT Project Athena
32c95b42baSmrg *		11-Jun-87
33c95b42baSmrg */
34c95b42baSmrg
35c95b42baSmrg#include <X11/Xlib.h>
36c95b42baSmrg#include <X11/Xutil.h>
37c95b42baSmrg#include <X11/Xatom.h>
38c95b42baSmrg#include <X11/Xmu/CurUtil.h>
39d80571a9Smrg#include <X11/Xcursor/Xcursor.h>
40c95b42baSmrg#include <stdio.h>
41c95b42baSmrg#include <stdlib.h>
42c95b42baSmrg#include <string.h>
43c95b42baSmrg#include "X11/bitmaps/gray"
44c95b42baSmrg
45c95b42baSmrg#define Dynamic 1
46c95b42baSmrg
47f40e0d56Smrgstatic char *program_name;
48f40e0d56Smrgstatic Display *dpy;
49f40e0d56Smrgstatic int screen;
50f40e0d56Smrgstatic Window root;
51f40e0d56Smrgstatic char *fore_color = NULL;
52f40e0d56Smrgstatic char *back_color = NULL;
53f40e0d56Smrgstatic int reverse = 0;
54f40e0d56Smrgstatic int save_colors = 0;
55f40e0d56Smrgstatic int unsave_past = 0;
56f40e0d56Smrgstatic Pixmap save_pixmap = (Pixmap)None;
57c95b42baSmrg
58c95b42baSmrgstatic void usage(void);
59c95b42baSmrgstatic void FixupState(void);
60c95b42baSmrgstatic void SetBackgroundToBitmap(Pixmap bitmap,
61c95b42baSmrg				  unsigned int width, unsigned int height);
62c95b42baSmrgstatic Cursor CreateCursorFromFiles(char *cursor_file, char *mask_file);
63c95b42baSmrgstatic Cursor CreateCursorFromName(char *name);
64c95b42baSmrgstatic Pixmap MakeModulaBitmap(int mod_x, int mod_y);
65c95b42baSmrgstatic XColor NameToXColor(char *name, unsigned long pixel);
66c95b42baSmrgstatic unsigned long NameToPixel(char *name, unsigned long pixel);
67c95b42baSmrgstatic Pixmap ReadBitmapFile(char *filename, unsigned int *width, unsigned int *height, int *x_hot, int *y_hot);
68c95b42baSmrg
69c95b42baSmrgstatic void
70c95b42baSmrgusage(void)
71c95b42baSmrg{
72c95b42baSmrg    fprintf(stderr, "usage: %s [options]\n", program_name);
73c95b42baSmrg    fprintf(stderr, "  where options are:\n");
74c95b42baSmrg    fprintf(stderr, "  -display <display>   or   -d <display>\n");
75c95b42baSmrg    fprintf(stderr, "  -fg <color>   or   -foreground <color>\n");
76c95b42baSmrg    fprintf(stderr, "  -bg <color>   or   -background <color>\n");
77c95b42baSmrg    fprintf(stderr, "  -rv   or   -reverse\n");
78c95b42baSmrg    fprintf(stderr, "  -help\n");
79c95b42baSmrg    fprintf(stderr, "  -def   or   -default\n");
80c95b42baSmrg    fprintf(stderr, "  -name <string>\n");
81c95b42baSmrg    fprintf(stderr, "  -cursor <cursor file> <mask file>\n");
82c95b42baSmrg    fprintf(stderr, "  -cursor_name <cursor-font name>\n");
83d80571a9Smrg    fprintf(stderr, "  -xcf <ARGB cursor file> <cursor size>\n");
84c95b42baSmrg    fprintf(stderr, "  -solid <color>\n");
85c95b42baSmrg    fprintf(stderr, "  -gray   or   -grey\n");
86c95b42baSmrg    fprintf(stderr, "  -bitmap <filename>\n");
87c95b42baSmrg    fprintf(stderr, "  -mod <x> <y>\n");
88c95b42baSmrg    exit(1);
89c95b42baSmrg    /*NOTREACHED*/
90c95b42baSmrg}
91c95b42baSmrg
92c95b42baSmrg
93c95b42baSmrgint
94c95b42baSmrgmain(int argc, char *argv[])
95c95b42baSmrg{
96c95b42baSmrg    int excl = 0;
97c95b42baSmrg    int nonexcl = 0;
98c95b42baSmrg    int restore_defaults = 0;
99c95b42baSmrg    char *display_name = NULL;
100c95b42baSmrg    char *name = NULL;
101c95b42baSmrg    char *cursor_file = NULL;
102c95b42baSmrg    char *cursor_mask = NULL;
103c95b42baSmrg    char *cursor_name = NULL;
104c95b42baSmrg    char *solid_color = NULL;
105d80571a9Smrg    char *xcf = NULL;
106d80571a9Smrg    int xcf_size = 32;
107c95b42baSmrg    Cursor cursor;
108c95b42baSmrg    int gray = 0;
109c95b42baSmrg    char *bitmap_file = NULL;
110c95b42baSmrg    int mod_x = 0;
111c95b42baSmrg    int mod_y = 0;
112c95b42baSmrg    register int i;
113c95b42baSmrg    unsigned int ww, hh;
114c95b42baSmrg    Pixmap bitmap;
115c95b42baSmrg
116c95b42baSmrg    program_name=argv[0];
117c95b42baSmrg
118c95b42baSmrg    for (i = 1; i < argc; i++) {
119c95b42baSmrg	if (!strcmp ("-display", argv[i]) || !strcmp ("-d", argv[i])) {
120c95b42baSmrg	    if (++i>=argc) usage ();
121c95b42baSmrg	    display_name = argv[i];
122c95b42baSmrg	    continue;
123c95b42baSmrg	}
124c95b42baSmrg	if (!strcmp("-help", argv[i])) {
125c95b42baSmrg	    usage();
126c95b42baSmrg	}
127c95b42baSmrg	if (!strcmp("-def", argv[i]) || !strcmp("-default", argv[i])) {
128c95b42baSmrg	    restore_defaults = 1;
129c95b42baSmrg	    continue;
130c95b42baSmrg	}
131c95b42baSmrg	if (!strcmp("-name", argv[i])) {
132c95b42baSmrg	    if (++i>=argc) usage();
133c95b42baSmrg	    name = argv[i];
134c95b42baSmrg	    nonexcl++;
135c95b42baSmrg	    continue;
136c95b42baSmrg	}
137c95b42baSmrg	if (!strcmp("-cursor", argv[i])) {
138c95b42baSmrg	    if (++i>=argc) usage();
139c95b42baSmrg	    cursor_file = argv[i];
140c95b42baSmrg	    if (++i>=argc) usage();
141c95b42baSmrg	    cursor_mask = argv[i];
142c95b42baSmrg	    nonexcl++;
143c95b42baSmrg	    continue;
144c95b42baSmrg	}
145c95b42baSmrg	if (!strcmp("-cursor_name", argv[i])) {
146c95b42baSmrg	    if (++i>=argc) usage();
147c95b42baSmrg	    cursor_name = argv[i];
148c95b42baSmrg	    nonexcl++;
149c95b42baSmrg	    continue;
150c95b42baSmrg	}
151d80571a9Smrg	if (!strcmp("-xcf", argv[i])) {
152d80571a9Smrg	    if (++i>=argc) usage();
153d80571a9Smrg	    xcf = argv[i];
154d80571a9Smrg	    if (++i>=argc) usage();
155d80571a9Smrg	    xcf_size = atoi(argv[i]);
156d80571a9Smrg	    if (xcf_size <= 0)
157d80571a9Smrg		xcf_size = 32;
158d80571a9Smrg	    nonexcl++;
159d80571a9Smrg	    continue;
160d80571a9Smrg	}
161c95b42baSmrg	if (!strcmp("-fg",argv[i]) || !strcmp("-foreground",argv[i])) {
162c95b42baSmrg	    if (++i>=argc) usage();
163c95b42baSmrg	    fore_color = argv[i];
164c95b42baSmrg	    continue;
165c95b42baSmrg	}
166c95b42baSmrg	if (!strcmp("-bg",argv[i]) || !strcmp("-background",argv[i])) {
167c95b42baSmrg	    if (++i>=argc) usage();
168c95b42baSmrg	    back_color = argv[i];
169c95b42baSmrg	    continue;
170c95b42baSmrg	}
171c95b42baSmrg	if (!strcmp("-solid", argv[i])) {
172c95b42baSmrg	    if (++i>=argc) usage();
173c95b42baSmrg	    solid_color = argv[i];
174c95b42baSmrg	    excl++;
175c95b42baSmrg	    continue;
176c95b42baSmrg	}
177c95b42baSmrg	if (!strcmp("-gray", argv[i]) || !strcmp("-grey", argv[i])) {
178c95b42baSmrg	    gray = 1;
179c95b42baSmrg	    excl++;
180c95b42baSmrg	    continue;
181c95b42baSmrg	}
182c95b42baSmrg	if (!strcmp("-bitmap", argv[i])) {
183c95b42baSmrg	    if (++i>=argc) usage();
184c95b42baSmrg	    bitmap_file = argv[i];
185c95b42baSmrg	    excl++;
186c95b42baSmrg	    continue;
187c95b42baSmrg	}
188c95b42baSmrg	if (!strcmp("-mod", argv[i])) {
189c95b42baSmrg	    if (++i>=argc) usage();
190c95b42baSmrg	    mod_x = atoi(argv[i]);
191c95b42baSmrg	    if (mod_x <= 0) mod_x = 1;
192c95b42baSmrg	    if (++i>=argc) usage();
193c95b42baSmrg	    mod_y = atoi(argv[i]);
194c95b42baSmrg	    if (mod_y <= 0) mod_y = 1;
195c95b42baSmrg	    excl++;
196c95b42baSmrg	    continue;
197c95b42baSmrg	}
198c95b42baSmrg	if (!strcmp("-rv",argv[i]) || !strcmp("-reverse",argv[i])) {
199c95b42baSmrg	    reverse = 1;
200c95b42baSmrg	    continue;
201c95b42baSmrg	}
202c95b42baSmrg	usage();
203c95b42baSmrg    }
204c95b42baSmrg
205c95b42baSmrg    /* Check for multiple use of exclusive options */
206c95b42baSmrg    if (excl > 1) {
207c95b42baSmrg	fprintf(stderr, "%s: choose only one of {solid, gray, bitmap, mod}\n",
208c95b42baSmrg		program_name);
209c95b42baSmrg	usage();
210c95b42baSmrg    }
211c95b42baSmrg
212c95b42baSmrg    dpy = XOpenDisplay(display_name);
213c95b42baSmrg    if (!dpy) {
214c95b42baSmrg	fprintf(stderr, "%s:  unable to open display '%s'\n",
215c95b42baSmrg		program_name, XDisplayName (display_name));
216c95b42baSmrg	exit (2);
217c95b42baSmrg    }
218c95b42baSmrg    screen = DefaultScreen(dpy);
219c95b42baSmrg    root = RootWindow(dpy, screen);
220c95b42baSmrg
221c95b42baSmrg    /* If there are no arguments then restore defaults. */
222c95b42baSmrg    if (!excl && !nonexcl)
223c95b42baSmrg	restore_defaults = 1;
224c95b42baSmrg
225c95b42baSmrg    /* Handle a cursor file */
226c95b42baSmrg    if (cursor_file) {
227c95b42baSmrg	cursor = CreateCursorFromFiles(cursor_file, cursor_mask);
228c95b42baSmrg	XDefineCursor(dpy, root, cursor);
229c95b42baSmrg	XFreeCursor(dpy, cursor);
230c95b42baSmrg    }
231c95b42baSmrg
232c95b42baSmrg    if (cursor_name) {
233c95b42baSmrg	cursor = CreateCursorFromName (cursor_name);
234c95b42baSmrg	if (cursor)
235c95b42baSmrg	{
236c95b42baSmrg	    XDefineCursor (dpy, root, cursor);
237c95b42baSmrg	    XFreeCursor (dpy, cursor);
238c95b42baSmrg	}
239c95b42baSmrg    }
240d80571a9Smrg    if (xcf) {
241d80571a9Smrg	XcursorImages *images = XcursorFilenameLoadImages(xcf, xcf_size);
242d80571a9Smrg	if (!images) {
243d80571a9Smrg	    fprintf(stderr, "Invalid cursor file \"%s\"\n", xcf);
244d80571a9Smrg	} else {
245d80571a9Smrg	    cursor = XcursorImagesLoadCursor(dpy, images);
246d80571a9Smrg	    if (cursor)
247d80571a9Smrg	    {
248d80571a9Smrg		XDefineCursor (dpy, root, cursor);
249d80571a9Smrg		XFreeCursor (dpy, cursor);
250d80571a9Smrg	    }
251d80571a9Smrg	}
252d80571a9Smrg    }
253c95b42baSmrg    /* Handle -gray and -grey options */
254c95b42baSmrg    if (gray) {
255c95b42baSmrg	bitmap = XCreateBitmapFromData(dpy, root, gray_bits,
256c95b42baSmrg				       gray_width, gray_height);
257c95b42baSmrg	SetBackgroundToBitmap(bitmap, gray_width, gray_height);
258c95b42baSmrg    }
259c95b42baSmrg
260c95b42baSmrg    /* Handle -solid option */
261c95b42baSmrg    if (solid_color) {
262c95b42baSmrg	XSetWindowBackground(dpy, root, NameToPixel(solid_color,
263c95b42baSmrg						    BlackPixel(dpy, screen)));
264c95b42baSmrg	XClearWindow(dpy, root);
265c95b42baSmrg	unsave_past = 1;
266c95b42baSmrg    }
267c95b42baSmrg
268c95b42baSmrg    /* Handle -bitmap option */
269c95b42baSmrg    if (bitmap_file) {
270c95b42baSmrg	bitmap = ReadBitmapFile(bitmap_file, &ww, &hh, (int *)NULL, (int *)NULL);
271c95b42baSmrg	SetBackgroundToBitmap(bitmap, ww, hh);
272c95b42baSmrg    }
273c95b42baSmrg
274c95b42baSmrg    /* Handle set background to a modula pattern */
275c95b42baSmrg    if (mod_x) {
276c95b42baSmrg	bitmap = MakeModulaBitmap(mod_x, mod_y);
277c95b42baSmrg	SetBackgroundToBitmap(bitmap, 16, 16);
278c95b42baSmrg    }
279c95b42baSmrg
280c95b42baSmrg    /* Handle set name */
281c95b42baSmrg    if (name)
282c95b42baSmrg	XStoreName(dpy, root, name);
283c95b42baSmrg
284c95b42baSmrg    /* Handle restore defaults */
285c95b42baSmrg    if (restore_defaults) {
286c95b42baSmrg	if (!cursor_file)
287c95b42baSmrg	    XUndefineCursor(dpy, root);
288c95b42baSmrg	if (!excl) {
289c95b42baSmrg	    XSetWindowBackgroundPixmap(dpy, root, (Pixmap) None);
290c95b42baSmrg	    XClearWindow(dpy, root);
291c95b42baSmrg	    unsave_past = 1;
292c95b42baSmrg	}
293c95b42baSmrg    }
294c95b42baSmrg
295c95b42baSmrg    FixupState();
296c95b42baSmrg    XCloseDisplay(dpy);
297c95b42baSmrg    exit (0);
298c95b42baSmrg}
299c95b42baSmrg
300c95b42baSmrg
301c95b42baSmrg/* Free past incarnation if needed, and retain state if needed. */
302c95b42baSmrgstatic void
303c95b42baSmrgFixupState(void)
304c95b42baSmrg{
305c95b42baSmrg    Atom prop, type;
306c95b42baSmrg    int format;
307c95b42baSmrg    unsigned long length, after;
308c95b42baSmrg    unsigned char *data;
309c95b42baSmrg
310c95b42baSmrg    if (!(DefaultVisual(dpy, screen)->class & Dynamic))
311c95b42baSmrg	unsave_past = 0;
312c95b42baSmrg    if (!unsave_past && !save_colors)
313c95b42baSmrg	return;
314c95b42baSmrg    prop = XInternAtom(dpy, "_XSETROOT_ID", False);
315c95b42baSmrg    if (unsave_past) {
316c95b42baSmrg	(void)XGetWindowProperty(dpy, root, prop, 0L, 1L, True, AnyPropertyType,
317c95b42baSmrg				 &type, &format, &length, &after, &data);
318c95b42baSmrg	if ((type == XA_PIXMAP) && (format == 32) &&
319c95b42baSmrg	    (length == 1) && (after == 0))
320c95b42baSmrg	    XKillClient(dpy, *((Pixmap *)data));
321c95b42baSmrg	else if (type != None)
322c95b42baSmrg	    fprintf(stderr, "%s: warning: _XSETROOT_ID property is garbage\n",
323c95b42baSmrg		    program_name);
324c95b42baSmrg    }
325c95b42baSmrg    if (save_colors) {
326c95b42baSmrg	if (!save_pixmap)
327c95b42baSmrg	    save_pixmap = XCreatePixmap(dpy, root, 1, 1, 1);
328c95b42baSmrg	XChangeProperty(dpy, root, prop, XA_PIXMAP, 32, PropModeReplace,
329c95b42baSmrg			(unsigned char *) &save_pixmap, 1);
330c95b42baSmrg	XSetCloseDownMode(dpy, RetainPermanent);
331c95b42baSmrg    }
332c95b42baSmrg}
333c95b42baSmrg
334c95b42baSmrg/*
335c95b42baSmrg * SetBackgroundToBitmap: Set the root window background to a caller supplied
336c95b42baSmrg *                        bitmap.
337c95b42baSmrg */
338c95b42baSmrgstatic void
339c95b42baSmrgSetBackgroundToBitmap(Pixmap bitmap, unsigned int width, unsigned int height)
340c95b42baSmrg{
341c95b42baSmrg    Pixmap pix;
342c95b42baSmrg    GC gc;
343c95b42baSmrg    XGCValues gc_init;
344c95b42baSmrg
345c95b42baSmrg    gc_init.foreground = NameToPixel(fore_color, BlackPixel(dpy, screen));
346c95b42baSmrg    gc_init.background = NameToPixel(back_color, WhitePixel(dpy, screen));
347c95b42baSmrg    if (reverse) {
348c95b42baSmrg	unsigned long temp=gc_init.foreground;
349c95b42baSmrg	gc_init.foreground=gc_init.background;
350c95b42baSmrg	gc_init.background=temp;
351c95b42baSmrg    }
352c95b42baSmrg    gc = XCreateGC(dpy, root, GCForeground|GCBackground, &gc_init);
353c95b42baSmrg    pix = XCreatePixmap(dpy, root, width, height,
354c95b42baSmrg			(unsigned int)DefaultDepth(dpy, screen));
355c95b42baSmrg    XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height, 0, 0, (unsigned long)1);
356c95b42baSmrg    XSetWindowBackgroundPixmap(dpy, root, pix);
357c95b42baSmrg    XFreeGC(dpy, gc);
358c95b42baSmrg    XFreePixmap(dpy, bitmap);
359c95b42baSmrg    if (save_colors)
360c95b42baSmrg	save_pixmap = pix;
361c95b42baSmrg    else
362c95b42baSmrg	XFreePixmap(dpy, pix);
363c95b42baSmrg    XClearWindow(dpy, root);
364c95b42baSmrg    unsave_past = 1;
365c95b42baSmrg}
366c95b42baSmrg
367c95b42baSmrg
368c95b42baSmrg/*
369c95b42baSmrg * CreateCursorFromFiles: make a cursor of the right colors from two bitmap
370c95b42baSmrg *                        files.
371c95b42baSmrg */
372c95b42baSmrg#define BITMAP_HOT_DEFAULT 8
373c95b42baSmrg
374c95b42baSmrgstatic Cursor
375c95b42baSmrgCreateCursorFromFiles(char *cursor_file, char *mask_file)
376c95b42baSmrg{
377c95b42baSmrg    Pixmap cursor_bitmap, mask_bitmap;
378c95b42baSmrg    unsigned int width, height, ww, hh;
379c95b42baSmrg    int x_hot, y_hot;
380c95b42baSmrg    Cursor cursor;
381c95b42baSmrg    XColor fg, bg, temp;
382c95b42baSmrg
383c95b42baSmrg    fg = NameToXColor(fore_color, BlackPixel(dpy, screen));
384c95b42baSmrg    bg = NameToXColor(back_color, WhitePixel(dpy, screen));
385c95b42baSmrg    if (reverse) {
386c95b42baSmrg	temp = fg; fg = bg; bg = temp;
387c95b42baSmrg    }
388c95b42baSmrg
389c95b42baSmrg    cursor_bitmap = ReadBitmapFile(cursor_file, &width, &height, &x_hot, &y_hot);
390c95b42baSmrg    mask_bitmap = ReadBitmapFile(mask_file, &ww, &hh, (int *)NULL, (int *)NULL);
391c95b42baSmrg
392c95b42baSmrg    if (width != ww || height != hh) {
393c95b42baSmrg	fprintf(stderr,
394c95b42baSmrg"%s: dimensions of cursor bitmap and cursor mask bitmap are different\n",
395c95b42baSmrg		program_name);
396c95b42baSmrg	exit(1);
397c95b42baSmrg	/*NOTREACHED*/
398c95b42baSmrg    }
399c95b42baSmrg
400c95b42baSmrg    if ((x_hot == -1) && (y_hot == -1)) {
401c95b42baSmrg	x_hot = BITMAP_HOT_DEFAULT;
402c95b42baSmrg	y_hot = BITMAP_HOT_DEFAULT;
403c95b42baSmrg    }
404c95b42baSmrg    if ((x_hot < 0) || (x_hot >= width) ||
405c95b42baSmrg	(y_hot < 0) || (y_hot >= height)) {
406c95b42baSmrg	fprintf(stderr, "%s: hotspot is outside cursor bounds\n", program_name);
407c95b42baSmrg	exit(1);
408c95b42baSmrg	/*NOTREACHED*/
409c95b42baSmrg    }
410c95b42baSmrg
411c95b42baSmrg    cursor = XCreatePixmapCursor(dpy, cursor_bitmap, mask_bitmap, &fg, &bg,
412c95b42baSmrg				 (unsigned int)x_hot, (unsigned int)y_hot);
413c95b42baSmrg    XFreePixmap(dpy, cursor_bitmap);
414c95b42baSmrg    XFreePixmap(dpy, mask_bitmap);
415c95b42baSmrg
416c95b42baSmrg    return(cursor);
417c95b42baSmrg}
418c95b42baSmrg
419c95b42baSmrgstatic Cursor
420c95b42baSmrgCreateCursorFromName(char *name)
421c95b42baSmrg{
422c95b42baSmrg    XColor fg, bg, temp;
423c95b42baSmrg    int	    i;
424c95b42baSmrg    Font    fid;
425c95b42baSmrg
426c95b42baSmrg    fg = NameToXColor(fore_color, BlackPixel(dpy, screen));
427c95b42baSmrg    bg = NameToXColor(back_color, WhitePixel(dpy, screen));
428c95b42baSmrg    if (reverse) {
429c95b42baSmrg	temp = fg; fg = bg; bg = temp;
430c95b42baSmrg    }
431c95b42baSmrg    i = XmuCursorNameToIndex (name);
432c95b42baSmrg    if (i == -1)
433c95b42baSmrg	return (Cursor) 0;
434c95b42baSmrg    fid = XLoadFont (dpy, "cursor");
435c95b42baSmrg    if (!fid)
436c95b42baSmrg	return (Cursor) 0;
437c95b42baSmrg    return XCreateGlyphCursor (dpy, fid, fid,
438c95b42baSmrg			       i, i+1, &fg, &bg);
439c95b42baSmrg}
440c95b42baSmrg
441c95b42baSmrg/*
442c95b42baSmrg * MakeModulaBitmap: Returns a modula bitmap based on an x & y mod.
443c95b42baSmrg */
444c95b42baSmrgstatic Pixmap
445c95b42baSmrgMakeModulaBitmap(int mod_x, int mod_y)
446c95b42baSmrg{
447c95b42baSmrg    int i;
448c95b42baSmrg    long pattern_line = 0;
449c95b42baSmrg    char modula_data[16*16/8];
450c95b42baSmrg
451c95b42baSmrg    for (i=16; i--; ) {
452c95b42baSmrg	pattern_line <<=1;
453c95b42baSmrg	if ((i % mod_x) == 0) pattern_line |= 0x0001;
454c95b42baSmrg    }
455c95b42baSmrg    for (i=0; i<16; i++) {
456c95b42baSmrg	if ((i % mod_y) == 0) {
457c95b42baSmrg	    modula_data[i*2] = (char)0xff;
458c95b42baSmrg	    modula_data[i*2+1] = (char)0xff;
459c95b42baSmrg	} else {
460c95b42baSmrg	    modula_data[i*2] = pattern_line & 0xff;
461c95b42baSmrg	    modula_data[i*2+1] = (pattern_line>>8) & 0xff;
462c95b42baSmrg	}
463c95b42baSmrg    }
464c95b42baSmrg
465c95b42baSmrg    return(XCreateBitmapFromData(dpy, root, modula_data, 16, 16));
466c95b42baSmrg}
467c95b42baSmrg
468c95b42baSmrg
469c95b42baSmrg/*
470c95b42baSmrg * NameToXColor: Convert the name of a color to its Xcolor value.
471c95b42baSmrg */
472c95b42baSmrgstatic XColor
473c95b42baSmrgNameToXColor(char *name, unsigned long pixel)
474c95b42baSmrg{
475c95b42baSmrg    XColor c;
476c95b42baSmrg
477c95b42baSmrg    if (!name || !*name) {
478c95b42baSmrg	c.pixel = pixel;
479c95b42baSmrg	XQueryColor(dpy, DefaultColormap(dpy, screen), &c);
480c95b42baSmrg    } else if (!XParseColor(dpy, DefaultColormap(dpy, screen), name, &c)) {
481c95b42baSmrg	fprintf(stderr, "%s: unknown color or bad color format: %s\n",
482c95b42baSmrg			program_name, name);
483c95b42baSmrg	exit(1);
484c95b42baSmrg	/*NOTREACHED*/
485c95b42baSmrg    }
486c95b42baSmrg    return(c);
487c95b42baSmrg}
488c95b42baSmrg
489c95b42baSmrgstatic unsigned long
490c95b42baSmrgNameToPixel(char *name, unsigned long pixel)
491c95b42baSmrg{
492c95b42baSmrg    XColor ecolor;
493c95b42baSmrg
494c95b42baSmrg    if (!name || !*name)
495c95b42baSmrg	return pixel;
496c95b42baSmrg    if (!XParseColor(dpy,DefaultColormap(dpy,screen),name,&ecolor)) {
497c95b42baSmrg	fprintf(stderr,"%s:  unknown color \"%s\"\n",program_name,name);
498c95b42baSmrg	exit(1);
499c95b42baSmrg	/*NOTREACHED*/
500c95b42baSmrg    }
501c95b42baSmrg    if (!XAllocColor(dpy, DefaultColormap(dpy, screen),&ecolor)) {
502c95b42baSmrg	fprintf(stderr, "%s:  unable to allocate color for \"%s\"\n",
503c95b42baSmrg		program_name, name);
504c95b42baSmrg	exit(1);
505c95b42baSmrg	/*NOTREACHED*/
506c95b42baSmrg    }
507c95b42baSmrg    if ((ecolor.pixel != BlackPixel(dpy, screen)) &&
508c95b42baSmrg	(ecolor.pixel != WhitePixel(dpy, screen)) &&
509c95b42baSmrg	(DefaultVisual(dpy, screen)->class & Dynamic))
510c95b42baSmrg	save_colors = 1;
511c95b42baSmrg    return(ecolor.pixel);
512c95b42baSmrg}
513c95b42baSmrg
514c95b42baSmrgstatic Pixmap
515c95b42baSmrgReadBitmapFile(char *filename, unsigned int *width, unsigned int *height,
516c95b42baSmrg	       int *x_hot, int *y_hot)
517c95b42baSmrg{
518c95b42baSmrg    Pixmap bitmap;
519c95b42baSmrg    int status;
520c95b42baSmrg
521c95b42baSmrg    status = XReadBitmapFile(dpy, root, filename, width,
522c95b42baSmrg			     height, &bitmap, x_hot, y_hot);
523c95b42baSmrg    if (status == BitmapSuccess)
524c95b42baSmrg      return(bitmap);
525c95b42baSmrg    else if (status == BitmapOpenFailed)
526c95b42baSmrg	fprintf(stderr, "%s: can't open file: %s\n", program_name, filename);
527c95b42baSmrg    else if (status == BitmapFileInvalid)
528c95b42baSmrg	fprintf(stderr, "%s: bad bitmap format file: %s\n",
529c95b42baSmrg			program_name, filename);
530c95b42baSmrg    else
531c95b42baSmrg	fprintf(stderr, "%s: insufficient memory for bitmap: %s",
532c95b42baSmrg			program_name, filename);
533c95b42baSmrg    exit(1);
534c95b42baSmrg    /*NOTREACHED*/
535c95b42baSmrg}
536