|  | /*
    
  autofocus.c: Crude hack to do uwm-style focus management.
               (Note that this breaks the DECwindows Quick-Copy feature.) 
*/
#include <stdio.h>
#include <stdlib.h>
#ifdef VMS
#include <decw$include/X.h>
#include <decw$include/Xlib.h>
#include <decw$include/Xutil.h>
#else
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#endif
#define forever           while(1)
static Window GetWMRoot();
static Window FrameOf();        /* Recursive */
static XWMHints *GetWMHints();  /* Recursive */
static int IgnoreDeadWindow();
main(argc,argv)
   unsigned int argc;
   char *argv[];
{
   Display *display;
   char display_name[10];
   Window wmroot,current,*children,*child;
   XWMHints *wmhints;
   int nchildren,i;
   /* Open the default display */
    
#ifdef VMS
   strcat(strcpy(display_name,getenv("SYS$NODE")),"0");
   if (!(display = XOpenDisplay(display_name))) {
#else 
   if (!(display = XOpenDisplay(NULL))) {
#endif     
      fprintf(stderr,"Can't open display\n");
      exit(0);
   }
   /* Find the window manager's pseudo-root window & its children */
   wmroot = GetWMRoot(display,&children,&nchildren);
   XSelectInput(display,wmroot,StructureNotifyMask|
                               SubstructureNotifyMask|
                               KeyPressMask);
   /* Find out which children have set window manager hints */
   for (i = 0, child = children; i < nchildren; ++i, ++child) {
      if (wmhints = GetWMHints(display,*child,¤t)) {
         XSelectInput(display,current,EnterWindowMask);
         XFree(wmhints);
      }
   }
   XFree(children);
   /* Ignore error when we try to set focus on a window which has died
      since we received the EnterWindow event */
   XSetErrorHandler(IgnoreDeadWindow);
   forever {
      XEvent event;
      XMapEvent *map = (XMapEvent *)&event;
      XEnterWindowEvent *enter = (XEnterWindowEvent *)&event;
      XDestroyWindowEvent *destroy = (XDestroyWindowEvent *)&event;
      XNextEvent(display,&event);
      switch (event.type) {
         case MapNotify: if (wmhints = GetWMHints(display,map->window,
                                                  ¤t)) {
                            XSelectInput(display,current,EnterWindowMask);
                            XFree(wmhints);
                         }
                         break;
         case EnterNotify: XSetInputFocus(display,enter->window,
                                          RevertToParent,CurrentTime);
                           break;
         case DestroyNotify: if (destroy->window == wmroot) {
                                fprintf(stderr,"Window Manager exited.\n");
                                exit(0);
                             }
      }
   }
}
static XWMHints *GetWMHints(display,window,app_window) /* Recursive */
   Display *display;
   Window window,*app_window;
{
   XWMHints *wmhints;
   if (wmhints = XGetWMHints(display,window)) {
      *app_window = window;
      return wmhints;
   }
   else {
      Window root,parent,*children,*child,current = window;
      int i,nchildren;
      XQueryTree(display,current,&root,&parent,&children,&nchildren);
      for (i = 0, child = children; i < nchildren; ++i, ++child) {
         if (wmhints = GetWMHints(display,*child,app_window)) {
            XFree(children);
            return wmhints;
         }
      }
      if (nchildren) XFree(children);
      return NULL;
   }
}
static Window GetWMRoot(display,children,nchildren)
   Display *display;
   Window **children;
   int *nchildren;
{
   Window window,root,parent,*child;
   XWMHints *wmhints;
   int x,y,width,height,bw,depth,found;
   register int i;
   /* Find first full-screen child of root */
   window = RootWindow(display,DefaultScreen(display));
   found = False;
   forever {
     XQueryTree(display,window,&root,&parent,children,nchildren);
     for (i = 0, child = *children; i < *nchildren; ++i, ++child) {
        XGetGeometry(display,*child,&root,&x,&y,&width,&height,&bw,&depth);
        found = width == DisplayWidth(display,DefaultScreen(display)) &&
                height == DisplayHeight(display,DefaultScreen(display));
        if (found) break;
     }
     if (found) break;
     if (*nchildren) XFree(*children);
     sleep(5);
   }
   /* Find first full-screen child of first full-screen child of root */
   window = *child;
   XFree(*children);
   found = False;
   forever {
     XQueryTree(display,window,&root,&parent,children,nchildren);
     for (i = 0, child = *children; i < *nchildren; ++i, ++child) {
        XGetGeometry(display,*child,&root,&x,&y,&width,&height,&bw,&depth);
        found = width == DisplayWidth(display,DefaultScreen(display)) &&
                height == DisplayHeight(display,DefaultScreen(display));
        if (found) break;
     }
     if (found) break;
     if (*nchildren) XFree(*children);
     sleep(5);
   }
   /* Found window manager's pseudo-root; return it & its children */
   window = *child;
   XFree(*children);
   XQueryTree(display,window,&root,&parent,children,nchildren);
   return window;
}
static int IgnoreDeadWindow(display,error)
   Display *display;
   XErrorEvent *error;
{
   if (error->request_code == 42)  /* Bad Window Id */
      return;
   else XSetErrorHandler(NULL);
}
static Window FrameOf(display,window,wmroot)    /* recursive */
   Display *display;
   Window window,wmroot;
{
   Window root,parent,*children;
   int nchildren;
   XQueryTree(display,window,&root,&parent,&children,&nchildren);
   return parent == wmroot ? window : FrameOf(display,parent,wmroot);
}
 |