home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / x / viewers / xloadimg.tar / root.c < prev    next >
C/C++ Source or Header  |  1991-05-20  |  6KB  |  218 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, &nitems,
  80.               &bytes_after, &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, (Pixmap *) *pm);
  86.       XFree(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. /* this returns the root window for DECWindows servers.  this is right
  96.  * out of xsetroot with minor formatting changes.
  97.  */
  98.  
  99. static Window getWmRootWindow(dpy, root)
  100.      Display *dpy;
  101.      Window root; 
  102. {
  103.   Window parent;
  104.   Window *child;
  105.   unsigned int nchildren;
  106.   XWindowAttributes rootatt, childatt;
  107.   if (!XGetWindowAttributes (dpy, root, &rootatt)) {
  108.     fprintf(stderr, "XGetWindowAttributes on root failed.\n");
  109.     exit(1);
  110.   }
  111.  
  112.   if (XQueryTree (dpy, root, &root, &parent, &child, &nchildren)) {
  113.     int i;
  114.     for (i = 0; i < nchildren; i++) {
  115.       if (!XGetWindowAttributes (dpy, child[i], &childatt)) {
  116.     fprintf(stderr, "XGetWindowAttributes on child failed.\n");
  117.     exit(1);
  118.       }
  119.       if ((rootatt.width == childatt.width) &&
  120.       (rootatt.height == childatt.height))
  121.     return child[i];
  122.     }
  123.     return root;
  124.   } else {
  125.     fprintf(stderr, "XQueryTree failed (window doesn't exist).\n");
  126.     exit(1);
  127.   }
  128. }
  129.  
  130. static Window getDECRootWindow(dpy, root)
  131.      Display *dpy;
  132.      Window root; 
  133. {
  134.   Window temporary_rootW;
  135.  
  136.   temporary_rootW = getWmRootWindow(dpy, root);
  137.   return(getWmRootWindow(dpy, temporary_rootW));
  138. }
  139.  
  140. void imageOnRoot(disp, scrn, window, image, verbose)
  141.      Display      *disp;
  142.      int           scrn;
  143.      Window        window;
  144.      Image        *image;
  145.      unsigned int  verbose;
  146. { Pixmap        pixmap;
  147.   XImageInfo   *ximageinfo;
  148.   Atom          __SWM_VROOT = None;
  149.   Window        root, rootReturn, parentReturn, *children;
  150.   unsigned int  numChildren;
  151.   int           i;
  152.   char         *s;
  153.  
  154.   if (window)
  155.     root= window;
  156.   else {
  157.     root = RootWindow(disp, scrn);
  158.  
  159.     /* look for DECWindows servers because they do strange stuff with the
  160.      * root window.  they should be shot for that one.
  161.      */
  162.  
  163.     for (s= ServerVendor(disp); *s; s++)
  164.       if (!strncmp(s, "DECWINDOWS", 10))
  165.     root= getDECRootWindow(disp, scrn);
  166.  
  167.     /* Added for window managers like swm and tvtwm that follow solbourne's 
  168.      * virtual root window concept.
  169.      */
  170.  
  171.     __SWM_VROOT = XInternAtom(disp, "__SWM_VROOT", False);
  172.     XQueryTree(disp, root, &rootReturn, &parentReturn, &children, &numChildren);
  173.     for(i = 0; i < numChildren; i++) {
  174.       Atom actual_type;
  175.       int actual_format;
  176.       long nitems, bytesafter;
  177.       Window *newRoot = NULL;
  178.       
  179.       if (XGetWindowProperty (disp, children[i], __SWM_VROOT,0,1,
  180.                   False, XA_WINDOW, &actual_type, &actual_format,
  181.                   &nitems, &bytesafter,
  182.                   (unsigned char **) &newRoot) ==
  183.       Success && newRoot) {
  184.     root = *newRoot;
  185.     break;
  186.       }
  187.     }
  188.   }
  189.   freePrevious(disp, root);
  190.  
  191.   if (! (ximageinfo= imageToXImage(disp, scrn,
  192.                    DefaultVisual(disp, scrn),
  193.                    DefaultDepth(disp, scrn),
  194.                    image, False, True, verbose))) {
  195.     fprintf(stderr, "Cannot convert Image to XImage\n");
  196.     exit(1);
  197.   }
  198.   if ((pixmap= ximageToPixmap(disp, root, ximageinfo)) == None) {
  199.     printf("Cannot create background (not enough resources, sorry)\n");
  200.     exit(1);
  201.   }
  202.  
  203.   /* changing the root colormap is A Bad Thing, so deny it.
  204.    */
  205.  
  206.   if (ximageinfo->cmap != DefaultColormap(disp, scrn)) {
  207.     printf("Loading image onto root would change default colormap (sorry)\n");
  208.     XFreePixmap(disp, pixmap);
  209.     exit(1);
  210.   }
  211.  
  212.   XSetWindowBackgroundPixmap(disp, root, pixmap);
  213.   XClearWindow(disp, root);
  214.   XFreePixmap(disp, pixmap);
  215.   freeXImage(image, ximageinfo);
  216.   preserveResource(disp, root);
  217. }
  218.