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