/*
* 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.
* 
* Copyright (c) 2005 X.Org Foundation LLC
* 
* 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.
* 
* Copyright 1990, 1991 by UniSoft Group Limited.
* 
* 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.
* 
* Copyright (c) 2005 X.Org Foundation LLC
* 
* 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.
* 
* Copyright 1990, 1991 by UniSoft Group Limited.
* 
* 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.
* 
* Copyright (c) 2005 X.Org Foundation LLC
* 
* 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.
* 
* Copyright 1990, 1991 by UniSoft Group Limited.
* 
* 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.
* 
* Copyright (c) 2005 X.Org Foundation LLC
* 
* 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.
* 
* Copyright 1990, 1991 by UniSoft Group Limited.
* 
* 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.
* 
*/
/*
 * SYNOPSIS:
 *   int
 *   XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime)
 *   Display	*display;
 *   Window	grab_window;
 *   Bool	owner_events;
 *   int 	pointer_mode;
 *   int 	keyboard_mode;
 *   Time	thetime;
 */


#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_XGrabKeyboard	1
char    *TestName = "XGrabKeyboard";

/*
 * Defines for different argument types
 */
#define A_DISPLAY display
#define A_WINDOW grab_window
#define A_DRAWABLE grab_window


/*
 * Arguments to the XGrabKeyboard function
 */
static Display	*display;
static Window	grab_window;
static Bool	owner_events;
static int 	pointer_mode;
static int 	keyboard_mode;
static Time	thetime;


static int 	ValueReturn;


/*
 * Returns True if the keyboard is frozen.
 */
static int
iskfrozen()
{
XEvent	ev;
int 	res;
static int 	key;

	XSync(display, True); /* Flush previous events */
	key = getkeycode(display);

	/*
	 * Try to provoke a keypress on grab_window.
	 */
	warppointer(display, grab_window, 1, 1);
	keypress(display, key);
	if (XCheckMaskEvent(display, (long)KeyPressMask, &ev))
		res = False;
	else
		res = True;

	return(res);
}



/*
 * Returns True if the pointer is frozen.
 */
static Bool
ispfrozen()
{
XEvent	ev;
Window	win;

	win = defwin(Dsp);
	warppointer(Dsp, win, 0, 0);
	XSync(Dsp, True);	/* discard events */

	XSelectInput(Dsp, win, PointerMotionMask);

	warppointer(Dsp, win, 1, 4);
	XSync(Dsp, False);

	if (XCheckWindowEvent(Dsp, win, PointerMotionMask, &ev))
		return(False);
	else
		return(True);
}



/* Value list for use in test t022 */
static int 	owner_eventsvallist[] = {
	True,
	False,
};



/* Value list for use in test t023 */
static int 	pointer_modevallist[] = {
	GrabModeSync,
	GrabModeAsync,
};



/* Value list for use in test t024 */
static int 	keyboard_modevallist[] = {
	GrabModeSync,
	GrabModeAsync,
};


int 	tet_thistest;

/*
 * Called at the beginning of each test purpose to reset the
 * arguments to their initial values
 */
static void
setargs()
{
	display = Dsp;
	grab_window = defwin(display);
	owner_events = False;
	pointer_mode = GrabModeAsync;
	keyboard_mode = GrabModeAsync;
	thetime = CurrentTime;
}

/*
 * Set the arguments to default values for error tests
 */
static void
seterrdef()
{
}

static void t001(){

int 	pass = 0, fail = 0;

 	report_purpose(1);

	report_assertion("Assertion XGrabKeyboard-1.(A)");
	report_assertion("A successful call to XGrabKeyboard actively grabs control");
	report_assertion("of the keyboard and returns GrabSuccess.");

	report_strategy("Touch test for return value.");

	tpstartup();
	setargs();
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	if (ValueReturn == GrabSuccess)
		PASS;
	tpcleanup();
	pfcount(pass, fail);
}

