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