open-src/app/gfx-utils/sun-src/vts/ast/libvtsSUNWast.c
changeset 1117 629ac4b133bc
child 1407 72726c775cc9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/app/gfx-utils/sun-src/vts/ast/libvtsSUNWast.c	Mon Apr 25 14:22:03 2011 -0700
@@ -0,0 +1,534 @@
+/*
+ * Copyright (c) 2006, 2009, Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>		/* MAXPATHLEN */
+#include <errno.h>
+#include <pwd.h>		/* getpwuid() */
+#include <signal.h>
+#include <stdio.h>		/* snprintf() */
+#include <stdlib.h>		/* exit(), malloc() */
+#include <string.h>		/* strcat(), strcpy() */
+#include <unistd.h>		/* sleep() */
+#include <sys/fbio.h>
+#include <sys/mman.h>
+#include <sys/systeminfo.h>	/* sysinfo() */
+#include <sys/visual_io.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include "graphicstest.h"
+#include "gfx_vts.h"		/* VTS Graphics Test common routines */
+
+#include "libvtsSUNWast.h"	/* VTS library definitions for ast device */
+
+
+#if (0)	/* Unused */
+#define	NO_DMA			0
+#define	USE_DMA			1
+#endif
+
+#define	MAX_DISPLAY_LEN		261
+
+
+static int		no_window = 1;
+static gfxtest_info	*tests_info;
+static int		received_control_c = 0;
+static int		need_screen_lock = 1;
+static Display		*dpy = NULL;
+
+
+/* Declarations needed for get_tests() */
+
+static unsigned int ast_mask_list[] = {
+	GRAPHICS_TEST_OPEN,
+	GRAPHICS_TEST_DMA,
+	GRAPHICS_TEST_MEM,
+	GRAPHICS_TEST_CHIP
+};
+
+static unsigned int ast_mesg_list[] = {
+	GRAPHICS_TEST_OPEN_MESG,
+	GRAPHICS_TEST_DMA_MESG,
+	GRAPHICS_TEST_MEM_MESG,
+	GRAPHICS_TEST_CHIP_MESG
+};
+
+static gfxtest_function ast_test_list[] = {
+	ast_test_open,
+	ast_test_dma,
+	ast_test_memory,
+	ast_test_chip
+};
+
+
+static void
+disable_pm(Display *dpy)
+{
+	int		dummy;
+
+	XSetScreenSaver(dpy, 0, 0, 0, 0);
+	if (DPMSQueryExtension(dpy, &dummy, &dummy)) {
+	    DPMSDisable(dpy);
+	}
+	if (FBPMQueryExtension(dpy, &dummy, &dummy)) {
+	    FBPMDisable(dpy);
+	}
+
+}	/* disable_pm() */
+
+
+int
+lock_display(int fd, Display** current_display)
+{
+	char		env_buf[5 + MAXPATHLEN]; /* "HOME=<pw_dir>" */
+	int		i;
+	int		screen;
+	Display		*dpy;
+	Window		win;
+	XSetWindowAttributes xswa;
+	char		hostname[MAX_DISPLAY_LEN];
+	char		display[MAX_DISPLAY_LEN];
+	struct sigaction act;
+	int		current_screen;
+	struct hostent	*Host;
+	struct passwd	*pw_entry;
+	int		status;
+	char		no_bits[] = { 0 };
+	XColor		dumcolor;
+	Pixmap		lockc;
+	Pixmap		lockm;
+	Cursor		cursor;
+
+	pw_entry = getpwuid(0);
+	if (strlen(pw_entry->pw_dir) >= MAXPATHLEN) {
+	    TraceMessage(VTS_DEBUG, __func__,
+			    "HOME= directory path is too long\n");
+	    return (1);
+	}
+	strcpy(env_buf, "HOME=");
+	strcat(env_buf, pw_entry->pw_dir);
+	if (putenv(env_buf) != 0) {
+	    TraceMessage(VTS_DEBUG, __func__,
+			    "putenv( HOME= ) failed, errno:%d\n", errno);
+	    return (1);
+	}
+
+	dpy = NULL;
+
+	if (gfx_vts_debug_mask & GRAPHICS_VTS_SLOCK_OFF) {
+	    TraceMessage(VTS_DEBUG, __func__, "lock_display() DISABLED\n");
+	    need_screen_lock = 0;
+	    *current_display = NULL;
+	    return (0);
+	}
+
+	current_screen = 0;
+
+	TraceMessage(VTS_DEBUG, __func__, "locking X screen %d\n",
+		    current_screen);
+
+#if (0)
+	/* Get the host machine name */
+	if (sysinfo(SI_HOSTNAME, hostname, MAX_DISPLAY_LEN) == -1) {
+	    TraceMessage(VTS_DEBUG, __func__,
+			"sysinfo(2) failed getting hostname\n");
+	    hostname[0] = '\0';
+	}
+#else
+	hostname[0] = '\0';
+#endif
+
+	snprintf(display, sizeof (display), "%s:0.%d",
+		hostname, current_screen);
+	dpy = XOpenDisplay(display);
+	TraceMessage(VTS_DEBUG, __func__,
+		    "XOpenDisplay, display = %s, dpy = 0x%p\n", display, dpy);
+
+	if (dpy == NULL) {
+	    TraceMessage(VTS_DEBUG, __func__, "Assuming no window_system\n");
+	    return (0);
+	}
+
+	TraceMessage(VTS_DEBUG, __func__,
+		    "XOpenDisplay successful, display = %s, dpy = 0x%p\n",
+		    display, dpy);
+
+	screen = DefaultScreen(dpy);
+
+	/*
+	 * Flush request buffer and wait for all requests to be processed
+	 */
+	XSync(dpy, False);
+
+	/* Tell server to report events as they occur */
+	XSynchronize(dpy, True);
+
+	disable_pm(dpy);
+
+	/* Create a blank cursor */
+	lockc = XCreateBitmapFromData(dpy, RootWindow(dpy, 0),
+					no_bits, 1, 1);
+	lockm = XCreateBitmapFromData(dpy, RootWindow(dpy, 0),
+					no_bits, 1, 1);
+	cursor = XCreatePixmapCursor(dpy, lockc, lockm, &dumcolor,
+					&dumcolor, 0, 0);
+
+	XFreePixmap(dpy, lockc);
+	XFreePixmap(dpy, lockm);
+
+	xswa.cursor = cursor;
+	xswa.override_redirect = True;
+	xswa.event_mask = (KeyPressMask | KeyReleaseMask | ExposureMask);
+	no_window = 0;
+	win = XCreateWindow(dpy,
+			    RootWindow(dpy, screen),
+			    0, 0,
+			    DisplayWidth(dpy, current_screen),
+			    DisplayHeight(dpy, current_screen),
+			    0,
+			    CopyFromParent,
+			    InputOutput,
+			    CopyFromParent,
+			    CWOverrideRedirect | CWEventMask, &xswa);
+
+	TraceMessage(VTS_DEBUG, __func__, " XCreateWindow win=%d\n", win);
+
+	XMapWindow(dpy, win);
+	XRaiseWindow(dpy, win);
+	TraceMessage(VTS_DEBUG, __func__, " no_window=%d\n", no_window);
+
+	if (!no_window) {
+	    /* Disable server from handling any requests */
+	    XGrabServer(dpy);
+	    /* Gain control of keyboard */
+	    status = XGrabKeyboard(dpy, win, False, GrabModeAsync,
+				   GrabModeAsync, CurrentTime);
+
+	    if (status != GrabSuccess) {
+		TraceMessage(VTS_DEBUG, __func__,
+			    "Cannot gain control of keyboard\n");
+	    }
+
+	    status = XGrabPointer(dpy,
+				win,
+				False,
+				ResizeRedirectMask,
+				GrabModeAsync,
+				GrabModeAsync,
+				None,
+				cursor,
+				CurrentTime);
+	    if (status != GrabSuccess) {
+		TraceMessage(VTS_DEBUG, __func__,
+			    "Cannot gain control of pointer\n");
+	    }
+	}
+
+	sleep(2);
+	*current_display = dpy;
+	return (0);
+
+}	/* lock_display() */
+
+void
+unlock_display(Display *dpy)
+{
+	if (dpy) {
+		XUngrabPointer(dpy, CurrentTime);
+		XUngrabKeyboard(dpy, CurrentTime);
+		XUngrabServer(dpy);
+	}
+}
+
+
+/* *** PUBLIC *** */
+
+/* These library functions are public and are expected to exist */
+
+int
+get_tests(gfxtest_info *tests)
+{
+	return_packet *ast_test_open(int fd);
+
+	/*
+	 * Set the gfx_vts_debug_mask bits according to environment variables
+	 */
+	gfx_vts_set_debug_mask();
+
+	/*
+	 * Disable screen lock by default
+	 */
+	gfx_vts_debug_mask |= GRAPHICS_VTS_SLOCK_OFF;
+
+	/*
+	 * Construct the list of tests to be performed
+	 */
+	tests->count = sizeof (ast_test_list) / sizeof (gfxtest_function);
+	tests->this_test_mask = (int *)malloc(sizeof (ast_mask_list));
+	tests->this_test_mesg = (int *)malloc(sizeof (ast_mesg_list));
+	tests->this_test_function =
+			(gfxtest_function *)malloc(sizeof (ast_test_list));
+
+	if ((tests->this_test_mask     == NULL) ||
+	    (tests->this_test_mesg     == NULL) ||
+	    (tests->this_test_function == NULL)) {
+	    gfx_vts_free_tests(tests);
+	    return (GRAPHICS_ERR_MALLOC_FAIL);
+	}
+
+	tests->connection_test_function = ast_test_open;
+
+	memcpy(tests->this_test_mask, ast_mask_list, sizeof (ast_mask_list));
+	memcpy(tests->this_test_mesg, ast_mesg_list, sizeof (ast_mesg_list));
+	memcpy(tests->this_test_function, ast_test_list,
+						sizeof (ast_test_list));
+
+	tests_info = tests;
+	return (0);
+
+}	/* get_tests() */
+
+
+int
+cleanup_tests(gfxtest_info *tests)
+{
+
+	TraceMessage(VTS_DEBUG, __func__, "call cleanup_tests\n");
+	gfx_vts_free_tests(tests);
+
+	if (need_screen_lock) {
+	    unlock_display(dpy);
+	}
+
+}	/* cleanup_tests() */
+
+
+/*
+ * ast_test_open()
+ *
+ *    This test will open the device, read and write some registers
+ *    after mmaping in the register and frame buffer spaces.
+ */
+
+return_packet *
+ast_test_open(int fd)
+{
+	static return_packet rp;
+	int		rc = 0;
+	struct vis_identifier vis_identifier;
+
+	if (need_screen_lock) {
+	    lock_display(fd, &dpy);
+	}
+
+	/* setup */
+	memset(&rp, 0, sizeof (return_packet));
+
+	if (gfx_vts_check_fd(fd, &rp)) {
+	    return (&rp);
+	}
+
+	TraceMessage(VTS_TEST_STATUS, __func__, "check_fd passed.\n");
+
+	/* vis identifier will do this */
+	rc = ioctl(fd, VIS_GETIDENTIFIER, &vis_identifier);
+
+	TraceMessage(VTS_TEST_STATUS, __func__, "rc = %d\n", rc);
+
+	if (rc != 0) {
+	    gfx_vts_set_message(&rp, 1, GRAPHICS_ERR_OPEN, NULL);
+	    return (&rp);
+	}
+
+	if (strncmp(vis_identifier.name, "SUNWast", 7) != 0) {
+	    gfx_vts_set_message(&rp, 1, GRAPHICS_ERR_OPEN, NULL);
+	    return (&rp);
+	}
+
+	map_me(&rp, fd);
+
+	TraceMessage(VTS_DEBUG, __func__, "Open completed OK\n");
+
+	check4abort(dpy);
+	return (&rp);
+
+}	/* ast_test_open() */
+
+
+/*
+ * ast_test_dma
+ *
+ *    This test will open the device, allocate the dma buffers to
+ *    separate memory spaces, and read/write the data, verifying it.
+ */
+
+return_packet *
+ast_test_dma(int fd)
+{
+	static return_packet rp;
+	int		i;
+
+	TraceMessage(VTS_DEBUG, __func__, "ast_test_dma running\n");
+
+	if (need_screen_lock) {
+	    lock_display(fd, &dpy);
+	}
+
+	dma_test(&rp, fd);
+
+	TraceMessage(VTS_DEBUG, __func__, " ast_test_dma completed\n");
+
+	check4abort(dpy);
+	return (&rp);
+
+}	/* ast_test_dma() */
+
+
+/*
+ * ast_test_memory()
+ *
+ *    This test will open the device and read and write to all memory
+ *    addresses.
+ */
+
+return_packet *
+ast_test_memory(int fd)
+{
+	static return_packet rp;
+
+	TraceMessage(VTS_DEBUG, __func__, " ast_test_memory running\n");
+
+	if (gfx_vts_debug_mask & GRAPHICS_VTS_MEM_OFF) {
+	    return (&rp);
+	}
+
+	if (need_screen_lock) {
+	    lock_display(fd, &dpy);
+	}
+
+	memory_test(&rp, fd);
+
+	TraceMessage(VTS_DEBUG, __func__, " ast_test_memory completed\n");
+
+	check4abort(dpy);
+	return (&rp);
+
+}	/* ast_test_memory() */
+
+
+/*
+ * ast_test_chip()
+ *
+ *    Test Chip, functional tests.
+ */
+
+return_packet *
+ast_test_chip(int fd)
+{
+	static return_packet rp;
+
+	if (gfx_vts_debug_mask & GRAPHICS_VTS_CHIP_OFF) {
+	    return (&rp);
+	}
+	TraceMessage(VTS_DEBUG, __func__, " ast_test_chip running\n");
+
+	if (need_screen_lock) {
+	    lock_display(fd, &dpy);
+	}
+
+	chip_test(&rp, fd);
+
+	TraceMessage(VTS_DEBUG, __func__, " ast_test_chip completed\n");
+
+	check4abort(dpy);
+	return (&rp);
+
+}	/* ast_test_chip() */
+
+
+void
+graphicstest_finish(int flag)
+{
+
+	TraceMessage(VTS_DEBUG, __func__, "call graphicstest_finish\n");
+
+	TraceMessage(VTS_DEBUG, __func__, "call reset_memory_state\n");
+
+	cleanup_tests(tests_info);
+
+	exit(0);
+
+}	/* graphicstest_finish() */
+
+
+/*
+ * check4abort()
+ *
+ *    This function sends a KILL signal to the program if it detects
+ *    that the user has pressed ^C.  This functionality is usually
+ *    performed by the Command Tool which spawned a program, but in this
+ *    case we need to do it because we have grabbed all keyboard events.
+ *    It should be called anywhere where it's safe to end the program.
+ */
+
+void
+check4abort(Display *dpy)
+{
+#define	CTRL_C	'\003'			/* Ctrl-C (^C) */
+
+	/*
+	 * If necessary, restore the original state following a test
+	 */
+#if !defined(VTS_STUBS)
+	chip_test_reset();
+#endif
+
+	if (dpy != NULL) {
+#if !defined(VTS_STUBS)
+	    while (XPending(dpy)) {
+		XEvent	event;		/* Key event structure */
+		int	i;		/* Loop counter / keystr[] index */
+		char	keystr[5] = "";	/* Buffer for returned string */
+		int	len;		/* Length of returned string */
+
+		XNextEvent(dpy, &event);
+		if (event.type == KeyPress) {
+		    len = XLookupString((XKeyEvent *)&event,
+					keystr, sizeof (keystr),
+					NULL, NULL);
+		    for (i = 0; i < len; i++) {
+			if (keystr[i] == CTRL_C) {
+			    kill(getpid(), SIGINT);
+			    graphicstest_finish(0);
+			}
+		    }
+		}
+	    }
+#endif	/* VTS_STUBS */
+	}
+
+}	/* check4abort() */
+
+
+/* End of libvtsSUNWast.c */