/*
* 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.
* 
*/
/*
 * SYNOPSIS:
 *   char *
 *   XGetDefault(display, program, option)
 *   Display	*display;
 *   char	*program;
 *   char	*option;
 */


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

/*
 * Defines for different argument types
 */
#define A_DISPLAY display


/*
 * Arguments to the XGetDefault function
 */
static Display	*display;
static char	*program;
static char	*option;


#include	"X11/Xatom.h"

extern char **environ;

static void
t003exec()
{
char	*argv[2];
char	*envp;

	argv[0] = "./Test3";
	argv[1] = (char *) NULL;
	envp = "HOME=./";
	if (xtest_putenv( envp )) {
		delete("xtest_putenv failed to add HOME to the environment");
		return;
	}
	tet_exec("./Test3", argv, environ);
	delete("tet_exec() of \"./Test3\" failed.");
}


static void
t004exec()
{
char	*argv[2];
char	*envp;

	argv[0] = "./Test4";
	argv[1] = NULL;
	envp = "XENVIRONMENT=./EnvXdefaults";
	if (xtest_putenv(envp)) {
		delete("xtest_putenv failed to add XENVIRONMENT to the environment");
	}

	tet_exec("./Test4", argv, environ);
	delete("tet_exec() of \"./Test4\" failed.");
}



static void
t005exec()
{
char	*argv[2];
char	*envp;

	argv[0] = "./Test5";
	argv[1] = (char *) NULL;
	envp = "HOME=.";
	if (xtest_putenv(envp)) {
		delete("xtest_putenv failed to add HOME to the environment");
		return;
	}

	if (getenv("XENVIRONMENT") != NULL) {
		char **newenv = environ; /* Remove XENVIRONMENT */
	
		trace("Removing XENVIRONMENT from environment");

		while( strncmp("XENVIRONMENT=", *newenv, 13)
			&& *newenv != NULL )
			newenv++;

		if (*newenv == NULL) {
			report("could not remove XENVIRONMENT from the environment");
			UNRESOLVED;
			return;
		}

		do {
			*newenv = *(newenv+1);
			newenv++;
		} while ( *newenv != NULL );
	}
	tet_exec("./Test5", argv, environ);
	delete("tet_exec() of \"./Test5\" failed.");
}

int 	tet_thistest;

/*
 * Called at the beginning of each test purpose to reset the
 * arguments to their initial values
 */
static void
setargs()
{
	display = Dsp;
	program = 0;
	option = 0;
}

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

