From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 14-DEC-1989 21:30
To:	MRGATE::"ARISIA::EVERHART"
Subj:	DecWindows mouse autofocusing program

Received: From YMIR.CLAREMONT.EDU by CRVAX.SRI.COM with TCP; Thu, 14 DEC 89 16:13:26 PDT
Received: from FRIDAY.A-T.COM by YMIR.BITNET; Thu, 14 Dec 89 15:59 PST
Date: Thu, 14 Dec 89 15:59 PST
From: Portia Shao <@YMIR.CLAREMONT.EDU:PORTIA@FRIDAY.A-T.COM>
Subject: DecWindows mouse autofocusing program
To: info-vax@sri.com
Message-Id: <0BEC5531113F6016D1@YMIR.BITNET>
X-Vms-To: IN%"info-vax@sri.com"

I got this program as an example while attending a DECwindows class,
use at your own risk.

$cc autofocus
$link autofocus,sys$input/opt
sys$share:decw$xlibshr/share
$spawn/nowait/input=nla0:/out=nla0: run autofocus

and the window where the cursor sits will be the current window, but
it does not automatically pop it to the top, which may or may not be
desired.

/*
    
  autofocus.c: Crude hack to do uwm-style focus management.
               Author: (chooses to remain anonymous)

*/
#include <stdio.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 void LowerWindow();
static Window FrameOf();        /* Recursive */
static XWMHints *GetWMHints();  /* Recursive */
static int IgnoreDeadWindow();

main(argc,argv)
   unsigned int argc;
   char *argv[];
{
   Display *display;
   Window wmroot,current,*children,*child,
          focus = 0;
   XWMHints *wmhints;
   int nchildren,i,revert_to;

   /* Open the default display */

   if (!(display = XOpenDisplay(NULL))) {
      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,&current)) {
         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);

   /* Grab the function keys used for push & pop */

   XGetInputFocus(display,&focus,&revert_to);

   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,
                                                  &current)) {
                            XSelectInput(display,current,EnterWindowMask);
                            XFree(wmhints);
                         }
                         break;

         case EnterNotify: focus = enter->window;
	   		   XSetInputFocus(display,focus,
                                          RevertToPointerRoot,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);
}

static void LowerWindow(display,window)
   Display *display;
   Window window;
{
   XWindowAttributes old;
   XSetWindowAttributes new;

   XGetWindowAttributes(display,window,&old);

   if (!old.override_redirect) {
     new.override_redirect = True;
     XChangeWindowAttributes(display,window,CWOverrideRedirect,&new);
   }

   XLowerWindow(display,window);

   if (!old.override_redirect) {
     new.override_redirect = False;
     XChangeWindowAttributes(display,window,CWOverrideRedirect,&new);
   }
}

