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