/* Copyright 1987, Massachusetts Institute of Technology */ #include #include #include #include #define gray_width 2 #define gray_height 2 static char gray_bits[] = { 0x01, 0x02}; /* * xsetroot.c MIT Project Athena, X Window system root window * parameter setting utility. This program will set * various parameters of the X root window. * * Author: Mark Lillibridge, MIT Project Athena * 11-Jun-87 */ char *index(); #define Dynamic 1 char *program_name; Display *dpy; int screen; Window root,wmroot; char *fore_color = NULL; char *back_color = NULL; int reverse = 0; int save_colors = 0; int unsave_past = 0; Pixmap save_pixmap = (Pixmap)None; usage() { fprintf(stderr, "usage: %s [options]\n", program_name); fprintf(stderr, " where options are:\n"); fprintf(stderr, " -display or -d \n"); fprintf(stderr, " -fg or -foreground \n"); fprintf(stderr, " -bg or -background \n"); fprintf(stderr, " -rv or -reverse\n"); fprintf(stderr, " -help\n"); fprintf(stderr, " -def or -default\n"); fprintf(stderr, " -name \n"); fprintf(stderr, " -cursor \n"); fprintf(stderr, " -solid \n"); fprintf(stderr, " -gray or -grey\n"); fprintf(stderr, " -bitmap \n"); fprintf(stderr, " -mod \n"); exit(1); /*NOTREACHED*/ } Pixmap MakeModulaBitmap(), ReadBitmapFile(); XColor NameToXColor(); XColor PixelToXColor(); unsigned long NameToPixel(); Window WmRootWindow(); main(argc, argv) int argc; char **argv; { int excl = 0; int nonexcl = 0; int restore_defaults = 0; char *display_name = NULL; char *name = NULL; char *cursor_file = NULL; char *cursor_mask = NULL; char *solid_color = NULL; Cursor cursor; int gray = 0; char *bitmap_file = NULL; int mod_x = 0; int mod_y = 0; register int i; unsigned int ww, hh; Pixmap bitmap; program_name=argv[0]; for (i = 1; i < argc; i++) { if (!strcmp ("-display", argv[i]) || !strcmp ("-d", argv[i])) { if (++i>=argc) usage (); display_name = argv[i]; continue; } if (!strcmp("-help", argv[i])) { usage(); } if (!strcmp("-def", argv[i]) || !strcmp("-default", argv[i])) { restore_defaults = 1; continue; } if (!strcmp("-name", argv[i])) { if (++i>=argc) usage(); name = argv[i]; nonexcl++; continue; } if (!strcmp("-cursor", argv[i])) { if (++i>=argc) usage(); cursor_file = argv[i]; if (++i>=argc) usage(); cursor_mask = argv[i]; nonexcl++; continue; } if (!strcmp("-fg",argv[i]) || !strcmp("-foreground",argv[i])) { if (++i>=argc) usage(); fore_color = argv[i]; continue; } if (!strcmp("-bg",argv[i]) || !strcmp("-background",argv[i])) { if (++i>=argc) usage(); back_color = argv[i]; continue; } if (!strcmp("-solid", argv[i])) { if (++i>=argc) usage(); solid_color = argv[i]; excl++; continue; } if (!strcmp("-gray", argv[i]) || !strcmp("-grey", argv[i])) { gray = 1; excl++; continue; } if (!strcmp("-bitmap", argv[i])) { if (++i>=argc) usage(); bitmap_file = argv[i]; excl++; continue; } if (!strcmp("-mod", argv[i])) { if (++i>=argc) usage(); mod_x = atoi(argv[i]); if (mod_x <= 0) mod_x = 1; if (++i>=argc) usage(); mod_y = atoi(argv[i]); if (mod_y <= 0) mod_y = 1; excl++; continue; } if (!strcmp("-rv",argv[i]) || !strcmp("-reverse",argv[i])) { reverse = 1; continue; } usage(); } /* Check for multiple use of exclusive options */ if (excl > 1) { fprintf(stderr, "%s: choose only one of {solid, gray, bitmap, mod}\n", program_name); usage(); } dpy = XOpenDisplay(display_name); if (!dpy) { fprintf(stderr, "%s: unable to open display '%s'\n", program_name, XDisplayName (display_name)); usage (); } screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); wmroot = WmRootWindow(dpy, root); wmroot = WmRootWindow(dpy, wmroot); /* If there are no arguments then restore defaults. */ if (!excl && !nonexcl) restore_defaults = 1; /* Handle a cursor file */ if (cursor_file) { cursor = CreateCursorFromFiles(cursor_file, cursor_mask); XDefineCursor(dpy, root, cursor); XDefineCursor(dpy, wmroot, cursor); XFreeCursor(dpy, cursor); } /* Handle -gray and -grey options */ if (gray) { bitmap = XCreateBitmapFromData(dpy, root, gray_bits, gray_width, gray_height); SetBackgroundToBitmap(bitmap, gray_width, gray_height); } /* Handle -solid option */ if (solid_color) { XSetWindowBackground ( dpy, root, NameToPixel ( solid_color, NameToPixel ( "DXmDynamicScreenForeground", BlackPixel(dpy, screen) ) ) ); XSetWindowBackground ( dpy, wmroot, NameToPixel ( solid_color, NameToPixel ( "DXmDynamicScreenForeground", BlackPixel(dpy, screen) ) ) ); XClearWindow(dpy, root); XClearWindow(dpy, wmroot); unsave_past = 1; } /* Handle -bitmap option */ if (bitmap_file) { bitmap = ReadBitmapFile(bitmap_file, &ww, &hh, (int *)NULL, (int *)NULL); SetBackgroundToBitmap(bitmap, ww, hh); } /* Handle set background to a modula pattern */ if (mod_x) { bitmap = MakeModulaBitmap(mod_x, mod_y); SetBackgroundToBitmap(bitmap, 16, 16); } /* Handle set name */ if (name) XStoreName(dpy, root, name); /* Handle restore defaults */ if (restore_defaults) { if (!cursor_file) { XUndefineCursor(dpy, root); XUndefineCursor(dpy, wmroot); } if (!excl) { XSetWindowBackgroundPixmap(dpy, root, (Pixmap) None); XSetWindowBackgroundPixmap(dpy, wmroot, (Pixmap) ParentRelative); XClearWindow(dpy, wmroot); unsave_past = 1; } } FixupState(); XCloseDisplay(dpy); } /* Free past incarnation if needed, and retain state if needed. */ FixupState() { Atom prop, type; int format; unsigned long length, after; unsigned char *data; if (!(DefaultVisual(dpy, screen)->class & Dynamic)) unsave_past = 0; if (!unsave_past && !save_colors) return; prop = XInternAtom(dpy, "_XSETROOT_ID", False); if (unsave_past) { (void)XGetWindowProperty(dpy, root, prop, 0L, 1L, True, AnyPropertyType, &type, &format, &length, &after, &data); if ((type == XA_PIXMAP) && (format == 32) && (length == 1) && (after == 0)) XKillClient(dpy, *((Pixmap *)data)); else if (type != None) fprintf(stderr, "%s: warning: _XSETROOT_ID property is garbage\n", program_name); } if (save_colors) { if (!save_pixmap) save_pixmap = XCreatePixmap(dpy, root, 1, 1, 1); XChangeProperty(dpy, root, prop, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &save_pixmap, 1); XSetCloseDownMode(dpy, RetainPermanent); } } /* * SetBackgroundToBitmap: Set the root window background to a caller supplied * bitmap. */ SetBackgroundToBitmap(bitmap, width, height) Pixmap bitmap; unsigned int width, height; { Pixmap pix; GC gc; XGCValues gc_init; gc_init.foreground = NameToPixel ( fore_color, NameToPixel ( "DXmDynamicScreenForeground", BlackPixel(dpy, screen) ) ); gc_init.background = NameToPixel ( back_color, NameToPixel ( "DXmDynamicScreenBackground", WhitePixel(dpy, screen) ) ); if (reverse) { unsigned long temp=gc_init.foreground; gc_init.foreground=gc_init.background; gc_init.background=temp; } gc = XCreateGC(dpy, root, GCForeground|GCBackground, &gc_init); pix = XCreatePixmap(dpy, root, width, height, (unsigned int)DefaultDepth(dpy, screen)); XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height, 0, 0, (unsigned long)1); XSetWindowBackgroundPixmap(dpy, root, pix); XSetWindowBackgroundPixmap(dpy, wmroot, pix); XFreeGC(dpy, gc); XFreePixmap(dpy, bitmap); if (save_colors) save_pixmap = pix; else XFreePixmap(dpy, pix); XClearWindow(dpy, wmroot); unsave_past = 1; } /* * CreateCursorFromFiles: make a cursor of the right colors from two bitmap * files. */ #define BITMAP_HOT_DEFAULT 8 CreateCursorFromFiles(cursor_file, mask_file) char *cursor_file, *mask_file; { Pixmap cursor_bitmap, mask_bitmap; unsigned int width, height, ww, hh; int x_hot, y_hot; Cursor cursor; XColor fg, bg, temp; unsigned long fp, bp; fp = NameToPixel("DXmDynamicPointerForeground", BlackPixel(dpy, screen)); fp = NameToPixel(fore_color,fp); bp = NameToPixel("DXmDynamicPointerBackground", WhitePixel(dpy, screen)); bp = NameToPixel(back_color,bp); fg = PixelToXColor(fp); bg = PixelToXColor(bp); if (reverse) { temp = fg; fg = bg; bg = temp; } cursor_bitmap = ReadBitmapFile(cursor_file, &width, &height, &x_hot, &y_hot); mask_bitmap = ReadBitmapFile(mask_file, &ww, &hh, (int *)NULL, (int *)NULL); if (width != ww || height != hh) { fprintf(stderr, "%s: dimensions of cursor bitmap and cursor mask bitmap are different\n", program_name); exit(1); /*NOTREACHED*/ } if ((x_hot == -1) && (y_hot == -1)) { x_hot = BITMAP_HOT_DEFAULT; y_hot = BITMAP_HOT_DEFAULT; } if ((x_hot < 0) || (x_hot >= width) || (y_hot < 0) || (y_hot >= height)) { fprintf(stderr, "%s: hotspot is outside cursor bounds\n", program_name); exit(1); /*NOTREACHED*/ } cursor = XCreatePixmapCursor(dpy, cursor_bitmap, mask_bitmap, &fg, &bg, (unsigned int)x_hot, (unsigned int)y_hot); XFreePixmap(dpy, cursor_bitmap); XFreePixmap(dpy, mask_bitmap); return(cursor); } /* * MakeModulaBitmap: Returns a modula bitmap based on an x & y mod. */ Pixmap MakeModulaBitmap(mod_x, mod_y) int mod_x, mod_y; { int i; long pattern_line = 0; char modula_data[16*16/8]; for (i=0; i<16; i++) { pattern_line <<=1; if (i % mod_x == 0) pattern_line |= 0x0001; } for (i=0; i<16; i++) { if (i % mod_y) { modula_data[i*2] = 0xff; modula_data[i*2+1] = 0xff; } else { modula_data[i*2] = pattern_line & 0xff; modula_data[i*2+1] = (pattern_line>>8) & 0xff; } } return(XCreateBitmapFromData(dpy, root, modula_data, 16, 16)); } /* * NameToXColor: Convert the name of a color to its Xcolor value. */ XColor NameToXColor(name, pixel) char *name; unsigned long pixel; { XColor c; if (!name || !*name) { c.pixel = pixel; XQueryColor(dpy, DefaultColormap(dpy, screen), &c); } else if (!XParseColor(dpy, DefaultColormap(dpy, screen), name, &c)) { fprintf(stderr, "%s: unknown color or bad color format: %s\n", program_name, name); exit(1); /*NOTREACHED*/ } return(c); } XColor PixelToXColor(pixel) unsigned long pixel; { XColor c; c.pixel = pixel; XQueryColor(dpy, DefaultColormap(dpy, screen), &c); return (c); } unsigned long NameToPixel(name, pixel) char *name; unsigned long pixel; { XColor scolor, ecolor; if (!name || !*name) return pixel; if (strncmp(name, "DXmDynamic", 9) == 0) { Atom type; int format; unsigned long nitems, left; unsigned long *colors = NULL; int i, index = -1; Atom name_atom = XInternAtom (dpy, name, TRUE); XGetWindowProperty ( dpy, DefaultRootWindow(dpy), XInternAtom (dpy, "DXM_DYNAMIC_COLORS", TRUE), 0, 999999, FALSE, AnyPropertyType, &type, &format, &nitems, &left, (unsigned char **) &colors ); for (i=0; ((index < 0) && (i < nitems)); i+=2) { if ((Atom) colors[i] == name_atom) index = i; } if (index >= 0) { ecolor.pixel = colors[index+1]; } else { return (pixel); } if (colors != NULL) XFree (colors); } else if (!XAllocNamedColor(dpy, DefaultColormap(dpy, screen), name, &scolor, &ecolor)) { fprintf(stderr, "%s: unknown color, or allocation failure: %s\n", program_name, name); exit(1); /*NOTREACHED*/ } if ((ecolor.pixel != BlackPixel(dpy, screen)) && (ecolor.pixel != WhitePixel(dpy, screen)) && (DefaultVisual(dpy, screen)->class & Dynamic)) save_colors = 1; return(ecolor.pixel); } Pixmap ReadBitmapFile(filename, width, height, x_hot, y_hot) char *filename; unsigned int *width, *height; int *x_hot, *y_hot; { Pixmap bitmap; int status; status = XReadBitmapFile(dpy, root, filename, width, height, &bitmap, x_hot, y_hot); if (status == BitmapSuccess) return(bitmap); else if (status == BitmapOpenFailed) fprintf(stderr, "%s: can't open file: %s\n", program_name, filename); else if (status == BitmapFileInvalid) fprintf(stderr, "%s: bad bitmap format file: %s\n", program_name, filename); else fprintf(stderr, "%s: insufficient memory for bitmap: %s", program_name, filename); exit(1); /*NOTREACHED*/ } Window WmRootWindow (dpy, root) Display *dpy; Window root; { Window parent; Window *child; unsigned int nchildren; XWindowAttributes rootatt, childatt; if (!XGetWindowAttributes (dpy, root, &rootatt)) { fprintf (stderr, "XGetWindowAttributes on root failed.\n"); exit(1); } if (XQueryTree (dpy, root, &root, &parent, &child, &nchildren)) { int i; for (i = 0; i < nchildren; i++) { if (!XGetWindowAttributes (dpy, child[i], &childatt)) { fprintf (stderr, "XGetWindowAttributes on child failed.\n"); exit(1); } if ((rootatt.width == childatt.width) && (rootatt.height == childatt.height)) return child[i]; } return root; } else { fprintf (stderr, "XQueryTree failed (window doesn't exist).\n"); exit(1); } }