--- /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 */