/*
* Copyright (c) 2005 X.Org Foundation L.L.C.
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 
* Copyright (c) Applied Testing and Technology, Inc. 1995
* All Rights Reserved.
* 
* 
* Portions of this software are based on Xlib and X Protocol Test Suite.
* We have used this material under the terms of its copyright, which grants
* free use, subject to the conditions below.  Note however that those
* portions of this software that are based on the original Test Suite have
* been significantly revised and that all such revisions are copyright (c)
* 1995 Applied Testing and Technology, Inc.  Insomuch as the proprietary
* revisions cannot be separated from the freely copyable material, the net
* result is that use of this software is governed by the ApTest copyright.
* 
* Copyright (c) 1990, 1991  X Consortium
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
* X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* 
* Except as contained in this notice, the name of the X Consortium shall not be
* used in advertising or otherwise to promote the sale, use or other dealings
* in this Software without prior written authorization from the X Consortium.
* 
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of UniSoft not be
* used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.  UniSoft
* makes no representations about the suitability of this software for any
* purpose.  It is provided "as is" without express or implied warranty.
* 
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include	<stdlib.h>
#include	<stdio.h>
#include	<string.h>
#include	"xtest.h"
#include	"X11/Xlib.h"
#include	"X11/Xutil.h"
#include	"X11/Xresource.h"
#include	"X11/keysym.h"
#include	"tet_api.h"
#include	"xtestlib.h"
#include	"pixval.h"
#ifdef INPUTEXTENSION
#include        "X11/extensions/XInput.h"
#include        "XItest.h"
#endif

extern	Display	*Dsp;
extern	Window	Win;

extern	Window	ErrdefWindow;
extern	Drawable ErrdefDrawable;
extern	GC		ErrdefGC;
extern	Colormap ErrdefColormap;
extern	Pixmap	ErrdefPixmap;
extern	Atom	ErrdefAtom;
extern	Cursor	ErrdefCursor;
extern	Font	ErrdefFont;


#define T_FocusIn	1
char    *TestName = "FocusIn";



#define	EVENT		FocusIn
#define	OTHEREVENT	FocusOut
#define	MASK		FocusChangeMask

static	Display	*_display_;
static	int	_detail_;
static	long	_event_mask_;
static	XEvent	good;

static	int
selectinput(start, stop, current, previous)
Winh	*start, *stop, *current, *previous;
{
#ifdef	lint
	winh_free(start);
	winh_free(stop);
	winh_free(previous);
#endif
	return(winh_selectinput(_display_, current, _event_mask_));
}

static	int
plant(start, stop, current, previous)
Winh	*start, *stop, *current, *previous;
{
#ifdef	lint
	winh_free(start);
	winh_free(stop);
	winh_free(previous);
#endif
	good.xany.window = current->window;
	return(winh_plant(current, &good, NoEventMask, WINH_NOMASK));
}

static	Bool	increasing;	/* event sequence increases as we climb */

static	int
checksequence(start, stop, current, previous)
Winh	*start, *stop, *current, *previous;
{
	Winhe	*d;
	int	current_sequence;
	int	status;
	static	int	last_sequence;

#ifdef	lint
	winh_free(start);
	winh_free(stop);
#endif
	/* look for desired event type */
	for (d = current->delivered; d != (Winhe *) NULL; d = d->next) {
		if (d->event->type == good.type) {
			current_sequence = d->sequence;
			break;
		}
	}
	if (d == (Winhe *) NULL) {
		report("%s event not delivered", eventname(good.type));
		delete("Missing event");
		return(-1);
	}
	if (previous == (Winh *) NULL)
		status = 0;	/* first call, no previous sequence value */
	else {
		/* assume sequence numbers are not the same */
		status = (current_sequence < last_sequence);
		if (increasing)
			status = (status ? 0 : 1);
		if (status)
			report("Ordering problem between 0x%x (%d) and 0x%x (%d)",
				current->window, current_sequence,
				previous->window, last_sequence);
	}
	last_sequence = current_sequence;
	return(status);
}

static	int
checkdetail(start, stop, current, previous)
Winh	*start, *stop, *current, *previous;
{
	Winhe	*d;

#ifdef	lint
	winh_free(start);
	winh_free(stop);
	winh_free(previous);
#endif
	/* look for desired event type */
	for (d = current->delivered; d != (Winhe *) NULL; d = d->next)
		if (d->event->type == good.type)
			break;
	if (d == (Winhe *) NULL) {
		report("%s event not delivered to window 0x%x",
			eventname(good.type), current->window);
		delete("Missing event");
		return(-1);
	}
	/* check detail */
	if (_detail_ != d->event->xfocus.detail) {
		report("Expected detail of %d, got %d on window 0x%x",
			_detail_, d->event->xfocus.detail, current->window);
		return(1);
	}
	return(0);
}

int 	tet_thistest;

