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