/*
* 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.
* 
*/
/*
 * SYNOPSIS:
 *   void
 *   XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode)
 *   Display	*display;
 *   int 	keycode;
 *   unsigned int 	modifiers;
 *   Window	grab_window;
 *   Bool	owner_events;
 *   int 	pointer_mode;
 *   int 	keyboard_mode;
 */


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

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


/*
 * Arguments to the XGrabKey function
 */
static Display	*display;
static int 	keycode;
static unsigned int 	modifiers;
static Window	grab_window;
static Bool	owner_events;
static int 	pointer_mode;
static int 	keyboard_mode;



/*
 * as unwarppointer but don't free ptr as this done at tpcleanup time.
 */
static void
my_unwarppointer(display, ptr)
Display *display;
PointerPlace *ptr;
{
        XWarpPointer(display, None, ptr->oroot, 0, 0, 0, 0, ptr->ox, ptr->oy);
}


static int minkc = -1,maxkc = -1;

static void set_kcs(dpy)
	Display *dpy;
{
	int kmin, kmax;

	if (minkc >= 8)
		return;
	XDisplayKeycodes(dpy, &kmin, &kmax);
	if (kmin < 8)
		kmin = 8;	/* For buggy servers */
	if (kmin >= kmax) {
		delete("Could not find two distinct key codes\n");
		delete("\t(min=%d, max=%d)\n", kmin, kmax);
		return;
	}
	minkc = kmin;
	maxkc = kmax;
}

#define	NMODS	8	/* Number of modifiers */

static int grab_key_code(dpy)
	Display *dpy;
{
	XModifierKeymap	*curmap;
	int i,key;

	set_kcs(dpy);
	curmap = XGetModifierMapping(dpy);
	for (key=minkc;key<=maxkc;key++) {
	    for (i = NMODS*curmap->max_keypermod; --i >= 0; )
		if (curmap->modifiermap[i] == key)
		    break;
	    if (i < 0) /* not a modifier, return it*/
		return key;
	}
	return minkc;
}

static int nongrab_key_code(dpy)
	Display *dpy;
{
	set_kcs(dpy);
	return (keycode == maxkc) ? minkc : maxkc;
}

#define	ACTPOSX	3
#define	ACTPOSY	6
/*
 * Warp to the grab_window and press the keys in modifiers and then press
 * the keycode in the 'keycode' arg.
 * (This activates the previously set up grab if the arg variables
 * have not been changed.)
 */
static void
activate_press()
{
	XSetInputFocus(display, grab_window, RevertToPointerRoot, CurrentTime);
	if (modifiers)
		modpress(display, modifiers);
	keypress(display, keycode);
}

/*
 * As above, but release (all) keys.
 */
static void
activate_release()
{
	XSetInputFocus(display, grab_window, RevertToPointerRoot, CurrentTime);
	keyrel(display, keycode);
	if (modifiers)
		modrel(display, modifiers);
}

/*
 * Returns True if the keyboard is grabbed.  This is not a general purpose
 * routine since it knows about the Grab Key args.
 * When the keyboard is grabbed then keyboard events are not reported to
 * non-grabbing clients. The grab client gets all keyboard events with
 * event window depending on owner_events and clients event mask.
 */
