0N/A/*
0N/A * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
1339N/A *
0N/A * Permission is hereby granted, free of charge, to any person obtaining a
1339N/A * copy of this software and associated documentation files (the "Software"),
0N/A * to deal in the Software without restriction, including without limitation
0N/A * the rights to use, copy, modify, merge, publish, distribute, sublicense,
919N/A * and/or sell copies of the Software, and to permit persons to whom the
919N/A * Software is furnished to do so, subject to the following conditions:
919N/A *
919N/A * The above copyright notice and this permission notice (including the next
919N/A * paragraph) shall be included in all copies or substantial portions of the
919N/A * Software.
919N/A *
919N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
919N/A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
919N/A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
919N/A * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
919N/A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
919N/A * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
919N/A * DEALINGS IN THE SOFTWARE.
919N/A */
919N/A
919N/A#include "libvtsSUNWefb.h"
0N/A
0N/Aefb_info_t efb_info;
0N/A
156N/Aefb_xw_t efb_xw;
493N/A
0N/Astatic gfxtest_info *tests_info;
1339N/A
1339N/A/* Declarations needed for get_tests() */
1339N/A
970N/Astatic uint_t efb_mask_list[] = {
970N/A GRAPHICS_TEST_OPEN,
970N/A GRAPHICS_TEST_DMA,
970N/A GRAPHICS_TEST_MEM,
970N/A GRAPHICS_TEST_CHIP
970N/A};
970N/A
970N/Astatic uint_t efb_mesg_list[] = {
970N/A GRAPHICS_TEST_OPEN_MESG,
970N/A GRAPHICS_TEST_DMA_MESG,
970N/A GRAPHICS_TEST_MEM_MESG,
970N/A GRAPHICS_TEST_CHIP_MESG
970N/A};
970N/A
970N/Astatic gfxtest_function efb_test_list[] = {
970N/A efb_test_open,
970N/A efb_test_dma,
970N/A efb_test_memory,
970N/A efb_test_chip
970N/A};
970N/A
970N/A
970N/A/* *** PUBLIC *** */
970N/A
1339N/A/* These library functions are public and are expected to exist */
970N/A
0N/Aint
950N/Aget_tests(
0N/A register gfxtest_info *const tests)
911N/A{
950N/A /*
950N/A * Set the gfx_vts_debug_mask bits according to environment variables
911N/A */
0N/A gfx_vts_set_debug_mask();
493N/A
493N/A /*
0N/A * Construct the list of tests to be performed
0N/A */
156N/A tests->count = sizeof (efb_test_list) / sizeof (gfxtest_function);
156N/A tests->this_test_mask = (int *)malloc(sizeof (efb_mask_list));
0N/A tests->this_test_mesg = (int *)malloc(sizeof (efb_mesg_list));
0N/A tests->this_test_function =
950N/A (gfxtest_function *)malloc(sizeof (efb_test_list));
950N/A
1466N/A if ((tests->this_test_mask == NULL) ||
950N/A (tests->this_test_mesg == NULL) ||
950N/A (tests->this_test_function == NULL)) {
950N/A gfx_vts_free_tests(tests);
1102N/A return (GRAPHICS_ERR_MALLOC_FAIL);
1160N/A }
1160N/A
364N/A tests->connection_test_function = efb_test_open;
156N/A
156N/A memcpy(tests->this_test_mask, efb_mask_list, sizeof (efb_mask_list));
0N/A memcpy(tests->this_test_mesg, efb_mesg_list, sizeof (efb_mesg_list));
591N/A memcpy(tests->this_test_function, efb_test_list,
947N/A sizeof (efb_test_list));
947N/A
591N/A tests_info = tests;
591N/A return (0);
591N/A
947N/A} /* get_tests() */
947N/A
947N/A
947N/Aint
947N/Acleanup_tests(
947N/A register gfxtest_info *const tests)
947N/A{
947N/A
947N/A TraceMessage(VTS_DEBUG, "cleanup_tests", "call cleanup_tests\n");
947N/A gfx_vts_free_tests(tests);
947N/A
947N/A return (0);
947N/A} /* cleanup_tests() */
947N/A
947N/A
947N/Avoid
0N/Aefb_block_signals(
1446N/A void)
1446N/A{
156N/A sigset_t newprocmask;
493N/A
493N/A sigemptyset(&newprocmask);
837N/A sigaddset(&newprocmask, SIGHUP);
837N/A sigaddset(&newprocmask, SIGINT);
846N/A sigaddset(&newprocmask, SIGTERM);
493N/A sigaddset(&newprocmask, SIGALRM);
156N/A
493N/A sigprocmask(SIG_BLOCK, &newprocmask, &efb_xw.xw_procmask);
493N/A}
493N/A
364N/A
0N/Avoid
493N/Aefb_restore_signals(
493N/A void)
156N/A{
493N/A sigprocmask(SIG_SETMASK, &efb_xw.xw_procmask, (sigset_t *)NULL);
493N/A}
0N/A
1196N/A
1196N/Aint
1196N/Aefb_lock_display(
1196N/A void)
1196N/A{
967N/A if (gfx_vts_debug_mask & GRAPHICS_VTS_SLOCK_OFF) {
967N/A TraceMessage(VTS_DEBUG, "efb_lock_display",
967N/A "efb_lock_display() DISABLED\n");
970N/A return (0);
980N/A }
0N/A
980N/A if (!efb_open_display()) {
339N/A return (0);
970N/A }
970N/A
0N/A efb_create_cursor();
837N/A
837N/A efb_create_window();
838N/A
837N/A XMapRaised(efb_xw.xw_display, efb_xw.xw_window);
837N/A
967N/A TraceMessage(VTS_DEBUG, "efb_lock_display",
967N/A "XMapRaised(display, 0x%lx)\n",
967N/A (ulong_t)efb_xw.xw_window);
779N/A
1467N/A /* Disable server from handling any requests */
838N/A efb_grab_server();
591N/A
967N/A /* Gain control of keyboard */
0N/A efb_grab_keyboard();
0N/A
0N/A /* Gain control of pointer */
0N/A efb_grab_pointer();
591N/A
0N/A efb_disable_screensaver();
339N/A
339N/A efb_disable_dpms();
591N/A
493N/A XSync(efb_xw.xw_display, False);
970N/A
970N/A return (1);
970N/A
970N/A} /* efb_lock_display() */
837N/A
837N/A
967N/Aint
967N/Aefb_unlock_display(
967N/A void)
779N/A{
156N/A if (efb_xw.xw_display == NULL)
156N/A return (0);
967N/A
591N/A XUnmapWindow(efb_xw.xw_display, efb_xw.xw_window);
1183N/A
591N/A TraceMessage(VTS_DEBUG, "efb_unlock_display",
591N/A "XUnmapWindow(display, 0x%lx)\n",
591N/A (ulong_t)efb_xw.xw_window);
935N/A
967N/A efb_restore_dpms();
967N/A
967N/A efb_restore_screensaver();
0N/A
efb_ungrab_pointer();
efb_ungrab_keyboard();
efb_ungrab_server();
XSync(efb_xw.xw_display, False);
efb_check_for_interrupt();
return (1);
}
int
efb_open_display(
void)
{
if (efb_xw.xw_dispname == NULL)
efb_xw.xw_dispname = ":0.0";
if (efb_xw.xw_display == NULL) {
efb_xw.xw_display = XOpenDisplay(efb_xw.xw_dispname);
if (efb_xw.xw_display == NULL) {
TraceMessage(VTS_DEBUG, "efb_open_display",
"XOpenDisplay(\"%s\") = NULL\n"
"Assuming no window system.\n",
efb_xw.xw_dispname);
return (0);
}
TraceMessage(VTS_DEBUG, "efb_open_display",
"XOpenDisplay(\"%s\") = 0x%p\n"
"Assuming a window system.\n",
efb_xw.xw_dispname, efb_xw.xw_display);
}
/* Tell server to report events as they occur */
XSynchronize(efb_xw.xw_display, True);
TraceMessage(VTS_DEBUG, "efb_open_display",
"XSynchronize(display, True).\n");
return (1);
}
int
efb_create_cursor(
void)
{
register Window const root = RootWindow(efb_xw.xw_display,
efb_xw.xw_screen);
register Pixmap emptypixmap;
XColor dummy_color = {0, 0, 0, 0, 0, 0};
if (efb_xw.xw_cursor != 0)
return (0);
emptypixmap = XCreateBitmapFromData(efb_xw.xw_display, root, "", 1, 1);
efb_xw.xw_cursor = XCreatePixmapCursor(efb_xw.xw_display,
emptypixmap, emptypixmap, &dummy_color, &dummy_color, 0, 0);
TraceMessage(VTS_DEBUG, "efb_create_cursor",
"XCreatePixmapCursor(display, 0x%lx, 0x%lx, &dummy_color, "
"&dummy_color, 0, 0) = 0x%lx\n",
(ulong_t)emptypixmap, (ulong_t)emptypixmap,
(ulong_t)efb_xw.xw_cursor);
XFreePixmap(efb_xw.xw_display, emptypixmap);
return (1);
}
int
efb_create_window(
void)
{
register Window const root = RootWindow(efb_xw.xw_display,
efb_xw.xw_screen);
register int const width = DisplayWidth(efb_xw.xw_display,
efb_xw.xw_screen);
register int const height = DisplayHeight(efb_xw.xw_display,
efb_xw.xw_screen);
XSetWindowAttributes xswa;
if (efb_xw.xw_window != NULL)
return (0);
memset(&xswa, 0, sizeof (xswa));
xswa.cursor = efb_xw.xw_cursor;
xswa.background_pixmap = None;
xswa.override_redirect = True;
xswa.backing_store = NotUseful;
xswa.save_under = False;
xswa.event_mask = KeyPressMask | KeyReleaseMask | ExposureMask;
efb_xw.xw_window = XCreateWindow(efb_xw.xw_display,
root, 0, 0, width, height,
0, CopyFromParent, InputOutput, CopyFromParent,
CWBackPixmap | CWOverrideRedirect | CWBackingStore |
CWSaveUnder | CWEventMask | CWCursor, &xswa);
TraceMessage(VTS_DEBUG, "efb_create_window",
"XCreateWindow(display, 0x%lx, %d, %d, %d, %d, "
"%d, %d, %d, %d, 0x%lx, &xswa) = 0x%lx\n",
(ulong_t)root, 0, 0, width, height,
0, CopyFromParent, InputOutput, CopyFromParent,
(ulong_t)(CWBackPixmap | CWOverrideRedirect |
CWBackingStore | CWSaveUnder | CWEventMask | CWCursor),
(ulong_t)efb_xw.xw_window);
XStoreName(efb_xw.xw_display, efb_xw.xw_window, "libvtsSUNWefb");
return (1);
}
int
efb_grab_server(
void)
{
if (efb_xw.xw_grab_server == True)
return (0);
efb_xw.xw_grab_server = XGrabServer(efb_xw.xw_display);
TraceMessage(VTS_DEBUG, "efb_grab_server",
"XGrabServer(display)\n");
return (1);
}
int
efb_ungrab_server(
void)
{
if (efb_xw.xw_grab_server != True)
return (0);
efb_xw.xw_grab_server = !XUngrabServer(efb_xw.xw_display);
TraceMessage(VTS_DEBUG, "efb_ungrab_server",
"XUngrabServer(display)\n");
return (1);
}
int
efb_grab_keyboard(
void)
{
register int status;
if (efb_xw.xw_grab_keyboard == True)
return (0);
status = XGrabKeyboard(efb_xw.xw_display, efb_xw.xw_window,
False, GrabModeAsync, GrabModeAsync, CurrentTime);
efb_xw.xw_grab_keyboard = status == GrabSuccess;
TraceMessage(VTS_DEBUG, "efb_grab_keyboard",
"XGrabKeyboard(display, 0x%lx, %d, %d, %d, %ld) = %d\n",
(ulong_t)efb_xw.xw_window,
False, GrabModeAsync, GrabModeAsync, CurrentTime,
status);
if (status != GrabSuccess) {
TraceMessage(VTS_DEBUG, "efb_grab_keyboard",
"Cannot gain control of keyboard\n");
return (-1);
} else {
return (1);
}
}
int
efb_ungrab_keyboard(
void)
{
register int status;
if (efb_xw.xw_grab_keyboard != True)
return (0);
status = XUngrabKeyboard(efb_xw.xw_display, CurrentTime);
efb_xw.xw_grab_keyboard = False;
TraceMessage(VTS_DEBUG, "efb_ungrab_keyboard",
"XGrabKeyboard(display, %ld) = %d\n",
CurrentTime, status);
return (1);
}
int
efb_grab_pointer(
void)
{
register int status;
if (efb_xw.xw_grab_pointer == True)
return (0);
status = XGrabPointer(efb_xw.xw_display, efb_xw.xw_window,
False, ResizeRedirectMask, GrabModeAsync, GrabModeAsync,
None, efb_xw.xw_cursor, CurrentTime);
efb_xw.xw_grab_pointer = status == GrabSuccess;
TraceMessage(VTS_DEBUG, "efb_grab_pointer",
"XGrabPointer(display, 0x%lx, %d, 0x%lx, %d, %d, "
"%d, %d, %ld) = %d\n",
(ulong_t)efb_xw.xw_window,
False, ResizeRedirectMask,
GrabModeAsync, GrabModeAsync,
None, None, CurrentTime,
status);
if (status != GrabSuccess) {
TraceMessage(VTS_DEBUG, "efb_grab_pointer",
"Cannot gain control of pointer\n");
return (-1);
} else {
return (1);
}
}
int
efb_ungrab_pointer(
void)
{
register int status;
if (efb_xw.xw_grab_pointer != True)
return (0);
status = XUngrabPointer(efb_xw.xw_display, CurrentTime);
efb_xw.xw_grab_pointer = False;
TraceMessage(VTS_DEBUG, "efb_ungrab_pointer",
"XGrabPointer(display, %ld) = %d\n",
CurrentTime, status);
return (1);
}
int
efb_disable_screensaver(
void)
{
XGetScreenSaver(efb_xw.xw_display,
&efb_xw.xw_ss_timeout,
&efb_xw.xw_ss_interval,
&efb_xw.xw_ss_prefer_blanking,
&efb_xw.xw_ss_allow_exposures);
efb_xw.xw_ss_saved = True;
TraceMessage(VTS_DEBUG, "efb_disable_screensaver",
"XGetScreenSaver(display) = %d, %d, %d, %d\n",
efb_xw.xw_ss_timeout,
efb_xw.xw_ss_interval,
efb_xw.xw_ss_prefer_blanking,
efb_xw.xw_ss_allow_exposures);
/* Reset the screen saver to reset its time. */
XResetScreenSaver(efb_xw.xw_display);
efb_xw.xw_ss_disabled = True;
XSetScreenSaver(efb_xw.xw_display,
DisableScreenSaver,
efb_xw.xw_ss_interval,
efb_xw.xw_ss_prefer_blanking,
efb_xw.xw_ss_allow_exposures);
TraceMessage(VTS_DEBUG, "efb_disable_screensaver",
"XSetScreenSaver(display, %d, %d, %d, %d)\n",
DisableScreenSaver,
efb_xw.xw_ss_interval,
efb_xw.xw_ss_prefer_blanking,
efb_xw.xw_ss_allow_exposures);
return (1);
}
int
efb_restore_screensaver(
void)
{
if (efb_xw.xw_ss_saved != True ||
efb_xw.xw_ss_disabled != True) {
efb_xw.xw_ss_disabled = False;
efb_xw.xw_ss_saved = False;
return (0);
} else {
XSetScreenSaver(efb_xw.xw_display,
efb_xw.xw_ss_timeout,
efb_xw.xw_ss_interval,
efb_xw.xw_ss_prefer_blanking,
efb_xw.xw_ss_allow_exposures);
efb_xw.xw_ss_disabled = False;
TraceMessage(VTS_DEBUG, "efb_restore_screensaver",
"XSetScreenSaver(display, %d, %d, %d, %d)\n",
efb_xw.xw_ss_timeout,
efb_xw.xw_ss_interval,
efb_xw.xw_ss_prefer_blanking,
efb_xw.xw_ss_allow_exposures);
efb_xw.xw_ss_saved = False;
return (1);
}
}
int
efb_disable_dpms(
void)
{
/* Disable the X Display Power Management Signaling. */
int status;
int dpms_error = 0;
int dpms_event = 0;
status = DPMSQueryExtension(efb_xw.xw_display,
&dpms_event, &dpms_error);
TraceMessage(VTS_DEBUG, "efb_disable_dpms",
"DPMSQueryExtension(display) = %d, %d, %d\n",
status,
dpms_event,
dpms_error);
if (status != True)
return (-1);
efb_xw.xw_dpms_saved = DPMSInfo(efb_xw.xw_display,
&efb_xw.xw_dpms_power, &efb_xw.xw_dpms_state);
TraceMessage(VTS_DEBUG, "efb_disable_dpms",
"DPMSInfo(display) = %d, %d, %d\n",
efb_xw.xw_dpms_saved,
efb_xw.xw_dpms_power,
efb_xw.xw_dpms_state);
if (efb_xw.xw_dpms_saved != True ||
efb_xw.xw_dpms_state != True)
return (0);
else {
efb_xw.xw_dpms_disabled = True;
DPMSDisable(efb_xw.xw_display);
TraceMessage(VTS_DEBUG, "efb_disable_dpms",
"DPMSDisable(display)\n");
return (1);
}
}
int
efb_restore_dpms(
void)
{
/* Restore the X Display Power Management Signaling. */
if (efb_xw.xw_dpms_saved != True ||
efb_xw.xw_dpms_disabled != True) {
efb_xw.xw_dpms_disabled = False;
efb_xw.xw_dpms_saved = False;
return (0);
} else {
DPMSEnable(efb_xw.xw_display);
efb_xw.xw_dpms_disabled = False;
TraceMessage(VTS_DEBUG, "efb_restore_dpms",
"DPMSEnable(display)\n");
efb_xw.xw_dpms_saved = False;
return (1);
}
}
int
efb_sleep(
uint_t const seconds)
{
register int signo;
struct sigaction oldhup;
struct sigaction oldint;
struct sigaction oldalrm;
struct sigaction oldterm;
struct sigaction newsigact;
sigset_t oldprocmask;
/*
* Allow a SIGHUP, SIGINT, SIGALRM, or SIGTERM to interrupt our
* sleep. These signals should already be masked from a
* call to efb_block_signals.
*/
/* Save the current signals. */
sigaction(SIGHUP, NULL, &oldhup);
sigaction(SIGINT, NULL, &oldint);
sigaction(SIGALRM, NULL, &oldalrm);
sigaction(SIGTERM, NULL, &oldterm);
/* Setup up new signal action. */
newsigact.sa_handler = efb_signal_routine;
sigemptyset(&newsigact.sa_mask);
newsigact.sa_flags = 0;
signo = sigsetjmp(efb_xw.xw_sigjmpbuf, 1);
if (!signo) {
/* First time goes here. */
/* Set signal routines. */
if (oldhup.sa_handler != SIG_IGN)
sigaction(SIGHUP, &newsigact, NULL);
if (oldint.sa_handler != SIG_IGN)
sigaction(SIGINT, &newsigact, NULL);
if (oldalrm.sa_handler != SIG_IGN)
sigaction(SIGALRM, &newsigact, NULL);
if (oldterm.sa_handler != SIG_IGN)
sigaction(SIGTERM, &newsigact, NULL);
/* Unmask SIGHUP, SIGINT, SIGALRM, SIGTERM. */
sigprocmask(SIG_SETMASK, &efb_xw.xw_procmask, &oldprocmask);
sleep(seconds);
/* Mask SIGHUP, SIGINT, SIGALRM, SIGTERM. */
sigprocmask(SIG_SETMASK, &oldprocmask, NULL);
/* Restore the signals. */
if (oldhup.sa_handler != SIG_IGN)
sigaction(SIGHUP, &oldhup, NULL);
if (oldint.sa_handler != SIG_IGN)
sigaction(SIGINT, &oldint, NULL);
if (oldalrm.sa_handler != SIG_IGN)
sigaction(SIGALRM, &oldalrm, NULL);
if (oldterm.sa_handler != SIG_IGN)
sigaction(SIGTERM, &oldterm, NULL);
}
else {
/* We come here from the siglongjmp in efb_signal_routine. */
/* Mask SIGHUP, SIGINT, SIGALRM, SIGTERM. */
sigprocmask(SIG_SETMASK, &oldprocmask, NULL);
/* Restore the signals. */
if (oldhup.sa_handler != SIG_IGN)
sigaction(SIGHUP, &oldhup, NULL);
if (oldint.sa_handler != SIG_IGN)
sigaction(SIGINT, &oldint, NULL);
if (oldalrm.sa_handler != SIG_IGN)
sigaction(SIGALRM, &oldalrm, NULL);
if (oldterm.sa_handler != SIG_IGN)
sigaction(SIGTERM, &oldterm, NULL);
/* Cause us to get the signal, when we unmask the signals. */
kill(getpid(), signo);
return (signo);
}
signo = efb_check_for_interrupt();
return (signo);
}
void
efb_signal_routine(
register int const signo)
{
siglongjmp(efb_xw.xw_sigjmpbuf, signo);
}
/*
* efb_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 *
efb_test_dma(
register int const fd)
{
static return_packet rp;
memset(&rp, 0, sizeof (rp));
TraceMessage(VTS_DEBUG, "efb_test_dma", "Not a DMA device\n");
return (&rp);
} /* efb_test_dma() */
void
graphicstest_finish(
register int const flag)
{
TraceMessage(VTS_DEBUG, "graphicstest_finish",
"call graphicstest_finish\n");
TraceMessage(VTS_DEBUG, "graphicstest_finish",
"call reset_memory_state\n");
cleanup_tests(tests_info);
exit(0);
} /* graphicstest_finish() */
#define CTRL(x) ((x) & 0x1f)
int
efb_check_for_interrupt(
void)
{
register size_t inputlength;
register size_t inputon;
register int ch;
struct sigaction oldint;
struct sigaction oldquit;
XEvent event;
char inputstring[16];
if (efb_xw.xw_display == NULL)
return (0);
while (XPending(efb_xw.xw_display)) {
XNextEvent(efb_xw.xw_display, &event);
if (event.type == KeyPress) {
inputlength = XLookupString(&event.xkey, inputstring,
sizeof (inputstring), NULL, NULL);
for (inputon = 0; inputon < inputlength; inputon++) {
ch = inputstring[inputon];
if (ch == CTRL('c')) {
sigaction(SIGINT, NULL, &oldint);
if (oldint.sa_handler != SIG_IGN) {
kill(getpid(), SIGINT);
return (SIGINT);
}
} else if (ch == CTRL('\\')) {
sigaction(SIGQUIT, NULL, &oldquit);
if (oldquit.sa_handler != SIG_IGN) {
kill(getpid(), SIGQUIT);
return (SIGQUIT);
}
}
}
}
}
return (0);
}
/* End of libvtsSUNWefb.c */