3 Copyright 1987, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
27 * xsetroot.c MIT Project Athena, X Window System root window
28 * parameter setting utility. This program will set
29 * various parameters of the X root window.
31 * Author: Mark Lillibridge, MIT Project Athena
36 #include <X11/Xutil.h>
37 #include <X11/Xatom.h>
38 #include <X11/Xmu/CurUtil.h>
39 #include <X11/Xcursor/Xcursor.h>
43 #include "X11/bitmaps/gray"
47 static char *program_name;
51 static char *fore_color = NULL;
52 static char *back_color = NULL;
53 static int reverse = 0;
54 static int save_colors = 0;
55 static int unsave_past = 0;
56 static Pixmap save_pixmap = (Pixmap)None;
58 static void usage(void);
59 static void FixupState(void);
60 static void SetBackgroundToBitmap(Pixmap bitmap,
61 unsigned int width, unsigned int height);
62 static Cursor CreateCursorFromFiles(char *cursor_file, char *mask_file);
63 static Cursor CreateCursorFromName(char *name);
64 static Pixmap MakeModulaBitmap(int mod_x, int mod_y);
65 static XColor NameToXColor(char *name, unsigned long pixel);
66 static unsigned long NameToPixel(char *name, unsigned long pixel);
67 static Pixmap ReadBitmapFile(char *filename, unsigned int *width, unsigned int *height, int *x_hot, int *y_hot);
72 fprintf(stderr, "usage: %s [options]\n", program_name);
73 fprintf(stderr, " where options are:\n");
74 fprintf(stderr, " -display <display> or -d <display>\n");
75 fprintf(stderr, " -fg <color> or -foreground <color>\n");
76 fprintf(stderr, " -bg <color> or -background <color>\n");
77 fprintf(stderr, " -rv or -reverse\n");
78 fprintf(stderr, " -help\n");
79 fprintf(stderr, " -def or -default\n");
80 fprintf(stderr, " -name <string>\n");
81 fprintf(stderr, " -cursor <cursor file> <mask file>\n");
82 fprintf(stderr, " -cursor_name <cursor-font name>\n");
83 fprintf(stderr, " -xcf <ARGB cursor file> <cursor size>\n");
84 fprintf(stderr, " -solid <color>\n");
85 fprintf(stderr, " -gray or -grey\n");
86 fprintf(stderr, " -bitmap <filename>\n");
87 fprintf(stderr, " -mod <x> <y>\n");
94 main(int argc, char *argv[])
98 int restore_defaults = 0;
99 char *display_name = NULL;
101 char *cursor_file = NULL;
102 char *cursor_mask = NULL;
103 char *cursor_name = NULL;
104 char *solid_color = NULL;
109 char *bitmap_file = NULL;
116 program_name=argv[0];
118 for (i = 1; i < argc; i++) {
119 if (!strcmp ("-display", argv[i]) || !strcmp ("-d", argv[i])) {
120 if (++i>=argc) usage ();
121 display_name = argv[i];
124 if (!strcmp("-help", argv[i])) {
127 if (!strcmp("-def", argv[i]) || !strcmp("-default", argv[i])) {
128 restore_defaults = 1;
131 if (!strcmp("-name", argv[i])) {
132 if (++i>=argc) usage();
137 if (!strcmp("-cursor", argv[i])) {
138 if (++i>=argc) usage();
139 cursor_file = argv[i];
140 if (++i>=argc) usage();
141 cursor_mask = argv[i];
145 if (!strcmp("-cursor_name", argv[i])) {
146 if (++i>=argc) usage();
147 cursor_name = argv[i];
151 if (!strcmp("-xcf", argv[i])) {
152 if (++i>=argc) usage();
154 if (++i>=argc) usage();
155 xcf_size = atoi(argv[i]);
161 if (!strcmp("-fg",argv[i]) || !strcmp("-foreground",argv[i])) {
162 if (++i>=argc) usage();
163 fore_color = argv[i];
166 if (!strcmp("-bg",argv[i]) || !strcmp("-background",argv[i])) {
167 if (++i>=argc) usage();
168 back_color = argv[i];
171 if (!strcmp("-solid", argv[i])) {
172 if (++i>=argc) usage();
173 solid_color = argv[i];
177 if (!strcmp("-gray", argv[i]) || !strcmp("-grey", argv[i])) {
182 if (!strcmp("-bitmap", argv[i])) {
183 if (++i>=argc) usage();
184 bitmap_file = argv[i];
188 if (!strcmp("-mod", argv[i])) {
189 if (++i>=argc) usage();
190 mod_x = atoi(argv[i]);
191 if (mod_x <= 0) mod_x = 1;
192 if (++i>=argc) usage();
193 mod_y = atoi(argv[i]);
194 if (mod_y <= 0) mod_y = 1;
198 if (!strcmp("-rv",argv[i]) || !strcmp("-reverse",argv[i])) {
205 /* Check for multiple use of exclusive options */
207 fprintf(stderr, "%s: choose only one of {solid, gray, bitmap, mod}\n",
212 dpy = XOpenDisplay(display_name);
214 fprintf(stderr, "%s: unable to open display '%s'\n",
215 program_name, XDisplayName (display_name));
218 screen = DefaultScreen(dpy);
219 root = RootWindow(dpy, screen);
221 /* If there are no arguments then restore defaults. */
222 if (!excl && !nonexcl)
223 restore_defaults = 1;
225 /* Handle a cursor file */
227 cursor = CreateCursorFromFiles(cursor_file, cursor_mask);
228 XDefineCursor(dpy, root, cursor);
229 XFreeCursor(dpy, cursor);
233 cursor = CreateCursorFromName (cursor_name);
236 XDefineCursor (dpy, root, cursor);
237 XFreeCursor (dpy, cursor);
241 XcursorImages *images = XcursorFilenameLoadImages(xcf, xcf_size);
243 fprintf(stderr, "Invalid cursor file \"%s\"\n", xcf);
245 cursor = XcursorImagesLoadCursor(dpy, images);
248 XDefineCursor (dpy, root, cursor);
249 XFreeCursor (dpy, cursor);
253 /* Handle -gray and -grey options */
255 bitmap = XCreateBitmapFromData(dpy, root, gray_bits,
256 gray_width, gray_height);
257 SetBackgroundToBitmap(bitmap, gray_width, gray_height);
260 /* Handle -solid option */
262 XSetWindowBackground(dpy, root, NameToPixel(solid_color,
263 BlackPixel(dpy, screen)));
264 XClearWindow(dpy, root);
268 /* Handle -bitmap option */
270 bitmap = ReadBitmapFile(bitmap_file, &ww, &hh, (int *)NULL, (int *)NULL);
271 SetBackgroundToBitmap(bitmap, ww, hh);
274 /* Handle set background to a modula pattern */
276 bitmap = MakeModulaBitmap(mod_x, mod_y);
277 SetBackgroundToBitmap(bitmap, 16, 16);
280 /* Handle set name */
282 XStoreName(dpy, root, name);
284 /* Handle restore defaults */
285 if (restore_defaults) {
287 XUndefineCursor(dpy, root);
289 XSetWindowBackgroundPixmap(dpy, root, (Pixmap) None);
290 XClearWindow(dpy, root);
301 /* Free past incarnation if needed, and retain state if needed. */
307 unsigned long length, after;
310 if (!(DefaultVisual(dpy, screen)->class & Dynamic))
312 if (!unsave_past && !save_colors)
314 prop = XInternAtom(dpy, "_XSETROOT_ID", False);
316 (void)XGetWindowProperty(dpy, root, prop, 0L, 1L, True, AnyPropertyType,
317 &type, &format, &length, &after, &data);
318 if ((type == XA_PIXMAP) && (format == 32) &&
319 (length == 1) && (after == 0))
320 XKillClient(dpy, *((Pixmap *)data));
321 else if (type != None)
322 fprintf(stderr, "%s: warning: _XSETROOT_ID property is garbage\n",
327 save_pixmap = XCreatePixmap(dpy, root, 1, 1, 1);
328 XChangeProperty(dpy, root, prop, XA_PIXMAP, 32, PropModeReplace,
329 (unsigned char *) &save_pixmap, 1);
330 XSetCloseDownMode(dpy, RetainPermanent);
335 * SetBackgroundToBitmap: Set the root window background to a caller supplied
339 SetBackgroundToBitmap(Pixmap bitmap, unsigned int width, unsigned int height)
345 gc_init.foreground = NameToPixel(fore_color, BlackPixel(dpy, screen));
346 gc_init.background = NameToPixel(back_color, WhitePixel(dpy, screen));
348 unsigned long temp=gc_init.foreground;
349 gc_init.foreground=gc_init.background;
350 gc_init.background=temp;
352 gc = XCreateGC(dpy, root, GCForeground|GCBackground, &gc_init);
353 pix = XCreatePixmap(dpy, root, width, height,
354 (unsigned int)DefaultDepth(dpy, screen));
355 XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height, 0, 0, (unsigned long)1);
356 XSetWindowBackgroundPixmap(dpy, root, pix);
358 XFreePixmap(dpy, bitmap);
362 XFreePixmap(dpy, pix);
363 XClearWindow(dpy, root);
369 * CreateCursorFromFiles: make a cursor of the right colors from two bitmap
372 #define BITMAP_HOT_DEFAULT 8
375 CreateCursorFromFiles(char *cursor_file, char *mask_file)
377 Pixmap cursor_bitmap, mask_bitmap;
378 unsigned int width, height, ww, hh;
383 fg = NameToXColor(fore_color, BlackPixel(dpy, screen));
384 bg = NameToXColor(back_color, WhitePixel(dpy, screen));
386 temp = fg; fg = bg; bg = temp;
389 cursor_bitmap = ReadBitmapFile(cursor_file, &width, &height, &x_hot, &y_hot);
390 mask_bitmap = ReadBitmapFile(mask_file, &ww, &hh, (int *)NULL, (int *)NULL);
392 if (width != ww || height != hh) {
394 "%s: dimensions of cursor bitmap and cursor mask bitmap are different\n",
400 if ((x_hot == -1) && (y_hot == -1)) {
401 x_hot = BITMAP_HOT_DEFAULT;
402 y_hot = BITMAP_HOT_DEFAULT;
404 if ((x_hot < 0) || (x_hot >= width) ||
405 (y_hot < 0) || (y_hot >= height)) {
406 fprintf(stderr, "%s: hotspot is outside cursor bounds\n", program_name);
411 cursor = XCreatePixmapCursor(dpy, cursor_bitmap, mask_bitmap, &fg, &bg,
412 (unsigned int)x_hot, (unsigned int)y_hot);
413 XFreePixmap(dpy, cursor_bitmap);
414 XFreePixmap(dpy, mask_bitmap);
420 CreateCursorFromName(char *name)
426 fg = NameToXColor(fore_color, BlackPixel(dpy, screen));
427 bg = NameToXColor(back_color, WhitePixel(dpy, screen));
429 temp = fg; fg = bg; bg = temp;
431 i = XmuCursorNameToIndex (name);
434 fid = XLoadFont (dpy, "cursor");
437 return XCreateGlyphCursor (dpy, fid, fid,
442 * MakeModulaBitmap: Returns a modula bitmap based on an x & y mod.
445 MakeModulaBitmap(int mod_x, int mod_y)
448 long pattern_line = 0;
449 char modula_data[16*16/8];
453 if ((i % mod_x) == 0) pattern_line |= 0x0001;
455 for (i=0; i<16; i++) {
456 if ((i % mod_y) == 0) {
457 modula_data[i*2] = (char)0xff;
458 modula_data[i*2+1] = (char)0xff;
460 modula_data[i*2] = pattern_line & 0xff;
461 modula_data[i*2+1] = (pattern_line>>8) & 0xff;
465 return(XCreateBitmapFromData(dpy, root, modula_data, 16, 16));
470 * NameToXColor: Convert the name of a color to its Xcolor value.
473 NameToXColor(char *name, unsigned long pixel)
477 if (!name || !*name) {
479 XQueryColor(dpy, DefaultColormap(dpy, screen), &c);
480 } else if (!XParseColor(dpy, DefaultColormap(dpy, screen), name, &c)) {
481 fprintf(stderr, "%s: unknown color or bad color format: %s\n",
490 NameToPixel(char *name, unsigned long pixel)
496 if (!XParseColor(dpy,DefaultColormap(dpy,screen),name,&ecolor)) {
497 fprintf(stderr,"%s: unknown color \"%s\"\n",program_name,name);
501 if (!XAllocColor(dpy, DefaultColormap(dpy, screen),&ecolor)) {
502 fprintf(stderr, "%s: unable to allocate color for \"%s\"\n",
507 if ((ecolor.pixel != BlackPixel(dpy, screen)) &&
508 (ecolor.pixel != WhitePixel(dpy, screen)) &&
509 (DefaultVisual(dpy, screen)->class & Dynamic))
511 return(ecolor.pixel);
515 ReadBitmapFile(char *filename, unsigned int *width, unsigned int *height,
516 int *x_hot, int *y_hot)
521 status = XReadBitmapFile(dpy, root, filename, width,
522 height, &bitmap, x_hot, y_hot);
523 if (status == BitmapSuccess)
525 else if (status == BitmapOpenFailed)
526 fprintf(stderr, "%s: can't open file: %s\n", program_name, filename);
527 else if (status == BitmapFileInvalid)
528 fprintf(stderr, "%s: bad bitmap format file: %s\n",
529 program_name, filename);
531 fprintf(stderr, "%s: insufficient memory for bitmap: %s",
532 program_name, filename);