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