/* $XConsortium: rnd_trans.c,v 1.0 93/11/22 12:40:00 rws Exp $ */

/******************************************************************************/
/*                                                                            */
/*  (c) Copyright Hewlett-Packard Company, 1993, Fort Collins, Colorado       */
/*                                                                            */
/*                            All Rights Reserved                             */
/*                                                                            */
/*  Permission to use, copy, modify, and distribute this software and its     */
/*  documentation for any purpose and without fee is hereby granted,          */
/*  provided that the above copyright notices appear in all copies and that   */
/*  both the copyright notices and this permission notice appear in           */
/*  supporting documentation, and that the name of Hewlett-Packard not be     */
/*  used in advertising or publicity pertaining to distribution of the        */
/*  software without specific, written prior permission.                      */
/*                                                                            */
/*  HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS         */
/*  SOFTWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
/*  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  Hewlett-Packard    */
/*  shall not be liable for errors contained herein or direct, indirect,      */
/*  special, incidental or consequential damages in connection with the       */
/*  furnishing, performance or use of this software.                          */
/*                                                                            */
/******************************************************************************/


/*
******************************************************************************
** Renderer resource state transition test
******************************************************************************
*/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/PEX5/PEXlib.h>

#ifdef XSYSTEM
#include <XSystemTest.h>
#endif

#include <pexutcmap.h>
#include <misc.h>
#include <common_hp.h>
#include <err_handler.h>

#include "rnd_utils.h"

#ifdef XSYSTEM
XSystemTestingControlStructure xtc;
#endif


#ifdef XSYSTEM
#define WIDTH 256
#define HEIGHT 256
#else
#define WIDTH 200
#define HEIGHT 200
#endif

static PEXViewport fullframe_data[]={
	{ {0, 0, 0.0},				{WIDTH, HEIGHT, 1.0},		True,	{ 0,0,0 }	},
};

#define NUM_WINDOWS 3
#define BAD_WINDOW_ID 52


#define IDLE		0
#define	RENDERING	1
#define PICK_ONE	2
#define PICK_ALL	3

/*
	This table describes expected values when
	various state transitions are attempted.
*/
static struct _state_value {
	int initial_set_state;
	int initial_expected_state;
	int begin_expected_error_type;
	int begin_expected_error_code;
	int begin_expected_state;
	int end_expected_error_type;
	int end_expected_error_code;
	int end_expected_state;
} state_values[]={

	{ IDLE, PEXIdle,
		NO_ERR, 0, PEXRendering,
		NO_ERR, 0, PEXIdle },
	{ RENDERING, PEXRendering,
		PEX_ERR, BadPEXRendererState, PEXRendering,
		NO_ERR, 0, PEXIdle },
	{ PICK_ONE, PEXPicking,
		PEX_ERR, BadPEXRendererState, PEXRendering,
		PEX_ERR, BadPEXRendererState, PEXPicking },
	{ PICK_ALL, PEXPicking,
		PEX_ERR, BadPEXRendererState, PEXRendering,
		PEX_ERR, BadPEXRendererState, PEXPicking },
};


#define VIEWPORT					0
#define PIPELINE_CONTEXT_ATTR		1
#define NUM_ATTRS 					2

#define NOT_A_RESOURCE		0
#define RESOURCE_ID			1
#define RESOURCE_CONTENTS	2

static struct _attr_info {
	int image_per_setting;
	int subframe_per_setting;
	int last_subframe_in_image;
	int suppress_clear_after_image;
	int resource_attr_type;
	XID *resource_id_attr;
	int resource_RA_bit;
	int lut_type;
	char *attr_name;
} attr_control[]={

	/* VIEWPORT */					{ True, False, False, False,
									NOT_A_RESOURCE, NULL, PEXRAViewport, 0,
									"Viewport" },
	/* PIPELINE_CONTEXT */			{ False, False, False, False,
									RESOURCE_ID, NULL, PEXRAPipelineContext, 0,
									"Pipeline Context ID" },
};

