• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *************************************************************************/
PVRShellOutputDebug(char const * const format,...) const53 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 *************************************************************************/
OsInit()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 *************************************************************************/
OsInitOS()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 *************************************************************************/
OsReleaseOS()204 void PVRShellInit::OsReleaseOS()
205 {
206 	XCloseDisplay( m_X11Display );
207 }
208 
209 /*!***********************************************************************
210  @Function		OsExit
211  @description	Destroys main window
212 *************************************************************************/
OsExit()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 *************************************************************************/
OsDoInitAPI()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 *************************************************************************/
OsDoReleaseAPI()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 *************************************************************************/
OsRenderComplete()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 *************************************************************************/
OsPixmapCopy()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 *************************************************************************/
OsGetNativeDisplayType()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 *************************************************************************/
OsGetNativePixmapType()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 *************************************************************************/
OsGetNativeWindowType()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 *************************************************************************/
OsGet(const prefNameIntEnum prefName,int * pn)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 *************************************************************************/
OsGet(const prefNamePtrEnum prefName,void ** pp)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 *************************************************************************/
OsSet(const prefNameBoolEnum prefName,const bool value)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 *************************************************************************/
OsSet(const prefNameIntEnum prefName,const int i32Value)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 *************************************************************************/
OsDisplayDebugString(char const * const str)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 *************************************************************************/
OsGetTime()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 *************************************************************************/
OpenX11Window(const PVRShell & shell)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 *************************************************************************/
CloseX11Window()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 
WaitForMapNotify(Display * d,XEvent * e,char * arg)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 *****************************************************************************/
main(int argc,char ** argv)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