From:	MERC::"uunet!CRVAX.SRI.COM!RELAY-INFO-VAX" 18-MAY-1992 20:41:03.83
To:	info-vax@kl.sri.com
CC:	
Subj:	Re: Paused session display (long)


In article <56843.glh@aplcomm.jhuapl.edu>,
glh@aplcomm.jhuapl.edu (, Gene A. Heyler) writes:
|>
|>Given : VaxStation 3100 running DESKTOP VMS
|>
|>Qestion: Now that I know how to display a picture of my choice (by 
|>         redefining DECW$LOGIN_BACKGROUND) in place of the DIGITAL logo, is 
|>         there also a way to display a picture when I 'pause' a session? 
|>         All I get is a brilliant white screen with the password prompt. 

Any program can draw into the Session Manager's pause window, if it knows the
window ID of that window.  The trick is finding that window ID.  DECwindows
Motif V1.0 and later versions store a root window property that contains
the Session Manager pause window ID, so you can fetch it from there.  For
previous versions of DECwindows, you have to walk the whole window hierarchy
and look for a window with the correct dimensions, number of children, and
parentage to be the pause window, then you must just assume that it is indeed
the pause window and go from there.

Once you have the pause window's window ID, you merely call the usual X
Windows and Motif or XUI drawing routines and pass them that window ID.

Here is code that will find the pause window ID under DECwindows MOTIF V1.0
or later.  The routine returns either the window ID of the pause window,
or 0 if there is no such window ID (which means that the session isn't
paused):

/* SMPAUSEWINDOW.C - Routine to find the Session Manager pause window for   */
/*                   SSB DECwindows MOTIF on VMS.                           */

#include <decw$include/Xatom.h>
#include <decw$include/Xlib.h>

static int SmPauseHandler(dpy, e)
    Display *dpy;
    XErrorEvent *e;
{
    /* ignore errors from GetWindowProperty */
    
    return 0;
}


Window SmPauseWindow(dpy, root)
    Display *dpy;
    Window root;
{
    char *pause_window = "_DEC_SM_PAUSE_WINDOW";
    Atom pause_window_atom; 
    Window *wid;
    Window retval;
    Atom type_returned;
    int format_returned, status;
    unsigned long num_items_returned, bytes_remaining;

    /* enable handler to trap errors (especially BadAtom) */
    
    XSetErrorHandler(&SmPauseHandler);

    pause_window_atom = XInternAtom (dpy, pause_window, True);

    status = XGetWindowProperty (dpy, root, pause_window_atom, 0, 1, False,
				 XA_WINDOW, &type_returned, &format_returned,
				 &num_items_returned, &bytes_remaining, &wid);

    /* disable the handler */
    
    XSetErrorHandler(0);

    if ((status != 0) || (type_returned == None))
	return 0;	/* XGetWindowProperty failed */

    retval = *wid;
    XFree(wid);
    return retval;	/* Success */
}

Here is a routine that will find the pause window's window ID under
DECwindows V2 for VMS or ULTRIX.  It rummages through the window hierarchy.
It will return either the window ID or 0 if the pause window doesn't exist.
Note that under DECwindow V2 the pause window isn't destroyed when you
unpause--it is merely unmapped.  Thus, you must query the window's mapping
state to see if the session is paused.  If the pause window is mapped, the
session is paused.  If it is unmapped, the session is not paused.
WARNING: no guarantees about this code--I haven't run DECwindows V2 in quite
a while and I'm not sure it still works.

/* SMPAUSEWINDOW.C - Routine to find the Session Manager pause window for
   VMS and Ultrix DECwindows
   
   Written by Paul S. Winalski
*/

static Window SmTestWindow(Display *dpy, Window w, XWindowAttributes *rootatt,
		XWindowAttributes *childatt, int win_offset, int n_children)
{
    Window r2;
    Window parent;
    Window *child1;
    Window *child2;
    unsigned int nc1;
    XWindowAttributes attr;

    if (childatt->width == rootatt->width - win_offset &&
	childatt->height == rootatt->height - win_offset &&
	childatt->x == 0 &&
	childatt->y == 0)
	{
	if (!XQueryTree(dpy, w, &r2, &parent, &child1, &nc1))
	    return 0;

	if (nc1 == 1)
	    {
	    if (!XGetWindowAttributes(dpy, child1[0], &attr))
		return 0;

	    if (!XQueryTree(dpy, child1[0], &r2, &parent, &child2,
		    &nc1))
		return 0;

	    if (attr.width == rootatt->width - win_offset &&
		attr.height == rootatt->height - win_offset &&
		attr.x == 0 &&
		attr.y == 0 &&
		nc1 == n_children)
		return child1[0];
	    }
	}

    return 0;
}

Window SmPauseWindow(dpy, root)
    Display *dpy;
    Window root;
{
#define V_WINDOW_OFFSET 6
#define V_NCHILDREN 2
#define U_WINDOW_OFFSET 0
#define U_NCHILDREN 1

    Window r2;
    Window parent;
    Window *child;
    Window *child1;
    Window *child2;
    unsigned int nchildren, nc1;
    XWindowAttributes rootatt, childatt;
    int x, y, w, h, bw, d;
    
    if (!XGetWindowAttributes(dpy, root, &rootatt))
	return 0;

    if (XQueryTree(dpy, root, &r2, &parent, &child, &nchildren))
        {
	int i;
	Window w;
	
	for (i = 0; i < nchildren; i++)
	    {
	    if (!XGetWindowAttributes(dpy, child[i], &childatt))
		return 0;

	    w = SmTestWindow(dpy, child[i], &rootatt, &childatt,
		    V_WINDOW_OFFSET, V_NCHILDREN);
	    if (w)
		return w;

	    w = SmTestWindow(dpy, child[i], &rootatt, &childatt,
		    U_WINDOW_OFFSET, U_NCHILDREN);
	    if (w)
		return w;
	    }
        }

    /* If we get here, we can't find the proper window */
    
    return 0;
}

