/*
* 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.
* 
* 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:
 *   void
 *   XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor)
 *   Display	*display;
 *   unsigned int	button;
 *   unsigned int	modifiers;
 *   Window	grab_window;
 *   Bool	owner_events;
 *   unsigned int	event_mask;
 *   int 	pointer_mode;
 *   int 	keyboard_mode;
 *   Window	confine_to;
 *   Cursor	cursor;
 */


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

/*
 * Defines for different argument types
 */
#define A_DISPLAY display
#define A_WINDOW grab_window
#define A_DRAWABLE grab_window
#define A_WINDOW2 confine_to
#define A_DRAWABLE2 confine_to
#define A_CURSOR cursor


/*
 * Arguments to the XGrabButton function
 */
static Display	*display;
static unsigned int	button;
static unsigned int	modifiers;
static Window	grab_window;
static Bool	owner_events;
static unsigned int	event_mask;
static int 	pointer_mode;
static int 	keyboard_mode;
static Window	confine_to;
static Cursor	cursor;



/*
 * Returns True if the pointer is grabbed.  This is not a general purpose
 * routine since it knows about the Grab Button args.
 * When the pointer is grabbed then pointer events are not reported to
 * non grabbing clients.
 */
static
pgrabbed()
{
Window	win;
Display	*client2;
XEvent	ev;

	if (confine_to != None)
		win = confine_to;
	else
		win = grab_window;

	client2 = opendisplay();
	
	XSelectInput(client2, win, PointerMotionMask|EnterWindowMask);
	/* Flush events for client2 */
	XSync(client2, True);

	/*
	 * Ensure that pointer either enters or moves within win.
	 */
	warppointer(display, win, 1, 1);
	warppointer(display, win, 1, 2);

	XSync(client2, False);
	if (getevent(client2, &ev)) {
		/*
		 * An event was reported - pointer isn't grabbed, do a sanity
		 * check on the type of event.
		 */
		if (ev.type != MotionNotify && ev.type != EnterNotify) {
			delete("Unexpected event received in pgrabbed()");
			delete("  event type %s", eventname(ev.type));
		}
		return(False);
	} else {
		return(True);
	}
}

/*
 * Get the window that the pointer is currently in, if the pointer
 * is in a child of the given window. Otherwise it returns None.
 */
static Window
getpointerwin(disp, win)
Display	*disp;
Window	win;
{
Window	child;
Window	wtmp;
int 	itmp;
unsigned uitmp;
Bool 	s;

	s = XQueryPointer(disp, win, &wtmp, &child, &itmp, &itmp
		, &itmp, &itmp , &uitmp);

	if (!s)
		delete("Could not get pointer window");

	return(child);
}

#define	ACTPOSX	3
#define	ACTPOSY	6
/*
 * Warp to the grab_window and press the keys in modifiers and then press
 * the button in the 'button' arg.
 * (This activates the previously set up grab if the arg variables
 * have not been changed.)
 */
static
activate()
{
	warppointer(display, grab_window, ACTPOSX, ACTPOSY);
	if (modifiers)
		modpress(display, modifiers);
	buttonpress(display, button);
}

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

	if (confine_to != None) {
		report("ERROR");
		delete("pfrozen should not be used with a confine_to win");
		return False;
	}

	XSync(display, True);	/* Flush events */

	win = defwin(display);
	XSelectInput(display, win, PointerMotionMask);
	warppointer(display, win, 1, 1);
	warppointer(display, win, 2, 2);
	if (XCheckMaskEvent(display, (long)PointerMotionMask, &ev))
		return False;
	else
		return True;
}

/*
 * Returns True if the keyboard is frozen.
 */
static
kfrozen()
{
XEvent	ev;
Window	win;
int 	minkc, maxkc;
int 	res;

	XSync(display, True); /* Flush previous events */
	XDisplayKeycodes(display, &minkc, &maxkc);
	if (minkc < 8)
		minkc = 8;	/* For buggy servers */

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

	keyrel(display, minkc);
	return(res);
}


static char	*WindowTree[]= {
	".",
		"child1 . (10,10) 30x30",
		"child2 . (50,50) 30x30",
			"grandchild child2 (2,2) 20x20",
};

static int NWindowTree = NELEM(WindowTree);



/* Value list for use in test t033 */
static unsigned long	event_maskvallist[] = {
	ButtonPressMask,
	ButtonReleaseMask,
	EnterWindowMask,
	LeaveWindowMask,
	PointerMotionMask,
	PointerMotionHintMask,
	Button1MotionMask,
	Button2MotionMask,
	Button3MotionMask,
	Button4MotionMask,
	Button5MotionMask,
	ButtonMotionMask,
	KeymapStateMask,
};



/* Value list for use in test t034 */
static unsigned long	modifiersvallist[] = {
	ShiftMask,
	LockMask,
	ControlMask,
	Mod1Mask,
	Mod2Mask,
	Mod3Mask,
	Mod4Mask,
	Mod5Mask,
	AnyModifier,
};



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



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



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


int 	tet_thistest;

/*
 * Called at the beginning of each test purpose to reset the
 * arguments to their initial values
 */
static void
setargs()
{
	display = Dsp;
	button = Button1;
	modifiers = 0;
	grab_window = defwin(Dsp);
	owner_events = False;
	event_mask = PointerMotionMask;
	pointer_mode = GrabModeAsync;
	keyboard_mode = GrabModeAsync;
	confine_to = None;
	cursor = None;
}

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

