/*
* 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) 2001 The Open Group
* 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.
* 
*/
/*
 * SYNOPSIS:
 *   int
 *   XGetWindowProperty(display, w, property, long_offset, long_length, delete_prop, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return)
 *   Display *display;
 *   Window w;
 *   Atom property;
 *   long long_offset;
 *   long long_length;
 *   Bool delete_prop;
 *   Atom req_type;
 *   Atom *actual_type_return;
 *   int *actual_format_return;
 *   unsigned long *nitems_return;
 *   unsigned long *bytes_after_return;
 *   unsigned char **prop_return;
 */


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

/*
 * Defines for different argument types
 */
#define A_DISPLAY display
#define A_WINDOW w
#define A_DRAWABLE w
#define A_ATOM property


/*
 * Arguments to the XGetWindowProperty function
 */
static Display *display;
static Window w;
static Atom property;
static long long_offset;
static long long_length;
static Bool delete_prop;
static Atom req_type;
static Atom *actual_type_return;
static int *actual_format_return;
static unsigned long *nitems_return;
static unsigned long *bytes_after_return;
static unsigned char **prop_return;


static int 	ValueReturn;

#include "X11/Xatom.h"

static Atom actual_type;
static int actual_format;
static unsigned long nitems;
static unsigned long bytes_after;
static unsigned char *prop;

static void
set_vars()
{
	actual_type = 0;
	actual_format = -1;
	nitems = -1;
	bytes_after = -1;
	prop = NULL;
}

static int
check_values( ex_actual_type, ex_actual_format, ex_nitems, ex_bytes_after )
Atom ex_actual_type;
int ex_actual_format;
unsigned long ex_nitems;
unsigned long ex_bytes_after;
{
	int fail;
	int pass;

	fail=0;
	pass=0;

#ifdef TESTING_CHECK
	ex_actual_type = XA_RESOLUTION;
	ex_actual_format = 6;
	ex_nitems=256;
	ex_bytes_after=256;
#endif
	if (actual_type != ex_actual_type) {
		FAIL;
		report("%s returned an incorrect actual_type_return",
			TestName);
		report("Expected actual_type_return: %u (%s)", ex_actual_type,
			(ex_actual_type==None?"None":atomname(ex_actual_type)));
		report("Returned actual_type_return: %u (%s)",
			actual_type, atomname(actual_type));
	} else
		pass++;

	if (actual_format != ex_actual_format) {
		FAIL;
		report("%s returned an incorrect actual_format_return",
			TestName);
		report("Expected actual_format_return: %d", ex_actual_format);
		report("Returned actual_format_return: %d", actual_format);
	} else
		pass++;

	if (nitems != ex_nitems) {
		FAIL;
		report("%s returned an incorrect nitems_return",
			TestName);
		report("Expected nitems_return: %d", ex_nitems);
		report("Returned nitems_return: %d", nitems);
	} else
		pass++;

	if (bytes_after != ex_bytes_after) {
		FAIL;
		report("%s returned an incorrect bytes_after_return",
			TestName);
		report("Expected bytes_after_return: %d", ex_bytes_after);
		report("Returned bytes_after_return: %d", bytes_after);
	} else
		pass++;

	return((fail==0 && pass==4?1:0));
}


int 	tet_thistest;

/*
 * Called at the beginning of each test purpose to reset the
 * arguments to their initial values
 */
static void
setargs()
{
	display = Dsp;
	w = defwin(display);
	property = XA_COPYRIGHT;
	long_offset = 2;
	long_length = 2;
	delete_prop = False;
	req_type = XA_STRING;
	actual_type_return = &actual_type;
	actual_format_return = &actual_format;
	nitems_return = &nitems;
	bytes_after_return = &bytes_after;
	prop_return = &prop;
}

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