static
kgrabbed_check(client2)
Display	*client2;
{
XEvent	ev;
int	saved_keyc = keycode;

	XSelectInput(client2, grab_window, KeyPressMask|KeyReleaseMask);
	/* Flush events for client2 */
	XSync(client2, True);

	/*
	 * Ensure another-key press release pair in grab_window.
	 */
	keycode = nongrab_key_code(display);
	activate_press();
	activate_release();
	keycode = saved_keyc;

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

/*
 * as for kgrabbed_check() but used where number of fd's consumed by
 * multiple calls doesn't outweigh convenience of avoiding extra arg.
 */
static
kgrabbed()
{
Display	*client2;

	client2 = opendisplay();
	return kgrabbed_check(client2);
}

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 t011 */
static unsigned long	modifiersvallist[] = {
	ShiftMask,
	LockMask,
	ControlMask,
	Mod1Mask,
	Mod2Mask,
	Mod3Mask,
	Mod4Mask,
	Mod5Mask,
	AnyModifier,
};



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



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



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


int 	tet_thistest;

/*
 * Called at the beginning of each test purpose to reset the
 * arguments to their initial values
 */
static void
setargs()
{
	display = Dsp;
	keycode = grab_key_code(display); /* always min. k.c. */
	modifiers = 0;
	grab_window = defwin(display);
	owner_events = False;
	pointer_mode = GrabModeAsync;
	keyboard_mode = GrabModeAsync;
}

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

static void t001(){

unsigned int    mask;
int     onemod;
int	keysave,otherkc;
Window	parent,child1,child2,gchild;
struct buildtree *tree;
PointerPlace *p;
XEvent	ev;
int	cantdoit;
int 	pass = 0, fail = 0;

 	report_purpose(1);

	report_assertion("Assertion XGrabKey-1.(B)");
	report_assertion("A call to XGrabKey establishes a passive grab on the");
	report_assertion("keyboard that is activated in the future by the specified");
	report_assertion("key being logically pressed, the specified modifier keys");
	report_assertion("being logically down, no other modifier keys being logically");
	report_assertion("down, the grab_window being the focus window or an ancestor");
	report_assertion("of the focus window or being a descendant of the focus");
	report_assertion("window that contains the pointer and a passive grab on the");
	report_assertion("same key combination not existing on any ancestor of");
	report_assertion("grab_window.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("Call XGrabKey as touch test.");
	report_strategy("If extensions available:");
	report_strategy("  Set focus to grab window.");
	report_strategy("  Simulate a key press of key.");
	report_strategy("  Verify that keyboard is now grabbed.");
	report_strategy("  Release grab & key.");
	report_strategy("");
	report_strategy("  Set up a grab with XGrabKey for a key.");
	report_strategy("  Set focus to grab window.");
	report_strategy("  Simulate press of another key.");
	report_strategy("  Simulate the key press.");
	report_strategy("  Verify that the keyboard is not grabbed.");
	report_strategy("  Release grab & key.");
	report_strategy("");
	report_strategy("  Set up a grab with XGrabKey for a key and modifier keys.");
	report_strategy("  Set focus to grab window.");
	report_strategy("  Simulate modifier key presses.");
	report_strategy("  Simulate the key press.");
	report_strategy("  Verify that the keyboard is grabbed.");
	report_strategy("  Release grab & key.");
	report_strategy("");
	report_strategy("  Set up a grab with XGrabKey for a key and modifier keys.");
	report_strategy("  Set focus to grab window.");
	report_strategy("  Simulate modifier key presses.");
	report_strategy("  Simulate extra modifier key presses.");
	report_strategy("  Simulate the key press.");
	report_strategy("  Verify that the keyboard is not grabbed.");
	report_strategy("  Release grab & key.");
	report_strategy("");
	report_strategy("  Make a child of current grab_window become focus window.");
	report_strategy("  Call XGrabKey for a passive grab with no modifiers on parent.");
	report_strategy("  Set focus window to child of grab window.");
	report_strategy("  Activate the grab.");
	report_strategy("  Check if grabbed.");
	report_strategy("  Release key & grab.");
	report_strategy("");
	report_strategy("  Have grab_window a child of focus window and containing the pointer.");
	report_strategy("  Call XGrabKey with no modifiers.");
	report_strategy("  Activate the grab.");
	report_strategy("  Check if grabbed.");
	report_strategy("  Release key & grab.");
	report_strategy("");
	report_strategy("  Have grab_window a child of focus window and not containing the pointer.");
	report_strategy("  Call XGrabKey with no modifiers.");
	report_strategy("  Activate the grab.");
	report_strategy("  Check not grabbed.");
	report_strategy("  Release key & grab.");
	report_strategy("");
	report_strategy("  Set grab with no modifiers and grab_window a top-level window.");
	report_strategy("  Set another grab on child of top-level window.");
	report_strategy("  Discard event queue.");
	report_strategy("  Attempt to activate second grab (in child).");
	report_strategy("  Check event reported w.r.t. parent.");
	report_strategy("  Check that no event reported for child.");
	report_strategy("  Check no further events outstanding.");
	report_strategy("  Check that a grab is active.");
	report_strategy("  Release parent grab and check grab not active on child.");
	report_strategy("  Activate child and check key grabbed.");
	report_strategy("  Release any grabs and keys outstanding.");
	report_strategy("");

	tpstartup();
	setargs();
	if (!(cantdoit=noext(0)) && kgrabbed()) { /* Sanity check */
		delete("Keyboard seemed to be grabbed before doing test");
		return;
	}

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

	if (cantdoit) {
		untested("There is no reliable test method, but a touch test was performed");
		XUngrabKey(display, AnyKey, AnyModifier, grab_window);
		return;
	}

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

	if (kgrabbed()) {
		CHECK;
	} else {
		report("Keyboard was not grabbed after key press");
		FAIL;
	}
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

	/*
	 * --- Press another key instead of the grabbed key.
	 * The keyboard should not be grabbed.
	 */
	if ((otherkc=nongrab_key_code(display)) != keycode) {
		startcall(display);
		if (isdeleted())
			return;
		XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
		endcall(display);
		if (geterr() != Success) {
			report("Got %s, Expecting Success", errorname(geterr()));
			FAIL;
		}

		keysave = keycode;
		keycode = otherkc;
		activate_press();
		keycode = keysave; /* restore to normality */
		if (kgrabbed()) {
			report("Keyboard was grabbed although another key was pressed");
			FAIL;
		} else
			CHECK;
		relalldev();
	} else {
		trace("Only one key supported");
		CHECK;
	}
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

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

	activate_press();
	if (kgrabbed()) {
		CHECK;
	} else {
		report("Keyboard was not grabbed for keycode %d and %s", keycode,
			keymaskname((unsigned long)modifiers));
		FAIL;
	}
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

	/*
	 * --- 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;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	XSetInputFocus(display, grab_window, RevertToPointerRoot, CurrentTime);
	/* Pressing an extra modifier */
	modpress(display, mask);
	keypress(display, keycode);

	if (mask && kgrabbed()) {
		report("Keyboard 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 realy 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;
	}
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

/* Make a child of current grab_window become focus window. */
	parent = grab_window;
	tree = buildtree(display, parent, WindowTree, NWindowTree);
	child1 = btntow(tree, "child1");
/* Call xname for a passive grab with no modifiers on parent. */
	modifiers = 0;
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
/* Set focus window to child of grab window. */
	XSetInputFocus(display, parent, RevertToPointerRoot, CurrentTime);
/* Activate the grab. */
	keypress(display, keycode);
/* Check if grabbed. */
	if (kgrabbed()) {
		CHECK;
	} else {
		report("Key not grabbed when focus is child of grab_window.");
		FAIL;
	}
/* Release key & grab. */
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);


/* Have grab_window a child of focus window and containing the pointer. */
	child2 = btntow(tree, "child2");
	gchild = btntow(tree, "grandchild");
	grab_window = gchild;
	XSetInputFocus(display, child2, RevertToPointerRoot, CurrentTime);
	p = warppointer(display, grab_window, 2, 2);
/* Call xname with no modifiers. */
	modifiers = 0;
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
/* Activate the grab. */
	keypress(display, keycode);
/* Check if grabbed. */
	if (kgrabbed()) {
		CHECK;
	} else {
		report("Key not grabbed with grab_window a descendent of focus");
		report(" and containing the pointer.");
		FAIL;
	}
	my_unwarppointer(display, p);
/* Release key & grab. */
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

/* Have grab_window a child of focus window and not containing the pointer. */
	grab_window = gchild;
	XSetInputFocus(display, child2, RevertToPointerRoot, CurrentTime);
	p = warppointer(display, child1, 2, 2);
/* Call xname with no modifiers. */
	modifiers = 0;
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
/* Activate the grab. */
	keypress(display, keycode);
/* Check not grabbed. */
	if (!kgrabbed()) {
		CHECK;
	} else {
		report("Key grabbed with grab_window a descendent of focus");
		report(" and not containing the pointer.");
		FAIL;
	}
	my_unwarppointer(display, p);
/* Release key & grab. */
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

/* Set grab with no modifiers and grab_window a top-level window. */
	modifiers = 0;
	grab_window = parent;
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
/* Set another grab on child of top-level window. */
	grab_window = child1;
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
/* Discard event queue. */
	XSync(display, True);
/* Attempt to activate second grab (in child). */
	grab_window = child1;
	activate_press();
/* Check event reported w.r.t. parent. */
	if (XCheckWindowEvent(display, parent, KeyPressMask, &ev))
		CHECK;
	else {
		report("No KeyPress event for parent window.");
		FAIL;
	}
/* Check that no event reported for child. */
	if (!XCheckWindowEvent(display, child1, KeyPressMask, &ev))
		CHECK;
	else {
		report("Unexpected KeyPress event for child window.");
		FAIL;
	}
/* Check no further events outstanding. */
	if (getevent(display, &ev) != 0) {
		report("Unexpected %s event on %s window.",
			eventname(ev.type),
			ev.xany.window == parent ? "parent" : (
				ev.xany.window == child1 ? "child" : "unexpected"
			));
		FAIL;
	} else
		CHECK;
/* Check that a grab is active. */
	if (kgrabbed())
		CHECK;
	else {
		report("Key not grabbed after set in parent and child and");
		report(" activation attempt in child.");
		FAIL;
	}
/* Release parent grab and check grab not active on child. */
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, parent);
	/* grab_window is child1, still, so kgrabbed() checking OK. */
	if (kgrabbed()) {
		report("Child grab became active after interfering parent released.");
		FAIL;
	} else
		CHECK;
/* Activate child and check key grabbed. */
	/* grab_window still child so activate_press etc. OK */
	activate_press();
	if (!kgrabbed()) {
		report("Child grab not active after interfering parent released.");
		FAIL;
	} else
		CHECK;
/* Release any grabs and keys outstanding. */
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);
	
	CHECKPASS(13);
	tpcleanup();
	pfcount(pass, fail);
}