static void t001(){

unsigned char 	*pval = (unsigned char *) "VAL*VAl\nXT.LEO:CAL\nXT.OPT:VAL\nXT.Bezoomny:Cal\n";
char		*valstr;
char		*res = (char *) NULL;
int 	pass = 0, fail = 0;

 	report_purpose(1);

	report_assertion("Assertion XGetDefault-1.(A)");
	report_assertion("A call to XGetDefault reads and returns from the resource");
	report_assertion("manager database the entry specified by the program and");
	report_assertion("option arguments.");

	report_strategy("Set the RESOURCE_MANAGER property on the default root window of screen 0 to contain the string XT.OPT.VAL");
	report_strategy("Open a display using XOpenDisplay.");
	report_strategy("Obtain the value of the XT.OPT resource using XGetDefault.");
	report_strategy("Verify that the returned value is \"OPT\".");

	tpstartup();
	setargs();
	valstr = "VAL";

	XChangeProperty (Dsp, RootWindow(Dsp, 0), XA_RESOURCE_MANAGER, XA_STRING, 8, PropModeReplace, pval, 1+strlen((char *)pval));
	XSync(Dsp, False);

	display = opendisplay();
	program = "XT";
	option  = "OPT";
	startcall(display);
	if (isdeleted())
		return;
	res = XGetDefault(display, program, option);	
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if(res == (char *) NULL) {
		report("%s() returned NULL.", TestName);
		FAIL;
	} else {
		CHECK;

		if(strcmp(res, valstr) != 0) {
			report("%s() retured \"%s\" instead of \"%s\"", TestName, res, valstr);
			FAIL;
		} else
			CHECK;
	}

	CHECKPASS(2);

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

static void t002(){

unsigned char 	*pval = (unsigned char *) "XT.LEO:CAL\nXT.OPT:VAL\nXT.Bezoomny:Cal\n";
char		*nullstr = "<NULL>";
char		*res = NULL;
int 	pass = 0, fail = 0;

 	report_purpose(2);

	report_assertion("Assertion XGetDefault-2.(A)");
	report_assertion("When the option specified by the program and option");
	report_assertion("arguments does not exist in the resource manager database,");
	report_assertion("then a call to XGetDefault returns NULL.");

	report_strategy("Set the RESOURCE_MANAGER property on the default root window to contain some valid strings not containing XT.Cal*");
	report_strategy("Open a display using XOpenDisplay.");
	report_strategy("Obtain the value of the XT.Cal resource using XGetDefault.");
	report_strategy("Verify that the call returned NULL.");

	tpstartup();
	setargs();

	XChangeProperty (Dsp, RootWindow(Dsp, 0), XA_RESOURCE_MANAGER, XA_STRING, 8, PropModeReplace, pval, 1+strlen((char *)pval));
	XSync(Dsp, False);

	display = opendisplay();
	program = "XT";
	option  = "Cal";
	startcall(display);
	if (isdeleted())
		return;
	res = XGetDefault(display, program, option);	
	endcall(display);
	if (geterr() != Success) {
		report("Got %s, Expecting Success", errorname(geterr()));
		FAIL;
	}

	if(res != (char *) NULL) {
		report("%s() retured \"%s\" instead of \"%s\"", TestName, res, nullstr);
		FAIL;
	} else
		PASS;

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

static void t003(){

int 	pass = 0, fail = 0;

 	report_purpose(3);

	report_assertion("Assertion XGetDefault-3.(C)");
	report_assertion("If the system is POSIX compliant: When the RESOURCE_MANAGER");
	report_assertion("property was defined at the time display was opened, then");
	report_assertion("the default resource manager database is taken from the");
	report_assertion("value of that property, otherwise the default resource");
	report_assertion("manager database is taken from the file $HOME/.Xdefaults in");
	report_assertion("the client's home directory.");

	report_strategy("Fork a new  process using tet_fork.");
	report_strategy("In the child process:");
	report_strategy("   Execute the file ./Test3 using tet_exec with the HOME environment variable set to \".\".");
	report_strategy("   In Test3:");
	report_strategy("      Delete the RESOURCE_MANAGER property using XDeleteProperty.");
	report_strategy("      Open a new display using XOpenDisplay.");
	report_strategy("      Obtain the value of the XTest.testval32 resource using XGetDefault.");
	report_strategy("      Verify that the returned value is \"VAL_b\".");
	report_strategy("      Set the RESOURCE_MANAGER property using XChangeProperty.");
	report_strategy("      Open a new display using XOpenDisplay.");
	report_strategy("      Obtain the value of the XTest.testval32 resource using XGetDefault.");
	report_strategy("      Verify that the returned value is \"pval_b\".");

	tpstartup();
	setargs();
	if(config.posix_system == 0)
		unsupported("This assertion can only be tested on a POSIX system.");
	else
		tet_fork(t003exec, TET_NULLFP, 0, ~0);

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

static void t004(){

int 	pass = 0, fail = 0;

 	report_purpose(4);

	report_assertion("Assertion XGetDefault-4.(C)");
	report_assertion("If the system is POSIX compliant: When the XENVIRONMENT");
	report_assertion("environment variable is defined, then the file named by the");
	report_assertion("XENVIRONMENT environment variable is merged to update the");
	report_assertion("default resource database.");

	report_strategy("Fork a new process using tet_fork.");
	report_strategy("In the child process:");
	report_strategy("   Execute the file ./Test4 using tet_exec with the XENVIRONMENT variable set to ./EnvXdefaults.");
	report_strategy("   In Test4:");
	report_strategy("      Set the RESOURCE_MANAGER property using XChangeProperty.");
	report_strategy("      Open a display using XOpenDisplay.");
	report_strategy("      Obtain the value of resources set by the ChangeProperty request and by the XENVIRONMENT file using XGetDefault.");
	report_strategy("      Verify that the resources are set from each source.");
	report_strategy("      Verify that the XENVIRONMENT resources updated those of the ChangeProperty request.");

	tpstartup();
	setargs();
	if(config.posix_system == 0)
		unsupported("This assertion can only be tested on a POSIX system.");
	else
		tet_fork(t004exec, TET_NULLFP, 0, ~0);

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

static void t005(){

int 	pass = 0, fail = 0;

 	report_purpose(5);

	report_assertion("Assertion XGetDefault-5.(C)");
	report_assertion("If the system is POSIX compliant: When the XENVIRONMENT");
	report_assertion("environment variable is not defined, then the file");
	report_assertion("$HOME/.Xdefaults-<name> is merged to update the default");
	report_assertion("resource database, where <name> specifies the name of the");
	report_assertion("machine on which the application is running.");

	report_strategy("Fork a new process using tet_fork.");
	report_strategy("In the child process:");
	report_strategy("   Remove XENVIRONMENT from the environment");
	report_strategy("   Execute the file ./Test5 using tet_exec with the HOME variable set to \".\".");
	report_strategy("   In Test5:");
	report_strategy("      Set the RESOURCE_MANAGER property using XChangeProperty.");
	report_strategy("      Open a display using XOpenDisplay.");
	report_strategy("      Obtain the value of resources set by the ChangeProperty request and by the file $HOME/.Xdefaults-<name> using XGetDefault.");
	report_strategy("      Verify that the resources are set from each source.");
	report_strategy("      Verify that the .Xdefaults-<name> resources updated those of the ChangeProperty request.");

	tpstartup();
	setargs();
	if(config.posix_system == 0)
		unsupported("This assertion can only be tested on a POSIX system.");
	else
		tet_fork(t005exec, TET_NULLFP, 0, ~0);

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

/* End of Test Cases */


struct tet_testlist tet_testlist[] = {
	{ t001, 1 },
	{ t002, 2 },
	{ t003, 3 },
	{ t004, 4 },
	{ t005, 5 },
	{ NULL, 0 }
};

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

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