home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / xsetroot / xsetroot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-17  |  13.2 KB  |  503 lines

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