static void t002(){

Window	win;
Window	ofocus;
XEvent	ev;
XFocusInEvent	figood;
XFocusOutEvent	fogood;
int 	orevert;
int 	pass = 0, fail = 0;

 	report_purpose(2);

	report_assertion("Assertion XGrabKeyboard-2.(A)");
	report_assertion("When the keyboard is grabbed, then FocusIn and FocusOut");
	report_assertion("events are generated as though the focus had changed from");
	report_assertion("the previous focus window to grab_window.");

	report_strategy("Create window.");
	report_strategy("Set Focus to that window.");
	report_strategy("Enable events on grab and focus window.");
	report_strategy("Grab keyboard.");
	report_strategy("Verify grab-mode FocusOut from window.");
	report_strategy("Verify grab-mode FocusIn to grab window.");

	tpstartup();
	setargs();
	/*
	 * Save current input focus to pose as little inconvenience as
	 * possible.
	 */
	XGetInputFocus(display, &ofocus, &orevert);

	win = defwin(display);
	XSetInputFocus(display, win, RevertToNone, CurrentTime);
	if (isdeleted()) {
		report("Could not set up focus");
		return;
	}

	XSelectInput(display, grab_window, FocusChangeMask);
	XSelectInput(display, win, FocusChangeMask);

	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	/*
	 * Set up the expected good events.
	 */
	defsetevent(figood, display, FocusIn);
	figood.window = grab_window;
	figood.mode = NotifyGrab;
	figood.detail = NotifyNonlinear;

	defsetevent(fogood, display, FocusOut);
	fogood.window = win;
	fogood.mode = NotifyGrab;
	fogood.detail = NotifyNonlinear;

	if (getevent(display, &ev) == 0 || ev.type != FocusOut) {
		report("Did not get expected FocusOut event");
		FAIL;
	} else
		CHECK;

	if (checkevent((XEvent*)&fogood, &ev))
		FAIL;
	else
		CHECK;

	if (getevent(display, &ev) == 0 || ev.type != FocusIn) {
		report("Did not get expected FocusIn event");
		FAIL;
	} else
		CHECK;

	if (checkevent((XEvent*)&figood, &ev))
		FAIL;
	else
		CHECK;

	/* Reset old focus */
	XSetInputFocus(display, ofocus, orevert, CurrentTime);

	CHECKPASS(4);
	tpcleanup();
	pfcount(pass, fail);
}

