/*
* 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.
* 
*/
/*
 * SYNOPSIS:
 *   void
 *   XMoveWindow(display, w, x, y)
 *   Display	*display;
 *   Window	w;
 *   int	x;
 *   int	y;
 */


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

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


/*
 * Arguments to the XMoveWindow function
 */
static Display	*display;
static Window	w;
static int	x;
static int	y;



/* The structure that is used as the default argument to the function. */
static XWindowChanges	winchng;

/*
 * Convenience routine that sets the 'w' argument to be simple window
 * with a background of W_FG at position (10,8) and * size 10x9.
 * The border width is 0.
 */
#define	OW_X	10
#define	OW_Y	8
#define	OW_WIDTH	23
#define	OW_HEIGHT	9

#define	NEW_X	OW_X+5
#define	NEW_Y	OW_Y+5


static	Window
onewin()
{
Window	base;
struct	area	area;

	base = defwin(display);
	setarea(&area, OW_X, OW_Y, OW_WIDTH, OW_HEIGHT);

	w = crechild(display, base, &area);
	XSetWindowBackground(display, w, W_FG);
	XClearWindow(display, w);

	return(base);
}


/*
 * Window tree for the restacking operations.
 */
static char	*Tstack[] = {
	". borders",
	"bottom . (30,2) 60x34",
	"A . (10,5) 30x20",
	"B . (15, 10) 30x20",
	"mid . (20, 15) 30x20",
	"C . (25, 20) 30x20",
	"D . (30, 25) 30x20",
	"alone . (50,50) 20x20",	/* does not overlap with any window */
	"olmid . (3,32) 20x20",	/* Overlaps mid */
	"top . (5,80) 19x4",
};
#define	NTstack	(NELEM(Tstack))

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 = 0;
	x = 0;
	y = 0;
}

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