static void t002(){

Window	w1,w2;
XEvent	ev;
int	n;
int	grabbed;
int	keysave,otherkc;
int 	pass = 0, fail = 0;

 	report_purpose(2);

	report_assertion("Assertion XGrabKey-2.(B)");
	report_assertion("When the conditions for activating the grab are otherwise");
	report_assertion("satisfied and the keyboard is already grabbed, 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 two windows that do not overlap.");
	report_strategy("  Check that at least two keycodes are available.");
	report_strategy("  Set and activate grab on first window.");
	report_strategy("  Check grab activated.");
	report_strategy("  Set grab on second window on another keycode.");
	report_strategy("  Attempt to activate grab on second window, using other keycode.");
	report_strategy("  Check that only one KeyPress event received.");
	report_strategy("  Check it was reported from first grab window.");
	report_strategy("  Check grab still outstanding.");
	report_strategy("  Release keys & grabs.");
	report_strategy("else");
	report_strategy("  Report untested.");

	tpstartup();
	setargs();
	if (noext(0))
		return;
	else
		CHECK;
	w1 = defwin(display);
	w2 = defwin(display);
	keysave = keycode;
	otherkc = nongrab_key_code(display);

	if (otherkc == keycode) {
		delete("Need at least two distinct keycodes.");
		return;
	} else
		CHECK;

	grab_window = w1;
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	activate_press();
	if (!kgrabbed()) {
		delete("Could not activate first grab.");
		relalldev();
		XUngrabKey(display, AnyKey, AnyModifier, grab_window);
		return;
	} else
		CHECK;

	grab_window = w2;
	keycode = otherkc;
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	XSync(display, True);
	activate_press();
	keycode = keysave;
	if ((n=getevent(display, &ev)) != 1) {
		report("Received %d events on key press when grab active, expected just %d.", n, 1);
		FAIL;
	} else
		CHECK;
	if (n > 0 && ev.type != KeyPress) {
		report("First event was type %s instead of KeyPress.",eventname(ev.type));
		FAIL;
	} else
		CHECK;
	grabbed = kgrabbed();
	if (n > 0 && ev.xany.window != w1) {
		report("Event appeared on %s window instead of first grab window.",
			ev.xany.window == w2 ? "second grab" : "unexpected");
		if (grabbed)
			report("Grab appears to have moved.");
		else
			report("Grab has been prematurely released.");
		FAIL;
	} else if (!grabbed) {
		report("Key grab erroneously released on trying to activate second.");
		FAIL;
	} else
		CHECK;
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, w1);
	XUngrabKey(display, AnyKey, AnyModifier, w2);

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