static void t001(){

int	i;
Display	*display;
Display	*client2, *client3;
Window	w;
XEvent	event;
XFocusChangeEvent	good;
int 	pass = 0, fail = 0;

 	report_purpose(1);

	report_assertion("Assertion FocusIn-1.(A)");
	report_assertion("When a FocusIn event is generated, then all clients having");
	report_assertion("set FocusChangeMask event mask bits on the event window are");
	report_assertion("delivered a FocusIn event.");

	report_strategy("Create client.");
	report_strategy("Create clients client2 and client3.");
	report_strategy("Create window.");
	report_strategy("Move pointer to known location.");
	report_strategy("Select for FocusIn events on window.");
	report_strategy("Select for FocusIn events on window with client2.");
	report_strategy("Select for no events on window with client3.");
	report_strategy("Generate FocusIn event by changing focus to window.");
	report_strategy("Verify that FocusIn event was delivered.");
	report_strategy("Verify members in delivered FocusIn event structure.");
	report_strategy("Verify that FocusIn event was delivered to client2.");
	report_strategy("Verify members in delivered FocusIn event structure.");
	report_strategy("Verify that no events were delivered to client3.");

	tpstartup();
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Create clients client2 and client3. */
	if ((client2 = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client2.");
		return;
	}
	else
		CHECK;
	if ((client3 = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client3.");
		return;
	}
	else
		CHECK;
/* Create window. */
	w = mkwin(display, (XVisualInfo *) NULL, (struct area *) NULL, True);
/* Move pointer to known location. */
	if (warppointer(display, DRW(display), 0, 0) == (PointerPlace *) NULL) {
		report("Couldn't move pointer");
		return;
	}
	else
		CHECK;
/* Select for xname events on window. */
	XSelectInput(display, w, MASK);
/* Select for xname events on window with client2. */
	XSelectInput(client2, w, MASK);
/* Select for no events on window with client3. */
	XSelectInput(client3, w, NoEventMask);
/* Generate xname event by changing focus to window. */
	XSync(display, True);
	XSync(client2, True);
	XSync(client3, True);
	XSetInputFocus(display, w, RevertToNone, CurrentTime);
	XSync(display, False);
	XSync(client2, False);
	XSync(client3, False);
/* Verify that xname event was delivered. */
	if (XPending(display) < 1) {
		report("Expected %s event not delivered.", eventname(EVENT));
		FAIL;
		return;
	}
	else
		CHECK;
/* Verify members in delivered xname event structure. */
	XNextEvent(display, &event);
	good = event.xfocus;
	good.type = EVENT;
	good.send_event = False;
	good.display = display;
	good.window = w;
	good.mode = NotifyNormal;
	good.detail = NotifyAncestor;
	if (checkevent((XEvent*)&good, &event)) {
		report("Unexpected event structure member value(s)");
		FAIL;
	}
	else
		CHECK;
	if ((i = XPending(display)) > 0) {
		report("Expected 1 event, got %d", i+1);
		FAIL;
	}
	else
		CHECK;
/* Verify that xname event was delivered to client2. */
	if (XPending(client2) < 1) {
		report("Expected %s event not delivered to client2.", eventname(EVENT));
		FAIL;
		return;
	}
	else
		CHECK;
/* Verify members in delivered xname event structure. */
	XNextEvent(client2, &event);
	good = event.xfocus;
	good.type = EVENT;
	good.send_event = False;
	good.display = client2;
	good.window = w;
	good.mode = NotifyNormal;
	good.detail = NotifyAncestor;
	if (checkevent((XEvent*)&good, &event)) {
		report("Unexpected event structure member value(s) for client2");
		FAIL;
	}
	else
		CHECK;
	if ((i = XPending(client2)) > 0) {
		report("Expected 1 event, got %d for client2", i+1);
		FAIL;
	}
	else
		CHECK;
/* Verify that no events were delivered to client3. */
	if ((i = XPending(client3)) > 0) {
		report("Expected 0 events, got %d for client3", i);
		FAIL;
	}
	else
		CHECK;
	CHECKPASS(11);
	tpcleanup();
	pfcount(pass, fail);
}

static void t002(){


 	report_purpose(2);

	report_assertion("Assertion FocusIn-2.(-)");
	report_assertion("When a FocusIn event is generated, then clients not having");
	report_assertion("set FocusChangeMask event mask bits on the event window are");
	report_assertion("not delivered a FocusIn event.");
	report_assertion("The assertion is descriptive or is tested elsewhere.");
	tet_result(TET_NOTINUSE);
}

static void t003(){


 	report_purpose(3);

	report_assertion("Assertion FocusIn-3.(-)");
	report_assertion("All FocusIn events are delivered after any related FocusOut");
	report_assertion("are delivered.");
	report_assertion("The assertion is descriptive or is tested elsewhere.");
	tet_result(TET_NOTINUSE);
}

static void t004(){

Display	*display;
int	depth = 3;
Winh	*A, *B;
int	status;
int 	pass = 0, fail = 0;

 	report_purpose(4);

	report_assertion("Assertion FocusIn-4.(A)");
	report_assertion("When the input focus moves from window A to window B and");
	report_assertion("window A is an inferior of window B and the pointer is in");
	report_assertion("window P, then a FocusIn event is generated on window B,");
	report_assertion("with detail set to NotifyInferior.");

	report_strategy("Create client.");
	report_strategy("Build window hierarchy.");
	report_strategy("Move pointer to known location.");
	report_strategy("Set window B.");
	report_strategy("Set window A to inferior of window B.");
	report_strategy("Set input focus to window A.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from A to B.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered to window B with detail set to NotifyInferior.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");

	tpstartup();
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy. */
	if (winh(display, depth, WINH_MAP)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Move pointer to known location. */
	if (warppointer(display, DRW(display), 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
/* Set window B. */
	B = guardian->firstchild;
/* Set window A to inferior of window B. */
	A = B->firstchild;
/* Set input focus to window A. */
	XSetInputFocus(display, A->window, RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
	_event_mask_ = MASK;
	_display_ = display;
	if (winh_climb(A, B, selectinput)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
	good.type = EVENT;
	good.xany.display = display;
	if (winh_climb(B, B, plant)) {
		report("Could not plant events");
		return;
	}
	else
		CHECK;
/* Generate xname event by changing focus from A to B. */
	XSync(display, True);
	XSetInputFocus(display, B->window, RevertToNone, CurrentTime);
	XSync(display, False);
	if (winh_harvest(display, (Winh *) NULL)) {
		report("Could not harvest events");
		return;
	}
	else
		CHECK;
/* Verify that the expected events were delivered. */
	if (winh_ignore_event(A, OTHEREVENT, WINH_NOMASK)) {
		delete("Could not ignore %s events", eventname(OTHEREVENT));
		return;
	}
	else
		CHECK;
	status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
	if (status < 0)
		return;
	else if (status > 0) {
		report("Event delivery was not as expected");
		FAIL;
	}
	else {
/* Verify that event delivered to window B with detail set to NotifyInferior. */
		_detail_ = NotifyInferior;
		if (winh_climb(B, B, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
		status = winh_ordercheck(OTHEREVENT, EVENT);
		if (status == -1)
			return;
		else if (status)
			FAIL;
		else
			CHECK;
	}
	CHECKPASS(9);
	tpcleanup();
	pfcount(pass, fail);
}

static void t005(){

Display	*display;
int	depth = 4;
Winh	*A, *B, *P, *Pancestor;
int	status;
int 	pass = 0, fail = 0;

 	report_purpose(5);

	report_assertion("Assertion FocusIn-5.(A)");
	report_assertion("When the input focus moves from window A to window B and");
	report_assertion("window A is an inferior of window B and the pointer is in");
	report_assertion("window P and window P is an inferior of window B and window");
	report_assertion("P is not the same window as window A and window P is not an");
	report_assertion("inferior of window A and window P is not an ancestor of");
	report_assertion("window A, then, after a FocusIn event is generated on window");
	report_assertion("B with detail set to NotifyInferior, a FocusIn event is");
	report_assertion("generated on each window below window B, down to and");
	report_assertion("including window P, with detail set to NotifyPointer.");

	report_strategy("Create client.");
	report_strategy("Build window hierarchy.");
	report_strategy("Move pointer to known location.");
	report_strategy("Set window B.");
	report_strategy("Set window A to inferior of window B.");
	report_strategy("Set window P to inferior of sibling of window A.");
	report_strategy("Move pointer to window P.");
	report_strategy("Set input focus to window A.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from A to B.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered to window B with detail set to NotifyInferior.");
	report_strategy("Verify that event delivered below window B, down to and including");
	report_strategy("window P, with detail set to NotifyPointer.");
	report_strategy("Verify order of FocusIn event delivery.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");

	tpstartup();
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy. */
	if (winh(display, depth, WINH_MAP)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Move pointer to known location. */
	if (warppointer(display, DRW(display), 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
/* Set window B. */
	B = guardian->firstchild;
/* Set window A to inferior of window B. */
	A = B->firstchild;
/* Set window P to inferior of sibling of window A. */
	Pancestor = B->firstchild->nextsibling;
	P = Pancestor->firstchild->firstchild;
/* Move pointer to window P. */
	XWarpPointer(display, None, P->window, 0, 0, 0, 0, 0, 0);
/* Set input focus to window A. */
	XSetInputFocus(display, A->window, RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
	_event_mask_ = MASK;
	_display_ = display;
	if (winh_climb(P, Pancestor, selectinput)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
	if (winh_climb(A, B, selectinput)) {
		report("Could not select for events between A and B");
		return;
	}
	else
		CHECK;
	good.type = EVENT;
	good.xany.display = display;
	if (winh_climb(P, B, plant)) {
		report("Could not plant events");
		return;
	}
	else
		CHECK;
/* Generate xname event by changing focus from A to B. */
	XSync(display, True);
	XSetInputFocus(display, B->window, RevertToNone, CurrentTime);
	XSync(display, False);
	if (winh_harvest(display, (Winh *) NULL)) {
		report("Could not harvest events");
		return;
	}
	else
		CHECK;
/* Verify that the expected events were delivered. */
	if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
		delete("Could not ignore %s events", eventname(OTHEREVENT));
		return;
	}
	else
		CHECK;
	status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
	if (status < 0)
		return;
	else if (status > 0) {
		report("Event delivery was not as expected");
		FAIL;
	}
	else {
/* Verify that event delivered to window B with detail set to NotifyInferior. */
		_detail_ = NotifyInferior;
		if (winh_climb(B, B, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify that event delivered below window B, down to and including */
/* window P, with detail set to NotifyPointer. */
		_detail_ = NotifyPointer;
		if (winh_climb(P, Pancestor, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify order of xname event delivery. */
		increasing = True;
		if (winh_climb(P, B, checksequence))
			FAIL;
		else
			CHECK;
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
		status = winh_ordercheck(OTHEREVENT, EVENT);
		if (status == -1)
			return;
		else if (status)
			FAIL;
		else
			CHECK;
	}
	CHECKPASS(12);
	tpcleanup();
	pfcount(pass, fail);
}

static void t006(){

Display	*display;
int	depth = 4;
Winh	*A, *B;
int	status;
int 	pass = 0, fail = 0;

 	report_purpose(6);

	report_assertion("Assertion FocusIn-6.(A)");
	report_assertion("When the input focus moves from window A to window B and");
	report_assertion("window B is an inferior of window A and the pointer is in");
	report_assertion("window P, then a FocusIn event is generated on each window");
	report_assertion("between window A and window B, exclusive, with detail set to");
	report_assertion("NotifyVirtual and then on window B with detail set to");
	report_assertion("NotifyAncestor.");

	report_strategy("Create client.");
	report_strategy("Build window hierarchy.");
	report_strategy("Move pointer to known location.");
	report_strategy("Set window A.");
	report_strategy("Set window B to inferior of window A.");
	report_strategy("Set input focus to window A.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from A to B.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered to windows between window A and window B, exclusive,");
	report_strategy("with detail set to NotifyVirtual.");
	report_strategy("Verify that event delivered to window B with detail set to NotifyAncestor.");
	report_strategy("Verify order of FocusIn event delivery.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");

	tpstartup();
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy. */
	if (winh(display, depth, WINH_MAP)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Move pointer to known location. */
	if (warppointer(display, DRW(display), 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
/* Set window A. */
	A = guardian->firstchild;
/* Set window B to inferior of window A. */
	B = A->firstchild->firstchild->firstchild;
/* Set input focus to window A. */
	XSetInputFocus(display, A->window, RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
	_display_ = display;
#if 0
	_event_mask_ = MASK;
	if (winh_climb(B, A->firstchild, selectinput)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
#endif
	if (winh_selectinput(display, (Winh *) NULL, MASK)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
	good.type = EVENT;
	good.xany.display = display;
	if (winh_climb(B, A->firstchild, plant)) {
		report("Could not plant events");
		return;
	}
	else
		CHECK;
/* Generate xname event by changing focus from A to B. */
	XSync(display, True);
	XSetInputFocus(display, B->window, RevertToNone, CurrentTime);
	XSync(display, False);
	if (winh_harvest(display, (Winh *) NULL)) {
		report("Could not harvest events");
		return;
	}
	else
		CHECK;
/* Verify that the expected events were delivered. */
	if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
		delete("Could not ignore %s events", eventname(OTHEREVENT));
		return;
	}
	else
		CHECK;
	status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
	if (status < 0)
		return;
	else if (status > 0) {
		report("Event delivery was not as expected");
		FAIL;
	}
	else {
/* Verify that event delivered to windows between window A and window B, exclusive, */
/* with detail set to NotifyVirtual. */
		_detail_ = NotifyVirtual;
		if (winh_climb(B->parent, A->firstchild, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify that event delivered to window B with detail set to NotifyAncestor. */
		_detail_ = NotifyAncestor;
		if (winh_climb(B, B, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify order of xname event delivery. */
		increasing = True;
		if (winh_climb(B, A->firstchild, checksequence))
			FAIL;
		else
			CHECK;
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
		status = winh_ordercheck(OTHEREVENT, EVENT);
		if (status == -1)
			return;
		else if (status)
			FAIL;
		else
			CHECK;
	}
	CHECKPASS(11);
	tpcleanup();
	pfcount(pass, fail);
}

static void t007(){

Display	*display;
int	depth = 4;
Winh	*A, *B, *C;
int	status;
int 	pass = 0, fail = 0;

 	report_purpose(7);

	report_assertion("Assertion FocusIn-7.(A)");
	report_assertion("When the input focus moves from window A to window B and");
	report_assertion("window C is their least common ancestor and the pointer is");
	report_assertion("in window P, then a FocusIn event is generated on each");
	report_assertion("window between C and B, exclusive, with detail set to");
	report_assertion("NotifyNonlinearVirtual and then on window B with detail set");
	report_assertion("to NotifyNonlinear.");

	report_strategy("Create client.");
	report_strategy("Build window hierarchy.");
	report_strategy("Move pointer to known location.");
	report_strategy("Set window C.");
	report_strategy("Set window B to inferior of window C.");
	report_strategy("Set window A to inferior of window C.");
	report_strategy("Set input focus to window A.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from A to B.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered to windows between window C and window B, exclusive,");
	report_strategy("with detail set to NotifyNonlinearVirtual.");
	report_strategy("Verify that event delivered to window B with detail set to NotifyNonlinear.");
	report_strategy("Verify order of FocusIn event delivery.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");

	tpstartup();
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy. */
	if (winh(display, depth, WINH_MAP)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Move pointer to known location. */
	if (warppointer(display, DRW(display), 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
/* Set window C. */
	C = guardian->firstchild;
/* Set window B to inferior of window C. */
	B = C->firstchild->firstchild->firstchild;
/* Set window A to inferior of window C. */
	A = C->firstchild->nextsibling->firstchild;
/* Set input focus to window A. */
	XSetInputFocus(display, A->window, RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
	_event_mask_ = MASK;
	_display_ = display;
	if (winh_climb(B, C->firstchild, selectinput)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
	if (winh_climb(A, C, selectinput)) {
		report("Could not select for events between A and C");
		return;
	}
	else
		CHECK;
	good.type = EVENT;
	good.xany.display = display;
	if (winh_climb(B, C->firstchild, plant)) {
		report("Could not plant events");
		return;
	}
	else
		CHECK;
/* Generate xname event by changing focus from A to B. */
	XSync(display, True);
	XSetInputFocus(display, B->window, RevertToNone, CurrentTime);
	XSync(display, False);
	if (winh_harvest(display, (Winh *) NULL)) {
		report("Could not harvest events");
		return;
	}
	else
		CHECK;
/* Verify that the expected events were delivered. */
	if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
		delete("Could not ignore %s events", eventname(OTHEREVENT));
		return;
	}
	else
		CHECK;
	status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
	if (status < 0)
		return;
	else if (status > 0) {
		report("Event delivery was not as expected");
		FAIL;
	}
	else {
/* Verify that event delivered to windows between window C and window B, exclusive, */
/* with detail set to NotifyNonlinearVirtual. */
		_detail_ = NotifyNonlinearVirtual;
		if (winh_climb(B->parent, C->firstchild, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify that event delivered to window B with detail set to NotifyNonlinear. */
		_detail_ = NotifyNonlinear;
		if (winh_climb(B, B, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify order of xname event delivery. */
		increasing = True;
		if (winh_climb(B, C->firstchild, checksequence))
			FAIL;
		else
			CHECK;
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
		status = winh_ordercheck(OTHEREVENT, EVENT);
		if (status == -1)
			return;
		else if (status)
			FAIL;
		else
			CHECK;
	}
	CHECKPASS(12);
	tpcleanup();
	pfcount(pass, fail);
}

static void t008(){

Display	*display;
int	depth = 5;
Winh	*A, *B, *C, *P;
int	status;
int 	pass = 0, fail = 0;

 	report_purpose(8);

	report_assertion("Assertion FocusIn-8.(A)");
	report_assertion("When the input focus moves from window A to window B and");
	report_assertion("window C is their least common ancestor and the pointer is");
	report_assertion("in window P and window P is an inferior of window B, then,");
	report_assertion("after the related FocusIn events are generated with detail");
	report_assertion("set to NotifyNonlinearVirtual and NotifyNonlinear, a");
	report_assertion("FocusIn event is generated on each window below window B");
	report_assertion("down to and including window P, with detail set to");
	report_assertion("NotifyPointer.");

	report_strategy("Create client.");
	report_strategy("Build window hierarchy.");
	report_strategy("Move pointer to known location.");
	report_strategy("Set window C.");
	report_strategy("Set window B to inferior of window C.");
	report_strategy("Set window P to inferior of window B.");
	report_strategy("Set window A to inferior of window C.");
	report_strategy("Move pointer to window P.");
	report_strategy("Set input focus to window A.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from A to B.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered to windows between window C and window B, exclusive,");
	report_strategy("with detail set to NotifyNonlinearVirtual.");
	report_strategy("Verify that event delivered to window B with detail set to NotifyNonlinear.");
	report_strategy("Verify that events were delivered to windows below window B down to and");
	report_strategy("including window P, exclusive,");
	report_strategy("with detail set to NotifyPointer.");
	report_strategy("Verify order of FocusIn event delivery.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");

	tpstartup();
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy. */
	if (winh(display, depth, WINH_MAP)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Move pointer to known location. */
	if (warppointer(display, DRW(display), 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
/* Set window C. */
	C = guardian->firstchild;
/* Set window B to inferior of window C. */
	B = C->firstchild->firstchild;
/* Set window P to inferior of window B. */
	P = B->firstchild->firstchild;
/* Set window A to inferior of window C. */
	A = C->firstchild->nextsibling->firstchild;
/* Move pointer to window P. */
	XWarpPointer(display, None, P->window, 0, 0, 0, 0, 0, 0);
/* Set input focus to window A. */
	XSetInputFocus(display, A->window, RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
	_event_mask_ = MASK;
	_display_ = display;
	if (winh_climb(B, C->firstchild, selectinput)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
	if (winh_climb(A, C, selectinput)) {
		report("Could not select for events between A and C");
		return;
	}
	else
		CHECK;
	if (winh_climb(P, B, selectinput)) {
		report("Could not select for events between P and B");
		return;
	}
	else
		CHECK;
	good.type = EVENT;
	good.xany.display = display;
	if (winh_climb(B, C->firstchild, plant)) {
		report("Could not plant events");
		return;
	}
	else
		CHECK;
	if (winh_climb(P, B->firstchild, plant)) {
		report("Could not plant events below B");
		return;
	}
	else
		CHECK;
/* Generate xname event by changing focus from A to B. */
	XSync(display, True);
	XSetInputFocus(display, B->window, RevertToNone, CurrentTime);
	XSync(display, False);
	if (winh_harvest(display, (Winh *) NULL)) {
		report("Could not harvest events");
		return;
	}
	else
		CHECK;
/* Verify that the expected events were delivered. */
	if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
		delete("Could not ignore %s events", eventname(OTHEREVENT));
		return;
	}
	else
		CHECK;
	status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
	if (status < 0)
		return;
	else if (status > 0) {
		report("Event delivery was not as expected");
		FAIL;
	}
	else {
/* Verify that event delivered to windows between window C and window B, exclusive, */
/* with detail set to NotifyNonlinearVirtual. */
		_detail_ = NotifyNonlinearVirtual;
		if (winh_climb(B->parent, C->firstchild, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify that event delivered to window B with detail set to NotifyNonlinear. */
		_detail_ = NotifyNonlinear;
		if (winh_climb(B, B, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify that events were delivered to windows below window B down to and */
/* including window P, exclusive, */
/* with detail set to NotifyPointer. */
		_detail_ = NotifyPointer;
		if (winh_climb(P, B->firstchild, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify order of xname event delivery. */
		increasing = True;
		if (winh_climb(B, C->firstchild, checksequence))
			FAIL;
		else
			CHECK;
		increasing = True;
		if (winh_climb(P, B->firstchild, checksequence))
			FAIL;
		else
			CHECK;
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
		status = winh_ordercheck(OTHEREVENT, EVENT);
		if (status == -1)
			return;
		else if (status)
			FAIL;
		else
			CHECK;
	}
	CHECKPASS(16);
	tpcleanup();
	pfcount(pass, fail);
}

static void t009(){

Display	*display;
int	depth = 4;
Winh	*A, *B, *Broot;
int	status;
int 	pass = 0, fail = 0;

 	report_purpose(9);

	report_assertion("Assertion FocusIn-9.(C)");
	report_assertion("If the implementation supports multiple screens: When the");
	report_assertion("input focus moves from window A to window B and window A and");
	report_assertion("window B are not on the same screens and the pointer is in");
	report_assertion("window P and window B is not a root window, then a FocusIn");
	report_assertion("event is generated on each window from window B's root down");
	report_assertion("to but not including window B, with detail set to");
	report_assertion("NotifyNonlinearVirtual.");

	report_strategy("Check to see if multiple screens are supported.");
	report_strategy("Create client.");
	report_strategy("Build window hierarchy on all supported screens.");
	report_strategy("Move pointer to known location.");
	report_strategy("Set window A.");
	report_strategy("Set window B to an inferior of the root window on a different screen than A.");
	report_strategy("Set input focus to window A.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from A to B.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered to each window from window B's root down");
	report_strategy("to but not including window B");
	report_strategy("with detail set to NotifyNonlinearVirtual.");
	report_strategy("Verify order of FocusIn event delivery.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");

	tpstartup();
/* Check to see if multiple screens are supported. */
	if (config.alt_screen == -1) {
		unsupported("Multiple screens not supported.");
		return;
	}
	else
		CHECK;
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy on all supported screens. */
	if (winh(display, depth, WINH_MAP|WINH_BOTH_SCREENS)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Move pointer to known location. */
	if (warppointer(display, DRW(display), 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
/* Set window A. */
	A = guardian->firstchild;
/* Set window B to an inferior of the root window on a different screen than A. */
	Broot = guardian->nextsibling;
	B = Broot->firstchild->firstchild->firstchild;
/* Set input focus to window A. */
	XSetInputFocus(display, A->window, RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
	_event_mask_ = MASK;
	_display_ = display;
	if (winh_climb(B->parent, Broot, selectinput)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
	if (winh_climb(A, A, selectinput)) {
		report("Could not select for events on window A");
		return;
	}
	else
		CHECK;
	good.type = EVENT;
	good.xany.display = display;
	if (winh_climb(B->parent, Broot, plant)) {
		report("Could not plant events");
		return;
	}
	else
		CHECK;
/* Generate xname event by changing focus from A to B. */
	XSync(display, True);
	XSetInputFocus(display, B->window, RevertToNone, CurrentTime);
	XSync(display, False);
	if (winh_harvest(display, (Winh *) NULL)) {
		report("Could not harvest events");
		return;
	}
	else
		CHECK;
/* Verify that the expected events were delivered. */
	if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
		delete("Could not ignore %s events", eventname(OTHEREVENT));
		return;
	}
	else
		CHECK;
	status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
	if (status < 0)
		return;
	else if (status > 0) {
		report("Event delivery was not as expected");
		FAIL;
	}
	else {
/* Verify that event delivered to each window from window B's root down */
/* to but not including window B */
/* with detail set to NotifyNonlinearVirtual. */
		_detail_ = NotifyNonlinearVirtual;
		if (winh_climb(B->parent, Broot, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify order of xname event delivery. */
		increasing = True;
		if (winh_climb(B->parent, Broot, checksequence))
			FAIL;
		else
			CHECK;
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
		status = winh_ordercheck(OTHEREVENT, EVENT);
		if (status == -1)
			return;
		else if (status)
			FAIL;
		else
			CHECK;
	}
	CHECKPASS(12);
	tpcleanup();
	pfcount(pass, fail);
}

static void t010(){

Display	*display;
int	depth = 4;
Winh	*A, *B, *Broot;
int	status;
int 	pass = 0, fail = 0;

 	report_purpose(10);

	report_assertion("Assertion FocusIn-10.(C)");
	report_assertion("If the implementation supports multiple screens: When the");
	report_assertion("input focus moves from window A to window B and window A and");
	report_assertion("window B are not on the same screens and the pointer is in");
	report_assertion("window P, then, after any related FocusIn events are");
	report_assertion("generated with detail set to NotifyNonlinearVirtual, a");
	report_assertion("FocusIn event is generated on window B with detail set to");
	report_assertion("NotifyNonlinear.");

	report_strategy("Check to see if multiple screens are supported.");
	report_strategy("Create client.");
	report_strategy("Build window hierarchy on all supported screens.");
	report_strategy("Move pointer to known location.");
	report_strategy("Set window A.");
	report_strategy("Set window B to an inferior of the root window on a different screen than A.");
	report_strategy("Set input focus to window A.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from A to B.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered to each window from window B's root down");
	report_strategy("to but not including window B");
	report_strategy("with detail set to NotifyNonlinearVirtual.");
	report_strategy("Verify that event delivered on window B with detail");
	report_strategy("set to NotifyNonlinear.");
	report_strategy("Verify order of FocusIn event delivery.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");

	tpstartup();
/* Check to see if multiple screens are supported. */
	if (config.alt_screen == -1) {
		unsupported("Multiple screens not supported.");
		return;
	}
	else
		CHECK;
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy on all supported screens. */
	if (winh(display, depth, WINH_MAP|WINH_BOTH_SCREENS)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Move pointer to known location. */
	if (warppointer(display, DRW(display), 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
/* Set window A. */
	A = guardian->firstchild;
/* Set window B to an inferior of the root window on a different screen than A. */
	Broot = guardian->nextsibling;
	B = Broot->firstchild->firstchild->firstchild;
/* Set input focus to window A. */
	XSetInputFocus(display, A->window, RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
	_event_mask_ = MASK;
	_display_ = display;
	if (winh_climb(B, Broot, selectinput)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
	if (winh_climb(A, A, selectinput)) {
		report("Could not select for events on window A");
		return;
	}
	else
		CHECK;
	good.type = EVENT;
	good.xany.display = display;
	if (winh_climb(B, Broot, plant)) {
		report("Could not plant events");
		return;
	}
	else
		CHECK;
/* Generate xname event by changing focus from A to B. */
	XSync(display, True);
	XSetInputFocus(display, B->window, RevertToNone, CurrentTime);
	XSync(display, False);
	if (winh_harvest(display, (Winh *) NULL)) {
		report("Could not harvest events");
		return;
	}
	else
		CHECK;
/* Verify that the expected events were delivered. */
	if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
		delete("Could not ignore %s events", eventname(OTHEREVENT));
		return;
	}
	else
		CHECK;
	status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
	if (status < 0)
		return;
	else if (status > 0) {
		report("Event delivery was not as expected");
		FAIL;
	}
	else {
/* Verify that event delivered to each window from window B's root down */
/* to but not including window B */
/* with detail set to NotifyNonlinearVirtual. */
		_detail_ = NotifyNonlinearVirtual;
		if (winh_climb(B->parent, Broot, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify that event delivered on window B with detail */
/* set to NotifyNonlinear. */
		_detail_ = NotifyNonlinear;
		if (winh_climb(B, B, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify order of xname event delivery. */
		increasing = True;
		if (winh_climb(B, Broot, checksequence))
			FAIL;
		else
			CHECK;
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
		status = winh_ordercheck(OTHEREVENT, EVENT);
		if (status == -1)
			return;
		else if (status)
			FAIL;
		else
			CHECK;
	}
	CHECKPASS(13);
	tpcleanup();
	pfcount(pass, fail);
}

static void t011(){

Display	*display;
int	depth = 2;
Winh	*A, *B, *P;
int	status;
int 	pass = 0, fail = 0;

 	report_purpose(11);

	report_assertion("Assertion FocusIn-11.(C)");
	report_assertion("If the implementation supports multiple screens: When the");
	report_assertion("input focus moves from window A to window B and window A and");
	report_assertion("window B are not on the same screens and the pointer is in");
	report_assertion("window P and window P is an inferior of window B, then a");
	report_assertion("FocusIn event is generated on window B with detail set to");
	report_assertion("NotifyNonlinear.");

	report_strategy("Check to see if multiple screens are supported.");
	report_strategy("Create client.");
	report_strategy("Build window hierarchy on all supported screens.");
	report_strategy("Move pointer to known location.");
	report_strategy("Set window A.");
	report_strategy("Set window B.");
	report_strategy("Set P to inferior of window B.");
	report_strategy("Set input focus to window A.");
	report_strategy("Move pointer to window P.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from A to B.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered on window B with detail");
	report_strategy("set to NotifyNonlinear.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");

	tpstartup();
/* Check to see if multiple screens are supported. */
	if (config.alt_screen == -1) {
		unsupported("Multiple screens not supported.");
		return;
	}
	else
		CHECK;
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy on all supported screens. */
	if (winh(display, depth, WINH_MAP|WINH_BOTH_SCREENS)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Move pointer to known location. */
	if (warppointer(display, DRW(display), 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
/* Set window A. */
	A = guardian->firstchild;
/* Set window B. */
	B = guardian->nextsibling->firstchild;
/* Set P to inferior of window B. */
	P = guardian->nextsibling->firstchild;
/* Set input focus to window A. */
	XSetInputFocus(display, A->window, RevertToNone, CurrentTime);
/* Move pointer to window P. */
	XWarpPointer(display, None, P->window, 0, 0, 0, 0, 0, 0);
/* Select for Focus events on windows. */
	_event_mask_ = MASK;
	_display_ = display;
	if (winh_climb(B, B, selectinput)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
	if (winh_climb(A, A, selectinput)) {
		report("Could not select for events on window A");
		return;
	}
	else
		CHECK;
	good.type = EVENT;
	good.xany.display = display;
	if (winh_climb(B, B, plant)) {
		report("Could not plant events");
		return;
	}
	else
		CHECK;
/* Generate xname event by changing focus from A to B. */
	XSync(display, True);
	XSetInputFocus(display, B->window, RevertToNone, CurrentTime);
	XSync(display, False);
	if (winh_harvest(display, (Winh *) NULL)) {
		report("Could not harvest events");
		return;
	}
	else
		CHECK;
/* Verify that the expected events were delivered. */
	if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
		delete("Could not ignore %s events", eventname(OTHEREVENT));
		return;
	}
	else
		CHECK;
	status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
	if (status < 0)
		return;
	else if (status > 0) {
		report("Event delivery was not as expected");
		FAIL;
	}
	else {
/* Verify that event delivered on window B with detail */
/* set to NotifyNonlinear. */
		_detail_ = NotifyNonlinear;
		if (winh_climb(B, B, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
		status = winh_ordercheck(OTHEREVENT, EVENT);
		if (status == -1)
			return;
		else if (status)
			FAIL;
		else
			CHECK;
	}
	CHECKPASS(11);
	tpcleanup();
	pfcount(pass, fail);
}

static void t012(){

Display	*display;
int	depth = 5;
Winh	*A, *B, *Broot, *P;
int	status;
int 	pass = 0, fail = 0;

 	report_purpose(12);

	report_assertion("Assertion FocusIn-12.(C)");
	report_assertion("If the implementation supports multiple screens: When the");
	report_assertion("input focus moves from window A to window B and window A and");
	report_assertion("window B are not on the same screens and the pointer is in");
	report_assertion("window P and window P is an inferior of window B, then,");
	report_assertion("after the related FocusIn events are generated with detail");
	report_assertion("set to NotifyNonlinearVirtual and NotifyNonlinear, a");
	report_assertion("FocusIn event is generated on each window below window B");
	report_assertion("down to and including window P with detail set to");
	report_assertion("NotifyPointer.");

	report_strategy("Check to see if multiple screens are supported.");
	report_strategy("Create client.");
	report_strategy("Build window hierarchy on all supported screens.");
	report_strategy("Move pointer to known location.");
	report_strategy("Set window A.");
	report_strategy("Set window B to an inferior of the root window on a different screen than A.");
	report_strategy("Set window P to an inferior of B.");
	report_strategy("Set input focus to window A.");
	report_strategy("Move pointer to window P.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from A to B.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered to each window from window B's root down");
	report_strategy("to but not including window B");
	report_strategy("with detail set to NotifyNonlinearVirtual.");
	report_strategy("Verify that event delivered on window B with detail");
	report_strategy("set to NotifyNonlinear.");
	report_strategy("Verify that event delivered to each window from window B down");
	report_strategy("to and including window P");
	report_strategy("with detail set to NotifyPointer.");
	report_strategy("Verify order of FocusIn event delivery.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");

	tpstartup();
/* Check to see if multiple screens are supported. */
	if (config.alt_screen == -1) {
		unsupported("Multiple screens not supported.");
		return;
	}
	else
		CHECK;
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy on all supported screens. */
	if (winh(display, depth, WINH_MAP|WINH_BOTH_SCREENS)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Move pointer to known location. */
	if (warppointer(display, DRW(display), 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
/* Set window A. */
	A = guardian->firstchild;
/* Set window B to an inferior of the root window on a different screen than A. */
	Broot = guardian->nextsibling;
	B = Broot->firstchild->firstchild;
/* Set window P to an inferior of B. */
	P = B->firstchild->firstchild;
/* Set input focus to window A. */
	XSetInputFocus(display, A->window, RevertToNone, CurrentTime);
/* Move pointer to window P. */
	XWarpPointer(display, None, P->window, 0, 0, 0, 0, 0, 0);
/* Select for Focus events on windows. */
	_event_mask_ = MASK;
	_display_ = display;
	if (winh_climb(P, Broot, selectinput)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
	if (winh_climb(A, A, selectinput)) {
		report("Could not select for events on window A");
		return;
	}
	else
		CHECK;
	good.type = EVENT;
	good.xany.display = display;
	if (winh_climb(P, Broot, plant)) {
		report("Could not plant events");
		return;
	}
	else
		CHECK;
/* Generate xname event by changing focus from A to B. */
	XSync(display, True);
	XSetInputFocus(display, B->window, RevertToNone, CurrentTime);
	XSync(display, False);
	if (winh_harvest(display, (Winh *) NULL)) {
		report("Could not harvest events");
		return;
	}
	else
		CHECK;
/* Verify that the expected events were delivered. */
	if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
		delete("Could not ignore %s events", eventname(OTHEREVENT));
		return;
	}
	else
		CHECK;
	status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
	if (status < 0)
		return;
	else if (status > 0) {
		report("Event delivery was not as expected");
		FAIL;
	}
	else {
/* Verify that event delivered to each window from window B's root down */
/* to but not including window B */
/* with detail set to NotifyNonlinearVirtual. */
		_detail_ = NotifyNonlinearVirtual;
		if (winh_climb(B->parent, Broot, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify that event delivered on window B with detail */
/* set to NotifyNonlinear. */
		_detail_ = NotifyNonlinear;
		if (winh_climb(B, B, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify that event delivered to each window from window B down */
/* to and including window P */
/* with detail set to NotifyPointer. */
		_detail_ = NotifyPointer;
		if (winh_climb(P, B->firstchild, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify order of xname event delivery. */
		increasing = True;
		if (winh_climb(P, Broot, checksequence))
			FAIL;
		else
			CHECK;
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
		status = winh_ordercheck(OTHEREVENT, EVENT);
		if (status == -1)
			return;
		else if (status)
			FAIL;
		else
			CHECK;
	}
	CHECKPASS(14);
	tpcleanup();
	pfcount(pass, fail);
}

static void t013(){


 	report_purpose(13);

	report_assertion("Assertion FocusIn-13.(-)");
	report_assertion("When the focus moves from window A to PointerRoot (events");
	report_assertion("sent to the window under the pointer) and the pointer is in");
	report_assertion("window P, then a FocusIn event is generated on the root");
	report_assertion("window of all screens, with detail set to NotifyPointerRoot.");
	report_assertion("The assertion is descriptive or is tested elsewhere.");
	tet_result(TET_NOTINUSE);
}

static void t014(){

Display	*display;
int	depth = 4;
Winh	*A, *P, *Proot, *ptr;
Winhe	*winhe;
int	status;
int	high;
int 	pass = 0, fail = 0;

 	report_purpose(14);

	report_assertion("Assertion FocusIn-14.(A)");
	report_assertion("When the focus moves from window A to PointerRoot (events");
	report_assertion("sent to the window under the pointer) and the pointer is in");
	report_assertion("window P, then, after the related FocusIn events are");
	report_assertion("generated with detail set to NotifyPointerRoot, a FocusIn");
	report_assertion("event is generated on each window from window P's root down");
	report_assertion("to and including window P, with detail set to NotifyPointer.");

	report_strategy("Create client.");
	report_strategy("Build window hierarchy on all supported screens.");
	report_strategy("Set window A.");
	report_strategy("Set window P.");
	report_strategy("Move pointer to window P.");
	report_strategy("Set input focus to window A.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from A to PointerRoot.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered to the root window of all screens");
	report_strategy("with detail set to NotifyPointerRoot.");
	report_strategy("Verify that event generated on each window from window P's root down");
	report_strategy("to and including window P with detail set to NotifyPointer.");
	report_strategy("Verify that these events occurred in the correct order.");
	report_strategy("Verify that the NotifyPointerRoot events were delivered before");
	report_strategy("NotifyPointer events.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");

	tpstartup();
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy on all supported screens. */
	if (winh(display, depth, WINH_MAP|WINH_BOTH_SCREENS)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Set window A. */
	A = guardian->firstchild;
/* Set window P. */
	Proot = guardian;
	P = Proot->firstchild->firstchild;
/* Move pointer to window P. */
	if (warppointer(display, P->window, 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
/* Set input focus to window A. */
	XSetInputFocus(display, A->window, RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
	if (winh_selectinput(display, (Winh *) NULL, MASK)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
	good.type = EVENT;
	good.xany.display = display;
	/* root window of all screens */
	for (ptr = guardian; ptr != (Winh *) NULL; ptr = ptr->nextsibling) {
		if (ptr == guardian)
			CHECK;
		good.xany.window = ptr->window;
		if (winh_plant(ptr, &good, MASK, WINH_NOMASK)) {
			report("Could not plant events");
			return;
		}
	}
	/* from P's root to P */
	if (winh_climb(P, Proot, plant)) {
		report("Could not plant events between P's root and P");
		return;
	}
	else
		CHECK;
/* Generate xname event by changing focus from A to PointerRoot. */
	XSync(display, True);
	XSetInputFocus(display, PointerRoot, RevertToNone, CurrentTime);
	XSync(display, False);
	if (winh_harvest(display, (Winh *) NULL)) {
		report("Could not harvest events");
		return;
	}
	else
		CHECK;
/* Verify that the expected events were delivered. */
	if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
		delete("Could not ignore %s events", eventname(OTHEREVENT));
		return;
	}
	else
		CHECK;
	status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
	if (status < 0)
		return;
	else if (status > 0) {
		report("Event delivery was not as expected");
		FAIL;
	}
	else {
/* Verify that event delivered to the root window of all screens */
/* with detail set to NotifyPointerRoot. */
		_detail_ = NotifyPointerRoot;
		/* used to keep track of last NotifyPointerRoot event */
		high = 0;
		for (ptr = guardian; ptr != (Winh *) NULL; ptr = ptr->nextsibling) {
			if (ptr == guardian)
				CHECK;
			/*
			 * skip to first FocusIn-type event
			 */
			for (winhe = ptr->delivered; winhe != (Winhe *) NULL; winhe = winhe->next) {
				if (winhe->event->type == EVENT)
					break;
			}
			if (winhe == (Winhe *) NULL) {
				delete("Lost %s event in delivered list",
					eventname(EVENT));
				return;
			}
			if (winhe->sequence > high)
				high = winhe->sequence;
			if (winhe->event->xfocus.detail != _detail_) {
				report("Got detail %d, expected %d on window 0x%x",
					winhe->event->xfocus.detail,
					_detail_, ptr->window);
				FAIL;
			}
			else {
				/*
				 * cause this event to be ignored during
				 * later checks for FocusIn events
				 */
				winhe->event->type = 0;
			}
		}
/* Verify that event generated on each window from window P's root down */
/* to and including window P with detail set to NotifyPointer. */
		_detail_ = NotifyPointer;
		if (winh_climb(P, Proot, checkdetail))
			FAIL;
		else
			CHECK;
/* Verify that these events occurred in the correct order. */
		increasing = True;
		if (winh_climb(P, Proot, checksequence))
			FAIL;
		else
			CHECK;
/* Verify that the NotifyPointerRoot events were delivered before */
/* NotifyPointer events. */
		for (winhe = Proot->delivered; winhe != (Winhe *) NULL; winhe = winhe->next) {
			if (winhe == Proot->delivered)
				CHECK;
			if (winhe->event->type == EVENT)
				break;
		}
		if (winhe == (Winhe *) NULL) {
			delete("Lost %s event in delivered list of Proot",
				eventname(EVENT));
			return;
		}
		else
			CHECK;
		if (high > winhe->sequence) {
			report("NotifyPointerRoot events not delivered before all NotifyPointer events");
			FAIL;
		}
		else
			CHECK;

/* Verify that all xname events are delivered after all */
/* FocusOut events. */
		status = winh_ordercheck(OTHEREVENT, EVENT);
		if (status == -1)
			return;
		else if (status) {
			int	in, out;

			in = winh_eventindex(EVENT);
			out = winh_eventindex(OTHEREVENT);
			report("%s: %d, %s: %d",
				eventname(EVENT), winh_event_stats[in].low,
				eventname(OTHEREVENT), winh_event_stats[out].high
				);
			FAIL;
		}
		else
			CHECK;
	}
	CHECKPASS(15);
	tpcleanup();
	pfcount(pass, fail);
}

static void t015(){

Display	*display;
int	depth = 1;
Winh	*A, *ptr;
Winhe	*winhe;
int	status;
int 	pass = 0, fail = 0;

 	report_purpose(15);

	report_assertion("Assertion FocusIn-15.(A)");
	report_assertion("When the focus moves from window A to None (discard) and");
	report_assertion("the pointer is in window P, then a FocusIn event is");
	report_assertion("generated on the root window of all screens, with detail set");
	report_assertion("to NotifyDetailNone.");

	report_strategy("Create client.");
	report_strategy("Build window hierarchy on all supported screens.");
	report_strategy("Set window A.");
	report_strategy("Set input focus to window A.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from A to None.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered to the root window of all screens");
	report_strategy("with detail set to NotifyDetailNone.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");

	tpstartup();
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy on all supported screens. */
	if (winh(display, depth, WINH_MAP|WINH_BOTH_SCREENS)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Set window A. */
	A = guardian->firstchild;
	/* Don't bother moving the pointer to known location. */
/* Set input focus to window A. */
	XSetInputFocus(display, A->window, RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
	if (winh_selectinput(display, (Winh *) NULL, MASK)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
	good.type = EVENT;
	good.xany.display = display;
	/* root window of all screens */
	for (ptr = guardian; ptr != (Winh *) NULL; ptr = ptr->nextsibling) {
		if (ptr == guardian)
			CHECK;
		good.xany.window = ptr->window;
		if (winh_plant(ptr, &good, MASK, WINH_NOMASK)) {
			report("Could not plant events");
			return;
		}
	}
/* Generate xname event by changing focus from A to None. */
	XSync(display, True);
	XSetInputFocus(display, None, RevertToNone, CurrentTime);
	XSync(display, False);
	if (winh_harvest(display, (Winh *) NULL)) {
		report("Could not harvest events");
		return;
	}
	else
		CHECK;
/* Verify that the expected events were delivered. */
	if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
		delete("Could not ignore %s events", eventname(OTHEREVENT));
		return;
	}
	else
		CHECK;
	status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
	if (status < 0)
		return;
	else if (status > 0) {
		report("Event delivery was not as expected");
		FAIL;
	}
	else {
/* Verify that event delivered to the root window of all screens */
/* with detail set to NotifyDetailNone. */
		_detail_ = NotifyDetailNone;
		for (ptr = guardian; ptr != (Winh *) NULL; ptr = ptr->nextsibling) {
			if (ptr == guardian)
				CHECK;
			/*
			 * skip to first FocusIn-type event
			 */
			for (winhe = ptr->delivered; winhe != (Winhe *) NULL; winhe = winhe->next) {
				if (winhe->event->type == EVENT)
					break;
			}
			if (winhe == (Winhe *) NULL) {
				delete("Lost %s event in delivered list",
					eventname(EVENT));
				return;
			}
			if (winhe->event->xfocus.detail != _detail_) {
				report("Got detail %d, expected %d on window 0x%x",
					winhe->event->xfocus.detail,
					_detail_, ptr->window);
				FAIL;
			}
		}
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
		status = winh_ordercheck(OTHEREVENT, EVENT);
		if (status == -1)
			return;
		else if (status)
			FAIL;
		else
			CHECK;
	}
	CHECKPASS(8);
	tpcleanup();
	pfcount(pass, fail);
}

static void t016(){

Display	*display;
int	depth = 4;
Winh	*A, *Aroot;
int	status;
int	i;
static	Window	focuses[] = {
	(Window) PointerRoot,
	(Window) None
};
int 	pass = 0, fail = 0;

 	report_purpose(16);

	report_assertion("Assertion FocusIn-16.(A)");
	report_assertion("When the focus moves from PointerRoot (events sent to the");
	report_assertion("window under the pointer) or None (discard) to window A and");
	report_assertion("the pointer is in window P and window A is not a root");
	report_assertion("window, then a FocusIn event is generated on each window");
	report_assertion("from window A's root down to but not including window A,");
	report_assertion("with detail set to NotifyNonlinearVirtual.");

	report_strategy("Create client.");
	report_strategy("Build window hierarchy.");
	report_strategy("Set window A.");
	report_strategy("Move pointer to known location.");
	report_strategy("Set input focus to PointerRoot.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from PointerRoot to A.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered on each window from window A's root down to");
	report_strategy("but not including window A");
	report_strategy("with detail set to NotifyNonlinearVirtual.");
	report_strategy("Verify that these events occurred in the correct order.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");
	report_strategy("Repeat with focus initially set to None.");

	tpstartup();
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy. */
	if (winh(display, depth, WINH_MAP)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Set window A. */
	Aroot = guardian;
	A = Aroot->firstchild->firstchild->firstchild;
/* Move pointer to known location. */
	if (warppointer(display, DRW(display), 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
	for (i = 0; i < NELEM(focuses); i++) {
/* Set input focus to PointerRoot. */
		XSetInputFocus(display, focuses[i], RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
		if (winh_selectinput(display, (Winh *) NULL, MASK)) {
			report("Could not select for events");
			return;
		}
		else
			CHECK;
		good.type = EVENT;
		good.xany.display = display;
		/*
		 * Plant at A instead of A->parent because we will also be getting
		 * an xname event on A with detail set to NotifyNonlinear.
		 */
		if (winh_climb(A, Aroot, plant)) {
			report("Could not plant events");
			return;
		}
		else
			CHECK;
/* Generate xname event by changing focus from PointerRoot to A. */
		XSync(display, True);
		XSetInputFocus(display, A->window, RevertToNone, CurrentTime);
		XSync(display, False);
		if (winh_harvest(display, (Winh *) NULL)) {
			report("Could not harvest events");
			return;
		}
		else
			CHECK;
/* Verify that the expected events were delivered. */
		if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
			delete("Could not ignore %s events", eventname(OTHEREVENT));
			return;
		}
		else
			CHECK;
		status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
		if (status < 0)
			return;
		else if (status > 0) {
			report("Event delivery was not as expected");
			FAIL;
		}
		else {
/* Verify that event delivered on each window from window A's root down to */
/* but not including window A */
/* with detail set to NotifyNonlinearVirtual. */
			_detail_ = NotifyNonlinearVirtual;
			if (winh_climb(A->parent, Aroot, checkdetail))
				FAIL;
			else
				CHECK;
/* Verify that these events occurred in the correct order. */
			increasing = True;
			if (winh_climb(A->parent, Aroot, checksequence))
				FAIL;
			else
				CHECK;
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
			status = winh_ordercheck(OTHEREVENT, EVENT);
			if (status == -1)
				return;
			else if (status)
				FAIL;
			else
				CHECK;
		}
/* Repeat with focus initially set to None. */
	}
	CHECKPASS(3 + (7*NELEM(focuses)));
	tpcleanup();
	pfcount(pass, fail);
}

static void t017(){

Display	*display;
int	depth = 4;
Winh	*A, *Aroot;
int	status;
int	i;
static	Window	focuses[] = {
	(Window) PointerRoot,
	(Window) None
};
int 	pass = 0, fail = 0;

 	report_purpose(17);

	report_assertion("Assertion FocusIn-17.(A)");
	report_assertion("When the focus moves from PointerRoot (events sent to the");
	report_assertion("window under the pointer) or None (discard) to window A and");
	report_assertion("the pointer is in window P, then, after any related FocusIn");
	report_assertion("events are generated with detail set to");
	report_assertion("NotifyNonlinearVirtual, a FocusIn event is generated on");
	report_assertion("window A with detail set to NotifyNonlinear.");

	report_strategy("Create client.");
	report_strategy("Build window hierarchy.");
	report_strategy("Set window A.");
	report_strategy("Move pointer to known location.");
	report_strategy("Set input focus to PointerRoot.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from PointerRoot to A.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered on each window from window A's root down to");
	report_strategy("but not including window A");
	report_strategy("with detail set to NotifyNonlinearVirtual.");
	report_strategy("Verify that event delivered on to window A");
	report_strategy("with detail set to NotifyNonlinear.");
	report_strategy("Verify that these events occurred in the correct order.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");
	report_strategy("Repeat with focus initially set to None.");

	tpstartup();
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy. */
	if (winh(display, depth, WINH_MAP)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Set window A. */
	Aroot = guardian;
	A = Aroot->firstchild->firstchild->firstchild;
/* Move pointer to known location. */
	if (warppointer(display, DRW(display), 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
	for (i = 0; i < NELEM(focuses); i++) {
/* Set input focus to PointerRoot. */
		XSetInputFocus(display, focuses[i], RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
		if (winh_selectinput(display, (Winh *) NULL, MASK)) {
			report("Could not select for events");
			return;
		}
		else
			CHECK;
		good.type = EVENT;
		good.xany.display = display;
		if (winh_climb(A, Aroot, plant)) {
			report("Could not plant events");
			return;
		}
		else
			CHECK;
/* Generate xname event by changing focus from PointerRoot to A. */
		XSync(display, True);
		XSetInputFocus(display, A->window, RevertToNone, CurrentTime);
		XSync(display, False);
		if (winh_harvest(display, (Winh *) NULL)) {
			report("Could not harvest events");
			return;
		}
		else
			CHECK;
/* Verify that the expected events were delivered. */
		if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
			delete("Could not ignore %s events", eventname(OTHEREVENT));
			return;
		}
		else
			CHECK;
		status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
		if (status < 0)
			return;
		else if (status > 0) {
			report("Event delivery was not as expected");
			FAIL;
		}
		else {
/* Verify that event delivered on each window from window A's root down to */
/* but not including window A */
/* with detail set to NotifyNonlinearVirtual. */
			_detail_ = NotifyNonlinearVirtual;
			if (winh_climb(A->parent, Aroot, checkdetail))
				FAIL;
			else
				CHECK;
/* Verify that event delivered on to window A */
/* with detail set to NotifyNonlinear. */
			_detail_ = NotifyNonlinear;
			if (winh_climb(A, A, checkdetail))
				FAIL;
			else
				CHECK;
/* Verify that these events occurred in the correct order. */
			increasing = True;
			if (winh_climb(A, Aroot, checksequence))
				FAIL;
			else
				CHECK;
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
			status = winh_ordercheck(OTHEREVENT, EVENT);
			if (status == -1)
				return;
			else if (status)
				FAIL;
			else
				CHECK;
		}
/* Repeat with focus initially set to None. */
	}
	CHECKPASS(3 + (8*NELEM(focuses)));
	tpcleanup();
	pfcount(pass, fail);
}

static void t018(){

Display	*display;
int	depth = 5;
Winh	*A, *Aroot, *P;
int	status;
int	i;
static	Window	focuses[] = {
	(Window) PointerRoot,
	(Window) None
};
int 	pass = 0, fail = 0;

 	report_purpose(18);

	report_assertion("Assertion FocusIn-18.(A)");
	report_assertion("When the focus moves from PointerRoot (events sent to the");
	report_assertion("window under the pointer) or None (discard) to window A and");
	report_assertion("the pointer is in window P and window P is an inferior of");
	report_assertion("window A, then, after the related FocusIn events are");
	report_assertion("generated with detail set to NotifyNonlinearVirtual and");
	report_assertion("NotifyNonlinear, a FocusIn event is generated on each");
	report_assertion("window below window A down to and including window P, with");
	report_assertion("detail set to NotifyPointer.");

	report_strategy("Create client.");
	report_strategy("Build window hierarchy.");
	report_strategy("Set window A.");
	report_strategy("Set window P.");
	report_strategy("Move pointer to window P.");
	report_strategy("Set input focus to PointerRoot.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from PointerRoot to A.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered on each window from window A's root down to");
	report_strategy("but not including window A");
	report_strategy("with detail set to NotifyNonlinearVirtual.");
	report_strategy("Verify that event delivered on to window A");
	report_strategy("with detail set to NotifyNonlinear.");
	report_strategy("Verify that event delivered on each window below window A down to");
	report_strategy("and including window P");
	report_strategy("with detail set to NotifyPointer.");
	report_strategy("Verify that these events occurred in the correct order.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");
	report_strategy("Repeat with focus initially set to None.");

	tpstartup();
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy. */
	if (winh(display, depth, WINH_MAP)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Set window A. */
	Aroot = guardian;
	A = Aroot->firstchild->firstchild;
/* Set window P. */
	P = A->firstchild->firstchild;
/* Move pointer to window P. */
	if (warppointer(display, P->window, 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
	for (i = 0; i < NELEM(focuses); i++) {
/* Set input focus to PointerRoot. */
		XSetInputFocus(display, focuses[i], RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
		if (winh_selectinput(display, (Winh *) NULL, MASK)) {
			report("Could not select for events");
			return;
		}
		else
			CHECK;
		good.type = EVENT;
		good.xany.display = display;
		if (winh_climb(P, Aroot, plant)) {
			report("Could not plant events");
			return;
		}
		else
			CHECK;
/* Generate xname event by changing focus from PointerRoot to A. */
		XSync(display, True);
		XSetInputFocus(display, A->window, RevertToNone, CurrentTime);
		XSync(display, False);
		if (winh_harvest(display, (Winh *) NULL)) {
			report("Could not harvest events");
			return;
		}
		else
			CHECK;
/* Verify that the expected events were delivered. */
		if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
			delete("Could not ignore %s events", eventname(OTHEREVENT));
			return;
		}
		else
			CHECK;
		status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
		if (status < 0)
			return;
		else if (status > 0) {
			report("Event delivery was not as expected");
			FAIL;
		}
		else {
/* Verify that event delivered on each window from window A's root down to */
/* but not including window A */
/* with detail set to NotifyNonlinearVirtual. */
			_detail_ = NotifyNonlinearVirtual;
			if (winh_climb(A->parent, Aroot, checkdetail)) {
				report("Bad detail on some window above A's parent");
				FAIL;
			}
			else
				CHECK;
/* Verify that event delivered on to window A */
/* with detail set to NotifyNonlinear. */
			_detail_ = NotifyNonlinear;
			if (winh_climb(A, A, checkdetail)) {
				report("Bad detail on window A");
				FAIL;
			}
			else
				CHECK;
/* Verify that event delivered on each window below window A down to */
/* and including window P */
/* with detail set to NotifyPointer. */
			_detail_ = NotifyPointer;
			if (winh_climb(P, A->firstchild, checkdetail)) {
				report("Bad detail on some window below window A down to window P");
				FAIL;
			}
			else
				CHECK;
/* Verify that these events occurred in the correct order. */
			increasing = True;
			if (winh_climb(P, Aroot, checksequence))
				FAIL;
			else
				CHECK;
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
			status = winh_ordercheck(OTHEREVENT, EVENT);
			if (status == -1)
				return;
			else if (status)
				FAIL;
			else
				CHECK;
		}
/* Repeat with focus initially set to None. */
	}
	CHECKPASS(3 + (9*NELEM(focuses)));
	tpcleanup();
	pfcount(pass, fail);
}

static void t019(){

Display	*display;
int	depth = 2;
Winh	*ptr;
Winhe	*winhe;
int	status;
int 	pass = 0, fail = 0;

 	report_purpose(19);

	report_assertion("Assertion FocusIn-19.(A)");
	report_assertion("When the focus moves from PointerRoot (events sent to the");
	report_assertion("window under the pointer) to None (discard) and the pointer");
	report_assertion("is in window P, then a FocusIn event is generated on the");
	report_assertion("root window of all screens, with detail set to");
	report_assertion("NotifyDetailNone.");

	report_strategy("Create client.");
	report_strategy("Build window hierarchy on all supported screens.");
	report_strategy("Move pointer to known location.");
	report_strategy("Set input focus to PointerRoot.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from PointerRoot to None.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered to the root window of all screens");
	report_strategy("with detail set to NotifyDetailNone.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");

	tpstartup();
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy on all supported screens. */
	if (winh(display, depth, WINH_MAP|WINH_BOTH_SCREENS)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Move pointer to known location. */
	if (warppointer(display, DRW(display), 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
/* Set input focus to PointerRoot. */
	XSetInputFocus(display, PointerRoot, RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
	if (winh_selectinput(display, (Winh *) NULL, MASK)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
	good.type = EVENT;
	good.xany.display = display;
	/* root window of all screens */
	for (ptr = guardian; ptr != (Winh *) NULL; ptr = ptr->nextsibling) {
		if (ptr == guardian)
			CHECK;
		good.xany.window = ptr->window;
		if (winh_plant(ptr, &good, MASK, WINH_NOMASK)) {
			report("Could not plant events");
			return;
		}
	}
/* Generate xname event by changing focus from PointerRoot to None. */
	XSync(display, True);
	XSetInputFocus(display, None, RevertToNone, CurrentTime);
	XSync(display, False);
	if (winh_harvest(display, (Winh *) NULL)) {
		report("Could not harvest events");
		return;
	}
	else
		CHECK;
/* Verify that the expected events were delivered. */
	if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
		delete("Could not ignore %s events", eventname(OTHEREVENT));
		return;
	}
	else
		CHECK;
	status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
	if (status < 0)
		return;
	else if (status > 0) {
		report("Event delivery was not as expected");
		FAIL;
	}
	else {
/* Verify that event delivered to the root window of all screens */
/* with detail set to NotifyDetailNone. */
		_detail_ = NotifyDetailNone;
		for (ptr = guardian; ptr != (Winh *) NULL; ptr = ptr->nextsibling) {
			if (ptr == guardian)
				CHECK;
			/*
			 * skip to first FocusIn-type event
			 */
			for (winhe = ptr->delivered; winhe != (Winhe *) NULL; winhe = winhe->next) {
				if (winhe->event->type == EVENT)
					break;
			}
			if (winhe == (Winhe *) NULL) {
				delete("Lost %s event in delivered list",
					eventname(EVENT));
				return;
			}
			if (winhe->event->xfocus.detail != _detail_) {
				report("Got detail %d, expected %d on window 0x%x",
					winhe->event->xfocus.detail,
					_detail_, ptr->window);
				FAIL;
			}
			else {
				/*
				 * cause this event to be ignored during
				 * later checks for FocusIn events
				 */
				winhe->event->type = 0;
			}
		}
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
		status = winh_ordercheck(OTHEREVENT, EVENT);
		if (status == -1)
			return;
		else if (status)
			FAIL;
		else
			CHECK;
	}
	CHECKPASS(9);
	tpcleanup();
	pfcount(pass, fail);
}

static void t020(){

Display	*display;
int	depth = 2;
Winh	*P, *ptr;
Winhe	*winhe;
int	status;
int 	pass = 0, fail = 0;

 	report_purpose(20);

	report_assertion("Assertion FocusIn-20.(A)");
	report_assertion("When the focus moves from None to PointerRoot and the");
	report_assertion("pointer is in window P, then a FocusIn event is generated on");
	report_assertion("the root window of all screens, with detail set to");
	report_assertion("NotifyPointerRoot.");

	report_strategy("Create client.");
	report_strategy("Build window hierarchy on all supported screens.");
	report_strategy("Set window P.");
	report_strategy("Move pointer to known location.");
	report_strategy("Set input focus to None.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from None to PointerRoot.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered to the root window of all screens");
	report_strategy("with detail set to NotifyPointerRoot.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");

	tpstartup();
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy on all supported screens. */
	if (winh(display, depth, WINH_MAP|WINH_BOTH_SCREENS)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Set window P. */
	P = guardian;
/* Move pointer to known location. */
	if (warppointer(display, P->window, 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
/* Set input focus to None. */
	XSetInputFocus(display, None, RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
	if (winh_selectinput(display, (Winh *) NULL, MASK)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
	good.type = EVENT;
	good.xany.display = display;
	/* root window of all screens */
	for (ptr = guardian; ptr != (Winh *) NULL; ptr = ptr->nextsibling) {
		if (ptr == guardian)
			CHECK;
		good.xany.window = ptr->window;
		if (winh_plant(ptr, &good, MASK, WINH_NOMASK)) {
			report("Could not plant events");
			return;
		}
	}
	/* also expect a subsequent event on P */
	good.xany.window = P->window;
	if (winh_plant(P, &good, MASK, WINH_NOMASK)) {
		report("Could not plant events on P");
		return;
	}
	else
		CHECK;
/* Generate xname event by changing focus from None to PointerRoot. */
	XSync(display, True);
	XSetInputFocus(display, PointerRoot, RevertToNone, CurrentTime);
	XSync(display, False);
	if (winh_harvest(display, (Winh *) NULL)) {
		report("Could not harvest events");
		return;
	}
	else
		CHECK;
/* Verify that the expected events were delivered. */
	if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
		delete("Could not ignore %s events", eventname(OTHEREVENT));
		return;
	}
	else
		CHECK;
	status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
	if (status < 0)
		return;
	else if (status > 0) {
		report("Event delivery was not as expected");
		FAIL;
	}
	else {
/* Verify that event delivered to the root window of all screens */
/* with detail set to NotifyPointerRoot. */
		_detail_ = NotifyPointerRoot;
		for (ptr = guardian; ptr != (Winh *) NULL; ptr = ptr->nextsibling) {
			if (ptr == guardian)
				CHECK;
			/*
			 * skip to first FocusIn-type event
			 */
			for (winhe = ptr->delivered; winhe != (Winhe *) NULL; winhe = winhe->next) {
				if (winhe->event->type == EVENT)
					break;
			}
			if (winhe == (Winhe *) NULL) {
				delete("Lost %s event in delivered list",
					eventname(EVENT));
				return;
			}
			if (winhe->event->xfocus.detail != _detail_) {
				report("Got detail %d, expected %d on window 0x%x",
					winhe->event->xfocus.detail,
					_detail_, ptr->window);
				FAIL;
			}
			else {
				/*
				 * cause this event to be ignored during
				 * later checks for FocusIn events
				 */
				winhe->event->type = 0;
			}
		}
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
		status = winh_ordercheck(OTHEREVENT, EVENT);
		if (status == -1)
			return;
		else if (status)
			FAIL;
		else
			CHECK;
	}
	CHECKPASS(10);
	tpcleanup();
	pfcount(pass, fail);
}

static void t021(){

Display	*display;
int	depth = 4;
Winh	*P, *Proot, *ptr;
Winhe	*winhe;
int	status;
int	high;
int 	pass = 0, fail = 0;

 	report_purpose(21);

	report_assertion("Assertion FocusIn-21.(A)");
	report_assertion("When the focus moves from None to PointerRoot and the");
	report_assertion("pointer is in window P, then, after the related FocusIn");
	report_assertion("events are generated with detail set to NotifyPointerRoot,");
	report_assertion("a FocusIn event is generated on each window from window P's");
	report_assertion("root down to and including window P, with detail set to");
	report_assertion("NotifyPointer.");

	report_strategy("Create client.");
	report_strategy("Build window hierarchy on all supported screens.");
	report_strategy("Set window P.");
	report_strategy("Move pointer to known location.");
	report_strategy("Set input focus to None.");
	report_strategy("Select for Focus events on windows.");
	report_strategy("Generate FocusIn event by changing focus from None to PointerRoot.");
	report_strategy("Verify that the expected events were delivered.");
	report_strategy("Verify that event delivered to the root window of all screens");
	report_strategy("with detail set to NotifyPointerRoot.");
	report_strategy("Verify that event delivered on each window from window P's root down to");
	report_strategy("and including window P");
	report_strategy("with detail set to NotifyPointer.");
	report_strategy("Verify that the NotifyPointerRoot events were delivered before");
	report_strategy("NotifyPointer events.");
	report_strategy("Verify that all FocusIn events are delivered after all");
	report_strategy("FocusOut events.");

	tpstartup();
/* Create client. */
	if ((display = opendisplay()) == (Display *) NULL) {
		delete("Couldn't create client.");
		return;
	}
	else
		CHECK;
/* Build window hierarchy on all supported screens. */
	if (winh(display, depth, WINH_MAP|WINH_BOTH_SCREENS)) {
		report("Could not build window hierarchy");
		return;
	}
	else
		CHECK;
/* Set window P. */
	Proot = guardian;
	P = Proot->firstchild->firstchild->firstchild;
/* Move pointer to known location. */
	if (warppointer(display, P->window, 0, 0) == (PointerPlace *) NULL)
		return;
	else
		CHECK;
/* Set input focus to None. */
	XSetInputFocus(display, None, RevertToNone, CurrentTime);
/* Select for Focus events on windows. */
	if (winh_selectinput(display, (Winh *) NULL, MASK)) {
		report("Could not select for events");
		return;
	}
	else
		CHECK;
	good.type = EVENT;
	good.xany.display = display;
	/* root window of all screens */
	for (ptr = guardian; ptr != (Winh *) NULL; ptr = ptr->nextsibling) {
		if (ptr == guardian)
			CHECK;
		good.xany.window = ptr->window;
		if (winh_plant(ptr, &good, MASK, WINH_NOMASK)) {
			report("Could not plant events");
			return;
		}
	}
	if (winh_climb(P, Proot, plant)) {
		report("Could not plant events from P's root to P");
		return;
	}
	else
		CHECK;
/* Generate xname event by changing focus from None to PointerRoot. */
	XSync(display, True);
	XSetInputFocus(display, PointerRoot, RevertToNone, CurrentTime);
	XSync(display, False);
	if (winh_harvest(display, (Winh *) NULL)) {
		report("Could not harvest events");
		return;
	}
	else
		CHECK;
/* Verify that the expected events were delivered. */
	if (winh_ignore_event((Winh *) NULL, OTHEREVENT, WINH_NOMASK)) {
		delete("Could not ignore %s events", eventname(OTHEREVENT));
		return;
	}
	else
		CHECK;
	status = winh_weed((Winh *) NULL, -1, WINH_WEED_IDENTITY);
	if (status < 0)
		return;
	else if (status > 0) {
		report("Event delivery was not as expected");
		FAIL;
	}
	else {
/* Verify that event delivered to the root window of all screens */
/* with detail set to NotifyPointerRoot. */
		_detail_ = NotifyPointerRoot;
		high = 0;
		for (ptr = guardian; ptr != (Winh *) NULL; ptr = ptr->nextsibling) {
			if (ptr == guardian)
				CHECK;
			/*
			 * skip to first FocusIn-type event
			 */
			for (winhe = ptr->delivered; winhe != (Winhe *) NULL; winhe = winhe->next) {
				if (winhe->event->type == EVENT)
					break;
			}
			if (winhe == (Winhe *) NULL) {
				delete("Lost %s event in delivered list",
					eventname(EVENT));
				return;
			}
			if (winhe->sequence > high)
				high = winhe->sequence;
			if (winhe->event->xfocus.detail != _detail_) {
				report("Got detail %d, expected %d on window 0x%x",
					winhe->event->xfocus.detail,
					_detail_, ptr->window);
				FAIL;
			}
			else {
				/*
				 * cause this event to be ignored during
				 * later checks for FocusIn events
				 */
				winhe->event->type = 0;
			}
		}
/* Verify that event delivered on each window from window P's root down to */
/* and including window P */
/* with detail set to NotifyPointer. */
			_detail_ = NotifyPointer;
			if (winh_climb(P, Proot, checkdetail)) {
				report("Bad detail on some window between windows P's root and P");
				FAIL;
			}
			else
				CHECK;
/* Verify that the NotifyPointerRoot events were delivered before */
/* NotifyPointer events. */
		for (winhe = Proot->delivered; winhe != (Winhe *) NULL; winhe = winhe->next) {
			if (winhe == Proot->delivered)
				CHECK;
			if (winhe->event->type == EVENT)
				break;
		}
		if (winhe == (Winhe *) NULL) {
			delete("Lost %s event in delivered list of Proot",
				eventname(EVENT));
			return;
		}
		else
			CHECK;
		if (high > winhe->sequence) {
			report("NotifyPointerRoot events not delivered before all NotifyPointer events");
			FAIL;
		}
		else
			CHECK;
/* Verify that all xname events are delivered after all */
/* FocusOut events. */
		status = winh_ordercheck(OTHEREVENT, EVENT);
		if (status == -1)
			return;
		else if (status)
			FAIL;
		else
			CHECK;
	}
	CHECKPASS(14);
	tpcleanup();
	pfcount(pass, fail);
}

/* End of Test Cases */


struct tet_testlist tet_testlist[] = {
	{ t001, 1 },
	{ t002, 2 },
	{ t003, 3 },
	{ t004, 4 },
	{ t005, 5 },
	{ t006, 6 },
	{ t007, 7 },
	{ t008, 8 },
	{ t009, 9 },
	{ t010, 10 },
	{ t011, 11 },
	{ t012, 12 },
	{ t013, 13 },
	{ t014, 14 },
	{ t015, 15 },
	{ t016, 16 },
	{ t017, 17 },
	{ t018, 18 },
	{ t019, 19 },
	{ t020, 20 },
	{ t021, 21 },
	{ NULL, 0 }
};

int 	ntests = sizeof(tet_testlist)/sizeof(struct tet_testlist)-1;

void	(*tet_startup)() = focusstartup;
void	(*tet_cleanup)() = focuscleanup;