static void t001(){

int ret;
unsigned char cbuf[5];
char *data = "a tested property";
int 	pass = 0, fail = 0;

 	report_purpose(1);

	report_assertion("Assertion XGetWindowProperty-1.(A)");
	report_assertion("A successful call to XGetWindowProperty returns Success and");
	report_assertion("the actual type of the property, the actual format of the");
	report_assertion("property, the number of 8-bit, 16-bit, or 32-bit items");
	report_assertion("transferred, the number of bytes remaining to be read in the");
	report_assertion("property, and a pointer to the data actually returned.");

	report_strategy("Create a window with a property.");
	report_strategy("Call XGetWindowProperty to obtain the property information.");
	report_strategy("Verify that the returned information was correct.");

	tpstartup();
	setargs();
/* Create a window with a property. */
	XChangeProperty(display, w, property, XA_STRING, 8,
		PropModeReplace,(unsigned char *)data, strlen(data));

/* Call xname to obtain the property information. */
	set_vars();
	long_offset = 3;
	long_length = 1;
	delete_prop = False;
	startcall(display);
	if (isdeleted())
		return;
	ret = XGetWindowProperty(display, w, property, long_offset, long_length, delete_prop, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

/* Verify that the returned information was correct. */
	if (ret != Success) {
		FAIL;
		report("%s returned %d (expecting Success (%d))", TestName,
			ret, Success);
	} else
		CHECK;

	if (check_values( XA_STRING, 8, (unsigned long)4, (unsigned long)1 )) {
		CHECK;
	} else 
		FAIL;

	strncpy((char *)cbuf, &(data[12]), 4);
	cbuf[4] = '\0';

	if (prop == (unsigned char *)NULL) {
		FAIL;
		report("%s returned an incorrect prop_return",
			TestName);
		report("Expected prop_return: unsigned char * pointer");
		report("Returned prop_return: NULL pointer");
	} else
		if (strncmp((char *)prop, (char *)cbuf, 5) != 0) {
			FAIL;
			report("%s returned an incorrect prop_return",
				TestName);
			report("Expected prop_return: '%s'", cbuf);
			report("Returned prop_return: '%s'", prop);
		} else
			CHECK;

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

static void t002(){

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

 	report_purpose(2);

	report_assertion("Assertion XGetWindowProperty-2.(A)");
	report_assertion("When the specified property does not exist for the");
	report_assertion("specified window w, then a call to XGetWindowProperty");
	report_assertion("returns None to actual_type_return, zero to");
	report_assertion("actual_format_return and bytes_after_return, the");
	report_assertion("nitems_return argument is empty, and the delete argument is");
	report_assertion("ignored.");

	report_strategy("Create a window with PropertyChangeMask events selected and no properties.");
	report_strategy("For delete_prop of True and False:");
	report_strategy("	Call XGetWindowProperty to obtain the property information.");
	report_strategy("	Verify that the returned values were correct.");
	report_strategy("	Verify that no PropertyNotify events were generated.");

	tpstartup();
	setargs();
/* Create a window with PropertyChangeMask events selected and no properties. */
	XDeleteProperty(display, w, property); /* ENSURE property is nuked. */
	XSync(display,True);
	XSelectInput(display, w, PropertyChangeMask);

/* For delete_prop of True and False: */
	for(mode=0; mode<2; mode++) {

/* 	Call xname to obtain the property information. */
		delete_prop = (mode==0?True:False);
		trace("delete_prop is %s", boolname(delete_prop));
		set_vars();
		long_offset = 3;
		long_length = 1;
		startcall(display);
		if (isdeleted())
			return;
		ret = XGetWindowProperty(display, w, property, long_offset, long_length, delete_prop, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return);
		endcall(display);
		if (geterr() != Success) {
			report("Got %s, Expecting Success", errorname(geterr()));
			FAIL;
		}
		XSync(display, False);

/* 	Verify that the returned values were correct. */
		if (ret != Success) {
			FAIL;
			report("%s returned %d (expecting Success (%d))",
				TestName, ret, Success);
		} else
			CHECK;

		if ( check_values( None, 0,
			(unsigned long)0, (unsigned long)0 ) ) {
			CHECK;
		} else
			FAIL;

/* 	Verify that no PropertyNotify events were generated. */
		ret = getevent(display, &ev);
#ifdef TESTING
	ret++;
	ev.type = PropertyNotify;
#endif
		if (ret != 0) {
			FAIL;
			report("%s caused %d unexpected event%s", TestName,
					ret, (ret==1?"":"s"));
			do {
				report("event %s returned", eventname(ev.type));
			} while(getevent(display, &ev) != 0) ;
		} else
			CHECK;
	}

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

static void t003(){

int mode;
int ret;
char *data = "a tested property";
XEvent ev;
int 	pass = 0, fail = 0;

 	report_purpose(3);

	report_assertion("Assertion XGetWindowProperty-3.(A)");
	report_assertion("When the specified property exists for the specified window");
	report_assertion("w and the type does not match the specified req_type, then");
	report_assertion("a call to XGetWindowProperty returns the actual property");
	report_assertion("type to actual_type_return, the actual property format to");
	report_assertion("actual_format_return, and the property length in bytes to");
	report_assertion("bytes_after_return, the nitems_return argument is empty,");
	report_assertion("and the delete argument is ignored.");

	report_strategy("Create a window with a property and PropertyChangeMask events selected.");
	report_strategy("For delete_prop of True and False:");
	report_strategy("	Call XGetWindowProperty to obtain the property information.");
	report_strategy("	Verify that the returned values were correct.");
	report_strategy("	Verify that no PropertyNotify events were generated.");

	tpstartup();
	setargs();
/* Create a window with a property and PropertyChangeMask events selected. */
	XChangeProperty(display, w, property, XA_STRING, 8,
		PropModeReplace,(unsigned char *)data, strlen(data));
	XSync(display,True);
	XSelectInput(display, w, PropertyChangeMask);

/* For delete_prop of True and False: */
	for(mode=0; mode<2; mode++) {

/* 	Call xname to obtain the property information. */
		delete_prop = (mode==0?True:False);
		trace("delete_prop is %s", boolname(delete_prop));
		set_vars();
		long_offset = 3;
		long_length = 1;
		req_type = XA_INTEGER;
		startcall(display);
		if (isdeleted())
			return;
		ret = XGetWindowProperty(display, w, property, long_offset, long_length, delete_prop, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return);
		endcall(display);
		if (geterr() != Success) {
			report("Got %s, Expecting Success", errorname(geterr()));
			FAIL;
		}
		XSync(display, False);

/* 	Verify that the returned values were correct. */
		if (ret != Success) {
			FAIL;
			report("%s returned %d (expecting Success (%d))",
				TestName, ret, Success);
		} else
			CHECK;

		if ( check_values( XA_STRING, 8,
			(unsigned long)0, (unsigned long)strlen(data) ) ) {
			CHECK;
		} else
			FAIL;

/* 	Verify that no PropertyNotify events were generated. */
		ret = getevent(display, &ev);
#ifdef TESTING
	ret++;
	ev.type = PropertyNotify;
#endif
		if (ret != 0) {
			FAIL;
			report("%s caused %d unexpected event%s", TestName,
					ret, (ret==1?"":"s"));
			do {
				report("event %s returned", eventname(ev.type));
			} while(getevent(display, &ev) != 0) ;
		} else
			CHECK;
	}

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

static void t004(){

int ret;
int mode;
char *cdata = "a tested property";
unsigned long idata[4];
XEvent ev;
int 	pass = 0, fail = 0;

 	report_purpose(4);

	report_assertion("Assertion XGetWindowProperty-4.(A)");
	report_assertion("When the specified property exists for the specified window");
	report_assertion("w, req_type is set to the type of the property or");
	report_assertion("AnyPropertyType, and delete is set to False, then a call");
	report_assertion("to XGetWindowProperty returns the actual property type to");
	report_assertion("actual_type_return, the actual property format to");
	report_assertion("actual_format_return, the number of trailing unread bytes");
	report_assertion("in the property in bytes_after_return, the number of");
	report_assertion("8/16/32 bit items in nitems_return, the data is placed in");
	report_assertion("prop_return, where the data is sourced from four times");
	report_assertion("long_offset bytes into the property, and is the minimum of");
	report_assertion("the remaining bytes left in the property and four times");
	report_assertion("long_length bytes long, and the property is not deleted.");

	report_strategy("Create a window with testable properties.");
	report_strategy("For req_type is the required type and AnyPropertyType:");
	report_strategy("	Call XGetWindowProperty to obtain the property information of a STRING property,");
	report_strategy("		with delete False.");
	report_strategy("	Verify that the returned values were correct.");
	report_strategy("	Verify that no PropertyNotify events were generated.");
	report_strategy("	Call XGetWindowProperty to obtain the property information of an INTEGER property,");
	report_strategy("		with delete False.");
	report_strategy("	Verify that the returned values were correct.");
	report_strategy("	Verify that no PropertyNotify events were generated.");

	tpstartup();
	setargs();
/* Create a window with testable properties. */
	XChangeProperty(display, w, XA_COPYRIGHT, XA_STRING, 8,
		PropModeReplace, (unsigned char *)cdata, strlen(cdata));

	for( ret=0; ret<4; ret++ )
		idata[ret] = ret;
	XChangeProperty(display, w, XA_NOTICE, XA_INTEGER, 32,
		PropModeReplace, (unsigned char *)idata, 4);

	XSync(display, True);
	XSelectInput(display, w, PropertyChangeMask);

/* For req_type is the required type and AnyPropertyType: */
	for(mode=0; mode<2 ;mode++) {
	
		trace("Calling %s to obtain string information", TestName);
/* 	Call xname to obtain the property information of a STRING property, */
/* 		with delete False. */
		set_vars();
		property = XA_COPYRIGHT;
		long_length = 2; /* Attempt to read 8 bytes from */
		long_offset = 4; /* 16 bytes into the property.   */
				 /* We expect only one byte to be returned. */
		trace("req_type is %s", (mode==0?"STRING":"AnyPropertyType"));
		req_type=(mode==0?XA_STRING:AnyPropertyType);
		startcall(display);
		if (isdeleted())
			return;
		ret = XGetWindowProperty(display, w, property, long_offset, long_length, delete_prop, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return);
		endcall(display);
		if (geterr() != Success) {
			report("Got %s, Expecting Success", errorname(geterr()));
			FAIL;
		}
		XSync(display, False);

/* 	Verify that the returned values were correct. */
		if (ret != Success) {
			FAIL;
			report("%s returned %d (expecting Success (%d))",
				TestName, ret, Success);
		} else
			CHECK;

		if ( check_values( XA_STRING, 8,
				(unsigned long)1, (unsigned long)0 ) ) {
			CHECK;
		} else
			FAIL;

		if (prop == (unsigned char *)NULL) {
			FAIL;
			report("%s returned an unexpected prop_return");
			report("Expected prop_return: unsigned char * pointer");
			report("Returned prop_return: NULL pointer");
		} else
			if (strncmp((char *)prop, "y", 1) != 0) {
				FAIL;
				report("%s returned an unexpected prop_return");
				report("Expected prop_return: 'y'");
				report("Returned prop_return: '%s'", prop);
			} else
				CHECK;

/* 	Verify that no PropertyNotify events were generated. */
		ret = getevent(display, &ev);
		if (ret != 0) {
			FAIL;
			report("%s caused %d unexpected event%s", TestName,
					ret, (ret==1?"":"s"));
			do {
				report("event %s returned", eventname(ev.type));
			} while(getevent(display, &ev) != 0) ;
		} else
			CHECK;

		trace("Calling %s to obtain integer information", TestName);
/* 	Call xname to obtain the property information of an INTEGER property, */
/* 		with delete False. */
		set_vars();
		property = XA_NOTICE;
		long_length = 1; /* Attempt to read 4 bytes from */
		long_offset = 1; /* 4 bytes into the property.   */
				 /* We expect one integer to be returned. */
		trace("req_type is %s", (mode==0?"INTEGER":"AnyPropertyType"));
		req_type=(mode==0?XA_INTEGER:AnyPropertyType);
		startcall(display);
		if (isdeleted())
			return;
		ret = XGetWindowProperty(display, w, property, long_offset, long_length, delete_prop, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return);
		endcall(display);
		if (geterr() != Success) {
			report("Got %s, Expecting Success", errorname(geterr()));
			FAIL;
		}
		XSync(display, False);

/* 	Verify that the returned values were correct. */
		if (ret != Success) {
			FAIL;
			report("%s returned %d (expecting Success (%d))",
				TestName, ret, Success);
		} else
			CHECK;

		if ( check_values( XA_INTEGER, 32,
			(unsigned long)1, (unsigned long)8 ) ) {
			CHECK;
		} else
			FAIL;

		if (prop == (unsigned char *)NULL) {
			FAIL;
			report("%s returned an unexpected prop_return");
			report("Expected prop_return: unsigned char * pointer");
			report("Returned prop_return: NULL pointer");
		} else
			if ( *(unsigned long *)prop != idata[1] ) {
				FAIL;
				report("%s returned an unexpected prop_return");
				report("Expected prop_return: %u", idata[1]);
				report("Returned prop_return: %u",
					*(unsigned long*)prop);
			} else
				CHECK;
		
/* 	Verify that no PropertyNotify events were generated. */
		ret = getevent(display, &ev);
		if (ret != 0) {
			FAIL;
			report("%s caused %d unexpected event%s", TestName,
					ret, (ret==1?"":"s"));
			do {
				report("event %s returned", eventname(ev.type));
			} while(getevent(display, &ev) != 0) ;
		} else
			CHECK;
	}

	CHECKPASS(2*8);

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

static void t005(){

int ret;
int mode;
char *cdata = "a tested property";
unsigned long idata[4];
XEvent ev;
int 	pass = 0, fail = 0;

 	report_purpose(5);

	report_assertion("Assertion XGetWindowProperty-5.(A)");
	report_assertion("When the specified property exists for the specified window");
	report_assertion("w, req_type is set to the type of the property or");
	report_assertion("AnyPropertyType, and delete is set to True, and on a call");
	report_assertion("to XGetWindowProperty the number of unread bytes in the");
	report_assertion("property returned to bytes_after_return is non-zero, then");
	report_assertion("the actual property type is returned to actual_type_return,");
	report_assertion("the actual property format to actual_format_return, the");
	report_assertion("number of trailing unread bytes in the property in");
	report_assertion("bytes_after_return, the number of 8/16/32 bit items in");
	report_assertion("nitems_return, the data is placed in prop_return, where");
	report_assertion("the data is sourced from four times long_offset bytes into");
	report_assertion("the property, and is the minimum of the remaining bytes");
	report_assertion("left in the property and four times long_length bytes long,");
	report_assertion("and the property is not deleted.");

	report_strategy("Create a window with testable properties.");
	report_strategy("For req_type is the required type and AnyPropertyType:");
	report_strategy("	Call XGetWindowProperty to obtain the property information of a STRING property,");
	report_strategy("		with delete True.");
	report_strategy("	Verify that the returned values were correct.");
	report_strategy("	Verify that no PropertyNotify events were generated.");
	report_strategy("	Call XGetWindowProperty to obtain the property information of an INTEGER property,");
	report_strategy("		with delete True.");
	report_strategy("	Verify that the returned values were correct.");
	report_strategy("	Verify that no PropertyNotify events were generated.");

	tpstartup();
	setargs();
/* Create a window with testable properties. */
	XChangeProperty(display, w, XA_COPYRIGHT, XA_STRING, 8,
		PropModeReplace, (unsigned char *)cdata, strlen(cdata));

	for( ret=0; ret<4; ret++ )
		idata[ret] = ret;
	XChangeProperty(display, w, XA_NOTICE, XA_INTEGER, 32,
		PropModeReplace, (unsigned char *)idata, 4);

	XSync(display, True);
	XSelectInput(display, w, PropertyChangeMask);

/* For req_type is the required type and AnyPropertyType: */
	for(mode=0; mode<2 ;mode++) {
	
		trace("Calling %s to obtain string information", TestName);
/* 	Call xname to obtain the property information of a STRING property, */
/* 		with delete True. */
		set_vars();
		property = XA_COPYRIGHT;
		long_length = 1; /* Attempt to read 4 bytes from */
		long_offset = 1; /* 4 bytes into the property.   */
				 /* We expect 4 bytes to be returned. */
		trace("req_type is %s", (mode==0?"STRING":"AnyPropertyType"));
		req_type=(mode==0?XA_STRING:AnyPropertyType);
		delete_prop=True;
		startcall(display);
		if (isdeleted())
			return;
		ret = XGetWindowProperty(display, w, property, long_offset, long_length, delete_prop, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return);
		endcall(display);
		if (geterr() != Success) {
			report("Got %s, Expecting Success", errorname(geterr()));
			FAIL;
		}
		XSync(display, False);

/* 	Verify that the returned values were correct. */
		if (ret != Success) {
			FAIL;
			report("%s returned %d (expecting Success (%d))",
				TestName, ret, Success);
		} else
			CHECK;

		if ( check_values( XA_STRING, 8,
				(unsigned long)4, (unsigned long)9 ) ) {
			CHECK;
		} else
			FAIL;

		if (prop == (unsigned char *)NULL) {
			FAIL;
			report("%s returned an unexpected prop_return");
			report("Expected prop_return: unsigned char * pointer");
			report("Returned prop_return: NULL pointer");
		} else
			if (strncmp((char *)prop, "sted", 1) != 0) {
				FAIL;
				report("%s returned an unexpected prop_return");
				report("Expected prop_return: 'sted'");
				report("Returned prop_return: '%s'", prop);
			} else
				CHECK;

/* 	Verify that no PropertyNotify events were generated. */
		ret = getevent(display, &ev);
		if (ret != 0) {
			FAIL;
			report("%s caused %d unexpected event%s", TestName,
					ret, (ret==1?"":"s"));
			do {
				report("event %s returned", eventname(ev.type));
			} while(getevent(display, &ev) != 0) ;
		} else
			CHECK;

		trace("Calling %s to obtain integer information", TestName);
/* 	Call xname to obtain the property information of an INTEGER property, */
/* 		with delete True. */
		set_vars();
		property = XA_NOTICE;
		long_length = 1; /* Attempt to read 4 bytes from */
		long_offset = 1; /* 4 bytes into the property.   */
				 /* We expect one integer to be returned. */
		trace("req_type is %s", (mode==0?"INTEGER":"AnyPropertyType"));
		req_type=(mode==0?XA_INTEGER:AnyPropertyType);
		delete_prop = True;
		startcall(display);
		if (isdeleted())
			return;
		ret = XGetWindowProperty(display, w, property, long_offset, long_length, delete_prop, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return);
		endcall(display);
		if (geterr() != Success) {
			report("Got %s, Expecting Success", errorname(geterr()));
			FAIL;
		}
		XSync(display, False);

/* 	Verify that the returned values were correct. */
		if (ret != Success) {
			FAIL;
			report("%s returned %d (expecting Success (%d))",
				TestName, ret, Success);
		} else
			CHECK;

		if ( check_values( XA_INTEGER, 32,
			(unsigned long)1, (unsigned long)8 ) ) {
			CHECK;
		} else
			FAIL;

		if (prop == (unsigned char *)NULL) {
			FAIL;
			report("%s returned an unexpected prop_return");
			report("Expected prop_return: unsigned char * pointer");
			report("Returned prop_return: NULL pointer");
		} else
			if ( *(unsigned long *)prop != idata[1] ) {
				FAIL;
				report("%s returned an unexpected prop_return");
				report("Expected prop_return: %u", idata[1]);
				report("Returned prop_return: %u",
					*(unsigned long *)prop);
			} else
				CHECK;
		
/* 	Verify that no PropertyNotify events were generated. */
		ret = getevent(display, &ev);
		if (ret != 0) {
			FAIL;
			report("%s caused %d unexpected event%s", TestName,
					ret, (ret==1?"":"s"));
			do {
				report("event %s returned", eventname(ev.type));
			} while(getevent(display, &ev) != 0) ;
		} else
			CHECK;
	}

	CHECKPASS(2*8);

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

static void t006(){

int mode;
int ret;
char *data="a tested property";
XEvent ev;
int 	pass = 0, fail = 0;

 	report_purpose(6);

	report_assertion("Assertion XGetWindowProperty-6.(A)");
	report_assertion("When the specified property exists for the specified window");
	report_assertion("w, req_type is set to the type of the property or");
	report_assertion("AnyPropertyType, delete is set to True, and on a call to");
	report_assertion("XGetWindowProperty the number of unread bytes in the");
	report_assertion("property returned to bytes_after_return is zero, then the");
	report_assertion("property is deleted from the window w and a PropertyNotify");
	report_assertion("event is generated on the specified window w.");

	report_strategy("Create a window with PropertyChangeMask events selected.");
	report_strategy("For req_type is the required type and AnyPropertyType:");
	report_strategy("	Create a property on the window.");
	report_strategy("	Call XGetWindowProperty to obtain the property information,");
	report_strategy("		with delete True.");
	report_strategy("	Verify that the returned values were correct.");
	report_strategy("	Verify that a single PropertyNotify event was generated.");
	report_strategy("	Verify that the property has been deleted.");

	tpstartup();
	setargs();
/* Create a window with PropertyChangeMask events selected. */
	XSelectInput(display, w, PropertyChangeMask);

/* For req_type is the required type and AnyPropertyType: */
	for(mode=0; mode<2 ;mode++) {

/* 	Create a property on the window. */
		XChangeProperty(display, w, XA_COPYRIGHT, XA_STRING, 8,
			PropModeReplace, (unsigned char *)data, strlen(data));
		XSync(display,True);

/* 	Call xname to obtain the property information, */
/* 		with delete True. */

		set_vars();

		delete_prop = True;
		req_type=(mode==0?XA_STRING:AnyPropertyType);
		long_offset = 3;
		long_length = 2;

		trace("delete_prop is %s", boolname(delete_prop));
		trace("req_type is %s", (mode==0?"STRING":"AnyPropertyType"));
		startcall(display);
		if (isdeleted())
			return;
		ret = XGetWindowProperty(display, w, property, long_offset, long_length, delete_prop, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return);
		endcall(display);
		if (geterr() != Success) {
			report("Got %s, Expecting Success", errorname(geterr()));
			FAIL;
		}
		XSync(display, False);

/* 	Verify that the returned values were correct. */
		if (ret != Success) {
			FAIL;
			report("%s returned %d (expecting Success (%d))",
				TestName, ret, Success);
		} else
			CHECK;

		if ( check_values( XA_STRING, 8,
			(unsigned long)5, (unsigned long)0 ) ) {
			CHECK;
		} else
			FAIL;

/* 	Verify that a single PropertyNotify event was generated. */
		ret = getevent(display, &ev);
		if (ret != 1 || ev.type != PropertyNotify) {
			FAIL;
			report("%s caused %d events", TestName, ret);
			report("Expecting a single PropertyNotify event");
			while(ret != 0) {
				report("Returned: %s event",
					eventname(ev.type));
				ret = getevent(display, &ev);
			}
		} else {
			XEvent good;
			good.type = PropertyNotify;
			good.xproperty.type = PropertyNotify;
			good.xproperty.display = display;
			good.xproperty.serial = 0; /* Can't know */
			good.xproperty.send_event = False;
			good.xproperty.display = display;
			good.xproperty.window = w;
			good.xproperty.atom = XA_COPYRIGHT;
			good.xproperty.time = 0 ; /* Can't know */
			good.xproperty.state = PropertyDelete;

			if (checkevent(&good, &ev) != 0) {
				FAIL;
			} else
				CHECK;
		}

/* 	Verify that the property has been deleted. */
		delete_prop=False;
		startcall(display);
		if (isdeleted())
			return;
		ret = XGetWindowProperty(display, w, property, long_offset, long_length, delete_prop, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return);
		endcall(display);
		if (geterr() != Success) {
			report("Got %s, Expecting Success", errorname(geterr()));
			FAIL;
		}
		
		if ((ret != Success) || !check_values(None, 0,
					(unsigned long)0, (unsigned long)0) ) {
			FAIL;
			report("Property was not deleted.");
		} else
			CHECK;
	}

	CHECKPASS(2*4);

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

static void t007(){

int ret;
char *data = "a tested property";
int 	pass = 0, fail = 0;

 	report_purpose(7);

	report_assertion("Assertion XGetWindowProperty-7.(A)");
	report_assertion("A call to XGetWindowProperty always allocates one extra");
	report_assertion("byte in prop_return and sets it to ASCII NULL.");

	report_strategy("Create a window with a property.");
	report_strategy("Call XGetWindowProperty to obtain property information.");
	report_strategy("Verify that prop_return contained an ASCII NULL.");

	tpstartup();
	setargs();
/* Create a window with a property. */
	XChangeProperty(display, w, property, XA_STRING, 8, PropModeReplace,
			(unsigned char *)data, strlen(data));

/* Call xname to obtain property information. */
	set_vars();
	long_offset=1;
	long_length=0;
	startcall(display);
	if (isdeleted())
		return;
	ret = XGetWindowProperty(display, w, property, long_offset, long_length, delete_prop, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (ret != Success) {
		delete("%s returned %d when expecting %d", ret, Success);
		return;
	} else
		CHECK;

	if (!check_values( XA_STRING, 8,
			(unsigned long)0, (unsigned long)13 )) {
		delete("%s returned unexpected values");
	} else
		CHECK;

/* Verify that prop_return contained an ASCII NULL. */

	if (prop == (unsigned char *)NULL) {
		FAIL;
		report("%s returned an unexpected prop_return", TestName);
		report("Expected prop_return: unsigned char * pointer");
		report("Returned prop_return: NULL pointer");
		return;
	} else
		CHECK;

	if (*prop != (unsigned char)'\0') {
		FAIL;
		report("%s did not allocate an ASCII NULL character beyond");
		report("the prop_return data.");
	} else
		CHECK;
 
	CHECKPASS(4);
	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 t008(){

int 	pass = 0, fail = 0;

 	report_purpose(8);

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

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

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

	A_WINDOW = badwin(A_DISPLAY);

	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGetWindowProperty(display, w, property, long_offset, long_length, delete_prop, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return);
	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 */

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

/* Including from file error/EAto.mc */
static void t009(){

int 	pass = 0, fail = 0;

 	report_purpose(9);

	report_assertion("Assertion XGetWindowProperty-9.(A)");
	report_assertion("When an atom argument does not name a valid Atom, then a");
	report_assertion("BadAtom error occurs.");

	report_strategy("Call test function using a value with the top bits set as the atom argument.");
	report_strategy("Verify that a BadAtom error occurs.");

	tpstartup();
	setargs();
	A_ATOM = ~0L;
	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGetWindowProperty(display, w, property, long_offset, long_length, delete_prop, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return);
	endcall(display);
	if (geterr() != BadAtom) {
		report("Got %s, Expecting BadAtom", errorname(geterr()));
		FAIL;
	}

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

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

static void t010(){

char *data = "a tested property";
int 	pass = 0, fail = 0;

 	report_purpose(10);

	report_assertion("Assertion XGetWindowProperty-10.(A)");
	report_assertion("When XGetWindowProperty is called with long_offset such");
	report_assertion("that the offset lies beyond the end of the property, then a");
	report_assertion("BadValue error occurs.");

	report_strategy("Create a window with a property and PropertyChangeMask events selected.");
	report_strategy("Call XGetWindowProperty with a long_offset beyond the property end.");
	report_strategy("Verify that a BadValue error occurred.");

	tpstartup();
	setargs();
/* Create a window with a property and PropertyChangeMask events selected. */
	XChangeProperty(display, w, property, XA_STRING, 8,
		PropModeReplace,(unsigned char *)data, strlen(data));

	seterrdef();

/* Call xname with a long_offset beyond the property end. */
	long_offset=5;
	long_length=0;

	startcall(display);
	if (isdeleted())
		return;
	ValueReturn = XGetWindowProperty(display, w, property, long_offset, long_length, delete_prop, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return);
	endcall(display);
	if (geterr() != BadValue) {
		report("Got %s, Expecting BadValue", errorname(geterr()));
		FAIL;
	}

/* Verify that a BadValue error occurred. */
	if (geterr() != BadValue) {
		FAIL;
		report("%s did not generate a BadValue when long_offset was",
			TestName);
		report("beyond the length of the property");
	} else
		CHECK;

	CHECKPASS(1);
	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 },
	{ NULL, 0 }
};

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

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