Home | History | Annotate | Download | only in LinuxX11
      1 /******************************************************************************
      2 
      3  @File         LinuxX11/PVRShellOS.cpp
      4 
      5  @Title        LinuxX11/PVRShellOS
      6 
      7  @Version
      8 
      9  @Copyright    Copyright (c) Imagination Technologies Limited.
     10 
     11  @Platform     X11
     12 
     13  @Description  Makes programming for 3D APIs easier by wrapping window creation
     14                and other functions for use by a demo.
     15 
     16 ******************************************************************************/
     17 
     18 #include <sys/time.h>
     19 #include <stdio.h>
     20 #include <stdarg.h>
     21 #include <time.h>
     22 #include <unistd.h>
     23 #include <string.h>
     24 
     25 #include "PVRShell.h"
     26 #include "PVRShellAPI.h"
     27 #include "PVRShellOS.h"
     28 #include "PVRShellImpl.h"
     29 
     30 // No Doxygen for CPP files, due to documentation duplication
     31 /// @cond NO_DOXYGEN
     32 
     33 /*!***************************************************************************
     34 	Defines
     35 *****************************************************************************/
     36 
     37 /*****************************************************************************
     38 	Declarations
     39 *****************************************************************************/
     40 static Bool WaitForMapNotify( Display *d, XEvent *e, char *arg );
     41 
     42 /*!***************************************************************************
     43 	Class: PVRShellInit
     44 *****************************************************************************/
     45 
     46 /*!***********************************************************************
     47 @Function		PVRShellOutputDebug
     48 @Input			format			printf style format followed by arguments it requires
     49 @Description	Writes the resultant string to the debug output (e.g. using
     50 				printf(), OutputDebugString(), ...). Check the SDK release notes for
     51 				details on how the string is output.
     52 *************************************************************************/
     53 void PVRShell::PVRShellOutputDebug(char const * const format, ...) const
     54 {
     55 	if(!format)
     56 		return;
     57 
     58 	va_list arg;
     59 	char	buf[1024];
     60 
     61 	va_start(arg, format);
     62 	vsnprintf(buf, 1024, format, arg);
     63 	va_end(arg);
     64 
     65 	// Passes the data to a platform dependant function
     66 	m_pShellInit->OsDisplayDebugString(buf);
     67 }
     68 
     69 /*!***********************************************************************
     70  @Function		OsInit
     71  @description	Initialisation for OS-specific code.
     72 *************************************************************************/
     73 void PVRShellInit::OsInit()
     74 {
     75 	XInitThreads();
     76 
     77     // set values to negative to mark that these are default values
     78     m_pShell->m_pShellData->nShellDimX = -240;
     79     m_pShell->m_pShellData->nShellDimY = -320;
     80 
     81 	m_X11Display = NULL;
     82 	m_X11Visual = NULL;
     83 
     84 	// Pixmap support: init variables to 0
     85 	m_X11Pixmap = BadValue;
     86 
     87 	/*
     88 		Construct the binary path for GetReadPath() and GetWritePath()
     89 	*/
     90 	// Get PID (Process ID)
     91 	pid_t ourPid = getpid();
     92 	char *pszExePath, pszSrcLink[64];
     93 	int len = 64;
     94 	int res;
     95 
     96 	sprintf(pszSrcLink, "/proc/%d/exe", ourPid);
     97 	pszExePath = 0;
     98 
     99 	do
    100 	{
    101 		len *= 2;
    102 		delete[] pszExePath;
    103 		pszExePath = new char[len];
    104 		res = readlink(pszSrcLink, pszExePath, len);
    105 
    106 		if(res < 0)
    107 		{
    108 			m_pShell->PVRShellOutputDebug("Warning Readlink %s failed. The application name, read path and write path have not been set.\n", pszExePath);
    109 			break;
    110 		}
    111 	} while(res >= len);
    112 
    113 	if(res >= 0)
    114 	{
    115 		pszExePath[res] = '\0'; // Null-terminate readlink's result
    116 		SetReadPath(pszExePath);
    117 		SetWritePath(pszExePath);
    118 		SetAppName(pszExePath);
    119 	}
    120 
    121 	delete[] pszExePath;
    122 
    123 	m_u32ButtonState = 0;
    124 
    125 	gettimeofday(&m_StartTime,NULL);
    126 }
    127 
    128 /*!***********************************************************************
    129  @Function		OsInitOS
    130  @description	Saves instance handle and creates main window
    131 				In this function, we save the instance handle in a global variable and
    132 				create and display the main program window.
    133 *************************************************************************/
    134 bool PVRShellInit::OsInitOS()
    135 {
    136 	m_X11Display = XOpenDisplay( NULL );
    137 
    138 	if(!m_X11Display)
    139 	{
    140 		m_pShell->PVRShellOutputDebug( "Unable to open X display\n");
    141 		return false;
    142 	}
    143 
    144 	m_X11Screen = XDefaultScreen( m_X11Display );
    145 
    146     /*
    147     	If there is a full screen request then
    148         set the window size to the display size.
    149         If there is no full screen request then reduce window size while keeping
    150 		the same aspect by dividing the dims by two until it fits inside the display area.
    151         If the position has not changed from its default value, set it to the middle of the screen.
    152     */
    153 
    154     int display_width  = XDisplayWidth(m_X11Display,m_X11Screen);
    155     int display_height = XDisplayHeight(m_X11Display,m_X11Screen);
    156 
    157     if(m_pShell->m_pShellData->bFullScreen)
    158     {
    159         // For OGL we do real fullscreen for others API set a window of fullscreen size
    160         if(m_pShell->m_pShellData->nShellDimX < 0) {
    161             m_pShell->m_pShellData->nShellDimX = display_width;
    162         }
    163         if(m_pShell->m_pShellData->nShellDimY < 0) {
    164             m_pShell->m_pShellData->nShellDimY = display_height;
    165         }
    166     }
    167     else
    168     {
    169 		if(m_pShell->m_pShellData->nShellDimX < 0)
    170 		    m_pShell->m_pShellData->nShellDimX = (display_width > display_height) ? 800 : 600;
    171 
    172 		if(m_pShell->m_pShellData->nShellDimY < 0)
    173 		    m_pShell->m_pShellData->nShellDimY = (display_width > display_height) ? 600 : 800;
    174 
    175         if(m_pShell->m_pShellData->nShellDimX > display_width)
    176             m_pShell->m_pShellData->nShellDimX = display_width;
    177 
    178         if(m_pShell->m_pShellData->nShellDimY > display_height)
    179             m_pShell->m_pShellData->nShellDimY = display_height;
    180     }
    181 
    182 	// Create the window
    183 	if(!OpenX11Window(*m_pShell))
    184 	{
    185 		m_pShell->PVRShellOutputDebug( "Unable to open X11 window\n" );
    186 		return false;
    187 	}
    188 
    189 	// Pixmap support: create the pixmap
    190 	if(m_pShell->m_pShellData->bNeedPixmap)
    191 	{
    192 		int depth = DefaultDepth(m_X11Display, m_X11Screen);
    193 		m_X11Pixmap = XCreatePixmap(m_X11Display,m_X11Window,m_pShell->m_pShellData->nShellDimX,m_pShell->m_pShellData->nShellDimY,depth);
    194 		m_X11GC	  = XCreateGC(m_X11Display,m_X11Window,0,0);
    195 	}
    196 
    197 	return true;
    198 }
    199 
    200 /*!***********************************************************************
    201  @Function		OsReleaseOS
    202  @description	Destroys main window
    203 *************************************************************************/
    204 void PVRShellInit::OsReleaseOS()
    205 {
    206 	XCloseDisplay( m_X11Display );
    207 }
    208 
    209 /*!***********************************************************************
    210  @Function		OsExit
    211  @description	Destroys main window
    212 *************************************************************************/
    213 void PVRShellInit::OsExit()
    214 {
    215 	// Show the exit message to the user
    216 	m_pShell->PVRShellOutputDebug((const char*)m_pShell->PVRShellGet(prefExitMessage));
    217 }
    218 
    219 /*!***********************************************************************
    220  @Function		OsDoInitAPI
    221  @Return		true on success
    222  @description	Perform API initialisation and bring up window / fullscreen
    223 *************************************************************************/
    224 bool PVRShellInit::OsDoInitAPI()
    225 {
    226 	if(!ApiInitAPI())
    227 	{
    228 		return false;
    229 	}
    230 
    231 	// No problem occured
    232 	return true;
    233 }
    234 
    235 /*!***********************************************************************
    236  @Function		OsDoReleaseAPI
    237  @description	Clean up after we're done
    238 *************************************************************************/
    239 void PVRShellInit::OsDoReleaseAPI()
    240 {
    241 	ApiReleaseAPI();
    242 
    243 	if(m_pShell->m_pShellData->bNeedPixmap)
    244 	{
    245 		// Pixmap support: free the pixmap
    246 		XFreePixmap(m_X11Display,m_X11Pixmap);
    247 		XFreeGC(m_X11Display,m_X11GC);
    248 	}
    249 
    250 	CloseX11Window();
    251 }
    252 
    253 /*!***********************************************************************
    254  @Function		OsRenderComplete
    255  @Returns		false when the app should quit
    256  @description	Main message loop / render loop
    257 *************************************************************************/
    258 void PVRShellInit::OsRenderComplete()
    259 {
    260 	int		numMessages;
    261 	XEvent	event;
    262 	char*		atoms;
    263 
    264 	// Are there messages waiting, maybe this should be a while loop
    265 	numMessages = XPending( m_X11Display );
    266 	for( int i = 0; i < numMessages; i++ )
    267 	{
    268 		XNextEvent( m_X11Display, &event );
    269 
    270 		switch( event.type )
    271 		{
    272 			case ClientMessage:
    273 				atoms = XGetAtomName(m_X11Display, event.xclient.message_type);
    274 				if (*atoms == *"WM_PROTOCOLS")
    275 				{
    276 					gShellDone = true;
    277 				}
    278 				XFree(atoms);
    279 				break;
    280 
    281 			case ButtonRelease:
    282 			{
    283 				XButtonEvent *button_event = ((XButtonEvent *) &event);
    284 				switch( button_event->button )
    285 				{
    286 					case 1 :
    287 					{
    288 						m_u32ButtonState &= ~1;
    289 
    290 						// Set the current pointer location
    291 						float vec2PointerLocation[2];
    292 						vec2PointerLocation[0] = (float)button_event->x / (float)m_pShell->m_pShellData->nShellDimX;
    293 						vec2PointerLocation[1] = (float)button_event->y / (float)m_pShell->m_pShellData->nShellDimY;
    294 						TouchEnded(vec2PointerLocation);
    295 					}
    296 					break;
    297 					case 2 : m_u32ButtonState &= ~4; break;
    298 					case 3 : m_u32ButtonState &= ~2; break;
    299 					default : break;
    300 				}
    301 				break;
    302 			}
    303         	case ButtonPress:
    304 			{
    305 				XButtonEvent *button_event = ((XButtonEvent *) &event);
    306 				switch( button_event->button )
    307 				{
    308 					case 1 :
    309 					{
    310 						m_u32ButtonState |= 1;
    311 
    312 						// Set the current pointer location
    313 						float vec2PointerLocation[2];
    314 						vec2PointerLocation[0] = (float)button_event->x / (float)m_pShell->m_pShellData->nShellDimX;
    315 						vec2PointerLocation[1] = (float)button_event->y / (float)m_pShell->m_pShellData->nShellDimY;
    316 						TouchBegan(vec2PointerLocation);
    317 					}
    318 					break;
    319 					case 2 : m_u32ButtonState |= 4; break;
    320 					case 3 : m_u32ButtonState |= 2; break;
    321 					default : break;
    322 				}
    323         		break;
    324 			}
    325 			case MotionNotify:
    326 			{
    327 				XMotionEvent *motion_event = ((XMotionEvent *) &event);
    328 
    329 				// Set the current pointer location
    330 				float vec2PointerLocation[2];
    331 				vec2PointerLocation[0] = (float)motion_event->x / (float)m_pShell->m_pShellData->nShellDimX;
    332 				vec2PointerLocation[1] = (float)motion_event->y / (float)m_pShell->m_pShellData->nShellDimY;
    333 				TouchMoved(vec2PointerLocation);
    334 				break;
    335 			}
    336 			// should SDK handle these?
    337 			case MapNotify:
    338         	case UnmapNotify:
    339         		break;
    340 
    341 			case KeyPress:
    342 			{
    343 				XKeyEvent *key_event = ((XKeyEvent *) &event);
    344 
    345 				switch(key_event->keycode)
    346 				{
    347 					case 9:	 	nLastKeyPressed = PVRShellKeyNameQUIT;	break; 			// Esc
    348 					case 95:	nLastKeyPressed = PVRShellKeyNameScreenshot;	break; 	// F11
    349 					case 36:	nLastKeyPressed = PVRShellKeyNameSELECT;	break; 		// Enter
    350 					case 10:	nLastKeyPressed = PVRShellKeyNameACTION1;	break; 		// number 1
    351 					case 11:	nLastKeyPressed = PVRShellKeyNameACTION2;	break; 		// number 2
    352 					case 98:
    353 					case 111:	nLastKeyPressed = m_eKeyMapUP;	break;
    354 					case 104:
    355 					case 116:	nLastKeyPressed = m_eKeyMapDOWN;	break;
    356 					case 100:
    357 					case 113:	nLastKeyPressed = m_eKeyMapLEFT;	break;
    358 					case 102:
    359 					case 114: 	nLastKeyPressed = m_eKeyMapRIGHT;	break;
    360 					default:
    361 						break;
    362 				}
    363 			}
    364 			break;
    365 
    366 			case KeyRelease:
    367 			{
    368 //				char buf[10];
    369 //				XLookupString(&event.xkey,buf,10,NULL,NULL);
    370 //				charsPressed[ (int) *buf ] = 0;
    371 			}
    372 			break;
    373 
    374 			default:
    375 				break;
    376 		}
    377 	}
    378 }
    379 
    380 /*!***********************************************************************
    381  @Function		OsPixmapCopy
    382  @Return		true if the copy succeeded
    383  @description	When using pixmaps, copy the render to the display
    384 *************************************************************************/
    385 bool PVRShellInit::OsPixmapCopy()
    386 {
    387 	XCopyArea(m_X11Display,m_X11Pixmap,m_X11Window,m_X11GC,0,0,m_pShell->m_pShellData->nShellDimX,m_pShell->m_pShellData->nShellDimY,0,0);
    388 	return true;
    389 }
    390 
    391 /*!***********************************************************************
    392  @Function		OsGetNativeDisplayType
    393  @Return		The 'NativeDisplayType' for EGL
    394  @description	Called from InitAPI() to get the NativeDisplayType
    395 *************************************************************************/
    396 void *PVRShellInit::OsGetNativeDisplayType()
    397 {
    398 	return m_X11Display;
    399 }
    400 
    401 /*!***********************************************************************
    402  @Function		OsGetNativePixmapType
    403  @Return		The 'NativePixmapType' for EGL
    404  @description	Called from InitAPI() to get the NativePixmapType
    405 *************************************************************************/
    406 void *PVRShellInit::OsGetNativePixmapType()
    407 {
    408 	// Pixmap support: return the pixmap
    409 	return (void*)m_X11Pixmap;
    410 }
    411 
    412 /*!***********************************************************************
    413  @Function		OsGetNativeWindowType
    414  @Return		The 'NativeWindowType' for EGL
    415  @description	Called from InitAPI() to get the NativeWindowType
    416 *************************************************************************/
    417 void *PVRShellInit::OsGetNativeWindowType()
    418 {
    419 	return (void*)m_X11Window;
    420 }
    421 
    422 /*!***********************************************************************
    423  @Function		OsGet
    424  @Input			prefName	Name of value to get
    425  @Modified		pn A pointer set to the value asked for
    426  @Returns		true on success
    427  @Description	Retrieves OS-specific data
    428 *************************************************************************/
    429 bool PVRShellInit::OsGet(const prefNameIntEnum prefName, int *pn)
    430 {
    431 	switch( prefName )
    432 	{
    433 	case prefButtonState:
    434 		*pn = m_u32ButtonState;
    435 		return true;
    436 	default:
    437 		return false;
    438 	};
    439 
    440 	return false;
    441 }
    442 
    443 /*!***********************************************************************
    444  @Function		OsGet
    445  @Input			prefName	Name of value to get
    446  @Modified		pp A pointer set to the value asked for
    447  @Returns		true on success
    448  @Description	Retrieves OS-specific data
    449 *************************************************************************/
    450 bool PVRShellInit::OsGet(const prefNamePtrEnum prefName, void **pp)
    451 {
    452 	return false;
    453 }
    454 
    455 /*!***********************************************************************
    456  @Function		OsSet
    457  @Input			prefName				Name of preference to set to value
    458  @Input			value					Value
    459  @Return		true for success
    460  @Description	Sets OS-specific data
    461 *************************************************************************/
    462 bool PVRShellInit::OsSet(const prefNameBoolEnum prefName, const bool value)
    463 {
    464 	return false;
    465 }
    466 
    467 /*!***********************************************************************
    468  @Function		OsSet
    469  @Input			prefName	Name of value to set
    470  @Input			i32Value 	The value to set our named value to
    471  @Returns		true on success
    472  @Description	Sets OS-specific data
    473 *************************************************************************/
    474 bool PVRShellInit::OsSet(const prefNameIntEnum prefName, const int i32Value)
    475 {
    476 	return false;
    477 }
    478 
    479 /*!***********************************************************************
    480  @Function		OsDisplayDebugString
    481  @Input			str		string to output
    482  @Description	Prints a debug string
    483 *************************************************************************/
    484 void PVRShellInit::OsDisplayDebugString(char const * const str)
    485 {
    486 	fprintf(stderr, "%s", str);
    487 }
    488 
    489 /*!***********************************************************************
    490  @Function		OsGetTime
    491  @Return		An incrementing time value measured in milliseconds
    492  @Description	Returns an incrementing time value measured in milliseconds
    493 *************************************************************************/
    494 unsigned long PVRShellInit::OsGetTime()
    495 {
    496 	timeval tv;
    497 	gettimeofday(&tv,NULL);
    498 
    499 	if(tv.tv_sec < m_StartTime.tv_sec)
    500 		m_StartTime.tv_sec = 0;
    501 
    502 	unsigned long sec = tv.tv_sec - m_StartTime.tv_sec;
    503 	return (unsigned long)((sec*(unsigned long)1000) + (tv.tv_usec/1000.0));
    504 }
    505 
    506 /*****************************************************************************
    507  Class: PVRShellInitOS
    508 *****************************************************************************/
    509 
    510 /*!***********************************************************************
    511  @Function		OpenX11Window
    512  @Return		true on success
    513  @Description	Opens an X11 window. This must be called after
    514 				SelectEGLConfiguration() for gEglConfig to be valid
    515 *************************************************************************/
    516 int PVRShellInitOS::OpenX11Window(const PVRShell &shell)
    517 {
    518     XSetWindowAttributes	WinAttibutes;
    519     XSizeHints				sh;
    520     XEvent					event;
    521     unsigned long			mask;
    522 
    523 #ifdef BUILD_OGL
    524     XF86VidModeModeInfo **modes;       // modes of display
    525     int numModes;                      // number of modes of display
    526     int chosenMode;
    527     int edimx,edimy;                   //established width and height of the chosen modeline
    528     int i;
    529 #endif
    530 
    531 	int depth = DefaultDepth(m_X11Display, m_X11Screen);
    532 	m_X11Visual = new XVisualInfo;
    533 	XMatchVisualInfo( m_X11Display, m_X11Screen, depth, TrueColor, m_X11Visual);
    534 
    535     if( !m_X11Visual )
    536     {
    537     	shell.PVRShellOutputDebug( "Unable to acquire visual" );
    538     	return false;
    539     }
    540 
    541     m_X11ColorMap = XCreateColormap( m_X11Display, RootWindow(m_X11Display, m_X11Screen), m_X11Visual->visual, AllocNone );
    542 
    543 #ifdef BUILD_OGL
    544     m_i32OriginalModeDotClock = XF86VidModeBadClock;
    545     if(shell.m_pShellData->bFullScreen)
    546     {
    547         // Get mode lines to see if there is requested modeline
    548         XF86VidModeGetAllModeLines(m_X11Display, m_X11Screen, &numModes, &modes);
    549 
    550         // look for mode with requested resolution
    551         chosenMode = -1;
    552         i=0;
    553         while((chosenMode == -1)&&(i<numModes))
    554         {
    555             if ((modes[i]->hdisplay == shell.m_pShellData->nShellDimX) && (modes[i]->vdisplay == shell.m_pShellData->nShellDimY))
    556             {
    557                 chosenMode = i;
    558             }
    559             ++i;
    560         }
    561 
    562         // If there is no requested resolution among modelines then terminate
    563         if(chosenMode == -1)
    564         {
    565             shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match any modeline available.\n" );
    566             return false;
    567         }
    568 
    569         // save desktop-resolution before switching modes
    570         XF86VidModeGetModeLine(m_X11Display,m_X11Screen, &m_i32OriginalModeDotClock, &m_OriginalMode );
    571 
    572         XF86VidModeSwitchToMode(m_X11Display, m_X11Screen, modes[chosenMode]);
    573         XF86VidModeSetViewPort(m_X11Display, m_X11Screen, 0, 0);
    574         edimx = modes[chosenMode]->hdisplay;
    575         edimy = modes[chosenMode]->vdisplay;
    576         printf("Fullscreen Resolution %dx%d (chosen mode = %d)\n", edimx, edimy,chosenMode);
    577         XFree(modes);
    578 
    579 		WinAttibutes.colormap = m_X11ColorMap;
    580 		WinAttibutes.background_pixel = 0xFFFFFFFF;
    581 		WinAttibutes.border_pixel = 0;
    582         WinAttibutes.override_redirect = true;
    583 
    584 		// add to these for handling other events
    585 		WinAttibutes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask;
    586 
    587         // The diffrence is that we want to ignore influence of window manager for our fullscreen window
    588         mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap | CWOverrideRedirect;
    589 
    590         m_X11Window = XCreateWindow( m_X11Display, RootWindow(m_X11Display, m_X11Screen), 0, 0, edimx, edimy, 0,
    591                                     CopyFromParent, InputOutput, CopyFromParent, mask, &WinAttibutes);
    592 
    593         // keeping the pointer of mouse and keyboard in window to prevent from scrolling the virtual screen
    594         XWarpPointer(m_X11Display, None ,m_X11Window, 0, 0, 0, 0, 0, 0);
    595 
    596         // Map and then wait till mapped, grabbing should be after mapping the window
    597         XMapWindow( m_X11Display, m_X11Window );
    598         XGrabKeyboard(m_X11Display, m_X11Window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
    599         XGrabPointer(m_X11Display, m_X11Window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_X11Window, None, CurrentTime);
    600         XIfEvent( m_X11Display, &event, WaitForMapNotify, (char*)m_X11Window );
    601 
    602     }
    603     else
    604 #endif
    605     {
    606         // For OGLES we assume that chaning of video mode is not available (freedesktop does not allow to do it)
    607         // so if requested resolution differs from the display dims then we quit
    608         #ifndef BUILD_OGL
    609         int display_width  = XDisplayWidth(m_X11Display,m_X11Screen);
    610         int display_height = XDisplayHeight(m_X11Display,m_X11Screen);
    611         if((shell.m_pShellData->bFullScreen)&&((shell.m_pShellData->nShellDimX != display_width)||(shell.m_pShellData->nShellDimY != display_height)) ) {
    612             shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match available modeline.\n" );
    613             return false;
    614         }
    615         #endif
    616 
    617 
    618 		WinAttibutes.colormap = m_X11ColorMap;
    619 		WinAttibutes.background_pixel = 0xFFFFFFFF;
    620 		WinAttibutes.border_pixel = 0;
    621 
    622 		// add to these for handling other events
    623 		WinAttibutes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask;
    624 
    625 		// The attribute mask
    626         mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap ;
    627 
    628         m_X11Window = XCreateWindow(  m_X11Display, 						// Display
    629 									RootWindow(m_X11Display, m_X11Screen), 	// Parent
    630 									shell.m_pShellData->nShellPosX, 	// X position of window
    631 									shell.m_pShellData->nShellPosY,		// Y position of window
    632 									shell.m_pShellData->nShellDimX,		// Window width
    633 									shell.m_pShellData->nShellDimY,		// Window height
    634 									0,									// Border width
    635 									CopyFromParent, 					// Depth (taken from parent)
    636 									InputOutput, 						// Window class
    637 									CopyFromParent, 					// Visual type (taken from parent)
    638 									mask, 								// Attributes mask
    639 									&WinAttibutes);						// Attributes
    640 
    641 		// Set the window position
    642         sh.flags = USPosition;
    643         sh.x = shell.m_pShellData->nShellPosX;
    644         sh.y = shell.m_pShellData->nShellPosY;
    645         XSetStandardProperties( m_X11Display, m_X11Window, shell.m_pShellData->pszAppName, shell.m_pShellData->pszAppName, None, 0, 0, &sh );
    646 
    647         // Map and then wait till mapped
    648         XMapWindow( m_X11Display, m_X11Window );
    649         XIfEvent( m_X11Display, &event, WaitForMapNotify, (char*)m_X11Window );
    650 
    651         // An attempt to hide a border for fullscreen on non OGL apis (OGLES,OGLES2)
    652         if(shell.m_pShellData->bFullScreen)
    653         {
    654 			XEvent xev;
    655 			Atom wmState = XInternAtom(m_X11Display, "_NET_WM_STATE", False);
    656 			Atom wmStateFullscreen = XInternAtom(m_X11Display, "_NET_WM_STATE_FULLSCREEN", False);
    657 
    658 			memset(&xev, 0, sizeof(XEvent));
    659 			xev.type = ClientMessage;
    660 			xev.xclient.window = m_X11Window;
    661 			xev.xclient.message_type = wmState;
    662 			xev.xclient.format = 32;
    663 			xev.xclient.data.l[0] = 1;
    664 			xev.xclient.data.l[1] = wmStateFullscreen;
    665 			xev.xclient.data.l[2] = 0;
    666 			XSendEvent(m_X11Display, RootWindow(m_X11Display, m_X11Screen), False, SubstructureNotifyMask, &xev);
    667         }
    668 
    669         Atom wmDelete = XInternAtom(m_X11Display, "WM_DELETE_WINDOW", True);
    670         XSetWMProtocols(m_X11Display, m_X11Window, &wmDelete, 1);
    671         XSetWMColormapWindows( m_X11Display, m_X11Window, &m_X11Window, 1 );
    672     }
    673 
    674     XFlush( m_X11Display );
    675 
    676     return true;
    677 }
    678 
    679 /*!***********************************************************************
    680  @Function		CloseX11Window
    681  @Return		void
    682  @Description	destroy the instance of a window, and release all relevent memory
    683 *************************************************************************/
    684 void PVRShellInitOS::CloseX11Window()
    685 {
    686     // revert introductional resolution (full screen case, bad clock is default value meaning that good was not acquired)
    687 #ifdef BUILD_OGL
    688     XF86VidModeModeInfo tmpmi;
    689 
    690     if(m_i32OriginalModeDotClock != XF86VidModeBadClock)
    691     {
    692         // revert desktop-resolution (stored previously) before exiting
    693         tmpmi.dotclock = m_i32OriginalModeDotClock;
    694         tmpmi.c_private = m_OriginalMode.c_private;
    695         tmpmi.flags = m_OriginalMode.flags;
    696         tmpmi.hdisplay = m_OriginalMode.hdisplay;
    697         tmpmi.hskew = m_OriginalMode.hskew;
    698         tmpmi.hsyncend = m_OriginalMode.hsyncend;
    699         tmpmi.hsyncstart = m_OriginalMode.hsyncstart;
    700         tmpmi.htotal = m_OriginalMode.htotal;
    701         tmpmi.privsize = m_OriginalMode.privsize;
    702         tmpmi.vdisplay = m_OriginalMode.vdisplay;
    703         tmpmi.vsyncend = m_OriginalMode.vsyncend;
    704         tmpmi.vsyncstart = m_OriginalMode.vsyncstart;
    705         tmpmi.vtotal = m_OriginalMode.vtotal;
    706 
    707         XF86VidModeSwitchToMode(m_X11Display,m_X11Screen,&tmpmi);
    708     }
    709 #endif
    710 
    711 	XDestroyWindow( m_X11Display, m_X11Window );
    712     XFreeColormap( m_X11Display, m_X11ColorMap );
    713 
    714 	if(m_X11Visual)
    715 		delete m_X11Visual;
    716 }
    717 
    718 /*****************************************************************************
    719  Global code
    720 *****************************************************************************/
    721 
    722 static Bool WaitForMapNotify( Display *d, XEvent *e, char *arg )
    723 {
    724 	return (e->type == MapNotify) && (e->xmap.window == (Window)arg);
    725 }
    726 
    727 /*!***************************************************************************
    728 @function		main
    729 @input			argc	count of args from OS
    730 @input			argv	array of args from OS
    731 @returns		result code to OS
    732 @description	Main function of the program
    733 *****************************************************************************/
    734 int main(int argc, char **argv)
    735 {
    736 	PVRShellInit init;
    737 
    738 	// Initialise the demo, process the command line, create the OS initialiser.
    739 	if(!init.Init())
    740 		return EXIT_ERR_CODE;
    741 
    742 	init.CommandLine((argc-1),&argv[1]);
    743 
    744 	// Initialise/run/shutdown
    745 	while(init.Run());
    746 
    747 	return EXIT_NOERR_CODE;
    748 }
    749 
    750 /// @endcond
    751 
    752 /*****************************************************************************
    753  End of file (PVRShellOS.cpp)
    754 *****************************************************************************/
    755 
    756