Add the OGLESBasicTnL sample for Linux.
Change-Id: I0c0a9bc99e8cf9ea92919c77ef6c05b1439f40da
Reviewed-on: https://swiftshader-review.googlesource.com/4941
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/SwiftShader.workspace b/src/SwiftShader.workspace
index bceebc3..fe7f333 100644
--- a/src/SwiftShader.workspace
+++ b/src/SwiftShader.workspace
@@ -13,5 +13,9 @@
<Depends filename="OpenGL/libEGL/libEGL.cbp" />
<Depends filename="OpenGL/libGLESv2/libGLESv2.cbp" />
</Project>
+ <Project filename="../tests/third_party/PowerVR/Examples/Beginner/04_BasicTnL/OGLES/Build/OGLESBasicTnL.cbp">
+ <Depends filename="OpenGL/libEGL/libEGL.cbp" />
+ <Depends filename="OpenGL/libGLES_CM/libGLES_CM.cbp" />
+ </Project>
</Workspace>
</CodeBlocks_workspace_file>
diff --git a/tests/third_party/PowerVR/Examples/Beginner/04_BasicTnL/OGLES/Build/OGLESBasicTnL.cbp b/tests/third_party/PowerVR/Examples/Beginner/04_BasicTnL/OGLES/Build/OGLESBasicTnL.cbp
new file mode 100644
index 0000000..dd5f835
--- /dev/null
+++ b/tests/third_party/PowerVR/Examples/Beginner/04_BasicTnL/OGLES/Build/OGLESBasicTnL.cbp
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+ <FileVersion major="1" minor="6" />
+ <Project>
+ <Option title="OGLESBasicTnL" />
+ <Option pch_mode="2" />
+ <Option compiler="clang" />
+ <Build>
+ <Target title="Debug x86">
+ <Option output="bin/Debug_x86/OGLESBasicTnL" prefix_auto="1" extension_auto="1" />
+ <Option object_output="obj/Debug_x86/" />
+ <Option type="1" />
+ <Option compiler="clang" />
+ <Compiler>
+ <Add option="-g" />
+ <Add option="-m32" />
+ </Compiler>
+ <Linker>
+ <Add option="-m32" />
+ <Add directory="../../../../../../../../lib/Debug_x86" />
+ </Linker>
+ </Target>
+ <Target title="Release x86">
+ <Option output="bin/Release_x86/OGLESBasicTnL" prefix_auto="1" extension_auto="1" />
+ <Option object_output="obj/Release_x86/" />
+ <Option type="1" />
+ <Option compiler="clang" />
+ <Compiler>
+ <Add option="-O2" />
+ <Add option="-m32" />
+ </Compiler>
+ <Linker>
+ <Add option="-s" />
+ <Add option="-m32" />
+ <Add directory="../../../../../../../../lib/Release_x86" />
+ </Linker>
+ </Target>
+ <Target title="Debug x64">
+ <Option output="bin/Debug_x64/OGLESBasicTnL" prefix_auto="1" extension_auto="1" />
+ <Option object_output="obj/Debug_x64/" />
+ <Option type="1" />
+ <Option compiler="clang" />
+ <Compiler>
+ <Add option="-g" />
+ </Compiler>
+ <Linker>
+ <Add directory="../../../../../../../../lib/Debug_x64" />
+ </Linker>
+ </Target>
+ <Target title="Release x64">
+ <Option output="bin/Release_x64/OGLESBasicTnL" prefix_auto="1" extension_auto="1" />
+ <Option object_output="obj/Release_x64/" />
+ <Option type="1" />
+ <Option compiler="clang" />
+ <Compiler>
+ <Add option="-O2" />
+ </Compiler>
+ <Linker>
+ <Add option="-s" />
+ <Add directory="../../../../../../../../lib/Release_x64" />
+ </Linker>
+ </Target>
+ </Build>
+ <Compiler>
+ <Add option="-Wall" />
+ <Add option="-std=c++11" />
+ <Add option="-fexceptions" />
+ <Add directory="../../../../../Builds/Include" />
+ <Add directory="../../../../../Shell" />
+ <Add directory="../../../../../Shell/OS/LinuxX11" />
+ <Add directory="../../../../../Shell/API/KEGL" />
+ </Compiler>
+ <Linker>
+ <Add option="-Wl,--rpath -Wl,./" />
+ <Add library="X11" />
+ <Add library="EGL" />
+ <Add library="GLES_CM" />
+ </Linker>
+ <Unit filename="../../../../../Shell/API/KEGL/PVRShellAPI.cpp" />
+ <Unit filename="../../../../../Shell/OS/LinuxX11/PVRShellOS.cpp" />
+ <Unit filename="../../../../../Shell/PVRShell.cpp" />
+ <Unit filename="../OGLESBasicTnL.cpp" />
+ <Extensions>
+ <code_completion />
+ <debugger />
+ </Extensions>
+ </Project>
+</CodeBlocks_project_file>
diff --git a/tests/third_party/PowerVR/Shell/OS/LinuxX11/PVRShellOS.cpp b/tests/third_party/PowerVR/Shell/OS/LinuxX11/PVRShellOS.cpp
new file mode 100644
index 0000000..f9a03b7
--- /dev/null
+++ b/tests/third_party/PowerVR/Shell/OS/LinuxX11/PVRShellOS.cpp
@@ -0,0 +1,755 @@
+/******************************************************************************
+
+ @File LinuxX11/PVRShellOS.cpp
+
+ @Title LinuxX11/PVRShellOS
+
+ @Version
+
+ @Copyright Copyright (c) Imagination Technologies Limited.
+
+ @Platform X11
+
+ @Description Makes programming for 3D APIs easier by wrapping window creation
+ and other functions for use by a demo.
+
+******************************************************************************/
+
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "PVRShell.h"
+#include "PVRShellAPI.h"
+#include "PVRShellOS.h"
+#include "PVRShellImpl.h"
+
+// No Doxygen for CPP files, due to documentation duplication
+/// @cond NO_DOXYGEN
+
+/*!***************************************************************************
+ Defines
+*****************************************************************************/
+
+/*****************************************************************************
+ Declarations
+*****************************************************************************/
+static Bool WaitForMapNotify( Display *d, XEvent *e, char *arg );
+
+/*!***************************************************************************
+ Class: PVRShellInit
+*****************************************************************************/
+
+/*!***********************************************************************
+@Function PVRShellOutputDebug
+@Input format printf style format followed by arguments it requires
+@Description Writes the resultant string to the debug output (e.g. using
+ printf(), OutputDebugString(), ...). Check the SDK release notes for
+ details on how the string is output.
+*************************************************************************/
+void PVRShell::PVRShellOutputDebug(char const * const format, ...) const
+{
+ if(!format)
+ return;
+
+ va_list arg;
+ char buf[1024];
+
+ va_start(arg, format);
+ vsnprintf(buf, 1024, format, arg);
+ va_end(arg);
+
+ // Passes the data to a platform dependant function
+ m_pShellInit->OsDisplayDebugString(buf);
+}
+
+/*!***********************************************************************
+ @Function OsInit
+ @description Initialisation for OS-specific code.
+*************************************************************************/
+void PVRShellInit::OsInit()
+{
+ XInitThreads();
+
+ // set values to negative to mark that these are default values
+ m_pShell->m_pShellData->nShellDimX = -240;
+ m_pShell->m_pShellData->nShellDimY = -320;
+
+ m_X11Display = NULL;
+ m_X11Visual = NULL;
+
+ // Pixmap support: init variables to 0
+ m_X11Pixmap = BadValue;
+
+ /*
+ Construct the binary path for GetReadPath() and GetWritePath()
+ */
+ // Get PID (Process ID)
+ pid_t ourPid = getpid();
+ char *pszExePath, pszSrcLink[64];
+ int len = 64;
+ int res;
+
+ sprintf(pszSrcLink, "/proc/%d/exe", ourPid);
+ pszExePath = 0;
+
+ do
+ {
+ len *= 2;
+ delete[] pszExePath;
+ pszExePath = new char[len];
+ res = readlink(pszSrcLink, pszExePath, len);
+
+ if(res < 0)
+ {
+ m_pShell->PVRShellOutputDebug("Warning Readlink %s failed. The application name, read path and write path have not been set.\n", pszExePath);
+ break;
+ }
+ } while(res >= len);
+
+ if(res >= 0)
+ {
+ pszExePath[res] = '\0'; // Null-terminate readlink's result
+ SetReadPath(pszExePath);
+ SetWritePath(pszExePath);
+ SetAppName(pszExePath);
+ }
+
+ delete[] pszExePath;
+
+ m_u32ButtonState = 0;
+
+ gettimeofday(&m_StartTime,NULL);
+}
+
+/*!***********************************************************************
+ @Function OsInitOS
+ @description Saves instance handle and creates main window
+ In this function, we save the instance handle in a global variable and
+ create and display the main program window.
+*************************************************************************/
+bool PVRShellInit::OsInitOS()
+{
+ m_X11Display = XOpenDisplay( NULL );
+
+ if(!m_X11Display)
+ {
+ m_pShell->PVRShellOutputDebug( "Unable to open X display\n");
+ return false;
+ }
+
+ m_X11Screen = XDefaultScreen( m_X11Display );
+
+ /*
+ If there is a full screen request then
+ set the window size to the display size.
+ If there is no full screen request then reduce window size while keeping
+ the same aspect by dividing the dims by two until it fits inside the display area.
+ If the position has not changed from its default value, set it to the middle of the screen.
+ */
+
+ int display_width = XDisplayWidth(m_X11Display,m_X11Screen);
+ int display_height = XDisplayHeight(m_X11Display,m_X11Screen);
+
+ if(m_pShell->m_pShellData->bFullScreen)
+ {
+ // For OGL we do real fullscreen for others API set a window of fullscreen size
+ if(m_pShell->m_pShellData->nShellDimX < 0) {
+ m_pShell->m_pShellData->nShellDimX = display_width;
+ }
+ if(m_pShell->m_pShellData->nShellDimY < 0) {
+ m_pShell->m_pShellData->nShellDimY = display_height;
+ }
+ }
+ else
+ {
+ if(m_pShell->m_pShellData->nShellDimX < 0)
+ m_pShell->m_pShellData->nShellDimX = (display_width > display_height) ? 800 : 600;
+
+ if(m_pShell->m_pShellData->nShellDimY < 0)
+ m_pShell->m_pShellData->nShellDimY = (display_width > display_height) ? 600 : 800;
+
+ if(m_pShell->m_pShellData->nShellDimX > display_width)
+ m_pShell->m_pShellData->nShellDimX = display_width;
+
+ if(m_pShell->m_pShellData->nShellDimY > display_height)
+ m_pShell->m_pShellData->nShellDimY = display_height;
+ }
+
+ // Create the window
+ if(!OpenX11Window(*m_pShell))
+ {
+ m_pShell->PVRShellOutputDebug( "Unable to open X11 window\n" );
+ return false;
+ }
+
+ // Pixmap support: create the pixmap
+ if(m_pShell->m_pShellData->bNeedPixmap)
+ {
+ int depth = DefaultDepth(m_X11Display, m_X11Screen);
+ m_X11Pixmap = XCreatePixmap(m_X11Display,m_X11Window,m_pShell->m_pShellData->nShellDimX,m_pShell->m_pShellData->nShellDimY,depth);
+ m_X11GC = XCreateGC(m_X11Display,m_X11Window,0,0);
+ }
+
+ return true;
+}
+
+/*!***********************************************************************
+ @Function OsReleaseOS
+ @description Destroys main window
+*************************************************************************/
+void PVRShellInit::OsReleaseOS()
+{
+ XCloseDisplay( m_X11Display );
+}
+
+/*!***********************************************************************
+ @Function OsExit
+ @description Destroys main window
+*************************************************************************/
+void PVRShellInit::OsExit()
+{
+ // Show the exit message to the user
+ m_pShell->PVRShellOutputDebug((const char*)m_pShell->PVRShellGet(prefExitMessage));
+}
+
+/*!***********************************************************************
+ @Function OsDoInitAPI
+ @Return true on success
+ @description Perform API initialisation and bring up window / fullscreen
+*************************************************************************/
+bool PVRShellInit::OsDoInitAPI()
+{
+ if(!ApiInitAPI())
+ {
+ return false;
+ }
+
+ // No problem occured
+ return true;
+}
+
+/*!***********************************************************************
+ @Function OsDoReleaseAPI
+ @description Clean up after we're done
+*************************************************************************/
+void PVRShellInit::OsDoReleaseAPI()
+{
+ ApiReleaseAPI();
+
+ if(m_pShell->m_pShellData->bNeedPixmap)
+ {
+ // Pixmap support: free the pixmap
+ XFreePixmap(m_X11Display,m_X11Pixmap);
+ XFreeGC(m_X11Display,m_X11GC);
+ }
+
+ CloseX11Window();
+}
+
+/*!***********************************************************************
+ @Function OsRenderComplete
+ @Returns false when the app should quit
+ @description Main message loop / render loop
+*************************************************************************/
+void PVRShellInit::OsRenderComplete()
+{
+ int numMessages;
+ XEvent event;
+ char* atoms;
+
+ // Are there messages waiting, maybe this should be a while loop
+ numMessages = XPending( m_X11Display );
+ for( int i = 0; i < numMessages; i++ )
+ {
+ XNextEvent( m_X11Display, &event );
+
+ switch( event.type )
+ {
+ case ClientMessage:
+ atoms = XGetAtomName(m_X11Display, event.xclient.message_type);
+ if (*atoms == *"WM_PROTOCOLS")
+ {
+ gShellDone = true;
+ }
+ XFree(atoms);
+ break;
+
+ case ButtonRelease:
+ {
+ XButtonEvent *button_event = ((XButtonEvent *) &event);
+ switch( button_event->button )
+ {
+ case 1 :
+ {
+ m_u32ButtonState &= ~1;
+
+ // Set the current pointer location
+ float vec2PointerLocation[2];
+ vec2PointerLocation[0] = (float)button_event->x / (float)m_pShell->m_pShellData->nShellDimX;
+ vec2PointerLocation[1] = (float)button_event->y / (float)m_pShell->m_pShellData->nShellDimY;
+ TouchEnded(vec2PointerLocation);
+ }
+ break;
+ case 2 : m_u32ButtonState &= ~4; break;
+ case 3 : m_u32ButtonState &= ~2; break;
+ default : break;
+ }
+ break;
+ }
+ case ButtonPress:
+ {
+ XButtonEvent *button_event = ((XButtonEvent *) &event);
+ switch( button_event->button )
+ {
+ case 1 :
+ {
+ m_u32ButtonState |= 1;
+
+ // Set the current pointer location
+ float vec2PointerLocation[2];
+ vec2PointerLocation[0] = (float)button_event->x / (float)m_pShell->m_pShellData->nShellDimX;
+ vec2PointerLocation[1] = (float)button_event->y / (float)m_pShell->m_pShellData->nShellDimY;
+ TouchBegan(vec2PointerLocation);
+ }
+ break;
+ case 2 : m_u32ButtonState |= 4; break;
+ case 3 : m_u32ButtonState |= 2; break;
+ default : break;
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+ XMotionEvent *motion_event = ((XMotionEvent *) &event);
+
+ // Set the current pointer location
+ float vec2PointerLocation[2];
+ vec2PointerLocation[0] = (float)motion_event->x / (float)m_pShell->m_pShellData->nShellDimX;
+ vec2PointerLocation[1] = (float)motion_event->y / (float)m_pShell->m_pShellData->nShellDimY;
+ TouchMoved(vec2PointerLocation);
+ break;
+ }
+ // should SDK handle these?
+ case MapNotify:
+ case UnmapNotify:
+ break;
+
+ case KeyPress:
+ {
+ XKeyEvent *key_event = ((XKeyEvent *) &event);
+
+ switch(key_event->keycode)
+ {
+ case 9: nLastKeyPressed = PVRShellKeyNameQUIT; break; // Esc
+ case 95: nLastKeyPressed = PVRShellKeyNameScreenshot; break; // F11
+ case 36: nLastKeyPressed = PVRShellKeyNameSELECT; break; // Enter
+ case 10: nLastKeyPressed = PVRShellKeyNameACTION1; break; // number 1
+ case 11: nLastKeyPressed = PVRShellKeyNameACTION2; break; // number 2
+ case 98:
+ case 111: nLastKeyPressed = m_eKeyMapUP; break;
+ case 104:
+ case 116: nLastKeyPressed = m_eKeyMapDOWN; break;
+ case 100:
+ case 113: nLastKeyPressed = m_eKeyMapLEFT; break;
+ case 102:
+ case 114: nLastKeyPressed = m_eKeyMapRIGHT; break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case KeyRelease:
+ {
+// char buf[10];
+// XLookupString(&event.xkey,buf,10,NULL,NULL);
+// charsPressed[ (int) *buf ] = 0;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+/*!***********************************************************************
+ @Function OsPixmapCopy
+ @Return true if the copy succeeded
+ @description When using pixmaps, copy the render to the display
+*************************************************************************/
+bool PVRShellInit::OsPixmapCopy()
+{
+ XCopyArea(m_X11Display,m_X11Pixmap,m_X11Window,m_X11GC,0,0,m_pShell->m_pShellData->nShellDimX,m_pShell->m_pShellData->nShellDimY,0,0);
+ return true;
+}
+
+/*!***********************************************************************
+ @Function OsGetNativeDisplayType
+ @Return The 'NativeDisplayType' for EGL
+ @description Called from InitAPI() to get the NativeDisplayType
+*************************************************************************/
+void *PVRShellInit::OsGetNativeDisplayType()
+{
+ return m_X11Display;
+}
+
+/*!***********************************************************************
+ @Function OsGetNativePixmapType
+ @Return The 'NativePixmapType' for EGL
+ @description Called from InitAPI() to get the NativePixmapType
+*************************************************************************/
+void *PVRShellInit::OsGetNativePixmapType()
+{
+ // Pixmap support: return the pixmap
+ return (void*)m_X11Pixmap;
+}
+
+/*!***********************************************************************
+ @Function OsGetNativeWindowType
+ @Return The 'NativeWindowType' for EGL
+ @description Called from InitAPI() to get the NativeWindowType
+*************************************************************************/
+void *PVRShellInit::OsGetNativeWindowType()
+{
+ return (void*)m_X11Window;
+}
+
+/*!***********************************************************************
+ @Function OsGet
+ @Input prefName Name of value to get
+ @Modified pn A pointer set to the value asked for
+ @Returns true on success
+ @Description Retrieves OS-specific data
+*************************************************************************/
+bool PVRShellInit::OsGet(const prefNameIntEnum prefName, int *pn)
+{
+ switch( prefName )
+ {
+ case prefButtonState:
+ *pn = m_u32ButtonState;
+ return true;
+ default:
+ return false;
+ };
+
+ return false;
+}
+
+/*!***********************************************************************
+ @Function OsGet
+ @Input prefName Name of value to get
+ @Modified pp A pointer set to the value asked for
+ @Returns true on success
+ @Description Retrieves OS-specific data
+*************************************************************************/
+bool PVRShellInit::OsGet(const prefNamePtrEnum prefName, void **pp)
+{
+ return false;
+}
+
+/*!***********************************************************************
+ @Function OsSet
+ @Input prefName Name of preference to set to value
+ @Input value Value
+ @Return true for success
+ @Description Sets OS-specific data
+*************************************************************************/
+bool PVRShellInit::OsSet(const prefNameBoolEnum prefName, const bool value)
+{
+ return false;
+}
+
+/*!***********************************************************************
+ @Function OsSet
+ @Input prefName Name of value to set
+ @Input i32Value The value to set our named value to
+ @Returns true on success
+ @Description Sets OS-specific data
+*************************************************************************/
+bool PVRShellInit::OsSet(const prefNameIntEnum prefName, const int i32Value)
+{
+ return false;
+}
+
+/*!***********************************************************************
+ @Function OsDisplayDebugString
+ @Input str string to output
+ @Description Prints a debug string
+*************************************************************************/
+void PVRShellInit::OsDisplayDebugString(char const * const str)
+{
+ fprintf(stderr, "%s", str);
+}
+
+/*!***********************************************************************
+ @Function OsGetTime
+ @Return An incrementing time value measured in milliseconds
+ @Description Returns an incrementing time value measured in milliseconds
+*************************************************************************/
+unsigned long PVRShellInit::OsGetTime()
+{
+ timeval tv;
+ gettimeofday(&tv,NULL);
+
+ if(tv.tv_sec < m_StartTime.tv_sec)
+ m_StartTime.tv_sec = 0;
+
+ unsigned long sec = tv.tv_sec - m_StartTime.tv_sec;
+ return (unsigned long)((sec*(unsigned long)1000) + (tv.tv_usec/1000.0));
+}
+
+/*****************************************************************************
+ Class: PVRShellInitOS
+*****************************************************************************/
+
+/*!***********************************************************************
+ @Function OpenX11Window
+ @Return true on success
+ @Description Opens an X11 window. This must be called after
+ SelectEGLConfiguration() for gEglConfig to be valid
+*************************************************************************/
+int PVRShellInitOS::OpenX11Window(const PVRShell &shell)
+{
+ XSetWindowAttributes WinAttibutes;
+ XSizeHints sh;
+ XEvent event;
+ unsigned long mask;
+
+#ifdef BUILD_OGL
+ XF86VidModeModeInfo **modes; // modes of display
+ int numModes; // number of modes of display
+ int chosenMode;
+ int edimx,edimy; //established width and height of the chosen modeline
+ int i;
+#endif
+
+ int depth = DefaultDepth(m_X11Display, m_X11Screen);
+ m_X11Visual = new XVisualInfo;
+ XMatchVisualInfo( m_X11Display, m_X11Screen, depth, TrueColor, m_X11Visual);
+
+ if( !m_X11Visual )
+ {
+ shell.PVRShellOutputDebug( "Unable to acquire visual" );
+ return false;
+ }
+
+ m_X11ColorMap = XCreateColormap( m_X11Display, RootWindow(m_X11Display, m_X11Screen), m_X11Visual->visual, AllocNone );
+
+#ifdef BUILD_OGL
+ m_i32OriginalModeDotClock = XF86VidModeBadClock;
+ if(shell.m_pShellData->bFullScreen)
+ {
+ // Get mode lines to see if there is requested modeline
+ XF86VidModeGetAllModeLines(m_X11Display, m_X11Screen, &numModes, &modes);
+
+ // look for mode with requested resolution
+ chosenMode = -1;
+ i=0;
+ while((chosenMode == -1)&&(i<numModes))
+ {
+ if ((modes[i]->hdisplay == shell.m_pShellData->nShellDimX) && (modes[i]->vdisplay == shell.m_pShellData->nShellDimY))
+ {
+ chosenMode = i;
+ }
+ ++i;
+ }
+
+ // If there is no requested resolution among modelines then terminate
+ if(chosenMode == -1)
+ {
+ shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match any modeline available.\n" );
+ return false;
+ }
+
+ // save desktop-resolution before switching modes
+ XF86VidModeGetModeLine(m_X11Display,m_X11Screen, &m_i32OriginalModeDotClock, &m_OriginalMode );
+
+ XF86VidModeSwitchToMode(m_X11Display, m_X11Screen, modes[chosenMode]);
+ XF86VidModeSetViewPort(m_X11Display, m_X11Screen, 0, 0);
+ edimx = modes[chosenMode]->hdisplay;
+ edimy = modes[chosenMode]->vdisplay;
+ printf("Fullscreen Resolution %dx%d (chosen mode = %d)\n", edimx, edimy,chosenMode);
+ XFree(modes);
+
+ WinAttibutes.colormap = m_X11ColorMap;
+ WinAttibutes.background_pixel = 0xFFFFFFFF;
+ WinAttibutes.border_pixel = 0;
+ WinAttibutes.override_redirect = true;
+
+ // add to these for handling other events
+ WinAttibutes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask;
+
+ // The diffrence is that we want to ignore influence of window manager for our fullscreen window
+ mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap | CWOverrideRedirect;
+
+ m_X11Window = XCreateWindow( m_X11Display, RootWindow(m_X11Display, m_X11Screen), 0, 0, edimx, edimy, 0,
+ CopyFromParent, InputOutput, CopyFromParent, mask, &WinAttibutes);
+
+ // keeping the pointer of mouse and keyboard in window to prevent from scrolling the virtual screen
+ XWarpPointer(m_X11Display, None ,m_X11Window, 0, 0, 0, 0, 0, 0);
+
+ // Map and then wait till mapped, grabbing should be after mapping the window
+ XMapWindow( m_X11Display, m_X11Window );
+ XGrabKeyboard(m_X11Display, m_X11Window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
+ XGrabPointer(m_X11Display, m_X11Window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_X11Window, None, CurrentTime);
+ XIfEvent( m_X11Display, &event, WaitForMapNotify, (char*)m_X11Window );
+
+ }
+ else
+#endif
+ {
+ // For OGLES we assume that chaning of video mode is not available (freedesktop does not allow to do it)
+ // so if requested resolution differs from the display dims then we quit
+ #ifndef BUILD_OGL
+ int display_width = XDisplayWidth(m_X11Display,m_X11Screen);
+ int display_height = XDisplayHeight(m_X11Display,m_X11Screen);
+ if((shell.m_pShellData->bFullScreen)&&((shell.m_pShellData->nShellDimX != display_width)||(shell.m_pShellData->nShellDimY != display_height)) ) {
+ shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match available modeline.\n" );
+ return false;
+ }
+ #endif
+
+
+ WinAttibutes.colormap = m_X11ColorMap;
+ WinAttibutes.background_pixel = 0xFFFFFFFF;
+ WinAttibutes.border_pixel = 0;
+
+ // add to these for handling other events
+ WinAttibutes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask;
+
+ // The attribute mask
+ mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap ;
+
+ m_X11Window = XCreateWindow( m_X11Display, // Display
+ RootWindow(m_X11Display, m_X11Screen), // Parent
+ shell.m_pShellData->nShellPosX, // X position of window
+ shell.m_pShellData->nShellPosY, // Y position of window
+ shell.m_pShellData->nShellDimX, // Window width
+ shell.m_pShellData->nShellDimY, // Window height
+ 0, // Border width
+ CopyFromParent, // Depth (taken from parent)
+ InputOutput, // Window class
+ CopyFromParent, // Visual type (taken from parent)
+ mask, // Attributes mask
+ &WinAttibutes); // Attributes
+
+ // Set the window position
+ sh.flags = USPosition;
+ sh.x = shell.m_pShellData->nShellPosX;
+ sh.y = shell.m_pShellData->nShellPosY;
+ XSetStandardProperties( m_X11Display, m_X11Window, shell.m_pShellData->pszAppName, shell.m_pShellData->pszAppName, None, 0, 0, &sh );
+
+ // Map and then wait till mapped
+ XMapWindow( m_X11Display, m_X11Window );
+ XIfEvent( m_X11Display, &event, WaitForMapNotify, (char*)m_X11Window );
+
+ // An attempt to hide a border for fullscreen on non OGL apis (OGLES,OGLES2)
+ if(shell.m_pShellData->bFullScreen)
+ {
+ XEvent xev;
+ Atom wmState = XInternAtom(m_X11Display, "_NET_WM_STATE", False);
+ Atom wmStateFullscreen = XInternAtom(m_X11Display, "_NET_WM_STATE_FULLSCREEN", False);
+
+ memset(&xev, 0, sizeof(XEvent));
+ xev.type = ClientMessage;
+ xev.xclient.window = m_X11Window;
+ xev.xclient.message_type = wmState;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1;
+ xev.xclient.data.l[1] = wmStateFullscreen;
+ xev.xclient.data.l[2] = 0;
+ XSendEvent(m_X11Display, RootWindow(m_X11Display, m_X11Screen), False, SubstructureNotifyMask, &xev);
+ }
+
+ Atom wmDelete = XInternAtom(m_X11Display, "WM_DELETE_WINDOW", True);
+ XSetWMProtocols(m_X11Display, m_X11Window, &wmDelete, 1);
+ XSetWMColormapWindows( m_X11Display, m_X11Window, &m_X11Window, 1 );
+ }
+
+ XFlush( m_X11Display );
+
+ return true;
+}
+
+/*!***********************************************************************
+ @Function CloseX11Window
+ @Return void
+ @Description destroy the instance of a window, and release all relevent memory
+*************************************************************************/
+void PVRShellInitOS::CloseX11Window()
+{
+ // revert introductional resolution (full screen case, bad clock is default value meaning that good was not acquired)
+#ifdef BUILD_OGL
+ XF86VidModeModeInfo tmpmi;
+
+ if(m_i32OriginalModeDotClock != XF86VidModeBadClock)
+ {
+ // revert desktop-resolution (stored previously) before exiting
+ tmpmi.dotclock = m_i32OriginalModeDotClock;
+ tmpmi.c_private = m_OriginalMode.c_private;
+ tmpmi.flags = m_OriginalMode.flags;
+ tmpmi.hdisplay = m_OriginalMode.hdisplay;
+ tmpmi.hskew = m_OriginalMode.hskew;
+ tmpmi.hsyncend = m_OriginalMode.hsyncend;
+ tmpmi.hsyncstart = m_OriginalMode.hsyncstart;
+ tmpmi.htotal = m_OriginalMode.htotal;
+ tmpmi.privsize = m_OriginalMode.privsize;
+ tmpmi.vdisplay = m_OriginalMode.vdisplay;
+ tmpmi.vsyncend = m_OriginalMode.vsyncend;
+ tmpmi.vsyncstart = m_OriginalMode.vsyncstart;
+ tmpmi.vtotal = m_OriginalMode.vtotal;
+
+ XF86VidModeSwitchToMode(m_X11Display,m_X11Screen,&tmpmi);
+ }
+#endif
+
+ XDestroyWindow( m_X11Display, m_X11Window );
+ XFreeColormap( m_X11Display, m_X11ColorMap );
+
+ if(m_X11Visual)
+ delete m_X11Visual;
+}
+
+/*****************************************************************************
+ Global code
+*****************************************************************************/
+
+static Bool WaitForMapNotify( Display *d, XEvent *e, char *arg )
+{
+ return (e->type == MapNotify) && (e->xmap.window == (Window)arg);
+}
+
+/*!***************************************************************************
+@function main
+@input argc count of args from OS
+@input argv array of args from OS
+@returns result code to OS
+@description Main function of the program
+*****************************************************************************/
+int main(int argc, char **argv)
+{
+ PVRShellInit init;
+
+ // Initialise the demo, process the command line, create the OS initialiser.
+ if(!init.Init())
+ return EXIT_ERR_CODE;
+
+ init.CommandLine((argc-1),&argv[1]);
+
+ // Initialise/run/shutdown
+ while(init.Run());
+
+ return EXIT_NOERR_CODE;
+}
+
+/// @endcond
+
+/*****************************************************************************
+ End of file (PVRShellOS.cpp)
+*****************************************************************************/
+
diff --git a/tests/third_party/PowerVR/Shell/OS/LinuxX11/PVRShellOS.h b/tests/third_party/PowerVR/Shell/OS/LinuxX11/PVRShellOS.h
new file mode 100644
index 0000000..0217433
--- /dev/null
+++ b/tests/third_party/PowerVR/Shell/OS/LinuxX11/PVRShellOS.h
@@ -0,0 +1,77 @@
+/*!****************************************************************************
+
+ @file LinuxX11/PVRShellOS.h
+ @ingroup OS_LinuxX11
+ @copyright Copyright (c) Imagination Technologies Limited.
+ @brief Initialization for the shell for LinuxX11.
+ @details Makes programming for 3D APIs easier by wrapping surface
+ initialization, Texture allocation and other functions for use by a demo.
+
+******************************************************************************/
+#ifndef _PVRSHELLOS_
+#define _PVRSHELLOS_
+
+#include "X11/Xlib.h"
+#include "X11/Xutil.h"
+#ifdef BUILD_OGL
+#include "X11/extensions/xf86vmode.h"
+#endif
+
+#define PVRSHELL_DIR_SYM '/'
+#define _stricmp strcasecmp
+
+/*!
+ @addtogroup OS_LinuxX11
+ @brief LinuxX11 OS
+ @details The following table illustrates how key codes are mapped in LinuxX11:
+ <table>
+ <tr><th> Key code </th><th> nLastKeyPressed (PVRShell) </th></tr>
+ <tr><td> Esc </td><td> PVRShellKeyNameQUIT </td></tr>
+ <tr><td> F11 </td><td> PVRShellKeyNameScreenshot </td></tr>
+ <tr><td> Enter </td><td> PVRShellKeyNameSELECT </td></tr>
+ <tr><td> '1' </td><td> PVRShellKeyNameACTION1 </td></tr>
+ <tr><td> '2' </td><td> PVRShellKeyNameACTION2 </td></tr>
+ <tr><td> Up arrow </td><td> m_eKeyMapUP </td></tr>
+ <tr><td> Down arrow </td><td> m_eKeyMapDOWN </td></tr>
+ <tr><td> Left arrow </td><td> m_eKeyMapLEFT </td></tr>
+ <tr><td> Right arrow </td><td> m_eKeyMapRIGHT </td></tr>
+ </table>
+ @{
+*/
+
+/*!***************************************************************************
+ @class PVRShellInitOS
+ @brief Interface with specific Operative System.
+*****************************************************************************/
+class PVRShellInitOS
+{
+public:
+ Display* m_X11Display;
+ long m_X11Screen;
+ XVisualInfo* m_X11Visual;
+ Colormap m_X11ColorMap;
+ Window m_X11Window;
+ timeval m_StartTime;
+#ifdef BUILD_OGL
+ XF86VidModeModeLine m_OriginalMode; // modeline that was active at the starting point of this aplication
+ int m_i32OriginalModeDotClock;
+#endif
+
+ // Pixmap support: variables for the pixmap
+ Pixmap m_X11Pixmap;
+ GC m_X11GC;
+
+ unsigned int m_u32ButtonState; // 1 = left, 2 = right, 4 = middle
+
+public:
+ int OpenX11Window(const PVRShell &shell);
+ void CloseX11Window();
+};
+
+/*! @} */
+
+#endif /* _PVRSHELLOS_ */
+/*****************************************************************************
+ End of file (PVRShellOS.h)
+*****************************************************************************/
+