static void t003(){

Display	*client2;
XEvent	ev;
int 	pass = 0, fail = 0;

 	report_purpose(3);

	report_assertion("Assertion XGrabKeyboard-3.(B)");
	report_assertion("When a successful call to XGrabKeyboard is made by a");
	report_assertion("client, then subsequent keyboard events are reported only to");
	report_assertion("that client.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Create a second client.");
	report_strategy("  Select key events for default client.");
	report_strategy("  Select key events for second client.");
	report_strategy("  Call XGrabKeyboard with default client.");
	report_strategy("");
	report_strategy("  Press key in window.");
	report_strategy("  Verify that key event is received only by default client.");

	tpstartup();
	setargs();
	if (noext(0))
		return;

	if ((client2 = opendisplay()) == NULL) {
		tccabort("Could not open display (%s)", config.display);
		return;
	} else
		CHECK;

	XSelectInput(display, grab_window, KeyPressMask|KeyReleaseMask);
	XSelectInput(client2, grab_window, KeyPressMask|KeyReleaseMask);

	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	warppointer(client2, grab_window, 1, 1);
	keypress(display, getkeycode(display));

	if (XCheckMaskEvent(display, KeyPressMask, &ev))
		CHECK;
	else {
		report("Keyboard event not received on the grabbing client");
		FAIL;
	}
	if (XCheckMaskEvent(client2, KeyPressMask, &ev)) {
		report("Keyboard event was received on a non-grabbing client");
		FAIL;
	} else
		CHECK;

	CHECKPASS(3);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t004(){

int 	pass = 0, fail = 0;

 	report_purpose(4);

	report_assertion("Assertion XGrabKeyboard-4.(A)");
	report_assertion("A call to XGrabKeyboard overrides any active keyboard grab");
	report_assertion("by this client.");

	report_strategy("Call XGrabKeyboard with pointer_mode GrabModeAsync.");
	report_strategy("Check that pointer is not frozen.");
	report_strategy("Call XGrabKeyboard with pointer_mode GrabModeSync.");
	report_strategy("Verify that pointer is frozen and so the last grab was overriden.");

	tpstartup();
	setargs();
	pointer_mode = GrabModeAsync;
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (ispfrozen()) {
		delete("Could not setup grab");
		return;
	}

	pointer_mode = GrabModeSync;
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (ispfrozen())
		CHECK;
	else {
		report("A second grab did not override the first");
		FAIL;
	}

	CHECKPASS(1);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t005(){

Window	window2;
XEvent	ev;
int 	pass = 0, fail = 0;

 	report_purpose(5);

	report_assertion("Assertion XGrabKeyboard-5.(B)");
	report_assertion("When owner_events is False, then all generated keyboard");
	report_assertion("events are reported with respect to the grab_window.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions available:");
	report_strategy("  Create grab_window.");
	report_strategy("  Create window2.");
	report_strategy("  Select key events on both windows.");
	report_strategy("  Call XGrabKeyboard with owner_events False.");
	report_strategy("  Move pointer to window2 (focus is the root).");
	report_strategy("  Press key.");
	report_strategy("  Verify that event is reported on grab_window.");

	tpstartup();
	setargs();
	if (noext(0))
		return;

	window2 = defwin(display);
	XSelectInput(display, grab_window, KeyPressMask|KeyReleaseMask);
	XSelectInput(display, window2, KeyPressMask|KeyReleaseMask);

	owner_events = False;
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	warppointer(display, window2, 1, 1);
	keypress(display, getkeycode(display));

	if (XCheckWindowEvent(display, grab_window, KeyPressMask, &ev))
		CHECK;
	else {
		report("Event was not reported on grab_window");
		FAIL;
	}
	if (XCheckWindowEvent(display, window2, KeyPressMask, &ev)) {
		report("Event was reported on the owner window");
		FAIL;
	} else
		CHECK;

	CHECKPASS(2);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t006(){

Window	window2;
XEvent	ev;
int 	pass = 0, fail = 0;

 	report_purpose(6);

	report_assertion("Assertion XGrabKeyboard-6.(B)");
	report_assertion("When owner_events is True and a keyboard event is generated");
	report_assertion("that would normally be reported to the client, then it is");
	report_assertion("reported on the window it would normally be reported on.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions available:");
	report_strategy("  Create grab_window.");
	report_strategy("  Create window2.");
	report_strategy("  Select key events on both windows.");
	report_strategy("  Call XGrabKeyboard with owner_events True.");
	report_strategy("  Move pointer to window2 (focus is the root).");
	report_strategy("  Press key.");
	report_strategy("  Verify that event is reported on window2.");

	tpstartup();
	setargs();
	if (noext(0))
		return;

	window2 = defwin(display);
	XSelectInput(display, grab_window, KeyPressMask|KeyReleaseMask);
	XSelectInput(display, window2, KeyPressMask|KeyReleaseMask);

	owner_events = True;
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	warppointer(display, window2, 1, 1);
	keypress(display, getkeycode(display));

	if (XCheckWindowEvent(display, window2, KeyPressMask, &ev))
		CHECK;
	else {
		report("Event was not reported on the owner window");
		FAIL;
	}
	if (XCheckWindowEvent(display, grab_window, KeyPressMask, &ev)) {
		report("Event was reported on the grab_window");
		FAIL;
	} else
		CHECK;

	CHECKPASS(2);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t007(){

Window	window2;
XEvent	ev;
int 	pass = 0, fail = 0;

 	report_purpose(7);

	report_assertion("Assertion XGrabKeyboard-7.(B)");
	report_assertion("When owner_events is True, and a keyboard event is");
	report_assertion("generated that would not normally be reported to the client,");
	report_assertion("then it is reported on the grab_window.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions available:");
	report_strategy("  Create grab_window.");
	report_strategy("  Create window2.");
	report_strategy("  Call XGrabKeyboard with owner_events True.");
	report_strategy("  Move pointer to window2 (focus is the root).");
	report_strategy("  Press key.");
	report_strategy("  Verify that event is reported on grab_window.");

	tpstartup();
	setargs();
	if (noext(0))
		return;

	window2 = defwin(display);

	owner_events = True;
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	warppointer(display, window2, 1, 1);
	keypress(display, getkeycode(display));

	if (XCheckWindowEvent(display, grab_window, KeyPressMask, &ev))
		CHECK;
	else {
		report("Event was not reported on grab_window");
		FAIL;
	}
	if (XCheckWindowEvent(display, window2, KeyPressMask, &ev)) {
		report("Event was reported on the owner window");
		FAIL;
	} else
		CHECK;

	CHECKPASS(2);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t008(){

XEvent	ev;
int 	key;
int 	pass = 0, fail = 0;

 	report_purpose(8);

	report_assertion("Assertion XGrabKeyboard-8.(B)");
	report_assertion("When the keyboard is grabbed, then KeyPress and KeyRelease");
	report_assertion("events are always reported, independent of any event");
	report_assertion("selection made by the client.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions available:");
	report_strategy("  Grab keyboard by calling XGrabKeyboard.");
	report_strategy("  Press key.");
	report_strategy("  Verify that a KeyPress event is reported.");
	report_strategy("  Release key.");
	report_strategy("  Verify that a KeyRelease event is reported.");

	tpstartup();
	setargs();
	if (noext(0))
		return;

	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	warppointer(display, grab_window, 1, 1);
	key = getkeycode(display);
	keypress(display, key);

	if (XCheckMaskEvent(display, KeyPressMask, &ev))
		CHECK;
	else {
		report("KeyPress event was not reported during grab when not selected");
		FAIL;
	}
	keyrel(display, key);

	if (XCheckMaskEvent(display, KeyReleaseMask, &ev))
		CHECK;
	else {
		report("KeyRelease event was not reported during grab when not selected");
		FAIL;
	}

	CHECKPASS(2);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t009(){

int 	pass = 0, fail = 0;

 	report_purpose(9);

	report_assertion("Assertion XGrabKeyboard-9.(B)");
	report_assertion("When keyboard_mode is GrabModeAsync, then keyboard event");
	report_assertion("processing continues normally.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions available:");
	report_strategy("  Call XGrabKeyboard with keyboard_mode GrabModeAsync.");
	report_strategy("  Verify that keyboard is not frozen.");

	tpstartup();
	setargs();
	if (noext(0))
		return;

	keyboard_mode = GrabModeAsync;
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (iskfrozen()) {
		report("Keyboard was frozen by GrabModeAsync");
		FAIL;
	} else
		CHECK;

	CHECKPASS(1);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t010(){

int 	pass = 0, fail = 0;

 	report_purpose(10);

	report_assertion("Assertion XGrabKeyboard-10.(B)");
	report_assertion("When keyboard_mode is GrabModeAsync, and the keyboard is");
	report_assertion("currently frozen by this client, then processing of keyboard");
	report_assertion("events is resumed.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions available:");
	report_strategy("  Freeze keyboard using XGrabPointer.");
	report_strategy("  Call XGrabKeyboard with keyboard_mode GrabModeAsync.");
	report_strategy("  Verify that keyboard is not frozen.");

	tpstartup();
	setargs();
	if (noext(0))
		return;

	XGrabPointer(display, grab_window, False, 0, GrabModeAsync, GrabModeSync,
		None, None, CurrentTime);

	keyboard_mode = GrabModeAsync;
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (iskfrozen()) {
		report("Keyboard was not released by GrabModeAsync");
		FAIL;
	} else
		CHECK;

	CHECKPASS(1);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t011(){

int 	pass = 0, fail = 0;

 	report_purpose(11);

	report_assertion("Assertion XGrabKeyboard-11.(B)");
	report_assertion("When keyboard_mode is GrabModeSync, then the state of the");
	report_assertion("keyboard, as seen by client applications, appears to freeze");
	report_assertion("and no further keyboard events are generated until the");
	report_assertion("grabbing client issues a releasing XAllowEvents call or");
	report_assertion("until the keyboard grab is released.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions available:");
	report_strategy("  Call XGrabKeyboard with keyboard_mode GrabModeSync.");
	report_strategy("  Verify that keyboard is frozen.");
	report_strategy("  Release grab.");
	report_strategy("  Verify that keyboard is not frozen.");

	tpstartup();
	setargs();
	if (noext(0))
		return;

	XSelectInput(display, grab_window, KeyPressMask);

	keyboard_mode = GrabModeSync;
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (iskfrozen())
		CHECK;
	else {
		report("Keyboard was not frozen with keyboard_mode GrabModeSync");
		FAIL;
	}

	XUngrabKeyboard(display, CurrentTime);
	XSync(display, False);
	if (iskfrozen()) {
		report("Keyboard was not thawed after the grab was released");
		FAIL;
	} else
		CHECK;

	CHECKPASS(2);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t012(){

int 	key;
int 	n;
int 	first;
XEvent	ev;
int 	pass = 0, fail = 0;

 	report_purpose(12);

	report_assertion("Assertion XGrabKeyboard-12.(B)");
	report_assertion("When the keyboard is frozen, then the actual keyboard");
	report_assertion("changes are not lost while the keyboard is frozen and are");
	report_assertion("processed after the grab is released or the client calls");
	report_assertion("XAllowEvents.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions available:");
	report_strategy("  Enable key events on grab_window.");
	report_strategy("  Call XGrabKeyboard with keyboard_mode GrabModeSync.");
	report_strategy("  Press and release key.");
	report_strategy("  Check no events arrived yet.");
	report_strategy("  Release grab.");
	report_strategy("  Verify that KeyPress and KeyRelease events are now received.");

	tpstartup();
	setargs();
	if (noext(0))
		return;

	key = getkeycode(display);
	XSelectInput(display, grab_window, KeyPressMask|KeyReleaseMask);

	keyboard_mode = GrabModeSync;
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	warppointer(display, grab_window, 10, 10);
	keypress(display, key);
	keyrel(display, key);

	if (XCheckMaskEvent(display, KeyPressMask|KeyReleaseMask, &ev)) {
		delete("Events received while keyboard supposed to be frozen");
		return;
	} else
		CHECK;

	XUngrabKeyboard(display, thetime);
	if (isdeleted())
		return;

	n = getevent(display, &ev);
	if (n != 2) {
		report("Expecting two events to be released after grab");
		report("  got %d", n);
		FAIL;
	} else {
		first = ev.type;
		getevent(display, &ev);
		/* (We have already checked that there is another event) */

		if (ev.type != KeyPress && first != KeyPress) {
			report("Did not get KeyPress event after releasing grab");
			FAIL;
		} else
			CHECK;
		if (ev.type != KeyRelease && first != KeyRelease) {
			report("Did not get KeyRelease event after releasing grab");
			FAIL;
		} else
			CHECK;
	}

	CHECKPASS(3);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t013(){

int 	pass = 0, fail = 0;

 	report_purpose(13);

	report_assertion("Assertion XGrabKeyboard-13.(A)");
	report_assertion("When pointer_mode is GrabModeAsync, then pointer event");
	report_assertion("processing is unaffected by activation of the grab.");

	report_strategy("Grab keyboard with pointer_mode GrabModeAsync.");
	report_strategy("Verify that pointer events are still received.");

	tpstartup();
	setargs();
	pointer_mode = GrabModeAsync;

	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (ispfrozen() == False)
		CHECK;
	else {
		report("Pointer events were affected by GrabModeAsync");
		FAIL;
	}

	CHECKPASS(1);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t014(){

int 	pass = 0, fail = 0;

 	report_purpose(14);

	report_assertion("Assertion XGrabKeyboard-14.(A)");
	report_assertion("When pointer_mode is GrabModeSync, then state of the");
	report_assertion("pointer as seen by client applications appears to freeze and");
	report_assertion("no further pointer events are generated until the grabbing");
	report_assertion("client issues a releasing XAllowEvents call or until the");
	report_assertion("keyboard grab is released.");

	report_strategy("Call XGrabKeyboard with pointer_mode GrabModeSync.");
	report_strategy("Verify that pointer events are frozen.");

	tpstartup();
	setargs();
	pointer_mode = GrabModeSync;

	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (ispfrozen() == True)
		CHECK;
	else {
		report("Pointer events were not frozen by GrabModeSync");
		FAIL;
	}

	CHECKPASS(1);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t015(){

XEvent	ev;
int 	pass = 0, fail = 0;

 	report_purpose(15);

	report_assertion("Assertion XGrabKeyboard-15.(A)");
	report_assertion("When the pointer is frozen, then the actual pointer changes");
	report_assertion("are not lost and are processed after the grab is released or");
	report_assertion("the client calls XAllowEvents.");

	report_strategy("Call XGrabKeyboard with pointer_mode GrabModeSync.");
	report_strategy("Warp pointer to create some pointer events.");
	report_strategy("Check that they are not received yet.");
	report_strategy("Release grab.");
	report_strategy("Verify that events are now received.");

	tpstartup();
	setargs();
	warppointer(display, grab_window, 0, 0);
	XSelectInput(display, grab_window, PointerMotionMask);

	pointer_mode = GrabModeSync;
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	warppointer(display, grab_window, 1, 1);
	XSync(display, False);	/* warppointer has effectivly done this */
	if (!XCheckWindowEvent(display, grab_window, PointerMotionMask, &ev))
		CHECK;
	else {
		report("Events were received while pointer was frozen");
		FAIL;
	}

	XUngrabKeyboard(display, CurrentTime);
	XSync(display, False);

	if (XCheckWindowEvent(display, grab_window, PointerMotionMask, &ev))
		CHECK;
	else {
		report("Events were not saved while pointer was frozen");
		FAIL;
	}

	CHECKPASS(2);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t016(){

int 	pass = 0, fail = 0;

 	report_purpose(16);

	report_assertion("Assertion XGrabKeyboard-16.(A)");
	report_assertion("When the event window for an active grab becomes not");
	report_assertion("viewable, then the grab is released automatically.");

	report_strategy("Call XGrabKeyboard with pointer_mode GrabModeSync to freeze pointer.");
	report_strategy("Unmap the grab_window.");
	report_strategy("Verify that pointer is unfrozen, and that therefore the grab has");
	report_strategy("been released.");

	tpstartup();
	setargs();
	pointer_mode = GrabModeSync;
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	XUnmapWindow(display, grab_window);
	if (isdeleted())
		return;

	if (ispfrozen()) {
		report("Grab was not released when grab_window was unmapped");
		FAIL;
	} else
		CHECK;

	CHECKPASS(1);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t017(){

int 	pass = 0, fail = 0;

 	report_purpose(17);

	report_assertion("Assertion XGrabKeyboard-17.(A)");
	report_assertion("A successful call to XGrabKeyboard sets the");
	report_assertion("last-keyboard-grab time to the specified time, with");
	report_assertion("CurrentTime being replaced by the current X server time.");

	report_strategy("Get a server time.");
	report_strategy("Use this time in the XGrabKeyboard call with a pointer_mode of GrabModeSync.");
	report_strategy("Check that pointer is frozen.");
	report_strategy("Call XUngrabKeyboard with time-1.");
	report_strategy("Verify that pointer is still frozen.");
	report_strategy("Call XUngrabKeyboard with time.");
	report_strategy("Verify that pointer is released.");

	tpstartup();
	setargs();
	thetime = gettime(display);
	pointer_mode = GrabModeSync;
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (ispfrozen())
		CHECK;
	else {
		delete("Could not freeze pointer");
		return;
	}

	XUngrabKeyboard(display, thetime-1);
	if (ispfrozen())
		CHECK;
	else {
		report("Last-keyboard-grab time not set correctly");
		FAIL;
	}
	XUngrabKeyboard(display, thetime);
	if (ispfrozen()) {
		report("Last-keyboard-grab time not set correctly");
		FAIL;
	} else
		CHECK;

	CHECKPASS(3);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t018(){

int 	ret;
Display	*client2;
int 	pass = 0, fail = 0;

 	report_purpose(18);

	report_assertion("Assertion XGrabKeyboard-18.(A)");
	report_assertion("When the keyboard is actively grabbed by some other client,");
	report_assertion("then a call to XGrabKeyboard fails and returns");
	report_assertion("AlreadyGrabbed.");

	report_strategy("Create client2.");
	report_strategy("Call XGrabKeyboard with default client.");
	report_strategy("Attempt to call XGrabKeyboard with client2.");
	report_strategy("Verify that XGrabKeyboard fails with AlreadyGrabbed.");

	tpstartup();
	setargs();
	client2 = opendisplay();

	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	display = client2;
	startcall(display);
	if (isdeleted())
		return;
	ret = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (ret == AlreadyGrabbed)
		CHECK;
	else {
		report("Return value was %s, expecting AlreadyGrabbed",
			grabreplyname(ret));
		FAIL;
	}

	CHECKPASS(1);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t019(){

int 	ret;
int 	pass = 0, fail = 0;

 	report_purpose(19);

	report_assertion("Assertion XGrabKeyboard-19.(A)");
	report_assertion("When the grab_window is not viewable, then a call to");
	report_assertion("XGrabKeyboard fails and returns GrabNotViewable.");

	report_strategy("Unmap grab_window.");
	report_strategy("Call XGrabKeyboard.");
	report_strategy("Verify that XGrabKeyboard fails with GrabNotViewable.");

	tpstartup();
	setargs();
	XUnmapWindow(display, grab_window);

	startcall(display);
	if (isdeleted())
		return;
	ret = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	if (ret == GrabNotViewable)
		CHECK;
	else {
		report("Return value was %s, expecting GrabNotViewable",
			grabreplyname(ret));
		FAIL;
	}

	CHECKPASS(1);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t020(){

int 	ret;
Display	*client2;
int 	pass = 0, fail = 0;

 	report_purpose(20);

	report_assertion("Assertion XGrabKeyboard-20.(A)");
	report_assertion("When the keyboard is frozen by an active grab of another");
	report_assertion("client, then a call to XGrabKeyboard fails and returns");
	report_assertion("GrabFrozen.");

	report_strategy("Grab and freeze keyboard with default client using XGrabPointer.");
	report_strategy("Create client2.");
	report_strategy("Call XGrabKeyboard with client2.");
	report_strategy("Verify that XGrabKeyboard returns GrabFrozen.");

	tpstartup();
	setargs();
	client2 = opendisplay();

	display = Dsp;
	XGrabPointer(Dsp, grab_window, False, 0, GrabModeAsync, GrabModeSync,
		None, None, CurrentTime);
	if (isdeleted())
		return;

	display = client2;
	startcall(display);
	if (isdeleted())
		return;
	ret = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	if (ret == GrabFrozen)
		CHECK;
	else {
		report("Return value was %s, expecting GrabFrozen",
			grabreplyname(ret));
		FAIL;
	}

	CHECKPASS(1);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t021(){

int 	ret;
int 	pass = 0, fail = 0;

 	report_purpose(21);

	report_assertion("Assertion XGrabKeyboard-21.(A)");
	report_assertion("When the specified time is earlier than the");
	report_assertion("last-keyboard-grab time or later than the current X server");
	report_assertion("time, then a call to XGrabKeyboard fails and returns");
	report_assertion("GrabInvalidTime.");

	report_strategy("Get current time.");
	report_strategy("Grab keyboard using this time to set last-keyboard-grab time.");
	report_strategy("Attempt to grab keyboard with an earlier time.");
	report_strategy("Verify that XGrabKeyboard returns GrabInvalidTime.");
	report_strategy("");
	report_strategy("Attempt to grab keyboard with a future time.");
	report_strategy("Verify that XGrabKeyboard returns GrabInvalidTime.");

	tpstartup();
	setargs();
	thetime = gettime(display);

	/* Set the last-keyboard-grab time */
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	XUngrabKeyboard(display, thetime);

	thetime -= 43;
	startcall(display);
	if (isdeleted())
		return;
	ret = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	if (ret == GrabInvalidTime)
		CHECK;
	else {
		report("Trying time earlier than last-keyboard-grab time");
		report("Return value was %s, expecting GrabInvalidTime",
			grabreplyname(ret));
		FAIL;
	}
	XUngrabKeyboard(display, thetime);

	thetime = gettime(display);
	thetime += ((config.speedfactor+1) * 1000000);
	startcall(display);
	if (isdeleted())
		return;
	ret = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	if (ret == GrabInvalidTime)
		CHECK;
	else {
		report("Trying time later than current X server time");
		report("Return value was %s, expecting GrabInvalidTime",
			grabreplyname(ret));
		FAIL;
	}

	CHECKPASS(2);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

/* Including from file Mval.tmc.508 */
/* End of included file Mval.tmc.508 */

/* Including from file error/EVal.mc */
static void t022(){

#undef	VALUE_ARG
#define	VALUE_ARG owner_events
#undef	VALUE_LIST
#define	VALUE_LIST owner_eventsvallist
#undef NOTMEMTYPE
#define NOTMEMTYPE 
#undef	NOTMEMBER
#define	NOTMEMBER notmember
int 	i;
int 	n;
NOTMEMTYPE
long	vals[NM_LEN];
int 	pass = 0, fail = 0;

 	report_purpose(22);

	report_assertion("Assertion XGrabKeyboard-22.(A)");
	report_assertion("When the value of owner_events is other than True or False,");
	report_assertion("then a BadValue error occurs.");

	report_strategy("Obtain a sequence of values which are not in the list specified by VALUE_LIST.");
	report_strategy("For each value:");
	report_strategy("  Call test function with this value in the VALUE_ARG argument.");
	report_strategy("  Verify that a BadValue error occurs.");

	tpstartup();
	setargs();
	seterrdef();

	n = NOTMEMBER(VALUE_LIST, NELEM(VALUE_LIST), vals);

	for (i = 0; i < n; i++) {

		debug(1, "Trying arg of %d", vals[i]);

		VALUE_ARG = vals[i];
		startcall(display);
		if (isdeleted())
			return;
		ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
		endcall(display);
		if (ValueReturn != GrabSuccess) {
			report("Returned value was %d, expecting GrabSuccess", ValueReturn);
			FAIL;
		}
		if (geterr() != BadValue) {
			report("Got %s, Expecting BadValue", errorname(geterr()));
			FAIL;
		}

		if (geterr() == BadValue)
			CHECK;
		else {
			trace("Value of %d did not give BadValue", vals[i]);
			FAIL;
		}
	}

	CHECKPASS(n);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

/* End of included file error/EVal.mc */

/* Including from file Mval.tmc.508 */
/* End of included file Mval.tmc.508 */

/* Including from file error/EVal.mc */
static void t023(){

#undef	VALUE_ARG
#define	VALUE_ARG pointer_mode
#undef	VALUE_LIST
#define	VALUE_LIST pointer_modevallist
#undef NOTMEMTYPE
#define NOTMEMTYPE 
#undef	NOTMEMBER
#define	NOTMEMBER notmember
int 	i;
int 	n;
NOTMEMTYPE
long	vals[NM_LEN];
int 	pass = 0, fail = 0;

 	report_purpose(23);

	report_assertion("Assertion XGrabKeyboard-23.(A)");
	report_assertion("When the value of pointer_mode is other than GrabModeSync");
	report_assertion("or GrabModeAsync, then a BadValue error occurs.");

	report_strategy("Obtain a sequence of values which are not in the list specified by VALUE_LIST.");
	report_strategy("For each value:");
	report_strategy("  Call test function with this value in the VALUE_ARG argument.");
	report_strategy("  Verify that a BadValue error occurs.");

	tpstartup();
	setargs();
	seterrdef();

	n = NOTMEMBER(VALUE_LIST, NELEM(VALUE_LIST), vals);

	for (i = 0; i < n; i++) {

		debug(1, "Trying arg of %d", vals[i]);

		VALUE_ARG = vals[i];
		startcall(display);
		if (isdeleted())
			return;
		ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
		endcall(display);
		if (ValueReturn != GrabSuccess) {
			report("Returned value was %d, expecting GrabSuccess", ValueReturn);
			FAIL;
		}
		if (geterr() != BadValue) {
			report("Got %s, Expecting BadValue", errorname(geterr()));
			FAIL;
		}

		if (geterr() == BadValue)
			CHECK;
		else {
			trace("Value of %d did not give BadValue", vals[i]);
			FAIL;
		}
	}

	CHECKPASS(n);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

/* End of included file error/EVal.mc */

/* Including from file Mval.tmc.508 */
/* End of included file Mval.tmc.508 */

/* Including from file error/EVal.mc */
static void t024(){

#undef	VALUE_ARG
#define	VALUE_ARG keyboard_mode
#undef	VALUE_LIST
#define	VALUE_LIST keyboard_modevallist
#undef NOTMEMTYPE
#define NOTMEMTYPE 
#undef	NOTMEMBER
#define	NOTMEMBER notmember
int 	i;
int 	n;
NOTMEMTYPE
long	vals[NM_LEN];
int 	pass = 0, fail = 0;

 	report_purpose(24);

	report_assertion("Assertion XGrabKeyboard-24.(A)");
	report_assertion("When the value of keyboard_mode is other than GrabModeSync");
	report_assertion("or GrabModeAsync, then a BadValue error occurs.");

	report_strategy("Obtain a sequence of values which are not in the list specified by VALUE_LIST.");
	report_strategy("For each value:");
	report_strategy("  Call test function with this value in the VALUE_ARG argument.");
	report_strategy("  Verify that a BadValue error occurs.");

	tpstartup();
	setargs();
	seterrdef();

	n = NOTMEMBER(VALUE_LIST, NELEM(VALUE_LIST), vals);

	for (i = 0; i < n; i++) {

		debug(1, "Trying arg of %d", vals[i]);

		VALUE_ARG = vals[i];
		startcall(display);
		if (isdeleted())
			return;
		ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
		endcall(display);
		if (ValueReturn != GrabSuccess) {
			report("Returned value was %d, expecting GrabSuccess", ValueReturn);
			FAIL;
		}
		if (geterr() != BadValue) {
			report("Got %s, Expecting BadValue", errorname(geterr()));
			FAIL;
		}

		if (geterr() == BadValue)
			CHECK;
		else {
			trace("Value of %d did not give BadValue", vals[i]);
			FAIL;
		}
	}

	CHECKPASS(n);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

/* End of included file error/EVal.mc */

/* Including from file error/EWin.mc */
/* End of included file error/EWin.mc */

/* Including from file error/EWin.mc */
static void t025(){

int 	pass = 0, fail = 0;

 	report_purpose(25);

	report_assertion("Assertion XGrabKeyboard-25.(A)");
	report_assertion("When a window argument does not name a valid Window, then a");
	report_assertion("BadWindow error occurs.");

	report_strategy("Create a bad window by creating and destroying a window.");
	report_strategy("Call test function using bad window as the window argument.");
	report_strategy("Verify that a BadWindow error occurs.");

	tpstartup();
	setargs();
	seterrdef();

	A_WINDOW = badwin(A_DISPLAY);

	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGrabKeyboard(display, grab_window, owner_events, pointer_mode, keyboard_mode, thetime);
	endcall(display);
	if (ValueReturn != GrabSuccess) {
		report("Returned value was %d, expecting GrabSuccess", ValueReturn);
		FAIL;
	}
	if (geterr() != BadWindow) {
		report("Got %s, Expecting BadWindow", errorname(geterr()));
		FAIL;
	}

	if (geterr() == BadWindow)
		PASS;
	else
		FAIL;

	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

/* End of included file error/EWin.mc */

/* 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 },
	{ t022, 22 },
	{ t023, 23 },
	{ t024, 24 },
	{ t025, 25 },
	{ NULL, 0 }
};

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

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