home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / xloadimg.zip / xloadimage.4.1 / root.c < prev    next >
C/C++ Source or Header  |  1993-11-08  |  6KB  |  227 lines

  1. /* root.c:
  2.  *
  3.  * this loads an image onto the root window.  changes to allow proper
  4.  * freeing of previously allocated resources made by Deron Dann Johnson
  5.  * (dj@eng.sun.com).
  6.  *
  7.  * jim frost 10.03.89
  8.  *
  9.  * Copyright 1989, 1990, 1991 Jim Frost.
  10.  * See included file "copyright.h" for complete copyright information.
  11.  */
  12.  
  13. #include "copyright.h"
  14. #include "xloadimage.h"
  15. #include <X11/Xatom.h>
  16.  
  17. #define RETAIN_PROP_NAME    "_XSETROOT_ID"
  18.  
  19. void updateProperty(dpy, w, name, type, format, data, nelem)
  20.      Display    *dpy;
  21.      Window    w;
  22.      char    *name;
  23.      Atom    type;
  24.      int    format;
  25.      int    data;
  26.      int    nelem;
  27. {
  28.   /* intern the property name */
  29.   Atom    atom = XInternAtom(dpy, name, 0);
  30.  
  31.   /* create or replace the property */
  32.   XChangeProperty(dpy, w, atom, type, format, PropModeReplace, 
  33.           (unsigned char *)&data, nelem);
  34. }
  35.  
  36.  
  37. /* Sets the close-down mode of the client to 'RetainPermanent'
  38.  * so all client resources will be preserved after the client
  39.  * exits.  Puts a property on the default root window containing
  40.  * an XID of the client so that the resources can later be killed.
  41.  */
  42.  
  43. static void
  44. preserveResource(dpy, w)
  45.      Display    *dpy;
  46.      Window    w;
  47. {
  48.   /* create dummy resource */
  49.   Pixmap pm= XCreatePixmap(dpy, w, 1, 1, 1);
  50.     
  51.   /* create/replace the property */
  52.   updateProperty(dpy, w, RETAIN_PROP_NAME, XA_PIXMAP, 32, (int)pm, 1);
  53.     
  54.   /* retain all client resources until explicitly killed */
  55.   XSetCloseDownMode(dpy, RetainPermanent);
  56. }
  57.  
  58.  
  59. /* Flushes any resources previously retained by the client,
  60.  * if any exist.
  61.  */
  62.  
  63. static void
  64. freePrevious(dpy, w)
  65.      Display    *dpy;
  66.      Window    w;
  67. {
  68.   Pixmap *pm;            
  69.   Atom    actual_type;        /* NOTUSED */
  70.   int    format;
  71.   int    nitems;
  72.   int    bytes_after;
  73.  
  74.   /* intern the property name */
  75.   Atom atom = XInternAtom(dpy, RETAIN_PROP_NAME, 0);
  76.  
  77.   /* look for existing resource allocation */
  78.   if ((XGetWindowProperty(dpy, w, atom, 0, 1, 1/*delete*/,
  79.               AnyPropertyType, &actual_type, &format, (unsigned long *)&nitems,
  80.               (unsigned long *)&bytes_after, (unsigned char **)&pm) == Success) &&
  81.       nitems == 1) 
  82.     if ((actual_type == XA_PIXMAP) && (format == 32) &&
  83.     (nitems == 1) && (bytes_after == 0)) {
  84.       /* blast it away */
  85.       XKillClient(dpy, (XID) *pm);
  86.       XFree((char *)pm);
  87.     }
  88.     else if (actual_type != None) {
  89.       fprintf(stderr,
  90.           "%s: warning: invalid format encountered for property %s\n",
  91.           RETAIN_PROP_NAME, "xloadimage");
  92.     }
  93. }
  94.  
  95. #if FIND_DEC_ROOTWINDOW
  96. /* this returns the root window for DECWindows servers.  this is right
  97.  * out of xsetroot with minor formatting changes.
  98.  */
  99.  
  100. static Window getWmRootWindow(dpy, root)
  101.      Display *dpy;
  102.      Window root; 
  103. {
  104.   Window parent;
  105.   Window *child;
  106.   unsigned int nchildren;
  107.   XWindowAttributes rootatt, childatt;
  108.   if (!XGetWindowAttributes (dpy, root, &rootatt))
  109.     return(0);
  110.  
  111.   if (XQueryTree (dpy, root, &root, &parent, &child, &nchildren)) {
  112.     int i;
  113.     for (i = 0; i < nchildren; i++) {
  114.       if (!XGetWindowAttributes (dpy, child[i], &childatt))
  115.     continue;
  116.       if ((rootatt.width == childatt.width) &&
  117.       (rootatt.height == childatt.height))
  118.     return child[i];
  119.     }
  120.     return root;
  121.   }
  122.   else
  123.     return((Window)0);
  124. }
  125.  
  126. static Window getDECRootWindow(dpy, root)
  127.      Display *dpy;
  128.      Window root; 
  129. {
  130.   Window temporary_rootW;
  131.  
  132.   if (!(temporary_rootW = getWmRootWindow(dpy, root)) ||
  133.       !(temporary_rootW = getWmRootWindow(dpy, temporary_rootW))) {
  134.     fprintf(stderr, "Can't find false root window on DECWINDOWS server, using true root\n");
  135.     return(root);
  136.   }
  137.   return(temporary_rootW);
  138. }
  139. #endif /* FIND_DEC_ROOTWINDOW */
  140.  
  141. void imageOnRoot(disp, scrn, image, options, verbose)
  142.      Display      *disp;
  143.      int           scrn;
  144.      Image        *image;
  145.      OptionSet    *options;
  146.      unsigned int  verbose;
  147. { Option       *opt;
  148.   Pixmap        pixmap;
  149.   XImageInfo   *ximageinfo;
  150.   Atom          __SWM_VROOT = None;
  151.   Window        root, rootReturn, parentReturn, *children;
  152.   unsigned int  numChildren;
  153.   int           i;
  154.   char         *s;
  155.  
  156.   if (opt= getOption(options, WINDOWID))
  157.     root= opt->info.windowid;
  158.   else {
  159.     root = RootWindow(disp, scrn);
  160.  
  161. #ifdef FIND_DEC_ROOTWINDOW
  162.     /* look for DECWindows servers because they do strange stuff with the
  163.      * root window.  they should be shot for that one.
  164.      *
  165.      * some X terminal vendors put DECWINDOWS in their vendor string to
  166.      * get DEC X utilities to work.  to get around them, we look for
  167.      * the string "DECWINDOWS Digital" because as of this writing DEC's
  168.      * vendorstrings look like "DECWINDOWS DigitalEquipmentCorporation".
  169.      */
  170.  
  171.     for (s= ServerVendor(disp); *s; s++)
  172.       if (!strncmp(s, "DECWINDOWS Digital", 18))
  173.     root= getDECRootWindow(disp, scrn);
  174. #endif /* FIND_DEC_ROOTWINDOW */
  175.  
  176.     /* Added for window managers like swm and tvtwm that follow solbourne's 
  177.      * virtual root window concept.
  178.      */
  179.  
  180.     __SWM_VROOT = XInternAtom(disp, "__SWM_VROOT", False);
  181.     XQueryTree(disp, root, &rootReturn, &parentReturn, &children, &numChildren);
  182.     for(i = 0; i < numChildren; i++) {
  183.       Atom actual_type;
  184.       int actual_format;
  185.       long nitems, bytesafter;
  186.       Window *newRoot = NULL;
  187.       
  188.       if (XGetWindowProperty (disp, children[i], __SWM_VROOT,0,1,
  189.                   False, XA_WINDOW, &actual_type, &actual_format,
  190.                   (unsigned long *)&nitems, (unsigned long *)&bytesafter,
  191.                   (unsigned char **) &newRoot) ==
  192.       Success && newRoot) {
  193.     root = *newRoot;
  194.     break;
  195.       }
  196.     }
  197.   }
  198.   freePrevious(disp, root);
  199.  
  200.   if (! (ximageinfo= imageToXImage(disp, scrn,
  201.                    DefaultVisual(disp, scrn),
  202.                    DefaultDepth(disp, scrn),
  203.                    image, False, True, verbose))) {
  204.     fprintf(stderr, "Cannot convert Image to XImage\n");
  205.     exit(1);
  206.   }
  207.   if ((pixmap= ximageToPixmap(disp, root, ximageinfo)) == None) {
  208.     printf("Cannot create background (not enough resources, sorry)\n");
  209.     exit(1);
  210.   }
  211.  
  212.   /* changing the root colormap is A Bad Thing, so deny it.
  213.    */
  214.  
  215.   if (ximageinfo->cmap != DefaultColormap(disp, scrn)) {
  216.     printf("Loading image onto root would change default colormap (sorry)\n");
  217.     XFreePixmap(disp, pixmap);
  218.     exit(1);
  219.   }
  220.  
  221.   XSetWindowBackgroundPixmap(disp, root, pixmap);
  222.   XClearWindow(disp, root);
  223.   XFreePixmap(disp, pixmap);
  224.   freeXImage(image, ximageinfo);
  225.   preserveResource(disp, root);
  226. }
  227.