| /*
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);
}
|