static struct _viewport_value {
	PEXViewport value;
	char *message;
} viewport_values[]={
	{ { {0, 0, 0.0},				{WIDTH, HEIGHT, 1.0},	False,	{ 0,0,0 }	},
	"First viewport value: Full-window viewport" },
	{ { {WIDTH/2, HEIGHT/2, 0.0},	{WIDTH, HEIGHT, 1.0},	False,	{ 0,0,0 }	},
	"Second viewport value: Viewport in upper-right quarter of window" },
};

static struct _plcattr_value {
	PEXEnumTypeIndex	line_type;
	PEXBitmask			asf_enables;
	PEXBitmask			asf_values;
	char *message;
} plcattr_values[]={
	{ PEXLineTypeSolid, 	PEXASFLineType,	PEXASFLineType,
	"First PLC value: Solid line type" },
	{ PEXLineTypeDashed,  	PEXASFLineType,	0,
	"Second PLC value: Dashed line type" },
};


main(argc, argv)
int argc;
char **argv;
{
	Display *display;
	Window window;
	Window windows[NUM_WINDOWS];
	PEXRenderer renderer;
	PEXRendererAttributes set_attrs, expected_attrs;
	unsigned long value_mask;
	PEXExtensionInfo *ext_info;

	char title[256];

	PEXUtWindowSpecification  window_info;
	PEXUtVisualCriteria       criteria;
	Atom                      prop_atom;
	XColor                    returned_background;
	XEvent                    event;
	unsigned int              unmet;
	int                       status;
	XVisualInfo 				vis_info;
	XStandardColormap 			cmap_info;
	PEXColorApproxEntry 		capx_info;
	int 						screen;
	XSizeHints                	hints;

	PEXElementRef current_path_elems;
	PEXStructure structure, substructure;
	long client_structure;
	PEXPickRecord pick_aperture;
	int pick_status, more_hits, nd_hits;
	unsigned long pick_path_count;
	PEXPickPath *pick_paths;

    XVisualInfo       	*visuals;
    int     		  	num_visuals;
    XVisualInfo       	vis_templ;
    unsigned int      	vis_mask;

	int i, j;
	int value_index, trans, state, attr;
	int image_number = 0;

	PEXCoord points[2];
	PEXPipelineContext pipeline_context;
	PEXPCAttributes plc_attrs;

	char *image_desc, image_msg[256];
	char image_name[80], test_name[80];

#ifdef XSYSTEM
    int XSystemValues[20];
#endif

    int			pexmode = 0;
	int			image_depth = 0;

#ifdef XSYSTEM
	openXSystemTesting(argc, argv, &xtc, 0, 0);
#else
    /* Handle other arguments. */
    if (parse_options (argc, argv, &pexmode, &image_depth))
	exit (1);
#endif

    _hppex_set_stderr("rnd_trans.stderr", "rnd_trans");

	describe_test("\n\n");
	describe_test("This is a test of PEXlib Renderer state transitions, in two parts.\n");

	describe_test("The first part tests binding the Renderer to multiple windows in succession,\n");
	describe_test("handling a PEXBegin* call when already active, and handling an inappropriate\n");
	describe_test("PEXEnd* for the current state.  Most of these conditions result in\n");
	describe_test("PEXBadRendererState errors, which are trapped and checked.  This part of the\n");
	describe_test("test does not generate images.  It succeeds if no messages starting with ERROR\n");
	describe_test("are printed to stderr.\n\n");

	describe_test("The second part of the test makes sure that if a Renderer attribute is changed,\n");
	describe_test("the change is effective on each of several windows that the Renderer might\n");
	describe_test("be bound to.  Actually, only a representative Pipeline Context attribute\n");
	describe_test("(line style), and a representative non-resource attribute (viewport), are tested\n\n");

	describe_test("The second part of the test generates images.  To demonstrate the viewport\n");
	describe_test("change, a rectangle is drawn that outlines the NPC subvolume.  To demonstrate\n");
	describe_test("the Pipeline Context change, a horizontal line is drawn.\n\n");

	describe_test("A third part of the test makes sure that primitives are not drawn when the\n");
	describe_test("Renderer is Idle.  This also generates one image.\n\n");

#ifdef XSYSTEM
	if (xtc.interactiveFramePrompt)
#else
	if (glob_verbose_mode && getenv("PAUSE"))
#endif
		prompt_user ("Hit return to continue with the test", "");

#ifndef XSYSTEM
    if (glob_verbose_mode)
	    fflush (stdout);
#endif


	/*
		Initialize X and PEX, and create two windows and a Renderer.
	*/

#ifdef XSYSTEM
    display = xtc.display;
#else
	if (NULL == (display = XOpenDisplay (NULL))) {

		_hppex_stderr_print( "PROCESS ERROR:  XOpenDisplay failed on %s\n", getenv("DISPLAY"));
		exit (1);
	}
#endif

	if (PEXInitialize (display, &ext_info, 0, NULL))
	{
		_hppex_stderr_print( "PROCESS ERROR:  PEXInitialize failed on %s\n", getenv("DISPLAY"));
		exit (1);
	}

	_hppex_test_init_error_handler();

	/*
		Create a window.
	*/

	strcpy (title, "Rnd Transition #0");
	screen = DefaultScreen(display);
	hints.x      = 100;
	hints.y      = 100;
	hints.width  = WIDTH;
	hints.height = HEIGHT;
	hints.flags  = (USSize|USPosition);

	window_info.attr_mask             = CWEventMask;
	window_info.attrs.event_mask      = ExposureMask;
	window_info.title                 = title;
	window_info.size_hints            = hints;
	window_info.parent                = RootWindow (display, screen);
	window_info.border_width          = 0;
	window_info.background_color_name = "black";
	window_info.border_color_name     = "white";
	
	if (image_depth == 0)
	{
		char *depth;

		if (depth = getenv("TEST_IMAGE_DEPTH"))
			{
			image_depth = atoi(depth);
			}
	}

	if (image_depth == 0)
	{
		criteria.hard_criteria_mask = PEXUtMinColors;
		criteria.soft_criteria_mask = PEXUtDepth | 
					  PEXUtStandardColormapProperty;
		criteria.depth = 24;
	}
	else
	{
		criteria.hard_criteria_mask = PEXUtMinColors | PEXUtDepth;
		criteria.soft_criteria_mask = PEXUtStandardColormapProperty;
		criteria.depth = image_depth;
	}

	criteria.min_colors = 2;
	criteria.standard_colormap_property = True;

	status = PEXUtCreateWindowAndColormap (display, screen,
					   &criteria,
					   &window_info, &(windows[0]),
					   &vis_info, &cmap_info, &capx_info,
					   &unmet, &prop_atom,
					   &returned_background);

	if ((status != PEXUtSuccess) &&
		(status != PEXUtQualifiedSuccess)) {
	    fprintf (stderr,
		    "PROCESS ERROR:  First window creation failed\n");
		exit (1);
	}

	window = windows[0];
	XSetWindowColormap(display, window, cmap_info.colormap);
#ifdef XSYSTEM
	XInstallColormap(display, cmap_info.colormap);
#endif
	XMapWindow(display, window);
	XFlush(display);

	/* Wait for the first exposure */
	XSelectInput( display, window, ExposureMask);
	XNextEvent(display, &event);

#ifdef XSYSTEM
    XSystemValues[0] = WINDOW_SMART_HW_CONFIG;
    XSystemValues[1] = windows[0];
    XSystemValues[2] = -1;
    defineXSystemTestControlParm(&xtc, ARCHIVE_MODE, XSystemValues);
#endif

	/*
		Create more windows (assume to be using same 
		colormap and visual).
	*/
	hints.x += 300;

	window_info.attr_mask             = CWColormap;
	window_info.attrs.colormap = cmap_info.colormap;

	for (i=1; i<NUM_WINDOWS; i++) {

		sprintf (title, "Rnd Transition #%d", i);

		window_info.size_hints = hints;
		status = PEXUtCreateWindow ( display, screen,
							&window_info,
							&vis_info,
							&(windows[i]),
							&returned_background);

		if ((status != PEXUtSuccess) &&
			(status != PEXUtQualifiedSuccess)) {

			_hppex_stderr_print( "PROCESS ERROR:  Window creation #%d failed\n", i);
			exit (1);
		}

		XMapWindow(display, windows[i]);
		XFlush(display);

		hints.y += HEIGHT + 50;
	}



	/*
		Create a Renderer.
	*/
	window = windows[0];
	renderer = PEXCreateRenderer (display, window, 0, NULL);
	if (renderer == None) {

		_hppex_stderr_print( "PROCESS ERROR: PEXCreateRenderer failed\n");
		exit (1);
	}

	/*
		Set up Renderer to clear image and Z planes.
	*/
	set_renderer_clear_flags (display, renderer, True, 0.0, 0.0, 0.0);


	/*
		Try a bad drawable ID in BeginRendering.
	*/
	_hppex_stderr_print( "\n\n");
	_hppex_stderr_print( "About to try PEXBeginRendering with a bad Window ID.\n");
	_hppex_test_set_expected_error (X_ERR, BadDrawable, 0, 0, 0);
	PEXBeginRendering (display, BAD_WINDOW_ID, renderer);
	XSync (display, 0);
	if (_hppex_test_check_expected_error (ERROR_CODE)) {
		_hppex_stderr_print( "\twhile calling PEXBeginRendering with a bad drawable\n");
	}
	_hppex_stderr_print( "\n\n");


	
	/*
		If more than one visual is supported on the screen,
		try BeginRendering with a drawable for a different target than
		the Renderer was created for.
	*/
    vis_templ.screen = screen;
    vis_mask = VisualScreenMask;

    if ((NULL != (visuals = XGetVisualInfo(display, vis_mask, &vis_templ, &num_visuals))) &&
		(num_visuals > 1)) {

		int i;
		PEXColorApproxEntry dummy_capx_info;
		XStandardColormap dummy_cmap_info;
		Window dummy_window;
		Colormap cmap_id;
		Atom dummy_prop_atom;

		for (i=0; i<num_visuals; i++)
			if (visuals[i].visualid != vis_info.visualid)
				break;

		status = PEXUtGetStandardColormapInfo (display,  
							&(visuals[i]),
							&dummy_cmap_info,
							&dummy_capx_info,
							&dummy_prop_atom);

		status = PEXUtCreateColormap (display, 
							&(visuals[i]),  
							&dummy_capx_info, 
							&cmap_id);

		hints.x = 700;
		hints.y = 100;
		hints.width = 200;
		hints.height = 100;
		hints.flags = (USSize|USPosition);

		window_info.attr_mask = CWColormap;
		window_info.attrs.colormap = cmap_id;
		window_info.size_hints = hints;
		window_info.title = "Rnd Transition Extra";

		status = PEXUtCreateWindow ( display, screen,
							&window_info,
							&(visuals[i]),
							&dummy_window,
							&returned_background);

		if ((status != PEXUtSuccess) &&
			(status != PEXUtQualifiedSuccess)) {

			_hppex_stderr_print( "PROCESS ERROR:  Extra window creation failed\n");
			exit (1);
		}

		XMapWindow(display, dummy_window);
		XFlush(display);

		_hppex_test_set_expected_error (X_ERR, BadMatch, 0, 0, 0);
		PEXBeginRendering (display, dummy_window, renderer);
		XSync (display, 0);
		if (_hppex_test_check_expected_error (ERROR_CODE)) {
			_hppex_stderr_print( "\twhile calling PEXBeginRendering with an inappropriate target \n");
			_hppex_stderr_print( "\n\n");
		}
		PEXEndRendering (display, renderer, False);

		XDestroyWindow(display, dummy_window);
		XFreeColormap (display, cmap_id);
		XFree (visuals);
	}

	
	/*
		Make sure Renderer can be bound to more than one window, more than
		one time in succession.
	*/
	for (i = 0; i<2; i++) {

		_hppex_test_set_expected_error (NO_ERR, 0, 0, 0, 0);

		for (j=0; j<NUM_WINDOWS; j++) {
			PEXBeginRendering (display, windows[j], renderer);
			XSync (display, 0);
			if (_hppex_test_check_expected_error (ERROR_CODE)) {
				_hppex_stderr_print( "\twhile calling PEXBeginRendering with window %d\n", j);
				_hppex_stderr_print( "\n\n");
			}
			PEXEndRendering (display, renderer, True);
			XSync (display, 0);
			if (_hppex_test_check_expected_error (ERROR_CODE)) {
				_hppex_stderr_print( "\twhile calling PEXEndRendering with window %d\n", j);
				_hppex_stderr_print( "\n\n");
			}
		}
	}


	/*
		Make sure that BeginRendering succeeds regardless of current Renderer state,
		and that EndRendering is a no-op except when in Rendering state.
	*/

	window = windows[0];
	client_structure = 52;
	pick_aperture.volume.min.x = 0.0;
	pick_aperture.volume.min.y = 0.0;
	pick_aperture.volume.min.z = 0.0;
	pick_aperture.volume.max.x = 0.0;
	pick_aperture.volume.max.y = 0.0;
	pick_aperture.volume.max.z = 0.0;

	for (trans = 0; trans < 2; trans++) {
		for (state = 0; state < 4; state++) {

			_hppex_test_set_expected_error (NO_ERR, 0, 0, 0, 0);
			expected_attrs.renderer_state = state_values[state].initial_expected_state;

			switch (state_values[state].initial_set_state) {

			case IDLE:
			break;

			case RENDERING:
			PEXBeginRendering (display, window, renderer);
			break;

			case PICK_ONE:
			PEXBeginPickOne (display, window, renderer, client_structure,
							PEXPickLast,
							PEXPickDeviceNPCHitVolume, &pick_aperture);
			break;

			case PICK_ALL:
			PEXBeginPickAll (display, window, renderer, client_structure,
							PEXPickAllAll, True, 5, 
							PEXPickDeviceNPCHitVolume, &pick_aperture);
			break;
			}

			XSync (display, 0);
			if (_hppex_test_check_expected_error(ERROR_CODE) ||
				(check_renderer_attrs (display, renderer,
								&expected_attrs, PEXRARendererState))) {
				_hppex_stderr_print( "\twhile attempting to enter state %d\n", 
									state_values[state].initial_expected_state);
				_hppex_stderr_print( "\n\n");
			}

			switch (trans) {

			case 0: 
				/* Do BeginRendering while in the initial state */
				_hppex_test_set_expected_error (state_values[state].begin_expected_error_type,
									state_values[state].begin_expected_error_code, 0, 0, 0);
				expected_attrs.renderer_state = state_values[state].begin_expected_state;

				PEXBeginRendering (display, window, renderer);

				XSync (display, 0);
				if (_hppex_test_check_expected_error(ERROR_CODE) ||
					(check_renderer_attrs (display, renderer,
									&expected_attrs, PEXRARendererState))) {
					_hppex_stderr_print( "\twhile attempting to do BeginRendering from state %d\n", 
										state_values[state].initial_expected_state);
					_hppex_stderr_print( "\n\n");
				}
				PEXEndRendering (display, renderer, True);
				break;

			case 1: 
				/* Do EndRendering while in the initial state */
				_hppex_test_set_expected_error (state_values[state].end_expected_error_type,
									state_values[state].end_expected_error_code, 0, 0, 0);
				expected_attrs.renderer_state = state_values[state].end_expected_state;

				PEXEndRendering (display, renderer, True);

				XSync (display, 0);
				if (_hppex_test_check_expected_error(ERROR_CODE) ||
					(check_renderer_attrs (display, renderer,
									&expected_attrs, PEXRARendererState))) {
					_hppex_stderr_print( "\twhile attempting to do EndRendering from state %d\n", 
										state_values[state].initial_expected_state);
					_hppex_stderr_print( "\n\n");
				}

				_hppex_test_set_expected_error (PEX_ERR, BadPEXRendererState, 0, 0, 0);
				PEXBeginRendering (display, window, renderer);
				PEXEndRendering (display, renderer, True);
				XSync (display,0);
				break;
			}
		}
	}
	_hppex_test_set_expected_error (NO_ERR, 0, 0, 0, 0);


	/*
		For a variety of attributes, make sure that installation of a new
		attribute value is done for each of several windows.
	*/

	/* clear all the windows */
	for (i=0; i < NUM_WINDOWS; i++) {
		PEXBeginRendering (display, windows[i], renderer);
		PEXEndRendering (display, renderer, True);
	}

	for (attr=0; attr<NUM_ATTRS; attr++) {
		unsigned long plc_mask[3];
		float y_offset;

		set_attrs.viewport = fullframe_data[0];
		PEXChangeRenderer (display, renderer, PEXRAViewport, &set_attrs);

		/* create resources if necessary */
		switch (attr) {

		case VIEWPORT:
#ifndef XSYSTEM
			if (glob_verbose_mode)
#endif
			printf ("Testing Renderer viewport attribute change\n");
			break;

		case PIPELINE_CONTEXT_ATTR:
#ifndef XSYSTEM
			if (glob_verbose_mode)
#endif
			printf ("Testing pipeline context attribute change\n");

			plc_mask[0] = 0;
			plc_mask[1] = 0;
			plc_mask[2] = 0;
			pipeline_context = PEXCreatePipelineContext (display, plc_mask, NULL);
			set_attrs.pipeline_context = pipeline_context;
			PEXChangeRenderer (display, renderer, PEXRAPipelineContext, &set_attrs);
			break;
		}

		/* for each value for the attribute, set the value while the Renderer is not bound */
		y_offset = 0.2;
		for (value_index=0; value_index < 2; value_index++) {

			switch (attr) {

			case VIEWPORT:
				set_attrs.viewport = viewport_values[value_index].value;
				image_desc = viewport_values[value_index].message;
				PEXChangeRenderer (display, renderer, PEXRAViewport, &set_attrs);
				break;

			case PIPELINE_CONTEXT_ATTR:
				plc_attrs.line_type = plcattr_values[value_index].line_type;
				image_desc = plcattr_values[value_index].message;
				PEXSetPCAttributeMask (plc_mask, PEXPCLineType);
				PEXChangePipelineContext (display, pipeline_context, plc_mask, &plc_attrs);
				break;
			}
#ifndef XSYSTEM
			if (glob_verbose_mode)
#endif
			printf ("%s\n", image_desc);

			for (i=0; i<NUM_WINDOWS; i++) {

#ifndef XSYSTEM
			if (glob_verbose_mode)
#endif
				printf ("Demonstrating attribute change on window %d\n", i);

				PEXBeginRendering (display, windows[i], renderer);

				switch (attr) {

				case VIEWPORT:
					/*
						Draw a hollow rectangle at the NPC limits;
						shows size of viewport assuming NPC refitted
						as expected.
					*/
					draw_primitive (display, renderer, PEXOCRender,
									RECTANGLE,
									0.0, 0.0, 0.0,
									1.0, 1.0, 0.0);
					break;

				case PIPELINE_CONTEXT_ATTR:
					draw_primitive (display, renderer, PEXOCRender,
									LINE,
									0.2, y_offset, 0.0,
									0.6, 0.0, 0.0);
					break;
				}

				PEXEndRendering (display, renderer, True);
			}
			y_offset += 0.2;

			/* capture image of each window */
			XSync (display, 0);
			for (i=0; i<NUM_WINDOWS; i++) {
#ifdef XSYSTEM
				strcpy (image_msg, "ERROR: ");
				strcat (image_msg, image_desc);

				XSystemValues[0] = WINDOW_SMART_EXTENT;
				XSystemValues[1] = windows[i];
				defineXSystemTestControlParm(&xtc, ARCHIVE_EXTENT, XSystemValues);

				XSystemCheck(image_msg, &xtc);
#else
				sprintf(image_name,"rnd_trans_%d", image_number);
				sprintf(test_name, "rnd_trans #%d", image_number);
				 image_testproc(image_name, test_name, img_desc,
								  display, windows[i], 0, 0,
								  WIDTH, HEIGHT);
#endif
				image_number++;
			}
#ifdef XSYSTEM
			printf ("\n");
#endif
		}

		switch (attr) {

		case PIPELINE_CONTEXT_ATTR:
			PEXFreePipelineContext (display, pipeline_context);
			set_attrs.pipeline_context = None;
			PEXChangeRenderer (display, renderer, PEXRAPipelineContext, &set_attrs);
			break;
		}
	}


	/*
		Check whether a typical OC behaves correctly across
		Renderer state transitions.
	*/

#ifndef XSYSTEM
	if (glob_verbose_mode) {
#endif
		printf ("Demonstrating that primitives are disabled when Renderer is Idle\n");
		printf ("Image should only contain two horizontal lines, in the center\n");
#ifndef XSYSTEM
	}
#endif

	window = windows[0];
	points[0].x = 0.2;
	points[1].x = 0.8;
	points[0].z = 0.0;
	points[1].z = 0.0;

	/* clear the window */
	PEXBeginRendering (display, window, renderer);
	PEXEndRendering (display, renderer, True);
	set_renderer_clear_flags (display, renderer, False, 0.0, 0.0, 0.0);
	
	points[0].y = 0.1;
	points[1].y = 0.1;
	PEXPolyline (display, renderer, PEXOCRender, 2, points);
	points[0].y = 0.2;
	points[1].y = 0.2;
	PEXPolyline (display, renderer, PEXOCRender, 2, points);

	PEXBeginRendering (display, window, renderer);

	points[0].y = 0.3;
	points[1].y = 0.3;
	PEXPolyline (display, renderer, PEXOCRender, 2, points);
	points[0].y = 0.4;
	points[1].y = 0.4;
	PEXPolyline (display, renderer, PEXOCRender, 2, points);

	PEXEndRendering (display, renderer, True);

	points[0].y = 0.5;
	points[1].y = 0.5;
	PEXPolyline (display, renderer, PEXOCRender, 2, points);
	points[0].y = 0.6;
	points[1].y = 0.6;
	PEXPolyline (display, renderer, PEXOCRender, 2, points);
	
	/* capture image of window */
	XSync (display, 0);
#ifdef XSYSTEM
    XSystemValues[0] = WINDOW_SMART_EXTENT;
    XSystemValues[1] = window;
    defineXSystemTestControlParm(&xtc, ARCHIVE_EXTENT, XSystemValues);

	XSystemCheck("ERROR: OC stream across Renderer state changes", &xtc);
	printf ("\n");
#else
	sprintf(image_name,"rnd_trans_%d", image_number);
	sprintf(test_name, "rnd_trans #%d", image_number);
	 image_testproc(image_name, test_name, img_desc,
					  display, window, 0, 0,
					  WIDTH, HEIGHT);
#endif
	image_number++;

	/*
		Close Renderer, windows, and X/PEX.
	*/
	PEXFreeRenderer(display, renderer);
	for (i=0; i < NUM_WINDOWS; i++)
		XDestroyWindow(display, windows[i]);

    _hppex_close_stderr();

#ifdef XSYSTEM
    closeXSystemTesting(&xtc);
#else
    file_testproc("rnd_trans.stderr", "rnd_trans");
	XCloseDisplay (display);
	exit(0);
#endif

} /* renderer state transition test */