xsetroot.c revision 62aeb71d
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
3562aeb71dSmrg#ifdef HAVE_CONFIG_H
3662aeb71dSmrg# include "config.h"
3762aeb71dSmrg#endif
3862aeb71dSmrg
39c95b42baSmrg#include <X11/Xlib.h>
40c95b42baSmrg#include <X11/Xutil.h>
41c95b42baSmrg#include <X11/Xatom.h>
42c95b42baSmrg#include <X11/Xmu/CurUtil.h>
43d80571a9Smrg#include <X11/Xcursor/Xcursor.h>
44c95b42baSmrg#include <stdio.h>
45c95b42baSmrg#include <stdlib.h>
46c95b42baSmrg#include <string.h>
47c95b42baSmrg#include "X11/bitmaps/gray"
48c95b42baSmrg
49c95b42baSmrg#define Dynamic 1
50c95b42baSmrg
51f40e0d56Smrgstatic char *program_name;
52f40e0d56Smrgstatic Display *dpy;
53f40e0d56Smrgstatic int screen;
54f40e0d56Smrgstatic Window root;
55f40e0d56Smrgstatic char *fore_color = NULL;
56f40e0d56Smrgstatic char *back_color = NULL;
57f40e0d56Smrgstatic int reverse = 0;
58f40e0d56Smrgstatic int save_colors = 0;
59f40e0d56Smrgstatic int unsave_past = 0;
60f40e0d56Smrgstatic Pixmap save_pixmap = (Pixmap)None;
61c95b42baSmrg
6262aeb71dSmrgstatic void usage(void) _X_NORETURN;
63c95b42baSmrgstatic void FixupState(void);
64c95b42baSmrgstatic void SetBackgroundToBitmap(Pixmap bitmap,
65c95b42baSmrg				  unsigned int width, unsigned int height);
66c95b42baSmrgstatic Cursor CreateCursorFromFiles(char *cursor_file, char *mask_file);
67c95b42baSmrgstatic Cursor CreateCursorFromName(char *name);
68c95b42baSmrgstatic Pixmap MakeModulaBitmap(int mod_x, int mod_y);
69c95b42baSmrgstatic XColor NameToXColor(char *name, unsigned long pixel);
70c95b42baSmrgstatic unsigned long NameToPixel(char *name, unsigned long pixel);
71c95b42baSmrgstatic Pixmap ReadBitmapFile(char *filename, unsigned int *width, unsigned int *height, int *x_hot, int *y_hot);
72c95b42baSmrg
73c95b42baSmrgstatic void
74c95b42baSmrgusage(void)
75c95b42baSmrg{
7662aeb71dSmrg    fprintf(stderr, "usage: %s [options]\n%s\n", program_name,
7762aeb71dSmrg            "  where options are:\n"
7862aeb71dSmrg            "  -display <display>   or   -d <display>\n"
7962aeb71dSmrg            "  -fg <color>   or   -foreground <color>\n"
8062aeb71dSmrg            "  -bg <color>   or   -background <color>\n"
8162aeb71dSmrg            "  -rv   or   -reverse\n"
8262aeb71dSmrg            "  -def   or   -default\n"
8362aeb71dSmrg            "  -name <string>\n"
8462aeb71dSmrg            "  -cursor <cursor file> <mask file>\n"
8562aeb71dSmrg            "  -cursor_name <cursor-font name>\n"
8662aeb71dSmrg            "  -xcf <ARGB cursor file> <cursor size>\n"
8762aeb71dSmrg            "  -solid <color>\n"
8862aeb71dSmrg            "  -gray   or   -grey\n"
8962aeb71dSmrg            "  -bitmap <filename>\n"
9062aeb71dSmrg            "  -mod <x> <y>\n"
9162aeb71dSmrg            "  -help\n"
9262aeb71dSmrg            "  -version\n"
9362aeb71dSmrg            );
94c95b42baSmrg    exit(1);
95c95b42baSmrg    /*NOTREACHED*/
96c95b42baSmrg}
97c95b42baSmrg
98c95b42baSmrg
99c95b42baSmrgint
100c95b42baSmrgmain(int argc, char *argv[])
101c95b42baSmrg{
102c95b42baSmrg    int excl = 0;
103c95b42baSmrg    int nonexcl = 0;
104c95b42baSmrg    int restore_defaults = 0;
105c95b42baSmrg    char *display_name = NULL;
106c95b42baSmrg    char *name = NULL;
107c95b42baSmrg    char *cursor_file = NULL;
108c95b42baSmrg    char *cursor_mask = NULL;
109c95b42baSmrg    char *cursor_name = NULL;
110c95b42baSmrg    char *solid_color = NULL;
111d80571a9Smrg    char *xcf = NULL;
112d80571a9Smrg    int xcf_size = 32;
113c95b42baSmrg    Cursor cursor;
114c95b42baSmrg    int gray = 0;
115c95b42baSmrg    char *bitmap_file = NULL;
116c95b42baSmrg    int mod_x = 0;
117c95b42baSmrg    int mod_y = 0;
118c95b42baSmrg    register int i;
119c95b42baSmrg    unsigned int ww, hh;
120c95b42baSmrg    Pixmap bitmap;
121c95b42baSmrg
122c95b42baSmrg    program_name=argv[0];
123c95b42baSmrg
124c95b42baSmrg    for (i = 1; i < argc; i++) {
125c95b42baSmrg	if (!strcmp ("-display", argv[i]) || !strcmp ("-d", argv[i])) {
126c95b42baSmrg	    if (++i>=argc) usage ();
127c95b42baSmrg	    display_name = argv[i];
128c95b42baSmrg	    continue;
129c95b42baSmrg	}
130c95b42baSmrg	if (!strcmp("-help", argv[i])) {
131c95b42baSmrg	    usage();
132c95b42baSmrg	}
13362aeb71dSmrg	if (!strcmp("-version", argv[i])) {
13462aeb71dSmrg            printf("%s\n", PACKAGE_STRING);
13562aeb71dSmrg            exit(0);
13662aeb71dSmrg	}
137c95b42baSmrg	if (!strcmp("-def", argv[i]) || !strcmp("-default", argv[i])) {
138c95b42baSmrg	    restore_defaults = 1;
139c95b42baSmrg	    continue;
140c95b42baSmrg	}
141c95b42baSmrg	if (!strcmp("-name", argv[i])) {
142c95b42baSmrg	    if (++i>=argc) usage();
143c95b42baSmrg	    name = argv[i];
144c95b42baSmrg	    nonexcl++;
145c95b42baSmrg	    continue;
146c95b42baSmrg	}
147c95b42baSmrg	if (!strcmp("-cursor", argv[i])) {
148c95b42baSmrg	    if (++i>=argc) usage();
149c95b42baSmrg	    cursor_file = argv[i];
150c95b42baSmrg	    if (++i>=argc) usage();
151c95b42baSmrg	    cursor_mask = argv[i];
152c95b42baSmrg	    nonexcl++;
153c95b42baSmrg	    continue;
154c95b42baSmrg	}
155c95b42baSmrg	if (!strcmp("-cursor_name", argv[i])) {
156c95b42baSmrg	    if (++i>=argc) usage();
157c95b42baSmrg	    cursor_name = argv[i];
158c95b42baSmrg	    nonexcl++;
159c95b42baSmrg	    continue;
160c95b42baSmrg	}
161d80571a9Smrg	if (!strcmp("-xcf", argv[i])) {
162d80571a9Smrg	    if (++i>=argc) usage();
163d80571a9Smrg	    xcf = argv[i];
164d80571a9Smrg	    if (++i>=argc) usage();
165d80571a9Smrg	    xcf_size = atoi(argv[i]);
166d80571a9Smrg	    if (xcf_size <= 0)
167d80571a9Smrg		xcf_size = 32;
168d80571a9Smrg	    nonexcl++;
169d80571a9Smrg	    continue;
170d80571a9Smrg	}
171c95b42baSmrg	if (!strcmp("-fg",argv[i]) || !strcmp("-foreground",argv[i])) {
172c95b42baSmrg	    if (++i>=argc) usage();
173c95b42baSmrg	    fore_color = argv[i];
174c95b42baSmrg	    continue;
175c95b42baSmrg	}
176c95b42baSmrg	if (!strcmp("-bg",argv[i]) || !strcmp("-background",argv[i])) {
177c95b42baSmrg	    if (++i>=argc) usage();
178c95b42baSmrg	    back_color = argv[i];
179c95b42baSmrg	    continue;
180c95b42baSmrg	}
181c95b42baSmrg	if (!strcmp("-solid", argv[i])) {
182c95b42baSmrg	    if (++i>=argc) usage();
183c95b42baSmrg	    solid_color = argv[i];
184c95b42baSmrg	    excl++;
185c95b42baSmrg	    continue;
186c95b42baSmrg	}
187c95b42baSmrg	if (!strcmp("-gray", argv[i]) || !strcmp("-grey", argv[i])) {
188c95b42baSmrg	    gray = 1;
189c95b42baSmrg	    excl++;
190c95b42baSmrg	    continue;
191c95b42baSmrg	}
192c95b42baSmrg	if (!strcmp("-bitmap", argv[i])) {
193c95b42baSmrg	    if (++i>=argc) usage();
194c95b42baSmrg	    bitmap_file = argv[i];
195c95b42baSmrg	    excl++;
196c95b42baSmrg	    continue;
197c95b42baSmrg	}
198c95b42baSmrg	if (!strcmp("-mod", argv[i])) {
199c95b42baSmrg	    if (++i>=argc) usage();
200c95b42baSmrg	    mod_x = atoi(argv[i]);
201c95b42baSmrg	    if (mod_x <= 0) mod_x = 1;
202c95b42baSmrg	    if (++i>=argc) usage();
203c95b42baSmrg	    mod_y = atoi(argv[i]);
204c95b42baSmrg	    if (mod_y <= 0) mod_y = 1;
205c95b42baSmrg	    excl++;
206c95b42baSmrg	    continue;
207c95b42baSmrg	}
208c95b42baSmrg	if (!strcmp("-rv",argv[i]) || !strcmp("-reverse",argv[i])) {
209c95b42baSmrg	    reverse = 1;
210c95b42baSmrg	    continue;
211c95b42baSmrg	}
212c95b42baSmrg	usage();
213c95b42baSmrg    }
214c95b42baSmrg
215c95b42baSmrg    /* Check for multiple use of exclusive options */
216c95b42baSmrg    if (excl > 1) {
217c95b42baSmrg	fprintf(stderr, "%s: choose only one of {solid, gray, bitmap, mod}\n",
218c95b42baSmrg		program_name);
219c95b42baSmrg	usage();
220c95b42baSmrg    }
221c95b42baSmrg
222c95b42baSmrg    dpy = XOpenDisplay(display_name);
223c95b42baSmrg    if (!dpy) {
224c95b42baSmrg	fprintf(stderr, "%s:  unable to open display '%s'\n",
225c95b42baSmrg		program_name, XDisplayName (display_name));
226c95b42baSmrg	exit (2);
227c95b42baSmrg    }
228c95b42baSmrg    screen = DefaultScreen(dpy);
229c95b42baSmrg    root = RootWindow(dpy, screen);
230c95b42baSmrg
231c95b42baSmrg    /* If there are no arguments then restore defaults. */
232c95b42baSmrg    if (!excl && !nonexcl)
233c95b42baSmrg	restore_defaults = 1;
234c95b42baSmrg
235c95b42baSmrg    /* Handle a cursor file */
236c95b42baSmrg    if (cursor_file) {
237c95b42baSmrg	cursor = CreateCursorFromFiles(cursor_file, cursor_mask);
238c95b42baSmrg	XDefineCursor(dpy, root, cursor);
239c95b42baSmrg	XFreeCursor(dpy, cursor);
240c95b42baSmrg    }
241c95b42baSmrg
242c95b42baSmrg    if (cursor_name) {
243c95b42baSmrg	cursor = CreateCursorFromName (cursor_name);
244c95b42baSmrg	if (cursor)
245c95b42baSmrg	{
246c95b42baSmrg	    XDefineCursor (dpy, root, cursor);
247c95b42baSmrg	    XFreeCursor (dpy, cursor);
248c95b42baSmrg	}
249c95b42baSmrg    }
250d80571a9Smrg    if (xcf) {
251d80571a9Smrg	XcursorImages *images = XcursorFilenameLoadImages(xcf, xcf_size);
252d80571a9Smrg	if (!images) {
253d80571a9Smrg	    fprintf(stderr, "Invalid cursor file \"%s\"\n", xcf);
254d80571a9Smrg	} else {
255d80571a9Smrg	    cursor = XcursorImagesLoadCursor(dpy, images);
256d80571a9Smrg	    if (cursor)
257d80571a9Smrg	    {
258d80571a9Smrg		XDefineCursor (dpy, root, cursor);
259d80571a9Smrg		XFreeCursor (dpy, cursor);
260d80571a9Smrg	    }
261d80571a9Smrg	}
262d80571a9Smrg    }
263c95b42baSmrg    /* Handle -gray and -grey options */
264c95b42baSmrg    if (gray) {
265c95b42baSmrg	bitmap = XCreateBitmapFromData(dpy, root, gray_bits,
266c95b42baSmrg				       gray_width, gray_height);
267c95b42baSmrg	SetBackgroundToBitmap(bitmap, gray_width, gray_height);
268c95b42baSmrg    }
269c95b42baSmrg
270c95b42baSmrg    /* Handle -solid option */
271c95b42baSmrg    if (solid_color) {
272c95b42baSmrg	XSetWindowBackground(dpy, root, NameToPixel(solid_color,
273c95b42baSmrg						    BlackPixel(dpy, screen)));
274c95b42baSmrg	XClearWindow(dpy, root);
275c95b42baSmrg	unsave_past = 1;
276c95b42baSmrg    }
277c95b42baSmrg
278c95b42baSmrg    /* Handle -bitmap option */
279c95b42baSmrg    if (bitmap_file) {
280c95b42baSmrg	bitmap = ReadBitmapFile(bitmap_file, &ww, &hh, (int *)NULL, (int *)NULL);
281c95b42baSmrg	SetBackgroundToBitmap(bitmap, ww, hh);
282c95b42baSmrg    }
283c95b42baSmrg
284c95b42baSmrg    /* Handle set background to a modula pattern */
285c95b42baSmrg    if (mod_x) {
286c95b42baSmrg	bitmap = MakeModulaBitmap(mod_x, mod_y);
287c95b42baSmrg	SetBackgroundToBitmap(bitmap, 16, 16);
288c95b42baSmrg    }
289c95b42baSmrg
290c95b42baSmrg    /* Handle set name */
291c95b42baSmrg    if (name)
292c95b42baSmrg	XStoreName(dpy, root, name);
293c95b42baSmrg
294c95b42baSmrg    /* Handle restore defaults */
295c95b42baSmrg    if (restore_defaults) {
296c95b42baSmrg	if (!cursor_file)
297c95b42baSmrg	    XUndefineCursor(dpy, root);
298c95b42baSmrg	if (!excl) {
299c95b42baSmrg	    XSetWindowBackgroundPixmap(dpy, root, (Pixmap) None);
300c95b42baSmrg	    XClearWindow(dpy, root);
301c95b42baSmrg	    unsave_past = 1;
302c95b42baSmrg	}
303c95b42baSmrg    }
304c95b42baSmrg
305c95b42baSmrg    FixupState();
306c95b42baSmrg    XCloseDisplay(dpy);
307c95b42baSmrg    exit (0);
308c95b42baSmrg}
309c95b42baSmrg
310c95b42baSmrg
311c95b42baSmrg/* Free past incarnation if needed, and retain state if needed. */
312c95b42baSmrgstatic void
313c95b42baSmrgFixupState(void)
314c95b42baSmrg{
315c95b42baSmrg    Atom prop, type;
316c95b42baSmrg    int format;
317c95b42baSmrg    unsigned long length, after;
318c95b42baSmrg    unsigned char *data;
319c95b42baSmrg
320c95b42baSmrg    if (!(DefaultVisual(dpy, screen)->class & Dynamic))
321c95b42baSmrg	unsave_past = 0;
322c95b42baSmrg    if (!unsave_past && !save_colors)
323c95b42baSmrg	return;
324c95b42baSmrg    prop = XInternAtom(dpy, "_XSETROOT_ID", False);
325c95b42baSmrg    if (unsave_past) {
326c95b42baSmrg	(void)XGetWindowProperty(dpy, root, prop, 0L, 1L, True, AnyPropertyType,
327c95b42baSmrg				 &type, &format, &length, &after, &data);
328c95b42baSmrg	if ((type == XA_PIXMAP) && (format == 32) &&
329c95b42baSmrg	    (length == 1) && (after == 0))
330c95b42baSmrg	    XKillClient(dpy, *((Pixmap *)data));
331c95b42baSmrg	else if (type != None)
332c95b42baSmrg	    fprintf(stderr, "%s: warning: _XSETROOT_ID property is garbage\n",
333c95b42baSmrg		    program_name);
334c95b42baSmrg    }
335c95b42baSmrg    if (save_colors) {
336c95b42baSmrg	if (!save_pixmap)
337c95b42baSmrg	    save_pixmap = XCreatePixmap(dpy, root, 1, 1, 1);
338c95b42baSmrg	XChangeProperty(dpy, root, prop, XA_PIXMAP, 32, PropModeReplace,
339c95b42baSmrg			(unsigned char *) &save_pixmap, 1);
340c95b42baSmrg	XSetCloseDownMode(dpy, RetainPermanent);
341c95b42baSmrg    }
342c95b42baSmrg}
343c95b42baSmrg
344c95b42baSmrg/*
345c95b42baSmrg * SetBackgroundToBitmap: Set the root window background to a caller supplied
346c95b42baSmrg *                        bitmap.
347c95b42baSmrg */
348c95b42baSmrgstatic void
349c95b42baSmrgSetBackgroundToBitmap(Pixmap bitmap, unsigned int width, unsigned int height)
350c95b42baSmrg{
351c95b42baSmrg    Pixmap pix;
352c95b42baSmrg    GC gc;
353c95b42baSmrg    XGCValues gc_init;
354c95b42baSmrg
355c95b42baSmrg    gc_init.foreground = NameToPixel(fore_color, BlackPixel(dpy, screen));
356c95b42baSmrg    gc_init.background = NameToPixel(back_color, WhitePixel(dpy, screen));
357c95b42baSmrg    if (reverse) {
358c95b42baSmrg	unsigned long temp=gc_init.foreground;
359c95b42baSmrg	gc_init.foreground=gc_init.background;
360c95b42baSmrg	gc_init.background=temp;
361c95b42baSmrg    }
362c95b42baSmrg    gc = XCreateGC(dpy, root, GCForeground|GCBackground, &gc_init);
363c95b42baSmrg    pix = XCreatePixmap(dpy, root, width, height,
364c95b42baSmrg			(unsigned int)DefaultDepth(dpy, screen));
365c95b42baSmrg    XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height, 0, 0, (unsigned long)1);
366c95b42baSmrg    XSetWindowBackgroundPixmap(dpy, root, pix);
367c95b42baSmrg    XFreeGC(dpy, gc);
368c95b42baSmrg    XFreePixmap(dpy, bitmap);
369c95b42baSmrg    if (save_colors)
370c95b42baSmrg	save_pixmap = pix;
371c95b42baSmrg    else
372c95b42baSmrg	XFreePixmap(dpy, pix);
373c95b42baSmrg    XClearWindow(dpy, root);
374c95b42baSmrg    unsave_past = 1;
375c95b42baSmrg}
376c95b42baSmrg
377c95b42baSmrg
378c95b42baSmrg/*
379c95b42baSmrg * CreateCursorFromFiles: make a cursor of the right colors from two bitmap
380c95b42baSmrg *                        files.
381c95b42baSmrg */
382c95b42baSmrg#define BITMAP_HOT_DEFAULT 8
383c95b42baSmrg
384c95b42baSmrgstatic Cursor
385c95b42baSmrgCreateCursorFromFiles(char *cursor_file, char *mask_file)
386c95b42baSmrg{
387c95b42baSmrg    Pixmap cursor_bitmap, mask_bitmap;
388c95b42baSmrg    unsigned int width, height, ww, hh;
389c95b42baSmrg    int x_hot, y_hot;
390c95b42baSmrg    Cursor cursor;
391c95b42baSmrg    XColor fg, bg, temp;
392c95b42baSmrg
393c95b42baSmrg    fg = NameToXColor(fore_color, BlackPixel(dpy, screen));
394c95b42baSmrg    bg = NameToXColor(back_color, WhitePixel(dpy, screen));
395c95b42baSmrg    if (reverse) {
396c95b42baSmrg	temp = fg; fg = bg; bg = temp;
397c95b42baSmrg    }
398c95b42baSmrg
399c95b42baSmrg    cursor_bitmap = ReadBitmapFile(cursor_file, &width, &height, &x_hot, &y_hot);
400c95b42baSmrg    mask_bitmap = ReadBitmapFile(mask_file, &ww, &hh, (int *)NULL, (int *)NULL);
401c95b42baSmrg
402c95b42baSmrg    if (width != ww || height != hh) {
403c95b42baSmrg	fprintf(stderr,
404c95b42baSmrg"%s: dimensions of cursor bitmap and cursor mask bitmap are different\n",
405c95b42baSmrg		program_name);
406c95b42baSmrg	exit(1);
407c95b42baSmrg	/*NOTREACHED*/
408c95b42baSmrg    }
409c95b42baSmrg
410c95b42baSmrg    if ((x_hot == -1) && (y_hot == -1)) {
411c95b42baSmrg	x_hot = BITMAP_HOT_DEFAULT;
412c95b42baSmrg	y_hot = BITMAP_HOT_DEFAULT;
413c95b42baSmrg    }
414c95b42baSmrg    if ((x_hot < 0) || (x_hot >= width) ||
415c95b42baSmrg	(y_hot < 0) || (y_hot >= height)) {
416c95b42baSmrg	fprintf(stderr, "%s: hotspot is outside cursor bounds\n", program_name);
417c95b42baSmrg	exit(1);
418c95b42baSmrg	/*NOTREACHED*/
419c95b42baSmrg    }
420c95b42baSmrg
421c95b42baSmrg    cursor = XCreatePixmapCursor(dpy, cursor_bitmap, mask_bitmap, &fg, &bg,
422c95b42baSmrg				 (unsigned int)x_hot, (unsigned int)y_hot);
423c95b42baSmrg    XFreePixmap(dpy, cursor_bitmap);
424c95b42baSmrg    XFreePixmap(dpy, mask_bitmap);
425c95b42baSmrg
426c95b42baSmrg    return(cursor);
427c95b42baSmrg}
428c95b42baSmrg
429c95b42baSmrgstatic Cursor
430c95b42baSmrgCreateCursorFromName(char *name)
431c95b42baSmrg{
432c95b42baSmrg    XColor fg, bg, temp;
433c95b42baSmrg    int	    i;
434c95b42baSmrg    Font    fid;
435c95b42baSmrg
436c95b42baSmrg    fg = NameToXColor(fore_color, BlackPixel(dpy, screen));
437c95b42baSmrg    bg = NameToXColor(back_color, WhitePixel(dpy, screen));
438c95b42baSmrg    if (reverse) {
439c95b42baSmrg	temp = fg; fg = bg; bg = temp;
440c95b42baSmrg    }
441c95b42baSmrg    i = XmuCursorNameToIndex (name);
442c95b42baSmrg    if (i == -1)
443c95b42baSmrg	return (Cursor) 0;
444c95b42baSmrg    fid = XLoadFont (dpy, "cursor");
445c95b42baSmrg    if (!fid)
446c95b42baSmrg	return (Cursor) 0;
447c95b42baSmrg    return XCreateGlyphCursor (dpy, fid, fid,
448c95b42baSmrg			       i, i+1, &fg, &bg);
449c95b42baSmrg}
450c95b42baSmrg
451c95b42baSmrg/*
452c95b42baSmrg * MakeModulaBitmap: Returns a modula bitmap based on an x & y mod.
453c95b42baSmrg */
454c95b42baSmrgstatic Pixmap
455c95b42baSmrgMakeModulaBitmap(int mod_x, int mod_y)
456c95b42baSmrg{
457c95b42baSmrg    int i;
458c95b42baSmrg    long pattern_line = 0;
459c95b42baSmrg    char modula_data[16*16/8];
460c95b42baSmrg
461c95b42baSmrg    for (i=16; i--; ) {
462c95b42baSmrg	pattern_line <<=1;
463c95b42baSmrg	if ((i % mod_x) == 0) pattern_line |= 0x0001;
464c95b42baSmrg    }
465c95b42baSmrg    for (i=0; i<16; i++) {
466c95b42baSmrg	if ((i % mod_y) == 0) {
467c95b42baSmrg	    modula_data[i*2] = (char)0xff;
468c95b42baSmrg	    modula_data[i*2+1] = (char)0xff;
469c95b42baSmrg	} else {
470c95b42baSmrg	    modula_data[i*2] = pattern_line & 0xff;
471c95b42baSmrg	    modula_data[i*2+1] = (pattern_line>>8) & 0xff;
472c95b42baSmrg	}
473c95b42baSmrg    }
474c95b42baSmrg
475c95b42baSmrg    return(XCreateBitmapFromData(dpy, root, modula_data, 16, 16));
476c95b42baSmrg}
477c95b42baSmrg
478c95b42baSmrg
479c95b42baSmrg/*
480c95b42baSmrg * NameToXColor: Convert the name of a color to its Xcolor value.
481c95b42baSmrg */
482c95b42baSmrgstatic XColor
483c95b42baSmrgNameToXColor(char *name, unsigned long pixel)
484c95b42baSmrg{
485c95b42baSmrg    XColor c;
486c95b42baSmrg
487c95b42baSmrg    if (!name || !*name) {
488c95b42baSmrg	c.pixel = pixel;
489c95b42baSmrg	XQueryColor(dpy, DefaultColormap(dpy, screen), &c);
490c95b42baSmrg    } else if (!XParseColor(dpy, DefaultColormap(dpy, screen), name, &c)) {
491c95b42baSmrg	fprintf(stderr, "%s: unknown color or bad color format: %s\n",
492c95b42baSmrg			program_name, name);
493c95b42baSmrg	exit(1);
494c95b42baSmrg	/*NOTREACHED*/
495c95b42baSmrg    }
496c95b42baSmrg    return(c);
497c95b42baSmrg}
498c95b42baSmrg
499c95b42baSmrgstatic unsigned long
500c95b42baSmrgNameToPixel(char *name, unsigned long pixel)
501c95b42baSmrg{
502c95b42baSmrg    XColor ecolor;
503c95b42baSmrg
504c95b42baSmrg    if (!name || !*name)
505c95b42baSmrg	return pixel;
506c95b42baSmrg    if (!XParseColor(dpy,DefaultColormap(dpy,screen),name,&ecolor)) {
507c95b42baSmrg	fprintf(stderr,"%s:  unknown color \"%s\"\n",program_name,name);
508c95b42baSmrg	exit(1);
509c95b42baSmrg	/*NOTREACHED*/
510c95b42baSmrg    }
511c95b42baSmrg    if (!XAllocColor(dpy, DefaultColormap(dpy, screen),&ecolor)) {
512c95b42baSmrg	fprintf(stderr, "%s:  unable to allocate color for \"%s\"\n",
513c95b42baSmrg		program_name, name);
514c95b42baSmrg	exit(1);
515c95b42baSmrg	/*NOTREACHED*/
516c95b42baSmrg    }
517c95b42baSmrg    if ((ecolor.pixel != BlackPixel(dpy, screen)) &&
518c95b42baSmrg	(ecolor.pixel != WhitePixel(dpy, screen)) &&
519c95b42baSmrg	(DefaultVisual(dpy, screen)->class & Dynamic))
520c95b42baSmrg	save_colors = 1;
521c95b42baSmrg    return(ecolor.pixel);
522c95b42baSmrg}
523c95b42baSmrg
524c95b42baSmrgstatic Pixmap
525c95b42baSmrgReadBitmapFile(char *filename, unsigned int *width, unsigned int *height,
526c95b42baSmrg	       int *x_hot, int *y_hot)
527c95b42baSmrg{
528c95b42baSmrg    Pixmap bitmap;
529c95b42baSmrg    int status;
530c95b42baSmrg
531c95b42baSmrg    status = XReadBitmapFile(dpy, root, filename, width,
532c95b42baSmrg			     height, &bitmap, x_hot, y_hot);
533c95b42baSmrg    if (status == BitmapSuccess)
534c95b42baSmrg      return(bitmap);
535c95b42baSmrg    else if (status == BitmapOpenFailed)
536c95b42baSmrg	fprintf(stderr, "%s: can't open file: %s\n", program_name, filename);
537c95b42baSmrg    else if (status == BitmapFileInvalid)
538c95b42baSmrg	fprintf(stderr, "%s: bad bitmap format file: %s\n",
539c95b42baSmrg			program_name, filename);
540c95b42baSmrg    else
541c95b42baSmrg	fprintf(stderr, "%s: insufficient memory for bitmap: %s",
542c95b42baSmrg			program_name, filename);
543c95b42baSmrg    exit(1);
544c95b42baSmrg    /*NOTREACHED*/
545c95b42baSmrg}
546