static void t003(){

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

 	report_purpose(3);

	report_assertion("Assertion XGrabKey-3.(B)");
	report_assertion("When the conditions for activating the grab are satisfied");
	report_assertion("and the grab subsequently becomes active, then the");
	report_assertion("last-keyboard-grab time is set to the time at which the key");
	report_assertion("was pressed.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extensions are available:");
	report_strategy("  Set and activate grab.");
	report_strategy("  Check activated.");
	report_strategy("  Check activating event received.");
	report_strategy("  Check event type and event window are KeyPress and grab_window.");
	report_strategy("  Attempt XUngrabKeyboard at time just before event time.");
	report_strategy("  Check still grabbed.");
	report_strategy("  Attempt XUngrabKeyboard at time equal to event time.");
	report_strategy("  Check no longer grabbed.");
	report_strategy("  Release grab & key.");
	report_strategy("else");
	report_strategy("  Report untested.");

	tpstartup();
	setargs();
	if (noext(0))
		return;
	else
		CHECK;
	XSync(display, True);
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	activate_press();
	if (!kgrabbed()) {
		delete("Failed to activate grab.");
		return;
	} else
		CHECK;
	if (!getevent(display, &ev)) {
		delete("No event reported for activating grab.");
		return;
	} else
		CHECK;
	/* sanity check on the event. */
	if (ev.type != KeyPress || ev.xany.window != grab_window) {
		delete("Reported event has type %s and event window 0x%x", eventname(ev.type), ev.xany.window);
		delete(" expected KeyPress and 0x%x.", grab_window);
		return;
	} else
		CHECK;
	/* now set up OK */
	trace("Grabbed at time 0x%lx.",(unsigned long)ev.xkey.time);
	XUngrabKeyboard(display, ev.xkey.time - 1);
	if (!kgrabbed()) {
		report("Last keyboard grab time set earlier than reported event time.");
		FAIL;
	} else
		CHECK;
	XUngrabKeyboard(display, ev.xkey.time);
	if (kgrabbed()) {
		report("Last keyboard grab time set later than reported event time.");
		FAIL;
	} else
		CHECK;
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

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

static void t004(){

int 	pass = 0, fail = 0;

 	report_purpose(4);

	report_assertion("Assertion XGrabKey-4.(B)");
	report_assertion("When the grab subsequently becomes active and later the");
	report_assertion("logical state of the keyboard has the specified key");
	report_assertion("released, then the active grab is terminated automatically.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extension available:");
	report_strategy("    Set grab with modifiers.");
	report_strategy("    Activate grab.");
	report_strategy("    Check grabbed.");
	report_strategy("    Simulate keycode only key release with testing extension.");
	report_strategy("    Check for grab release.");
	report_strategy("    Simulate modifiers only key release with testing extension.");
	report_strategy("    Check for grab release.");
	report_strategy("    Release grab & keys.");
	report_strategy("  Repeat but in opposite order with grab release expected on keycode up only.");
	report_strategy("  Do the same for keycode = AnyKey, no modifiers.");
	report_strategy("    (releasing the grab with XUngrabKey before expected !kgrabbed() tests.)");
	report_strategy("else");
	report_strategy("  Report untested.");

	tpstartup();
	setargs();
	if (noext(0))
		return;
	else
		CHECK;
	modifiers = wantmods(display, 2);
	trace("Grabbing keycode %d with mods %s", keycode,
		keymaskname((unsigned long)modifiers));
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate_press();
	if (kgrabbed()) {
		CHECK;
	} else {
		delete("Keyboard was not grabbed for keycode %d and %s", keycode,
			keymaskname((unsigned long)modifiers));
		return;
	}
	trace("releasing keycode %d only.", keycode);
	keyrel(display, keycode); /* leaving modifiers down. */
	if (!kgrabbed()) {
		CHECK;
	} else {
		report("Keyboard still grabbed for keycode %d and %s after keycode release.", keycode,
			keymaskname((unsigned long)modifiers));
		FAIL;
	}
	modrel(display, modifiers); /* there go the modifiers. */
	if (!kgrabbed()) {
		CHECK;
	} else {
		report("Keyboard still grabbed for keycode %d and %s even after all keys released.", keycode,
			keymaskname((unsigned long)modifiers));
		FAIL;
	}
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);
	/* repeat but now release modifiers first and keycode last */
	trace("Grabbing keycode %d with mods %s", keycode,
		keymaskname((unsigned long)modifiers));
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	activate_press();
	if (kgrabbed()) {
		CHECK;
	} else {
		delete("Keyboard was not grabbed for keycode %d and %s", keycode,
			keymaskname((unsigned long)modifiers));
		return;
	}
	trace("releasing modifiers %s only.", keymaskname((unsigned long)modifiers));
	modrel(display, modifiers); /* leaving keycode down. */
	if (kgrabbed()) {
		CHECK;
	} else {
		report("Keyboard no longer grabbed for keycode %d and %s after %s release.", keycode,
			keymaskname((unsigned long)modifiers),
			keymaskname((unsigned long)modifiers));
		FAIL;
	}
	keyrel(display, keycode); /* there goes the keycode key. */
	if (!kgrabbed()) {
		CHECK;
	} else {
		report("Keyboard still grabbed for keycode %d and %s even after all keys released.", keycode,
			keymaskname((unsigned long)modifiers));
		FAIL;
	}
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

	/*
	 * Finally test AnyKey grabs only release when activating key released.
	 */
	modifiers = 0;
	keycode = AnyKey;
	trace("Grabbing keycode AnyKey with mods %s",
		keymaskname((unsigned long)modifiers));
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	keycode = grab_key_code(display);
	activate_press();
	if (kgrabbed()) {
		CHECK;
	} else {
		delete("Keyboard was not grabbed for keycode AnyKey when keycode %d only pressed.", keycode);
		return;
	}
	trace("releasing non activating keycode only.");
	/* already released by previous kgrabbed test but can't check
	 * if grabbed with kgrabbed as that would just make it active if
	 * (erroneously) passive. So, try and release grab with XUngrabKey
	 * which will do nothing if its active, as it should be, but will
	 * allow subsequent kgrabbed to return False if it wasn't active.
	 */
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);
	if (kgrabbed()) {
		CHECK;
	} else {
		delete("Keyboard was not grabbed for keycode AnyKey after press/release of non-activating key.");
		return;
	}
	trace("releasing activating keycode %d only.", keycode);
	keyrel(display, keycode);
	/*
	 * now the XUngrabKey should find it non-active so kgrabbed => False
	 */
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);
	if (!kgrabbed()) {
		CHECK;
	} else {
		report("Keyboard still grabbed for keycode AnyKey after keycode %d release.", keycode);
		FAIL;
	}
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

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