static void t001(){

unsigned int 	mask;
int 	onemod;
int 	pass = 0, fail = 0;

 	report_purpose(1);

	report_assertion("Assertion XGrabButton-1.(B)");
	report_assertion("A call to XGrabButton establishes a passive grab that is");
	report_assertion("activated in the future by the specified button being");
	report_assertion("logically pressed, the modifier keys given by modifiers");
	report_assertion("being logically down, no other buttons or modifier keys");
	report_assertion("being logically down and the pointer being contained in the");
	report_assertion("grab_window.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("Call XGrabButton as touch test.");
	report_strategy("If extensions available:");
	report_strategy("  Warp pointer into grab window.");
	report_strategy("  Simulate a button press of button.");
	report_strategy("  Verify that pointer is now grabbed.");
	report_strategy("  Release grab.");
	report_strategy("");
	report_strategy("  Set up a grab with XGrabButton for a button.");
	report_strategy("  Warp pointer into grab window.");
	report_strategy("  Simulate press of another button.");
	report_strategy("  Simulate the button press.");
	report_strategy("  Verify that the pointer is not grabbed.");
	report_strategy("  Release grab.");
	report_strategy("");
	report_strategy("  Set up a grab with XGrabButton for a button and modifier keys.");
	report_strategy("  Warp pointer to grab window.");
	report_strategy("  Simulate modifier key presses.");
	report_strategy("  Simulate the button press.");
	report_strategy("  Verify that the pointer is grabbed.");
	report_strategy("  Release grab.");
	report_strategy("");
	report_strategy("  Set up a grab with XGrabButton for a button and modifier keys.");
	report_strategy("  Warp pointer to grab window.");
	report_strategy("  Simulate modifier key presses.");
	report_strategy("  Simulate extra modifier key presses.");
	report_strategy("  Simulate the button press.");
	report_strategy("  Verify that the pointer is not grabbed.");
	report_strategy("  Release grab.");

	tpstartup();
	setargs();
	if (pgrabbed()) { /* Sanity check */
		delete("Pointer seemed to be grabbed before doing test");
		return;
	}

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (noext(1)) {
		untested("There is no reliable test method, but a touch test was performed");
		return;
	}

	/*
	 * --- Simple case no modifiers.
	 */
	activate();

	if (pgrabbed()) {
		CHECK;
	} else {
		report("Pointer was not grabbed after button press");
		FAIL;
	}
	relalldev();

	/*
	 * --- Press another button first and then press the grabbed button.
	 * The pointer should not be grabbed.
	 */
	if (nbuttons() > 1) {
		button = Button1;
		startcall(display);
		if (isdeleted())
			return;
		XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
		endcall(display);
		if (geterr() != Success) {
			report("Got %s, Expecting Success", errorname(geterr()));
			FAIL;
		}

		warppointer(display, grab_window, 2, 2);
		buttonpress(display, button+1);
		buttonpress(display, button);
		if (pgrabbed()) {
			report("Pointer was grabbed although another button was pressed");
			FAIL;
		} else
			CHECK;
		relalldev();
	} else {
		trace("Only one button supported");
		CHECK;
	}

	/*
	 * --- Set up a grab with modifiers.
	 */
	modifiers = wantmods(display, 2);
	grab_window = defwin(display);
	trace("Grabbing %s with mods %s", buttonname((int)button),
		keymaskname((unsigned long)modifiers));
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();
	if (pgrabbed()) {
		CHECK;
	} else {
		report("Pointer was not grabbed for %s and %s", buttonname((int)button),
			keymaskname((unsigned long)modifiers));
		FAIL;
	}
	relalldev();

	/*
	 * --- Set up a grab with modifiers, try to activate the grab with
	 * too many modifiers held down.  Grab should not become active.
	 */
	mask = wantmods(display, 2);
	for (onemod = 1; onemod; onemod <<= 1) {
		if (mask & onemod)
			break;
	}
	/* Only assumes one modifier */
	modifiers = mask & ~onemod;
	grab_window = defwin(display);
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	warppointer(display, grab_window, 2, 2);
	/* Pressing an extra modifier */
	modpress(display, mask);
	buttonpress(display, button);

	if (mask && pgrabbed()) {
		report("Pointer was grabbed when there were extra modifier keys down");
		FAIL;
	} else {
		/*
		 * If mask was zero this means that there are no modifiers KeyCodes
		 * available.  This is unlikely and really means that we cannot test
		 * this part of the assertion.  However in this case this part of
		 * the assertion has no meaning so say it passes.
		 */
		CHECK;
	}
	
	CHECKPASS(4);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t002(){

Window	win1, win2;
Window	win;
int 	pass = 0, fail = 0;

 	report_purpose(2);

	report_assertion("Assertion XGrabButton-2.(B)");
	report_assertion("When the conditions for activating the grab are otherwise");
	report_assertion("satisfied and the pointer is already grabbed, then no active");
	report_assertion("grab is established.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Create two windows that do not overlap.");
	report_strategy("  Call XGrabButton with one of the windows as the confine_to.");
	report_strategy("  Activate grab with a button press.");
	report_strategy("  Check that pointer is within that window.");
	report_strategy("  Call XGrabButton with confine_to as the other window.");
	report_strategy("  Press button in grab_window.");
	report_strategy("  Verify that pointer has not been warped to second confine_to window.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	win1 = defwin(display);
	win2 = defwin(display);

	confine_to = win1;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	if (getpointerwin(display, DRW(display)) == confine_to)
		CHECK;
	else {
		delete("Could not set up first grab");
		return;
	}

	confine_to = win2;
	if (nbuttons() > 1)
		button = Button2;
	grab_window = defwin(display);
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	win = getpointerwin(display, DRW(display));
	if (win == win1)
		CHECK;
	else if (win == win2) {
		report("A second grab became active while another was active");
		FAIL;
	} else {
		/* Our test went unexpectedly wrong */
		delete("Pointer in unexpected window");
	}

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

static void t003(){

int 	pass = 0, fail = 0;

 	report_purpose(3);

	report_assertion("Assertion XGrabButton-3.(B)");
	report_assertion("When the conditions for activating the grab are otherwise");
	report_assertion("satisfied and the confine_to window is not viewable, then no");
	report_assertion("active grab is established.");
	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 confine_to window.");
	report_strategy("  Unmap the confine to window.");
	report_strategy("  Set up a passive grab.");
	report_strategy("  Move pointer to grab window.");
	report_strategy("  Attempt to activate grab by simulating a button press.");
	report_strategy("  Verify that grab is not activated.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	confine_to = defwin(display);
	XUnmapWindow(display, confine_to);

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	/*
	 * Since confine_to is not viewable then the pointer should still
	 * be in grab_window.
	 */
	if (getpointerwin(display, DRW(display)) != grab_window) {
		report("Pointer was warped out of the grab_window");
		FAIL;
	}

	confine_to = None;	/* Unmapped so no use for pgrabbed() */
	if (!pgrabbed())
		CHECK;
	else {
		report("Pointer was grabbed when confine_to was not viewable");
		FAIL;
	}

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

static void t004(){

struct	area	area;
Window	parent;
XEvent	ev;
int 	pass = 0, fail = 0;

 	report_purpose(4);

	report_assertion("Assertion XGrabButton-4.(B)");
	report_assertion("When the conditions for activating the grab are otherwise");
	report_assertion("satisfied and a passive grab on the same button/key");
	report_assertion("combination exists for an ancestor of grab_window, then no");
	report_assertion("active grab is established.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Call XGrabButton to place a passive grab.");
	report_strategy("  Create a child of the grab_window.");
	report_strategy("  Place a passive grab for the same key/button combination on the child.");
	report_strategy("  Move pointer into the child.");
	report_strategy("  Attempt to activate grab by simulating button press.");
	report_strategy("  Verify that pointer is not grabbed by the child window.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	modifiers = wantmods(display, 2);
	event_mask = PointerMotionMask;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	parent = grab_window;
	setarea(&area, 10, 10, 20, 24);
	grab_window = crechild(display, grab_window, &area);

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	/*
	 * Provoke an event by moving the pointer on the child window,  since
	 * this child grab should not have become active then no events should
	 * be received on the child.
	 * However the assertion does not apply to the parent, so the grab will
	 * have become active on the parent -- therefore we expect the events
	 * to show up on the parent.
	 */
	warppointer(display, grab_window, 1, 1);
	warppointer(display, grab_window, 8, 8);

	/*
	 * Since no events are selected on the windows, any event must
	 * be the result of a grab.
	 */
	if (XCheckWindowEvent(display, grab_window, (long)event_mask, &ev)) {
		report("Grab was activated on a window which had an ancestor with the same grab");
		FAIL;
	} else
		CHECK;

	if (XCheckWindowEvent(display, parent, (long)event_mask, &ev))
		CHECK;
	else {
		report("Grab was not activated on the parent");
		FAIL;
	}

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

static void t005(){

XEvent	ev;
XButtonPressedEvent	good;
XWindowAttributes	atts;
int 	n;
int 	pass = 0, fail = 0;

 	report_purpose(5);

	report_assertion("Assertion XGrabButton-5.(B)");
	report_assertion("When the conditions for activating the grab are satisfied,");
	report_assertion("then the last-pointer-grab time is set to the time at which");
	report_assertion("the button was pressed and a ButtonPress event is generated.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Call XGrabButton to place passive grab.");
	report_strategy("  Enable events on grab window.");
	report_strategy("  Move pointer into grab window.");
	report_strategy("  Activate grab with simulated device events.");
	report_strategy("  Verify that a ButtonPress event is generated.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	XSelectInput(display, grab_window, ALLEVENTS);

	warppointer(display, grab_window, ACTPOSX, ACTPOSY);
	XSync(display, True);	/* Discard any events */
	buttonpress(display, button);

	XGetWindowAttributes(display, grab_window, &atts);
	n = getevent(display, &ev);
	if (n)
		CHECK;
	else {
		report("No events received");
		FAIL;
		return;
	}

	defsetevent(good, display, ButtonPress);
	good.window = grab_window;
	good.root = DRW(display);
	good.subwindow = None;
	good.time = ((XButtonPressedEvent*)&ev)->time;
	good.x = ACTPOSX;
	good.y = ACTPOSY;
	good.x_root = good.x + atts.x + atts.border_width;
	good.y_root = good.y + atts.y + atts.border_width;
	good.state = modifiers;
	good.button = button;
	good.same_screen = True;

	if (checkevent((XEvent*)&good, &ev) == 0)
		CHECK;
	else
		FAIL;

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

static void t006(){

unsigned int 	mods;
int 	pass = 0, fail = 0;

 	report_purpose(6);

	report_assertion("Assertion XGrabButton-6.(B)");
	report_assertion("When the grab subsequently becomes active and later the");
	report_assertion("logical state of the pointer has all buttons released, then");
	report_assertion("the active grab is terminated automatically.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Place passive grab with XGrabButton.");
	report_strategy("  Activate grab with simulated device events.");
	report_strategy("  Simulate pressing some modifier keys.");
	report_strategy("  Release the button.");
	report_strategy("  Verify that the grab has been released.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	mods = wantmods(display, 3);
	modpress(display, mods);

	buttonrel(display, button);

	if (pgrabbed()) {
		report("Grab was not released, when button was released and modifier");
		report("  keys were down");
		FAIL;
	} else
		PASS;

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

static void t007(){

int 	pass = 0, fail = 0;

 	report_purpose(7);

	report_assertion("Assertion XGrabButton-7.(B)");
	report_assertion("A call to XGrabButton overrides all previous passive grabs");
	report_assertion("by the same client on the same button/key combinations on");
	report_assertion("the same window.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Place a passive grab with no confine_to window.");
	report_strategy("  Place a passive grab as before but with a confine_to window.");
	report_strategy("  Move pointer to grab_window and activate grab.");
	report_strategy("  Verify that pointer is warped to the confine_to window and thus the second");
	report_strategy("  grab overrode the first.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	/* Try to override first grab */
	confine_to = defwin(display);
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	if (getpointerwin(display, DRW(display)) == confine_to)
		PASS;
	else {
		report("A second passive grab did not override the first");
		FAIL;
	}

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

static void t008(){

unsigned int 	mods;
int 	pass = 0, fail = 0;

 	report_purpose(8);

	report_assertion("Assertion XGrabButton-8.(B)");
	report_assertion("A modifiers argument of AnyModifier is equivalent to");
	report_assertion("issuing the grab request for all possible modifier");
	report_assertion("combinations including no modifiers.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Place passive grab with a modifiers of AnyModifier.");
	report_strategy("  Press a bunch of modifier keys.");
	report_strategy("  Press button to activate grab.");
	report_strategy("  Verify that grab is activated.");
	report_strategy("  Release button and keys.");
	report_strategy("");
	report_strategy("  Press button (no modifiers).");
	report_strategy("  Verify that grab is active.");
	report_strategy("else");
	report_strategy("  Perform touch test.");
	report_strategy("  Report untested.");

	tpstartup();
	setargs();
	modifiers = AnyModifier;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (noext(1)) {
		untested("There is no reliable test method, but a touch test was performed");
		return;
	}

	mods = wantmods(display, 4);
	modpress(display, mods);

	/*
	 * modifiers was AnyModifier, several modifier keys are held down.
	 */
	activate();
	if (pgrabbed())
		CHECK;
	else {
		report("Grab not activated for AnyModifier");
		report("  Modifiers used %s", keymaskname((unsigned long)mods));
		FAIL;
	}

	/* Release all buttons and modifiers */
	relalldev();

	if (pgrabbed()) {
		delete("Could not release grab for second part of test");
		return;
	} else
		CHECK;

	buttonpress(display, button);
	if (pgrabbed())
		CHECK;
	else {
		report("Grab with AnyModifier was not activated by a button press with");
		report("  no modifiers");
		FAIL;
	}

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

static void t009(){

XModifierKeymap	*mmap;
XModifierKeymap	*newmap;
int 	i;
int 	pass = 0, fail = 0;

 	report_purpose(9);

	report_assertion("Assertion XGrabButton-9.(B)");
	report_assertion("It is not required that all modifiers specified have");
	report_assertion("currently assigned KeyCodes.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Get a modifier mask.");
	report_strategy("  Remove the keycode for the modifier from the map.");
	report_strategy("  Call XGrabButton to set up a passive grab with that modifier.");
	report_strategy("  Reset the keycode in the modifier map.");
	report_strategy("  Verify that the grab can be activated with the newly set modifier.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	modifiers = wantmods(display, 1);
	if (modifiers == 0) {
		untested("No available modifier keys");
		return;
	} else
		CHECK;

	mmap = XGetModifierMapping(display);
	if (mmap == NULL) {
		delete("Could not get modifier map");
		return;
	} else
		CHECK;

	/*
	 * Remove all the modifiers mappings.
	 */
	newmap = XNewModifiermap(mmap->max_keypermod);
	for (i = 0; i < newmap->max_keypermod*8; i++)
		newmap->modifiermap[i] = NoSymbol;

	if (XSetModifierMapping(display, newmap) == MappingSuccess)
		CHECK;
	else {
		delete("Could not remove modifier mapping");
		return;
	}

	/*
	 * Now we have a modifier that has no keycode - set up a passive grab.
	 */
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	/*
	 * Reset the modifier map, and try to activate the grab.
	 */
	if (XSetModifierMapping(display, mmap) == MappingSuccess)
		CHECK;
	else {
		delete("Could not reset modifier mapping");
		return;
	}

	activate();

	if (pgrabbed())
		CHECK;
	else {
		report("Passive grab not set when the modifier did not have a current keycode");
		FAIL;
	}
	CHECKPASS(5);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t010(){

extern	struct	valname	S_button[];
extern	int	NS_button;
int 	i;
int 	pass = 0, fail = 0;

 	report_purpose(10);

	report_assertion("Assertion XGrabButton-10.(B)");
	report_assertion("A button argument of AnyButton is equivalent to issuing the");
	report_assertion("grab request for all possible buttons.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Set up a passive grab using AnyButton.");
	report_strategy("  Move pointer to grab window.");
	report_strategy("  Simulate a button press.");
	report_strategy("  Verify that pointer is grabbed.");
	report_strategy("  Repeat for other buttons.");
	report_strategy("else");
	report_strategy("  Touch test using AnyButton.");
	report_strategy("  Report untested.");

	tpstartup();
	setargs();
	button = AnyButton;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (noext(1)) {
		untested("There is no reliable test method, but a touch test was performed");
		return;
	} else
		CHECK;

	warppointer(display, grab_window, 10, 10);

	for (i = 0; i < NS_button; i++) {
		buttonpress(display, (unsigned int)S_button[i].val);
		if (pgrabbed())
			CHECK;
		else {
			report("Passive grab of AnyButton, not grabbed for %s",
				S_button[i].name);
			FAIL;
		}

		/*
		 * Release this grab and try next button.
		 */
		relbuttons();
		if (pgrabbed()) {
			delete("Could not release grab for next part of test");
			return;
		} else
			CHECK;
	}

	CHECKPASS(1+2*NS_button);
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

static void t011(){

unsigned char	pmap[100];
int 	savebutton;
int 	n;
int 	pass = 0, fail = 0;

 	report_purpose(11);

	report_assertion("Assertion XGrabButton-11.(B)");
	report_assertion("It is not required that the specified button currently be");
	report_assertion("assigned to a physical button.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Remove a button from the button map.");
	report_strategy("  Set a passive grab with that button.");
	report_strategy("  Replace the button in the map.");
	report_strategy("  Simulate pressing button in window.");
	report_strategy("  Verify that grab is activated.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	n = XGetPointerMapping(display, pmap, (int)sizeof(pmap));
	savebutton = pmap[0];
	pmap[0] = 0;	/* Disable button1 */
	if (XSetPointerMapping(display, pmap, n) == MappingSuccess)
		CHECK;
	else {
		delete("Could not change pointer mapping");
		return;
	}

	button = Button1;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	pmap[0] = savebutton;
	if (XSetPointerMapping(display, pmap, n) == MappingSuccess)
		CHECK;
	else {
		delete("Could not restore pointer mapping");
		return;
	}

	activate();
	if (pgrabbed())
		CHECK;
	else {
		report("Could not set grab when button was not assigned a physical button");
		FAIL;
	}

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

static void t012(){

Window	win;
XEvent	ev;
XMotionEvent	*mp;
int 	pass = 0, fail = 0;

 	report_purpose(12);

	report_assertion("Assertion XGrabButton-12.(B)");
	report_assertion("When owner_events is False and the grab is now active, then");
	report_assertion("all generated pointer events that are selected by the");
	report_assertion("event_mask 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 are available:");
	report_strategy("  Set owner_events to False.");
	report_strategy("  Set event_mask to select for PointerMotion.");
	report_strategy("  Set passive grab.");
	report_strategy("  Activate grab by simulated button press.");
	report_strategy("  Create a window.");
	report_strategy("  Select events on the window.");
	report_strategy("  Warp pointer into window.");
	report_strategy("  Verify MotionNotify reported to grab_window.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	owner_events = False;
	event_mask = PointerMotionMask;

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	/* Flush any events so far */
	XSync(display, True);

	win = defwin(display);
	XSelectInput(display, win, PointerMotionMask);
	warppointer(display, win, 1, 2);
	warppointer(display, win, 2, 3);

	if (getevent(display, &ev) == 0) {
		report("No events received");
		FAIL;
	} else
		CHECK;

	if (ev.type != MotionNotify) {
		report("Got event %s, expecting MotionNotify", eventname(ev.type));
		FAIL;
	} else
		CHECK;

	mp = (XMotionEvent*)&ev;
	if (mp->window == grab_window)
		CHECK;
	else if (mp->window == win) {
		report("Event was reported on the window the pointer was in");
		FAIL;
	} else {
		report("Event was not reported on the grab_window");
		FAIL;
	}

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

static void t013(){

Window	win;
XEvent	ev;
XMotionEvent	*mp;
int 	pass = 0, fail = 0;

 	report_purpose(13);

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

	report_strategy("If extensions are available:");
	report_strategy("  Set owner_events to True.");
	report_strategy("  Set passive grab.");
	report_strategy("  Activate grab by simulated button press.");
	report_strategy("  Create a window.");
	report_strategy("  Select events on the window.");
	report_strategy("  Warp pointer into window.");
	report_strategy("  Verify events are reported on window.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	owner_events = True;
	event_mask = PointerMotionMask;

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	/* Flush any events so far */
	XSync(display, True);

	win = defwin(display);
	XSelectInput(display, win, PointerMotionMask);
	warppointer(display, win, 1, 2);
	warppointer(display, win, 1, 6);

	if (getevent(display, &ev) == 0) {
		report("No events received");
		FAIL;
	} else
		CHECK;

	if (ev.type != MotionNotify) {
		report("Got event %s, expecting MotionNotify", eventname(ev.type));
		FAIL;
	} else
		CHECK;

	mp = (XMotionEvent*)&ev;
	if (mp->window == win)
		CHECK;
	else if (mp->window == grab_window) {
		report("Event was reported on the grab_window");
		FAIL;
	} else {
		report("Event was not reported on the normal window");
		FAIL;
	}

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

static void t014(){

Window	win;
XEvent	ev;
XMotionEvent	*mp;
int 	pass = 0, fail = 0;

 	report_purpose(14);

	report_assertion("Assertion XGrabButton-14.(B)");
	report_assertion("When owner_events is True, the grab is now active, a");
	report_assertion("pointer event is generated that would not normally be");
	report_assertion("reported to the client and it is selected by event_mask,");
	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 are available:");
	report_strategy("  Set owner_events to True.");
	report_strategy("  Set passive grab.");
	report_strategy("  Activate grab by simulated button press.");
	report_strategy("  Create a window.");
	report_strategy("  Warp pointer into window and simulate a button press/release.");
	report_strategy("  Verify events are reported to grab_window.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	owner_events = True;
	event_mask = PointerMotionMask;

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	/* Flush any events so far */
	XSync(display, True);

	win = defwin(display);
	warppointer(display, win, 1, 2);
	warppointer(display, win, 4, 12);

	if (getevent(display, &ev) == 0) {
		report("No events received");
		FAIL;
	} else
		CHECK;

	if (!fail && ev.type != MotionNotify) {
		report("Got event %s, expecting MotionNotify", eventname(ev.type));
		FAIL;
	} else
		CHECK;

	mp = (XMotionEvent*)&ev;
	if (!fail) {
		if (mp->window == grab_window)
			CHECK;
		else if (mp->window == win) {
			report("Event was reported on the window the pointer was in");
			FAIL;
		} else {
			report("Event was not reported on the grab_window");
			FAIL;
		}
	}

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

static void t015(){

int 	pass = 0, fail = 0;

 	report_purpose(15);

	report_assertion("Assertion XGrabButton-15.(B)");
	report_assertion("When pointer_mode is GrabModeAsync and the grab is now");
	report_assertion("active, then pointer event processing continues normally.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Set pointer_mode to GrabModeAsync.");
	report_strategy("  Set passive grab.");
	report_strategy("  Press button in grab_window to activate grab.");
	report_strategy("  Verify that pointer is not frozen.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	pointer_mode = GrabModeAsync;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	if (!pfrozen())
		CHECK;
	else {
		report("Pointer was frozen with GrabModeAsync");
		FAIL;
	}

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

static void t016(){

int 	pass = 0, fail = 0;

 	report_purpose(16);

	report_assertion("Assertion XGrabButton-16.(B)");
	report_assertion("When pointer_mode is GrabModeSync and the grab is now");
	report_assertion("active, then the state of the pointer, as seen by client");
	report_assertion("applications, appears to freeze, and no further pointer");
	report_assertion("events are generated until the grabbing client calls");
	report_assertion("XAllowEvents or until the grab is released.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Set pointer_mode to GrabModeSync.");
	report_strategy("  Set grab with XGrabButton and activate.");
	report_strategy("  Verify that pointer is frozen.");
	report_strategy("  Allow events with XAllowEvents().");
	report_strategy("  Verify that pointer is not frozen.");
	report_strategy("  Release the grab and restore the device state.");
	report_strategy("  Set grab with XGrabButton and activate.");
	report_strategy("  Verify that pointer is frozen.");
	report_strategy("  Release grab.");
	report_strategy("  Verify that pointer is not frozen.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	pointer_mode = GrabModeSync;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	if (pfrozen())
		CHECK;
	else {
		report("Pointer not frozen when pointer mode was GrabModeSync after first activate");
		FAIL;
	}

	XAllowEvents(display, AsyncPointer, CurrentTime);
	XSync(display,False);

	if (pfrozen()) {
		report("Pointer was still frozen after XAllowEvents()");
		FAIL;
	} else
		CHECK;

	relalldev();
	XUngrabPointer(display, CurrentTime);
	XUngrabButton(display, AnyButton, AnyModifier, grab_window);

	pointer_mode = GrabModeSync;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	if (pfrozen())
		CHECK;
	else {
		report("Pointer not frozen when pointer mode was GrabModeSync after second activate");
		FAIL;
	}

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

	if (pfrozen()) {
		report("Pointer was still frozen after grab released");
		FAIL;
	} else
		CHECK;

	XUngrabButton(display, AnyButton, AnyModifier, grab_window);

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

static void t017(){

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

 	report_purpose(17);

	report_assertion("Assertion XGrabButton-17.(B)");
	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_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Set pointer_mode to GrabModeSync.");
	report_strategy("  Set grab with XGrabButton and activate.");
	report_strategy("  Check that no pointer events are generated.");
	report_strategy("  Release grab.");
	report_strategy("  Verify that events are now received.");
	report_strategy("  Release the grab and restore the device state.");
	report_strategy("  Set grab with XGrabButton and activate.");
	report_strategy("  Check that no pointer events are generated.");
	report_strategy("  Allow events with XAllowEvents().");
	report_strategy("  Verify that events are now received.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	XSelectInput(display, grab_window, event_mask);
	pointer_mode = GrabModeSync;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	XSync(display, True);	/* Flush events */
	warppointer(display, grab_window, ACTPOSX+3, ACTPOSY+4);
	if (XCheckMaskEvent(display, (long)event_mask, &ev)) {
		delete("Pointer event was received while pointer was frozen");
		trace("ev.type = %s", eventname(ev.type));
		return;
	} else
		CHECK;

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

	if (XCheckMaskEvent(display, (long)event_mask, &ev)) {
		if( ev.type == MotionNotify) {
			CHECK;
		} else {
			report("Unexpected event (%s)was received",
				eventname(ev.type));
			FAIL;
		}
	} else {
		if(pgrabbed())
			report("Grab was not released.");
		else
			report("Pointer event was not saved while pointer was frozen");
		FAIL;
	}

	relalldev();
	XUngrabButton(display, AnyButton, AnyModifier, grab_window);
	
	pointer_mode = GrabModeSync;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	XSync(display, True);
	warppointer(display, grab_window, ACTPOSX+3, ACTPOSY+4);
        if (XCheckMaskEvent(display, (long)event_mask, &ev)) {
                delete("Pointer event was received while pointer was frozen");
		trace("ev.type = %s", eventname(ev.type));
                return;
        } else
                CHECK;

	XAllowEvents(display, AsyncPointer, CurrentTime);
	XSync(display, False);

	if (XCheckMaskEvent(display, (long)event_mask, &ev)) {
		if( ev.type == MotionNotify) {
			CHECK;
		} else {
			report("Unexpected event (%s) was received",
				eventname(ev.type));
			FAIL;
		}
	} else {
		report("Pointer event was not saved while pointer was frozen");
		report("  or grab was not released by a call to XAllowEvents()");
		FAIL;
	}

	XUngrabButton(display, AnyButton, AnyModifier, grab_window);

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

static void t018(){

int 	pass = 0, fail = 0;

 	report_purpose(18);

	report_assertion("Assertion XGrabButton-18.(B)");
	report_assertion("When keyboard_mode is GrabModeAsync, then keyboard event");
	report_assertion("processing is unaffected by activation of the grab.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Set keyboard_mode to GrabModeAsync.");
	report_strategy("  Set grab with XGrabButton and activate.");
	report_strategy("  Verify that keyboard is not frozen.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	keyboard_mode = GrabModeAsync;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	activate();

	if (kfrozen()) {
		report("Keyboard was frozen when keyboard_mode was GrabModeAsync");
		FAIL;
	} else
		CHECK;

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

static void t019(){

int 	pass = 0, fail = 0;

 	report_purpose(19);

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

	report_strategy("If extensions are available:");
	report_strategy("  Set keyboard_mode to GrabModeSync.");
	report_strategy("  Set grab with XGrabButton and activate.");
	report_strategy("  Verify that keyboard is frozen.");
	report_strategy("  Allow events with XAllowEvents().");
	report_strategy("  Verify that keyboard is not frozen.");
	report_strategy("  Release the grab and restore the device state.");
	report_strategy("  Set grab with XGrabButton and activate.");
	report_strategy("  Verify that keyboard is frozen.");
	report_strategy("  Release grab.");
	report_strategy("  Verify that keyboard is not frozen.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	keyboard_mode = GrabModeSync;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	activate();

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

	XAllowEvents(display, AsyncKeyboard, CurrentTime);
	XSync(display, False);

	if(kfrozen())  {
		report("Keyboard still frozen after XAllowEvents()");
		FAIL;
	} else
		CHECK;

	relbuttons();
	XUngrabPointer(display, CurrentTime);
	XUngrabButton(display, AnyButton, AnyModifier, grab_window);

	keyboard_mode = GrabModeSync;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	activate();

	if (kfrozen())
		CHECK;
	else {
		report("Keyboard was not frozen when keyboard_mode was GrabModeSync");
		FAIL;
	}
	
	buttonrel(display, button);

	if (kfrozen()) {
		report("Keyboard not thawed after a button grab released");
		FAIL;
	} else
		CHECK;

	XUngrabButton(display, AnyButton, AnyModifier, grab_window);

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

static void t020(){

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

 	report_purpose(20);

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

	report_strategy("If extensions are available:");
	report_strategy("  Enable key press events.");
	report_strategy("  Set keyboard_mode to GrabModeSync.");
	report_strategy("  Set grab with XGrabButton and activate.");
	report_strategy("  Press key.");
	report_strategy("  Check that no pointer events are generated.");
	report_strategy("  Allow events with XAllowEvents().");
	report_strategy("  Verify that events are now received.");
	report_strategy("  Release the grab and restore the device state.");
	report_strategy("  Set grab with XGrabButton and activate.");
	report_strategy("  Press key.");
	report_strategy("  Check that no pointer events are generated.");
	report_strategy("  Release grab.");
	report_strategy("  Verify that events are now received.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	XSelectInput(display, grab_window, KeyPressMask);
	keyboard_mode = GrabModeSync;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();
	XSync(display, True);	/* Flush events */

	XDisplayKeycodes(display, &minkc, &maxkc);
	keypress(display, minkc);
	keyrel(display, minkc);

	if (XCheckMaskEvent(display, (long)KeyPressMask, &ev)) {
		delete("KeyPress event was received while pointer was frozen");
		return;
	} else
		CHECK;

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

	if (XCheckMaskEvent(display, (long)KeyPressMask, &ev))
		CHECK;
	else {
		if(pgrabbed()) {
			report("Grab was not released");
		} else {
			report("KeyPress event was not saved while keyboard was frozen");
		}
		FAIL;
	}

	relalldev();
	XUngrabButton(display, AnyButton, AnyModifier, grab_window);

	pointer_mode = GrabModeSync;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	XSync(display, True);
	keypress(display, minkc);
	keyrel(display, minkc);

	if (XCheckMaskEvent(display, (long)KeyPressMask, &ev)) {
		delete("KeyPress event was received while pointer was frozen");
		return;
	} else
		CHECK;

	XAllowEvents(display, AsyncKeyboard, CurrentTime);
	XSync(display, False);

	if (XCheckMaskEvent(display, (long)KeyPressMask, &ev))
		CHECK;
	else {
		if(pgrabbed()) {
			report("Grab was not released");
		} else {
			report("KeyPress event was not saved while keyboard was frozen");
		}
		FAIL;
	}

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

static void t021(){

Cursor	goodcur;
Window	parent,curwin;
Window	windows[7]; /* root + 5 above + None stopper */
Window	root;
Window	*wp;
struct buildtree *tree;
char	*wname;
int 	pass = 0, fail = 0;

 	report_purpose(21);

	report_assertion("Assertion XGrabButton-21.(B)");
	report_assertion("When cursor is a valid cursor and the grab is now active,");
	report_assertion("then it is displayed regardless of which window the pointer");
	report_assertion("is in.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions available:");
	report_strategy("  Make a tree of windows rooted at grab_window, all with default cursor.");
	report_strategy("  Make a non-overlapping sibling of grab_window, the cursor window.");
	report_strategy("  Set that window's cursor to be a good, non default, cursor.");
	report_strategy("  Call XGrabButton with cursor = the good cursor.");
	report_strategy("  Activate grab by simulating button press.");
	report_strategy("  Warp pointer to all windows in the tree, root and cursor window, and");
	report_strategy("    validate that current cursor is equal to that of cursor window");
	report_strategy("    using extension.");
	report_strategy("else:");
	report_strategy("  Perform touch test.");

	tpstartup();
	setargs();
	if (!noext(1)) {

		goodcur = makecur(display);
		wp = windows;
		*wp++ = root = DRW(display);
		*wp++ = parent = grab_window;
		tree = buildtree(display, parent, WindowTree, NWindowTree);
		*wp++ = btntow(tree, "child1");
		*wp++ = btntow(tree, "child2");
		*wp++ = btntow(tree, "grandchild");
		*wp++ = curwin = defwin(display);
		*wp = None;
		XDefineCursor(display, curwin, goodcur);
		(void)warppointer(display, curwin, 2, 2);
		if (spriteiswin(display, parent)) {
			delete("Require XT_FONTCURSOR_GOOD to be other than default.");
			return;
		} else
			CHECK;
	
		cursor = goodcur;
		startcall(display);
		if (isdeleted())
			return;
		XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
		endcall(display);
		if (geterr() != Success) {
			report("Got %s, Expecting Success", errorname(geterr()));
			FAIL;
		}
		activate();
	
		for(wp=windows; *wp != None; wp++) { /* around 6 times */
			(void)warppointer(display, *wp, 0,0);
			/* use 0,0 as window making stuff keeps away from there on
			 * root. All of our tree windows are not at 0,0 either
			 */
			if (spriteiswin(display, curwin)) /* true at least once! */
				CHECK;
			else {
				report("Window %s did not have specified cursor as displayed cursor.",
					(wname=btwton(tree,*wp)) ? wname :
						( *wp == root ? "ROOT" : "<Unknown>" ));
				FAIL;
			}
		}
	
		CHECKPASS(1+6);
	
	} else {

		cursor = makecur(display);

		startcall(display);
		if (isdeleted())
			return;
		XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
		endcall(display);
		if (geterr() != Success) {
			report("Got %s, Expecting Success", errorname(geterr()));
			FAIL;
		}
		CHECK;

		CHECKUNTESTED(1);
	}

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

static void t022(){

Cursor	goodcur1, goodcur2;
Window	parent,gchild;
Window	windows[6]; /* root + 4 above + None stopper */
Window	root;
Window	*wp;
struct buildtree *tree;
char	*wname;
int 	pass = 0, fail = 0;

 	report_purpose(22);

	report_assertion("Assertion XGrabButton-22.(B)");
	report_assertion("When cursor is None and the grab is now active, then the");
	report_assertion("normal cursor is displayed for the grab_window and its");
	report_assertion("subwindows and the grab_window cursor is displayed for all");
	report_assertion("other windows.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions available:");
	report_strategy("  Make a tree of windows rooted at grab_window (parent), all with default cursor.");
	report_strategy("  Set grab_window to be one of its own children (child2), which has its own");
	report_strategy("    child (grandchild).");
	report_strategy("  Set grab_window's cursor to be a good, non default, cursor.");
	report_strategy("  Set grab_window's child's (grandchild) cursor to be yet another good,");
	report_strategy("    non default, cursor.");
	report_strategy("  Call XGrabButton with cursor = None.");
	report_strategy("  Activate grab by simulating button press.");
	report_strategy("  Warp pointer to all windows in the tree, plus root, and");
	report_strategy("    validate that current cursor is equal to that of grab_window & grandchild,");
	report_strategy("    respectively, when in the corresponding windows, but equal to that of");
	report_strategy("    grab_window otherwise, using extension.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	goodcur1 = makecur(display);
	goodcur2 = makecur2(display);
	if (isdeleted()) {
		report("Could not make cursors. Check that XT_FONTCURSOR_GOOD");
		report("and XT_FONTCURSOR_GOOD+2 both are good glyphs in cursor font.");
		return;
	}
	wp = windows;
	*wp++ = root = DRW(display);
	*wp++ = parent = grab_window;
	tree = buildtree(display, parent, WindowTree, NWindowTree);
	*wp++ = btntow(tree, "child1");
	*wp++ = grab_window = btntow(tree, "child2");
	*wp++ = gchild = btntow(tree, "grandchild");
	*wp = None;
	XDefineCursor(display, grab_window, goodcur1);
	XDefineCursor(display, gchild, goodcur2);

	(void)warppointer(display, gchild, 2, 2);
	if (spriteiswin(display, grab_window)) {
		delete("Require glyphs XT_FONTCURSOR_GOOD and XT_FONTCURSOR_GOOD+2 to differ in cursor font.");
		return;
	} else
		CHECK;

	cursor = None;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	activate();

	for(wp=windows; *wp != None; wp++) { /* around 5 times */
		(void)warppointer(display, *wp, 0,0);
		/* use 0,0 as window making stuff keeps away from there on
		 * root. All of our tree windows are not at 0,0 either
		 */
		if (!(wname = btwton(tree,*wp)))
			wname = (*wp == root) ? "ROOT" : "<Unknown>";
		if (*wp == grab_window || *wp == gchild) {
			if (spriteiswin(display, *wp))
				CHECK;
			else {
				report("Window %s did not have cursor as its normal cursor", wname);
				report("\twhen in grab_window or descendent.");
				FAIL;
			}
		} else {
			if (spriteiswin(display, grab_window))
				CHECK;
			else {
				report("Window %s did not have cursor as grab_window's cursor", wname);
				report("\twhen not in grab_window or descendent.");
				FAIL;
			}
		}
	}

	CHECKPASS(1+5);

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

static void t023(){

int 	pass = 0, fail = 0;

 	report_purpose(23);

	report_assertion("Assertion XGrabButton-23.(B)");
	report_assertion("When confine_to is specified and the grab is now active,");
	report_assertion("then the pointer is confined to that window.");
	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 confine_to window.");
	report_strategy("  Set up grab with XGrabButton.");
	report_strategy("  Active grab.");
	report_strategy("  Verify that pointer is within confine_to window.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	confine_to = defwin(display);
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	if (getpointerwin(display, DRW(display)) == confine_to)
		CHECK;
	else {
		report("Pointer was not within the confine_to window");
		FAIL;
	}

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

static void t024(){

XEvent	ev;
XCrossingEvent	*cp;
XEnterWindowEvent	entergood;
XLeaveWindowEvent	leavegood;
int 	pass = 0, fail = 0;

 	report_purpose(24);

	report_assertion("Assertion XGrabButton-24.(B)");
	report_assertion("When the pointer is not initially contained in the");
	report_assertion("confine_to window, then it is warped automatically to the");
	report_assertion("closest edge just before the grab activates and enter and");
	report_assertion("leave events are generated.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Create confine_to window.");
	report_strategy("  Enable events on the grab_window and the confine_to windows.");
	report_strategy("  Set owner_events to True.");
	report_strategy("  Set and activate button grab.");
	report_strategy("  Verify that a leave event is generated on the window the pointer was in.");
	report_strategy("  Verify that an enter event is generated on the confine_to window.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	confine_to = defwin(display);

	XSelectInput(display, confine_to, EnterWindowMask|LeaveWindowMask);
	XSelectInput(display, grab_window, EnterWindowMask|LeaveWindowMask);
	owner_events = True;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	warppointer(display, grab_window, ACTPOSX, ACTPOSY);
	XSync(display, True);	/* Discard events so far */
	buttonpress(display, button);

	defsetevent(entergood, display, EnterNotify);
	entergood.window = confine_to;
	entergood.root = DRW(display);
	entergood.subwindow = None;
	entergood.time = 0;
	entergood.mode = NotifyNormal;
	entergood.detail = NotifyNonlinear;
	entergood.same_screen = True;
	entergood.focus = False;
	entergood.state = Button1Mask;

	defsetevent(leavegood, display, LeaveNotify);
	leavegood.window = grab_window;
	leavegood.root = DRW(display);
	leavegood.subwindow = None;
	leavegood.time = 0;
	leavegood.mode = NotifyNormal;
	leavegood.detail = NotifyNonlinear;
	leavegood.same_screen = True;
	leavegood.focus = False;
	leavegood.state = Button1Mask;

	/* Event of the pointer leaving the grab_window */
	if (getevent(display, &ev) == 0 || ev.type != LeaveNotify) {
		report("No leave notify event for grab_window received");
		FAIL;
	} else
		CHECK;

	cp = (XCrossingEvent*)&ev;
	/* Set the fields that we can't conveniently check */
	leavegood.time = cp->time;
	leavegood.x = cp->x;
	leavegood.y = cp->y;
	leavegood.x_root = cp->x_root;
	leavegood.y_root = cp->y_root;
	leavegood.focus = cp->focus;
	if (checkevent((XEvent*)&leavegood, &ev))
		FAIL;
	else
		CHECK;

	/* Now the Enter into the confine_to window */
	if (getevent(display, &ev) == 0 || ev.type != EnterNotify) {
		report("No enter notify event for confine_to received");
		FAIL;
	} else
		CHECK;

	cp = (XCrossingEvent*)&ev;
	/* Set the fields that we can't conveniently check */
	entergood.time = cp->time;
	entergood.x = cp->x;
	entergood.y = cp->y;
	entergood.x_root = cp->x_root;
	entergood.y_root = cp->y_root;
	entergood.focus = cp->focus;
	if (checkevent((XEvent*)&entergood, &ev))
		FAIL;
	else
		CHECK;

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

static void t025(){

struct	area	area;
int 	pass = 0, fail = 0;

 	report_purpose(25);

	report_assertion("Assertion XGrabButton-25.(B)");
	report_assertion("When the confine_to window is subsequently reconfigured and");
	report_assertion("the grab is now active, then the pointer is warped");
	report_assertion("automatically to keep it within the window.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Create confine_to window.");
	report_strategy("  Set up and activate button grab,");
	report_strategy("  Move confine_to so that it does not overlap with it's previous position.");
	report_strategy("  Verify that the pointer has been warped to the new position.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	warppointer(display, DRW(display), 0, 0);

	/*
	 * This time make confine_to a child of grab_window, also make it small
	 * so that moving it will force the pointer to move.
	 */
	setarea(&area, 1, 1, 2, 2);
	confine_to = crechild(display, grab_window, &area);

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	activate();

	XMoveWindow(display, confine_to, 20, 20);
	if (isdeleted())
		return;

	if (getpointerwin(display, grab_window) == confine_to)
		CHECK;
	else {
		report("Pointer was not kept within confine_to when confine_to was moved");
		FAIL;
	}

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

static void t026(){

Window  root;
Window  wtmp;
int     itmp;
unsigned uitmp;
Bool    s;
int 	pass = 0, fail = 0;

 	report_purpose(26);

	report_assertion("Assertion XGrabButton-26.(D)");
	report_assertion("If multiple screens are supported: It is valid for the");
	report_assertion("confine_to window to be on a different screen to the");
	report_assertion("grab_window.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If only one screen");
	report_strategy("  UNSUPPORTED.");
	report_strategy("If extensions are available:");
	report_strategy("  Create grab_window on default screen.");
	report_strategy("  Create confine_to window on alternate screen.");
	report_strategy("  Set up and activate grab.");
	report_strategy("  Verify that pointer is warped to other screen.");
	report_strategy("else");
	report_strategy("  Touch test with grab_window and confine_to on different screens.");

	tpstartup();
	setargs();
	if (config.alt_screen < 0) {
		unsupported("Only one screen supported");
		return;
	}

	confine_to = defdraw(display, VI_ALT_WIN);

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (noext(1)) {
		untested("There is no reliable test method, but a touch test was performed");
		return;
	}

	activate();

	/*
	 * Query Pointer returns false if the pointer is not the same screen as
	 * the given window.  Check with both windows, mainly as a sanity check
	 * against them being on the same screen.
	 */
	s = XQueryPointer(display, confine_to, &root, &wtmp, &itmp, &itmp,
		&itmp, &itmp , &uitmp);
	if (s)
		CHECK;
	else {
		report("Pointer was not warped to confine_to window on other screen");
		FAIL;
	}

	s = XQueryPointer(display, grab_window, &root, &wtmp, &itmp, &itmp,
		&itmp, &itmp , &uitmp);
	if (s) {
		report("Pointer was not warped to confine_to window on other screen");
		FAIL;
	} else
		CHECK;

	CHECKPASS(2);

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

static void t027(){

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

 	report_purpose(27);

	report_assertion("Assertion XGrabButton-27.(B)");
	report_assertion("When the button/key combination is pressed and the grab");
	report_assertion("becomes active, then the last-pointer-grab time is set to");
	report_assertion("the time the button was pressed.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions available:");
	report_strategy("  Call XGrabButton to set up passive grab.");
	report_strategy("  Press button.");
	report_strategy("  Get the ButtonPress event.");
	report_strategy("  Save the time field in the event.");
	report_strategy("  Release grab by releasing button.");
	report_strategy("  Attempt to grab pointer using the saved time - 1.");
	report_strategy("  Verify that pointer is not grabbed.");
	report_strategy("  Attempt to grab pointer using the saved time.");
	report_strategy("  Verify that pointer is grabbed.");

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

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	activate();

	if (getevent(display, &ev) == 0) {
		delete("Could not get button event");
		return;
	} else
		CHECK;

	if (ev.type != ButtonPress) {
		delete("Did not get ButtonPressEvent");
		return;
	} else
		CHECK;

	savtime = ((XButtonPressedEvent*)&ev)->time;

	relbuttons();
	if (pgrabbed()) {
		delete("Could not release grab");
		return;
	} else
		CHECK;

	XGrabPointer(display, grab_window, False, 0, GrabModeAsync, GrabModeAsync,
		None, None, savtime-1);

	if (pgrabbed()) {
		report("Pointer was grabbed when time was earlier than the");
		report("  pointer-last-grab time");
		FAIL;
	} else
		CHECK;

	XGrabPointer(display, grab_window, False, 0, GrabModeAsync, GrabModeAsync,
		None, None, savtime);
	if (pgrabbed())
		CHECK;
	else {
		report("Pointer was not grabbed when time was equal to the");
		report("  pointer-last-grab time");
		FAIL;
	}

	CHECKPASS(5);

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

static void t028(){

Window	win;
XMotionEvent	*mep;
XEvent	ev;
int 	pass = 0, fail = 0;

 	report_purpose(28);

	report_assertion("Assertion XGrabButton-28.(B)");
	report_assertion("A call to XGrabButton has no effect on an active grab.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions available:");
	report_strategy("  Create window.");
	report_strategy("  Grab pointer on this window.");
	report_strategy("  Set up passive grab on another window.");
	report_strategy("  Verify that pointer is still grabbed on first window.");

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

	win = defwin(display);
	XGrabPointer(display, win, False, PointerMotionMask,
		GrabModeAsync, GrabModeAsync, None, None, CurrentTime);

	/* This sets the grab on grab_window */
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	warppointer(display, grab_window, 1, 1);
	warppointer(display, grab_window, 3, 3);

	if (getevent(display, &ev) < 1) {
		delete("Could not get motion event");
		return;
	} else
		CHECK;

	mep = (XMotionEvent*)&ev;
	if (mep->window == win)
		CHECK;
	else if (!fail) {
		report("A call to %s had an effect on an active grab", TestName);
		report("  A new grab window was set");
		FAIL;
	}

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

static void t029(){

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

 	report_purpose(29);

	report_assertion("Assertion XGrabButton-29.(B)");
	report_assertion("When the grab_window or confine_to window becomes not");
	report_assertion("viewable during an active pointer grab, then the grab is");
	report_assertion("released.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Create grab and confine_to windows.");
	report_strategy("  Set up passive grab with XGrabButton.");
	report_strategy("");
	report_strategy("  Activate grab with a button press.");
	report_strategy("  Unmap grab_window.");
	report_strategy("  Verify that pointer is not grabbed.");
	report_strategy("");
	report_strategy("  Re-map grab_window.");
	report_strategy("  Activate grab with a button press.");
	report_strategy("  Unmap confine_to window.");
	report_strategy("  Verify that pointer is not grabbed.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	warppointer(display, DRW(display), 0, 0);

	client2 = opendisplay();
	win = defwin(display);
	XSelectInput(client2, win, PointerMotionMask|EnterWindowMask);
	XSync(client2, True);

	confine_to = defwin(display);
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate();

	XUnmapWindow(display, grab_window);

	/*
	 * Warp into win and force all events to be received.
	 * If the grab has been released then this will generate
	 * an event for client2.
	 */
	warppointer(display, win, 0, 0);
	XSync(client2, False);

	if (XCheckWindowEvent(client2, win, (long)PointerMotionMask|EnterWindowMask, &ev))
		CHECK;
	else {
		report("Grab was not released when grab_window was unmapped");
		FAIL;
	}

	/* Clear any extra events */
	XSync(client2, True);

	/* Now repeat for confine_to window. */
	XMapWindow(display, grab_window);

	activate();

	XUnmapWindow(display, confine_to);

	/* Warp to win and check for events on client2 */
	warppointer(display, win, 0, 0);
	XSync(client2, False);

	if (XCheckWindowEvent(client2, win, (long)PointerMotionMask|EnterWindowMask, &ev))
		CHECK;
	else {
		report("Grab was not released when confine_to window was unmapped");
		FAIL;
	}

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

static void t030(){

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

 	report_purpose(30);

	report_assertion("Assertion XGrabButton-30.(B)");
	report_assertion("When window reconfiguration causes the confine_to window to");
	report_assertion("lie completely outside the boundaries of the root window");
	report_assertion("during an active pointer grab, then the grab is released.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Create grab and confine_to windows.");
	report_strategy("  Set up and activate grab.");
	report_strategy("  Move confine_to window off the root window.");
	report_strategy("  Verify that grab is released.");
	report_strategy("else");
	report_strategy("  Report untested.");

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

	warppointer(display, DRW(display), 0, 0);

	client2 = opendisplay();

	confine_to = defwin(display);
	win = defwin(display);

	XSelectInput(client2, win, PointerMotionMask|EnterWindowMask);
	XSync(client2, True);

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	activate();

	XMoveWindow(display, confine_to, -9000, -9000);
	warppointer(display, win, 0, 0);
	XSync(client2, False);

	if (isdeleted())
		return;

	if (XCheckWindowEvent(client2, win, (long)PointerMotionMask|EnterWindowMask, &ev))
		CHECK;
	else {
		report("Grab was not released when the confine_to window was placed beyond root window");
		FAIL;
	}

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

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

static void t031(){

Display	*client1;
int 	pass = 0, fail = 0;

 	report_purpose(31);

	report_assertion("Assertion XGrabButton-31.(A)");
	report_assertion("When an attempt to grab a key/button combination already");
	report_assertion("grabbed by another client is made, then a BadAccess error");
	report_assertion("occurs.");

	report_strategy("Grab a button.");
	report_strategy("Create new client, client1.");
	report_strategy("Attempt to grab same button with client1.");
	report_strategy("Verify that a BadAccess error occurs.");

	tpstartup();
	setargs();
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);

	if ((client1 = opendisplay()) == 0) {
		delete("Could not open display");
		return;
	}

	display = client1;
	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != BadAccess) {
		report("Got %s, Expecting BadAccess", errorname(geterr()));
		FAIL;
	}

	if (geterr() == BadAccess)
		PASS;
	else
		FAIL;
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

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

/* Including from file error/ECur.mc */
static void t032(){

unsigned int shape;
int 	pass = 0, fail = 0;

 	report_purpose(32);

	report_assertion("Assertion XGrabButton-32.(A)");
	report_assertion("When a cursor argument does not name a valid Cursor, then a");
	report_assertion("BadCursor error occurs.");

	report_strategy("Create cursor with shape XT_FONTCURSOR_GOOD in font cursor.");
	report_strategy("Free cursor.");
	report_strategy("Call test function using bad cursor as the cursor argument.");
	report_strategy("Verify that a BadCursor error occurs.");

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

	/* UNSUPPORTED is not allowed */
	shape = config.fontcursor_good;
	if (config.fontcursor_good == -1) {
		delete("A value of UNSUPPORTED is not allowed for XT_FONTCURSOR_GOOD");
		return;
	}

	A_CURSOR = XCreateFontCursor(A_DISPLAY, shape);
	XFreeCursor(A_DISPLAY, A_CURSOR);

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != BadCursor) {
		report("Got %s, Expecting BadCursor", errorname(geterr()));
		FAIL;
	}

	if (geterr() == BadCursor)
		PASS;
	else
		FAIL;
	restoredevstate();
	tpcleanup();
	pfcount(pass, fail);
}

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

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

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

#undef	VALUE_ARG
#define	VALUE_ARG event_mask
#undef	VALUE_LIST
#define	VALUE_LIST event_maskvallist
#undef NOTMEMTYPE
#define NOTMEMTYPE unsigned
#undef	NOTMEMBER
#define	NOTMEMBER notmaskmember
int 	i;
int 	n;
NOTMEMTYPE
long	vals[NM_LEN];
int 	pass = 0, fail = 0;

 	report_purpose(33);

	report_assertion("Assertion XGrabButton-33.(A)");
	report_assertion("When the value of event_mask is not a bitwise combination");
	report_assertion("of ButtonPressMask, ButtonReleaseMask, EnterWindowMask,");
	report_assertion("LeaveWindowMask, PointerMotionMask, PointerMotionHintMask,");
	report_assertion("Button1MotionMask, Button2MotionMask, Button3MotionMask,");
	report_assertion("Button4MotionMask, Button5MotionMask, ButtonMotionMask or");
	report_assertion("KeymapStateMask, 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;
		XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
		endcall(display);
		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.2516 */
/* End of included file Mval.tmc.2516 */

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

#undef	VALUE_ARG
#define	VALUE_ARG modifiers
#undef	VALUE_LIST
#define	VALUE_LIST modifiersvallist
#undef NOTMEMTYPE
#define NOTMEMTYPE unsigned
#undef	NOTMEMBER
#define	NOTMEMBER notmaskmember
int 	i;
int 	n;
NOTMEMTYPE
long	vals[NM_LEN];
int 	pass = 0, fail = 0;

 	report_purpose(34);

	report_assertion("Assertion XGrabButton-34.(A)");
	report_assertion("When the value of modifiers is not a bitwise combination of");
	report_assertion("ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask,");
	report_assertion("Mod3Mask, Mod4Mask, Mod5Mask or AnyModifier, then a");
	report_assertion("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;
		XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
		endcall(display);
		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.2516 */
/* End of included file Mval.tmc.2516 */

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

#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(35);

	report_assertion("Assertion XGrabButton-35.(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;
		XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
		endcall(display);
		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.2516 */
/* End of included file Mval.tmc.2516 */

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

#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(36);

	report_assertion("Assertion XGrabButton-36.(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;
		XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
		endcall(display);
		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.2516 */
/* End of included file Mval.tmc.2516 */

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

#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(37);

	report_assertion("Assertion XGrabButton-37.(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;
		XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
		endcall(display);
		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 */

static void t038(){

int 	pass = 0, fail = 0;

 	report_purpose(38);

	report_assertion("Assertion XGrabButton-38.(A)");
	report_assertion("When the grab_window argument does not name a valid Window,");
	report_assertion("then a BadWindow error occurs.");

	report_strategy("Set grab_window to invalid window.");
	report_strategy("Call XGrabButton.");
	report_strategy("Verify that a BadWindow error occurs.");

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

	grab_window = badwin(display);

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != BadWindow) {
		report("Got %s, Expecting BadWindow", errorname(geterr()));
		FAIL;
	}

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

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

static void t039(){

int 	pass = 0, fail = 0;

 	report_purpose(39);

	report_assertion("Assertion XGrabButton-39.(A)");
	report_assertion("When the confine_to argument does not name a valid Window");
	report_assertion("or None, then a BadWindow error occurs.");

	report_strategy("Set confine_to to invalid window.");
	report_strategy("Call XGrabButton.");
	report_strategy("Verify that a BadWindow error occurs.");

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

	confine_to = badwin(display);

	startcall(display);
	if (isdeleted())
		return;
	XGrabButton(display, button, modifiers, grab_window, owner_events, event_mask, pointer_mode, keyboard_mode, confine_to, cursor);
	endcall(display);
	if (geterr() != BadWindow) {
		report("Got %s, Expecting BadWindow", errorname(geterr()));
		FAIL;
	}

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

	restoredevstate();
	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 },
	{ t022, 22 },
	{ t023, 23 },
	{ t024, 24 },
	{ t025, 25 },
	{ t026, 26 },
	{ t027, 27 },
	{ t028, 28 },
	{ t029, 29 },
	{ t030, 30 },
	{ t031, 31 },
	{ t032, 32 },
	{ t033, 33 },
	{ t034, 34 },
	{ t035, 35 },
	{ t036, 36 },
	{ t037, 37 },
	{ t038, 38 },
	{ t039, 39 },
	{ NULL, 0 }
};

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

void	(*tet_startup)() = startup;
void	(*tet_cleanup)() = cleanup;