static void t001(){

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

 	report_purpose(1);

	report_assertion("Assertion XMoveWindow-1.(A)");
	report_assertion("A call to XMoveWindow moves the window so that the");
	report_assertion("coordinates of the upper-left outer corner of the window are");
	report_assertion("x, y relative to the origin of the parent window.");

	report_strategy("Create test window with background of W_FG.");
	report_strategy("Set x and y.");
	report_strategy("Call XMoveWindow.");
	report_strategy("Verify that window has moved on screen with checkarea().");

	tpstartup();
	setargs();
	base = onewin();

	setarea(&area, 20, 50, OW_WIDTH, OW_HEIGHT);
	x = area.x;
	y = area.y;

	startcall(display);
	if (isdeleted())
		return;
	XMoveWindow(display, w, x, y);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (checkarea(display, base, &area, W_FG, W_BG, CHECK_ALL))
		CHECK;
	else {
		report("Error in moving window");
		FAIL;
	}

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

static void t002(){

XImage	*imp;
int 	pass = 0, fail = 0;

 	report_purpose(2);

	report_assertion("Assertion XMoveWindow-2.(A)");
	report_assertion("When the window is moved and the window is mapped and the");
	report_assertion("window is not obscured by non-children, then the current");
	report_assertion("window contents are not lost.");

	report_strategy("Create window.");
	report_strategy("Draw pattern in window.");
	report_strategy("Move window without a size change.");
	report_strategy("Verify that window contents are unchanged.");

	tpstartup();
	setargs();
	onewin();

	pattern(display, w);

	x = NEW_X;
	y = NEW_Y;

	imp = savimage(display, w);

	startcall(display);
	if (isdeleted())
		return;
	XMoveWindow(display, w, x, y);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (compsavimage(display, w, imp))
		CHECK;
	else {
		report("Window contents affected by moving window");
		FAIL;
	}

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

/* Including from file Mdefcode.tmc.3980 */
static void t003(){

int 	pass = 0, fail = 0;

 	report_purpose(3);

	report_assertion("Assertion XMoveWindow-3.(D)");
	report_assertion("When the window is moved and the window is mapped and");
	report_assertion("backing store is being maintained for the window, then the");
	report_assertion("current window contents are not lost.");
	report_assertion("Reason for omission: There is no known reliable test method for this assertion");

	report_strategy("Report UNTESTED");

	tpstartup();
	setargs();
	UNTESTED;
	tpcleanup();
	pfcount(pass, fail);
}

/* End of included file Mdefcode.tmc.3980 */

static void t004(){

Window	base;
Display	*client2;
struct	buildtree	*bt;
int 	i;
int 	pass = 0, fail = 0;

 	report_purpose(4);

	report_assertion("Assertion XMoveWindow-4.(A)");
	report_assertion("When a call to XMoveWindow uncovers part of any window that");
	report_assertion("was formerly obscured, then either Expose events are");
	report_assertion("generated or the contents are restored from backing store.");

	report_strategy("Create windows.");
	report_strategy("Create second client to receive events on.");
	report_strategy("Call setforexpose() on unobscured window.");
	report_strategy("Create other windows to partially obscure this window.");
	report_strategy("Reconfigure window with XMoveWindow, ensuring that first window is now unobscured.");
	report_strategy("Verify for correct expose or backing store behaviour with exposecheck().");

	tpstartup();
	setargs();
	base = defwin(display);
	setforexpose(display, base);

	bt = buildtree(display, base, Tstack, NTstack);

	client2 = opendisplay();
	XSelectInput(client2, base, ExposureMask);
	XSync(client2, False);

	/*
	 * This loop will throw all the subwindows outside the borders of the
	 * parent window.
	 */
	x = W_STDWIDTH+9000;
	for (i = 1; i < NTstack; i++) {
		w = bt[i].wid;
		startcall(display);
		if (isdeleted())
			return;
		XMoveWindow(display, w, x, y);
		endcall(display);
		if (geterr() != Success) {
			report("Got %s, Expecting Success", errorname(geterr()));
			FAIL;
		}
	}
	XSync(client2, False);

	if (exposecheck(client2, base))
		CHECK;
	else {
		report("Neither Expose events or backing store processing");
		report("  could correctly restore the window contents.");
		FAIL;
	}
	CHECKPASS(1);
	tpcleanup();
	pfcount(pass, fail);
}

static void t005(){

int 	pass = 0, fail = 0;

 	report_purpose(5);

	report_assertion("Assertion XMoveWindow-5.(A)");
	report_assertion("When the window is a root window, then a call to");
	report_assertion("XMoveWindow has no effect.");

	report_strategy("Call XMoveWindow on root window.");
	report_strategy("Touch test only.");

	tpstartup();
	setargs();
	w = DefaultRootWindow(display);

	startcall(display);
	if (isdeleted())
		return;
	XMoveWindow(display, w, x, y);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if (fail == 0)
		PASS;
	tpcleanup();
	pfcount(pass, fail);
}

static void t006(){

Window	base;
XConfigureRequestEvent	good;
XSetWindowAttributes	setatts;
Display	*client2;
XEvent	ev;
XImage	*imp;
int 	n;
int 	pass = 0, fail = 0;

 	report_purpose(6);

	report_assertion("Assertion XMoveWindow-6.(A)");
	report_assertion("When the override-redirect flag of the window is False and");
	report_assertion("some other client has selected SubstructureRedirectMask on");
	report_assertion("the parent window, then a ConfigureRequest event is");
	report_assertion("generated, and the window position is not changed.");

	report_strategy("Create windows.");
	report_strategy("Set override-redirect to False.");
	report_strategy("Create second client.");
	report_strategy("Select SubstructureRedirectMask for second client on parent of window.");
	report_strategy("Set some parameters.");
	report_strategy("Call XMoveWindow.");
	report_strategy("Verify that a ConfigureRequest event is generated.");
	report_strategy("Verify that window configuration has not changed on the screen.");

	tpstartup();
	setargs();
	base = onewin();

	setatts.override_redirect = False;
	XChangeWindowAttributes(display, w, CWOverrideRedirect, &setatts);

	client2 = opendisplay();
	XSelectInput(client2, base, SubstructureRedirectMask);
	XSync(client2, False);

	x = NEW_X;
	y = NEW_Y;

	good.type = ConfigureRequest;
	good.serial = 0L;
	good.send_event = False;
	good.display = client2;
	good.parent = base;
	good.window = w;
	good.x = NEW_X;
	good.y = NEW_Y;
	good.width = OW_WIDTH;
	good.height = OW_HEIGHT;
	good.border_width = 0;
	good.above = None;
	good.detail = Above;
	good.value_mask = CWX | CWY;

	imp = savimage(display, base);

	startcall(display);
	if (isdeleted())
		return;
	XMoveWindow(display, w, x, y);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	XSync(client2, False);

	n = getevent(client2, &ev);
	if (n != 1) {
		report("Expecting 1 event");
		FAIL;
	} else
		CHECK;

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

	if (compsavimage(display, base, imp))
		CHECK;
	else {
		report("Screen contents changed");
		FAIL;
	}

	CHECKPASS(3);

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

static void t007(){

XConfigureEvent	good;
XEvent	ev;
int 	n;
int 	pass = 0, fail = 0;

 	report_purpose(7);

	report_assertion("Assertion XMoveWindow-7.(A)");
	report_assertion("When the position actually changes, then a ConfigureNotify");
	report_assertion("event is generated.");

	report_strategy("Create windows.");
	report_strategy("Enable SubstructureNotify events.");
	report_strategy("Call XMoveWindow such that the window configuration changes.");
	report_strategy("Verify that a ConfigureNotify event is generated.");
	report_strategy("Call XMoveWindow again with the same parameters.");
	report_strategy("Verify that no ConfigureNotify event is generated.");

	tpstartup();
	setargs();
	onewin();

	XSelectInput(display, w, StructureNotifyMask);

	x = NEW_X;
	y = NEW_Y;

	startcall(display);
	if (isdeleted())
		return;
	XMoveWindow(display, w, x, y);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	good.type = ConfigureNotify;
	good.serial = 0L;
	good.send_event = False;
	good.display = display;
	good.event = w;
	good.window = w;
	good.x = NEW_X;
	good.y = NEW_Y;
	good.width = OW_WIDTH;
	good.height = OW_HEIGHT;
	good.border_width = 0;
	good.above = None;
	good.override_redirect = False;

	n = getevent(display, &ev);
	if (n != 1) {
		report("Expecting 1 event, got %d", n);
		FAIL;
	} else
		CHECK;
	if (n > 0 && checkevent((XEvent*)&good, &ev) == 0)
		CHECK;
	else
		FAIL;

	/* Call again */
	startcall(display);
	if (isdeleted())
		return;
	XMoveWindow(display, w, x, y);
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}
	if ((n = XPending(display)) == 0)
		CHECK;
	else {
		report("Received event when configuration was not changed");
		FAIL;
	}

	CHECKPASS(3);

	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 XMoveWindow-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;
	XMoveWindow(display, w, x, y);
	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 },
	{ NULL, 0 }
};

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

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