static void t005(){

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

 	report_purpose(5);

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

	report_strategy("If extensions available:");
	report_strategy("  Create a window for event reporting and set event mask to KeyPressMask.");
	report_strategy("  Set a grab with owner_events False on another window.");
	report_strategy("  Set a grab with owner_events True on this other window.");
	report_strategy("  Activate the grab.");
	report_strategy("  Check it activated.");
	report_strategy("  Simulate a KeyPress in the reporting window.");
	report_strategy("  Check that the reported event has event window equal to reporting");
	report_strategy("    window rather than grab_window showing that second overrode first.");
	report_strategy("  Release grabs & keys.");
	report_strategy("else");
	report_strategy("  Report untested.");

	tpstartup();
	setargs();
	if (noext(0))
		return;
	else
		CHECK;
	reportwin = defwin(display);
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	owner_events = True;
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	activate_press();
	if (!kgrabbed()) {
		delete("Failed to activate grab.");
		return;
	} else
		CHECK;
	XSync(display, True); /* empty event-Q */
	XSelectInput(display, reportwin, KeyPressMask);
	/* now cause key-press in reportwin */
	XSetInputFocus(display, reportwin, RevertToPointerRoot, CurrentTime);
	keypress(display, nongrab_key_code(display));
	/* check it was reported w.r.t. reportwin, not grab_window */
	if (!getevent(display, &ev)) {
		delete("Event not reported to grabbing client.");
		return;
	} else
		CHECK;
	if (ev.type != KeyPress) {
		delete("Reported event of type %s rather than KeyPress.", eventname(ev.type));
		return;
	} else
		CHECK;
	if (ev.xany.window != reportwin) {
		if (ev.xany.window == grab_window) {
			report("First grab not overridden by second.");
			FAIL;
		} else {
			delete("Unexpected window 0x%lx in reported event (not grab_window or reportwin).",
				(unsigned long)ev.xany.window);
			return;
		}
	} else
		CHECK;
	
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

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

static void t006(){

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

 	report_purpose(6);

	report_assertion("Assertion XGrabKey-6.(B)");
	report_assertion("When the modifiers argument is AnyModifier, then this is");
	report_assertion("equivalent to separate calls to XGrabKey for all possible");
	report_assertion("modifier 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 keycode to activate grab.");
	report_strategy("  Verify that grab is activated.");
	report_strategy("  Release keys & grab.");
	report_strategy("");
	report_strategy("  Press keycode (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;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

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

	modifiers = mods = wantmods(display, 4);

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

	/* Release all grabs, keys and modifiers */
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

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

	modifiers = AnyModifier;
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	modifiers = 0; /* cause keycode only to be pressed */
	activate_press();
	if (kgrabbed())
		CHECK;
	else {
		report("Grab with AnyModifier was not activated by pressing keycode %d with", keycode);
		report("  no modifiers");
		FAIL;
	}

	/* Release all grabs, keys etc. */
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

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

static void t007(){

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

 	report_purpose(7);

	report_assertion("Assertion XGrabKey-7.(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 XGrabKey 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(0))
		return;
	else
		CHECK;

	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;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	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_press();

	if (kgrabbed())
		CHECK;
	else {
		report("Passive grab not set when the modifier did not have a current keycode");
		FAIL;
	}
	/* Release all grabs, keys etc. */
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

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

static void t008(){

int 	i;
int 	minkc, maxkc;
Display	*client2;
int 	pass = 0, fail = 0;

 	report_purpose(8);

	report_assertion("Assertion XGrabKey-8.(B)");
	report_assertion("When the keycode argument is AnyKey, then this is");
	report_assertion("equivalent to separate calls to XGrabKey for all possible");
	report_assertion("KeyCodes.");
	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 AnyKey.");
	report_strategy("    Activate grab with simulated key press.");
	report_strategy("    Verify that keyboard is grabbed.");
	report_strategy("    Release key & grab.");
	report_strategy("    Repeat for other keycodes in range min_keycode to max_keycode.");
	report_strategy("  Release all grabs & keys.");
	report_strategy("else");
	report_strategy("  Touch test using AnyKey.");
	report_strategy("  Report untested.");

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

	XDisplayKeycodes(display, &minkc, &maxkc);

	keycode = AnyKey;
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

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

	XSetInputFocus(display, grab_window, RevertToPointerRoot, CurrentTime);

	for (i = minkc; i <= maxkc; i++) {
		keycode = i; /* let nongrab_key_code know */
		keypress(display, i);
		if (kgrabbed_check(client2))
			CHECK;
		else {
			report("Passive grab of AnyKey, not grabbed for keycode %d", (int)i);
			FAIL;
		}

		/*
		 * Release this grab and try next key.
		 */
		relkeys();
		/*
		 * This XUngrabKey must be in or else the key release is not
		 * enough because the press/release in kgrabbed will
		 * trigger/release the grab again. To test properly we
		 * must try and remove the grab, which only works if not
		 * active.
		 */
		XUngrabKey(display, AnyKey, AnyModifier, grab_window);
		XSync(display, True);
		if (kgrabbed_check(client2)) {
			delete("Could not release grab for next part of test");
			return;
		} else
			CHECK;
		/*
		 * The XUngrabKey requires us to have another passive
		 * grab installed for next iteration.
		 */
		keycode = AnyKey;
		startcall(display);
		if (isdeleted())
			return;
		XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
		endcall(display);
		if (geterr() != Success) {
			report("Got %s, Expecting Success", errorname(geterr()));
			FAIL;
		}
	}
	/* Release all grabs, keys etc. */
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

	CHECKPASS(1+2*(1 + maxkc - minkc));
	tpcleanup();
	pfcount(pass, fail);
}

static void t009(){

Window	win;
struct area	a;
int 	pass = 0, fail = 0;

 	report_purpose(9);

	report_assertion("Assertion XGrabKey-9.(B)");
	report_assertion("When the event window for an active grab becomes not");
	report_assertion("viewable, then the grab is released automatically.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("If extension is available:");
	report_strategy("  Set up grab on a child window (to avoid window manager interference).");
	report_strategy("  Activate grab.");
	report_strategy("  Check grabbed.");
	report_strategy("  Unmap grab_window.");
	report_strategy("  Map grab_window back again (to perform grab check).");
	report_strategy("  Check no longer grabbed.");
	report_strategy("  Release key & grab.");
	report_strategy("else");
	report_strategy("  Report untested.");

	tpstartup();
	setargs();
	if (noext(0))
		return;
	else
		CHECK;
	setarea(&a, 2, 2, 0, 0);
	win = crechild(display, grab_window, &a);
	grab_window = win;
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	activate_press();
	if (!kgrabbed()) {
		delete("Failed to activate grab.");
		return;
	} else
		CHECK;
	XUnmapWindow(display, grab_window);
	XSync(display, True);
	XMapWindow(display, grab_window);
	XSync(display, True);
	if (kgrabbed()) {
		report("Unmapping grab_window did not inactivate grab.");
		FAIL;
	} else
		CHECK;
	/* Release all grabs, keys etc. */
	relalldev();
	XUngrabKey(display, AnyKey, AnyModifier, grab_window);

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

static void t010(){

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

 	report_purpose(10);

	report_assertion("Assertion XGrabKey-10.(A)");
	report_assertion("When the specified keycode is not in the range specified by");
	report_assertion("min_keycode and max_keycode in the connection setup or");
	report_assertion("AnyKey, then a BadValue error occurs.");

	report_strategy("Call XGrabKey with keycode less than min_keycode.");
	report_strategy("Verify that a BadValue error occurs.");
	report_strategy("Call XGrabKey with keycode greater than max_keycode if it is less than 255.");
	report_strategy("Verify that a BadValue error occurs.");

	tpstartup();
	setargs();
	XDisplayKeycodes(display, &minkc, &maxkc);

	keycode = minkc - 2;
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != BadValue) {
		report("Got %s, Expecting BadValue", errorname(geterr()));
		FAIL;
	}

	if (geterr() == BadValue)
		CHECK;

	/*
	 * Since the protocol only has one byte for the key then this
	 * assertion cannot be tested when max_keycode is 255.
	 */
	if (maxkc < 255) {

		keycode = maxkc+1;

		startcall(display);
		if (isdeleted())
			return;
		XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
		endcall(display);
		if (geterr() != BadValue) {
			report("Got %s, Expecting BadValue", errorname(geterr()));
			FAIL;
		}

		if (geterr() == BadValue)
			CHECK;
	} else
		CHECK;

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

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

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

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

	report_assertion("Assertion XGrabKey-11.(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;
		XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
		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);
	tpcleanup();
	pfcount(pass, fail);
}

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

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

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

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

	report_assertion("Assertion XGrabKey-12.(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;
		XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
		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);
	tpcleanup();
	pfcount(pass, fail);
}

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

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

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

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

	report_assertion("Assertion XGrabKey-13.(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;
		XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
		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);
	tpcleanup();
	pfcount(pass, fail);
}

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

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

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

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

	report_assertion("Assertion XGrabKey-14.(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;
		XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
		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);
	tpcleanup();
	pfcount(pass, fail);
}

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

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

static void t015(){

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

 	report_purpose(15);

	report_assertion("Assertion XGrabKey-15.(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 key/modifier.");
	report_strategy("Create client2.");
	report_strategy("Attempt to grab same key modifier for client2.");
	report_strategy("Verify BadAccess error.");

	tpstartup();
	setargs();
	XGrabKey(Dsp, keycode, modifiers, grab_window, owner_events, pointer_mode,
		keyboard_mode);
	if (isdeleted()) {
		delete("Could not set up initial grab");
		return;
	}

	if ((client2 = opendisplay()) == NULL)
		return;

	display = client2;
	startcall(display);
	if (isdeleted())
		return;
	XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
	endcall(display);
	if (geterr() != BadAccess) {
		report("Got %s, Expecting BadAccess", errorname(geterr()));
		FAIL;
	}

	if (geterr() == BadAccess)
		CHECK;
	else
		FAIL;

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

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

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

int 	pass = 0, fail = 0;

 	report_purpose(16);

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

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

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

	A_WINDOW = badwin(A_DISPLAY);

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

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

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

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

/* End of Test Cases */


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

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

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