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