| /****************************************************************************** |
| |
| @File LinuxX11/PVRShellOS.cpp |
| |
| @Title LinuxX11/PVRShellOS |
| |
| @Version |
| |
| @Copyright Copyright (c) Imagination Technologies Limited. |
| |
| @Platform X11 |
| |
| @Description Makes programming for 3D APIs easier by wrapping window creation |
| and other functions for use by a demo. |
| |
| ******************************************************************************/ |
| |
| #include <sys/time.h> |
| #include <stdio.h> |
| #include <stdarg.h> |
| #include <time.h> |
| #include <unistd.h> |
| #include <string.h> |
| |
| #include "PVRShell.h" |
| #include "PVRShellAPI.h" |
| #include "PVRShellOS.h" |
| #include "PVRShellImpl.h" |
| |
| // No Doxygen for CPP files, due to documentation duplication |
| /// @cond NO_DOXYGEN |
| |
| /*!*************************************************************************** |
| Defines |
| *****************************************************************************/ |
| |
| /***************************************************************************** |
| Declarations |
| *****************************************************************************/ |
| static Bool WaitForMapNotify( Display *d, XEvent *e, char *arg ); |
| |
| /*!*************************************************************************** |
| Class: PVRShellInit |
| *****************************************************************************/ |
| |
| /*!*********************************************************************** |
| @Function PVRShellOutputDebug |
| @Input format printf style format followed by arguments it requires |
| @Description Writes the resultant string to the debug output (e.g. using |
| printf(), OutputDebugString(), ...). Check the SDK release notes for |
| details on how the string is output. |
| *************************************************************************/ |
| void PVRShell::PVRShellOutputDebug(char const * const format, ...) const |
| { |
| if(!format) |
| return; |
| |
| va_list arg; |
| char buf[1024]; |
| |
| va_start(arg, format); |
| vsnprintf(buf, 1024, format, arg); |
| va_end(arg); |
| |
| // Passes the data to a platform dependant function |
| m_pShellInit->OsDisplayDebugString(buf); |
| } |
| |
| /*!*********************************************************************** |
| @Function OsInit |
| @description Initialisation for OS-specific code. |
| *************************************************************************/ |
| void PVRShellInit::OsInit() |
| { |
| XInitThreads(); |
| |
| // set values to negative to mark that these are default values |
| m_pShell->m_pShellData->nShellDimX = -240; |
| m_pShell->m_pShellData->nShellDimY = -320; |
| |
| m_X11Display = NULL; |
| m_X11Visual = NULL; |
| |
| // Pixmap support: init variables to 0 |
| m_X11Pixmap = BadValue; |
| |
| /* |
| Construct the binary path for GetReadPath() and GetWritePath() |
| */ |
| // Get PID (Process ID) |
| pid_t ourPid = getpid(); |
| char *pszExePath, pszSrcLink[64]; |
| int len = 64; |
| int res; |
| |
| sprintf(pszSrcLink, "/proc/%d/exe", ourPid); |
| pszExePath = 0; |
| |
| do |
| { |
| len *= 2; |
| delete[] pszExePath; |
| pszExePath = new char[len]; |
| res = readlink(pszSrcLink, pszExePath, len); |
| |
| if(res < 0) |
| { |
| m_pShell->PVRShellOutputDebug("Warning Readlink %s failed. The application name, read path and write path have not been set.\n", pszExePath); |
| break; |
| } |
| } while(res >= len); |
| |
| if(res >= 0) |
| { |
| pszExePath[res] = '\0'; // Null-terminate readlink's result |
| SetReadPath(pszExePath); |
| SetWritePath(pszExePath); |
| SetAppName(pszExePath); |
| } |
| |
| delete[] pszExePath; |
| |
| m_u32ButtonState = 0; |
| |
| gettimeofday(&m_StartTime,NULL); |
| } |
| |
| /*!*********************************************************************** |
| @Function OsInitOS |
| @description Saves instance handle and creates main window |
| In this function, we save the instance handle in a global variable and |
| create and display the main program window. |
| *************************************************************************/ |
| bool PVRShellInit::OsInitOS() |
| { |
| m_X11Display = XOpenDisplay( NULL ); |
| |
| if(!m_X11Display) |
| { |
| m_pShell->PVRShellOutputDebug( "Unable to open X display\n"); |
| return false; |
| } |
| |
| m_X11Screen = XDefaultScreen( m_X11Display ); |
| |
| /* |
| If there is a full screen request then |
| set the window size to the display size. |
| If there is no full screen request then reduce window size while keeping |
| the same aspect by dividing the dims by two until it fits inside the display area. |
| If the position has not changed from its default value, set it to the middle of the screen. |
| */ |
| |
| int display_width = XDisplayWidth(m_X11Display,m_X11Screen); |
| int display_height = XDisplayHeight(m_X11Display,m_X11Screen); |
| |
| if(m_pShell->m_pShellData->bFullScreen) |
| { |
| // For OGL we do real fullscreen for others API set a window of fullscreen size |
| if(m_pShell->m_pShellData->nShellDimX < 0) { |
| m_pShell->m_pShellData->nShellDimX = display_width; |
| } |
| if(m_pShell->m_pShellData->nShellDimY < 0) { |
| m_pShell->m_pShellData->nShellDimY = display_height; |
| } |
| } |
| else |
| { |
| if(m_pShell->m_pShellData->nShellDimX < 0) |
| m_pShell->m_pShellData->nShellDimX = (display_width > display_height) ? 800 : 600; |
| |
| if(m_pShell->m_pShellData->nShellDimY < 0) |
| m_pShell->m_pShellData->nShellDimY = (display_width > display_height) ? 600 : 800; |
| |
| if(m_pShell->m_pShellData->nShellDimX > display_width) |
| m_pShell->m_pShellData->nShellDimX = display_width; |
| |
| if(m_pShell->m_pShellData->nShellDimY > display_height) |
| m_pShell->m_pShellData->nShellDimY = display_height; |
| } |
| |
| // Create the window |
| if(!OpenX11Window(*m_pShell)) |
| { |
| m_pShell->PVRShellOutputDebug( "Unable to open X11 window\n" ); |
| return false; |
| } |
| |
| // Pixmap support: create the pixmap |
| if(m_pShell->m_pShellData->bNeedPixmap) |
| { |
| int depth = DefaultDepth(m_X11Display, m_X11Screen); |
| m_X11Pixmap = XCreatePixmap(m_X11Display,m_X11Window,m_pShell->m_pShellData->nShellDimX,m_pShell->m_pShellData->nShellDimY,depth); |
| m_X11GC = XCreateGC(m_X11Display,m_X11Window,0,0); |
| } |
| |
| return true; |
| } |
| |
| /*!*********************************************************************** |
| @Function OsReleaseOS |
| @description Destroys main window |
| *************************************************************************/ |
| void PVRShellInit::OsReleaseOS() |
| { |
| XCloseDisplay( m_X11Display ); |
| } |
| |
| /*!*********************************************************************** |
| @Function OsExit |
| @description Destroys main window |
| *************************************************************************/ |
| void PVRShellInit::OsExit() |
| { |
| // Show the exit message to the user |
| m_pShell->PVRShellOutputDebug((const char*)m_pShell->PVRShellGet(prefExitMessage)); |
| } |
| |
| /*!*********************************************************************** |
| @Function OsDoInitAPI |
| @Return true on success |
| @description Perform API initialisation and bring up window / fullscreen |
| *************************************************************************/ |
| bool PVRShellInit::OsDoInitAPI() |
| { |
| if(!ApiInitAPI()) |
| { |
| return false; |
| } |
| |
| // No problem occured |
| return true; |
| } |
| |
| /*!*********************************************************************** |
| @Function OsDoReleaseAPI |
| @description Clean up after we're done |
| *************************************************************************/ |
| void PVRShellInit::OsDoReleaseAPI() |
| { |
| ApiReleaseAPI(); |
| |
| if(m_pShell->m_pShellData->bNeedPixmap) |
| { |
| // Pixmap support: free the pixmap |
| XFreePixmap(m_X11Display,m_X11Pixmap); |
| XFreeGC(m_X11Display,m_X11GC); |
| } |
| |
| CloseX11Window(); |
| } |
| |
| /*!*********************************************************************** |
| @Function OsRenderComplete |
| @Returns false when the app should quit |
| @description Main message loop / render loop |
| *************************************************************************/ |
| void PVRShellInit::OsRenderComplete() |
| { |
| int numMessages; |
| XEvent event; |
| char* atoms; |
| |
| // Are there messages waiting, maybe this should be a while loop |
| numMessages = XPending( m_X11Display ); |
| for( int i = 0; i < numMessages; i++ ) |
| { |
| XNextEvent( m_X11Display, &event ); |
| |
| switch( event.type ) |
| { |
| case ClientMessage: |
| atoms = XGetAtomName(m_X11Display, event.xclient.message_type); |
| if (*atoms == *"WM_PROTOCOLS") |
| { |
| gShellDone = true; |
| } |
| XFree(atoms); |
| break; |
| |
| case ButtonRelease: |
| { |
| XButtonEvent *button_event = ((XButtonEvent *) &event); |
| switch( button_event->button ) |
| { |
| case 1 : |
| { |
| m_u32ButtonState &= ~1; |
| |
| // Set the current pointer location |
| float vec2PointerLocation[2]; |
| vec2PointerLocation[0] = (float)button_event->x / (float)m_pShell->m_pShellData->nShellDimX; |
| vec2PointerLocation[1] = (float)button_event->y / (float)m_pShell->m_pShellData->nShellDimY; |
| TouchEnded(vec2PointerLocation); |
| } |
| break; |
| case 2 : m_u32ButtonState &= ~4; break; |
| case 3 : m_u32ButtonState &= ~2; break; |
| default : break; |
| } |
| break; |
| } |
| case ButtonPress: |
| { |
| XButtonEvent *button_event = ((XButtonEvent *) &event); |
| switch( button_event->button ) |
| { |
| case 1 : |
| { |
| m_u32ButtonState |= 1; |
| |
| // Set the current pointer location |
| float vec2PointerLocation[2]; |
| vec2PointerLocation[0] = (float)button_event->x / (float)m_pShell->m_pShellData->nShellDimX; |
| vec2PointerLocation[1] = (float)button_event->y / (float)m_pShell->m_pShellData->nShellDimY; |
| TouchBegan(vec2PointerLocation); |
| } |
| break; |
| case 2 : m_u32ButtonState |= 4; break; |
| case 3 : m_u32ButtonState |= 2; break; |
| default : break; |
| } |
| break; |
| } |
| case MotionNotify: |
| { |
| XMotionEvent *motion_event = ((XMotionEvent *) &event); |
| |
| // Set the current pointer location |
| float vec2PointerLocation[2]; |
| vec2PointerLocation[0] = (float)motion_event->x / (float)m_pShell->m_pShellData->nShellDimX; |
| vec2PointerLocation[1] = (float)motion_event->y / (float)m_pShell->m_pShellData->nShellDimY; |
| TouchMoved(vec2PointerLocation); |
| break; |
| } |
| // should SDK handle these? |
| case MapNotify: |
| case UnmapNotify: |
| break; |
| |
| case KeyPress: |
| { |
| XKeyEvent *key_event = ((XKeyEvent *) &event); |
| |
| switch(key_event->keycode) |
| { |
| case 9: nLastKeyPressed = PVRShellKeyNameQUIT; break; // Esc |
| case 95: nLastKeyPressed = PVRShellKeyNameScreenshot; break; // F11 |
| case 36: nLastKeyPressed = PVRShellKeyNameSELECT; break; // Enter |
| case 10: nLastKeyPressed = PVRShellKeyNameACTION1; break; // number 1 |
| case 11: nLastKeyPressed = PVRShellKeyNameACTION2; break; // number 2 |
| case 98: |
| case 111: nLastKeyPressed = m_eKeyMapUP; break; |
| case 104: |
| case 116: nLastKeyPressed = m_eKeyMapDOWN; break; |
| case 100: |
| case 113: nLastKeyPressed = m_eKeyMapLEFT; break; |
| case 102: |
| case 114: nLastKeyPressed = m_eKeyMapRIGHT; break; |
| default: |
| break; |
| } |
| } |
| break; |
| |
| case KeyRelease: |
| { |
| // char buf[10]; |
| // XLookupString(&event.xkey,buf,10,NULL,NULL); |
| // charsPressed[ (int) *buf ] = 0; |
| } |
| break; |
| |
| default: |
| break; |
| } |
| } |
| } |
| |
| /*!*********************************************************************** |
| @Function OsPixmapCopy |
| @Return true if the copy succeeded |
| @description When using pixmaps, copy the render to the display |
| *************************************************************************/ |
| bool PVRShellInit::OsPixmapCopy() |
| { |
| XCopyArea(m_X11Display,m_X11Pixmap,m_X11Window,m_X11GC,0,0,m_pShell->m_pShellData->nShellDimX,m_pShell->m_pShellData->nShellDimY,0,0); |
| return true; |
| } |
| |
| /*!*********************************************************************** |
| @Function OsGetNativeDisplayType |
| @Return The 'NativeDisplayType' for EGL |
| @description Called from InitAPI() to get the NativeDisplayType |
| *************************************************************************/ |
| void *PVRShellInit::OsGetNativeDisplayType() |
| { |
| return m_X11Display; |
| } |
| |
| /*!*********************************************************************** |
| @Function OsGetNativePixmapType |
| @Return The 'NativePixmapType' for EGL |
| @description Called from InitAPI() to get the NativePixmapType |
| *************************************************************************/ |
| void *PVRShellInit::OsGetNativePixmapType() |
| { |
| // Pixmap support: return the pixmap |
| return (void*)m_X11Pixmap; |
| } |
| |
| /*!*********************************************************************** |
| @Function OsGetNativeWindowType |
| @Return The 'NativeWindowType' for EGL |
| @description Called from InitAPI() to get the NativeWindowType |
| *************************************************************************/ |
| void *PVRShellInit::OsGetNativeWindowType() |
| { |
| return (void*)m_X11Window; |
| } |
| |
| /*!*********************************************************************** |
| @Function OsGet |
| @Input prefName Name of value to get |
| @Modified pn A pointer set to the value asked for |
| @Returns true on success |
| @Description Retrieves OS-specific data |
| *************************************************************************/ |
| bool PVRShellInit::OsGet(const prefNameIntEnum prefName, int *pn) |
| { |
| switch( prefName ) |
| { |
| case prefButtonState: |
| *pn = m_u32ButtonState; |
| return true; |
| default: |
| return false; |
| }; |
| |
| return false; |
| } |
| |
| /*!*********************************************************************** |
| @Function OsGet |
| @Input prefName Name of value to get |
| @Modified pp A pointer set to the value asked for |
| @Returns true on success |
| @Description Retrieves OS-specific data |
| *************************************************************************/ |
| bool PVRShellInit::OsGet(const prefNamePtrEnum prefName, void **pp) |
| { |
| return false; |
| } |
| |
| /*!*********************************************************************** |
| @Function OsSet |
| @Input prefName Name of preference to set to value |
| @Input value Value |
| @Return true for success |
| @Description Sets OS-specific data |
| *************************************************************************/ |
| bool PVRShellInit::OsSet(const prefNameBoolEnum prefName, const bool value) |
| { |
| return false; |
| } |
| |
| /*!*********************************************************************** |
| @Function OsSet |
| @Input prefName Name of value to set |
| @Input i32Value The value to set our named value to |
| @Returns true on success |
| @Description Sets OS-specific data |
| *************************************************************************/ |
| bool PVRShellInit::OsSet(const prefNameIntEnum prefName, const int i32Value) |
| { |
| return false; |
| } |
| |
| /*!*********************************************************************** |
| @Function OsDisplayDebugString |
| @Input str string to output |
| @Description Prints a debug string |
| *************************************************************************/ |
| void PVRShellInit::OsDisplayDebugString(char const * const str) |
| { |
| fprintf(stderr, "%s", str); |
| } |
| |
| /*!*********************************************************************** |
| @Function OsGetTime |
| @Return An incrementing time value measured in milliseconds |
| @Description Returns an incrementing time value measured in milliseconds |
| *************************************************************************/ |
| unsigned long PVRShellInit::OsGetTime() |
| { |
| timeval tv; |
| gettimeofday(&tv,NULL); |
| |
| if(tv.tv_sec < m_StartTime.tv_sec) |
| m_StartTime.tv_sec = 0; |
| |
| unsigned long sec = tv.tv_sec - m_StartTime.tv_sec; |
| return (unsigned long)((sec*(unsigned long)1000) + (tv.tv_usec/1000.0)); |
| } |
| |
| /***************************************************************************** |
| Class: PVRShellInitOS |
| *****************************************************************************/ |
| |
| /*!*********************************************************************** |
| @Function OpenX11Window |
| @Return true on success |
| @Description Opens an X11 window. This must be called after |
| SelectEGLConfiguration() for gEglConfig to be valid |
| *************************************************************************/ |
| int PVRShellInitOS::OpenX11Window(const PVRShell &shell) |
| { |
| XSetWindowAttributes WinAttibutes; |
| XSizeHints sh; |
| XEvent event; |
| unsigned long mask; |
| |
| #ifdef BUILD_OGL |
| XF86VidModeModeInfo **modes; // modes of display |
| int numModes; // number of modes of display |
| int chosenMode; |
| int edimx,edimy; //established width and height of the chosen modeline |
| int i; |
| #endif |
| |
| int depth = DefaultDepth(m_X11Display, m_X11Screen); |
| m_X11Visual = new XVisualInfo; |
| XMatchVisualInfo( m_X11Display, m_X11Screen, depth, TrueColor, m_X11Visual); |
| |
| if( !m_X11Visual ) |
| { |
| shell.PVRShellOutputDebug( "Unable to acquire visual" ); |
| return false; |
| } |
| |
| m_X11ColorMap = XCreateColormap( m_X11Display, RootWindow(m_X11Display, m_X11Screen), m_X11Visual->visual, AllocNone ); |
| |
| #ifdef BUILD_OGL |
| m_i32OriginalModeDotClock = XF86VidModeBadClock; |
| if(shell.m_pShellData->bFullScreen) |
| { |
| // Get mode lines to see if there is requested modeline |
| XF86VidModeGetAllModeLines(m_X11Display, m_X11Screen, &numModes, &modes); |
| |
| // look for mode with requested resolution |
| chosenMode = -1; |
| i=0; |
| while((chosenMode == -1)&&(i<numModes)) |
| { |
| if ((modes[i]->hdisplay == shell.m_pShellData->nShellDimX) && (modes[i]->vdisplay == shell.m_pShellData->nShellDimY)) |
| { |
| chosenMode = i; |
| } |
| ++i; |
| } |
| |
| // If there is no requested resolution among modelines then terminate |
| if(chosenMode == -1) |
| { |
| shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match any modeline available.\n" ); |
| return false; |
| } |
| |
| // save desktop-resolution before switching modes |
| XF86VidModeGetModeLine(m_X11Display,m_X11Screen, &m_i32OriginalModeDotClock, &m_OriginalMode ); |
| |
| XF86VidModeSwitchToMode(m_X11Display, m_X11Screen, modes[chosenMode]); |
| XF86VidModeSetViewPort(m_X11Display, m_X11Screen, 0, 0); |
| edimx = modes[chosenMode]->hdisplay; |
| edimy = modes[chosenMode]->vdisplay; |
| printf("Fullscreen Resolution %dx%d (chosen mode = %d)\n", edimx, edimy,chosenMode); |
| XFree(modes); |
| |
| WinAttibutes.colormap = m_X11ColorMap; |
| WinAttibutes.background_pixel = 0xFFFFFFFF; |
| WinAttibutes.border_pixel = 0; |
| WinAttibutes.override_redirect = true; |
| |
| // add to these for handling other events |
| WinAttibutes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask; |
| |
| // The diffrence is that we want to ignore influence of window manager for our fullscreen window |
| mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap | CWOverrideRedirect; |
| |
| m_X11Window = XCreateWindow( m_X11Display, RootWindow(m_X11Display, m_X11Screen), 0, 0, edimx, edimy, 0, |
| CopyFromParent, InputOutput, CopyFromParent, mask, &WinAttibutes); |
| |
| // keeping the pointer of mouse and keyboard in window to prevent from scrolling the virtual screen |
| XWarpPointer(m_X11Display, None ,m_X11Window, 0, 0, 0, 0, 0, 0); |
| |
| // Map and then wait till mapped, grabbing should be after mapping the window |
| XMapWindow( m_X11Display, m_X11Window ); |
| XGrabKeyboard(m_X11Display, m_X11Window, True, GrabModeAsync, GrabModeAsync, CurrentTime); |
| XGrabPointer(m_X11Display, m_X11Window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_X11Window, None, CurrentTime); |
| XIfEvent( m_X11Display, &event, WaitForMapNotify, (char*)m_X11Window ); |
| |
| } |
| else |
| #endif |
| { |
| // For OGLES we assume that chaning of video mode is not available (freedesktop does not allow to do it) |
| // so if requested resolution differs from the display dims then we quit |
| #ifndef BUILD_OGL |
| int display_width = XDisplayWidth(m_X11Display,m_X11Screen); |
| int display_height = XDisplayHeight(m_X11Display,m_X11Screen); |
| if((shell.m_pShellData->bFullScreen)&&((shell.m_pShellData->nShellDimX != display_width)||(shell.m_pShellData->nShellDimY != display_height)) ) { |
| shell.PVRShellOutputDebug( "Chosen resolution for full screen mode does not match available modeline.\n" ); |
| return false; |
| } |
| #endif |
| |
| |
| WinAttibutes.colormap = m_X11ColorMap; |
| WinAttibutes.background_pixel = 0xFFFFFFFF; |
| WinAttibutes.border_pixel = 0; |
| |
| // add to these for handling other events |
| WinAttibutes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask; |
| |
| // The attribute mask |
| mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap ; |
| |
| m_X11Window = XCreateWindow( m_X11Display, // Display |
| RootWindow(m_X11Display, m_X11Screen), // Parent |
| shell.m_pShellData->nShellPosX, // X position of window |
| shell.m_pShellData->nShellPosY, // Y position of window |
| shell.m_pShellData->nShellDimX, // Window width |
| shell.m_pShellData->nShellDimY, // Window height |
| 0, // Border width |
| CopyFromParent, // Depth (taken from parent) |
| InputOutput, // Window class |
| CopyFromParent, // Visual type (taken from parent) |
| mask, // Attributes mask |
| &WinAttibutes); // Attributes |
| |
| // Set the window position |
| sh.flags = USPosition; |
| sh.x = shell.m_pShellData->nShellPosX; |
| sh.y = shell.m_pShellData->nShellPosY; |
| XSetStandardProperties( m_X11Display, m_X11Window, shell.m_pShellData->pszAppName, shell.m_pShellData->pszAppName, None, 0, 0, &sh ); |
| |
| // Map and then wait till mapped |
| XMapWindow( m_X11Display, m_X11Window ); |
| XIfEvent( m_X11Display, &event, WaitForMapNotify, (char*)m_X11Window ); |
| |
| // An attempt to hide a border for fullscreen on non OGL apis (OGLES,OGLES2) |
| if(shell.m_pShellData->bFullScreen) |
| { |
| XEvent xev; |
| Atom wmState = XInternAtom(m_X11Display, "_NET_WM_STATE", False); |
| Atom wmStateFullscreen = XInternAtom(m_X11Display, "_NET_WM_STATE_FULLSCREEN", False); |
| |
| memset(&xev, 0, sizeof(XEvent)); |
| xev.type = ClientMessage; |
| xev.xclient.window = m_X11Window; |
| xev.xclient.message_type = wmState; |
| xev.xclient.format = 32; |
| xev.xclient.data.l[0] = 1; |
| xev.xclient.data.l[1] = wmStateFullscreen; |
| xev.xclient.data.l[2] = 0; |
| XSendEvent(m_X11Display, RootWindow(m_X11Display, m_X11Screen), False, SubstructureNotifyMask, &xev); |
| } |
| |
| Atom wmDelete = XInternAtom(m_X11Display, "WM_DELETE_WINDOW", True); |
| XSetWMProtocols(m_X11Display, m_X11Window, &wmDelete, 1); |
| XSetWMColormapWindows( m_X11Display, m_X11Window, &m_X11Window, 1 ); |
| } |
| |
| XFlush( m_X11Display ); |
| |
| return true; |
| } |
| |
| /*!*********************************************************************** |
| @Function CloseX11Window |
| @Return void |
| @Description destroy the instance of a window, and release all relevent memory |
| *************************************************************************/ |
| void PVRShellInitOS::CloseX11Window() |
| { |
| // revert introductional resolution (full screen case, bad clock is default value meaning that good was not acquired) |
| #ifdef BUILD_OGL |
| XF86VidModeModeInfo tmpmi; |
| |
| if(m_i32OriginalModeDotClock != XF86VidModeBadClock) |
| { |
| // revert desktop-resolution (stored previously) before exiting |
| tmpmi.dotclock = m_i32OriginalModeDotClock; |
| tmpmi.c_private = m_OriginalMode.c_private; |
| tmpmi.flags = m_OriginalMode.flags; |
| tmpmi.hdisplay = m_OriginalMode.hdisplay; |
| tmpmi.hskew = m_OriginalMode.hskew; |
| tmpmi.hsyncend = m_OriginalMode.hsyncend; |
| tmpmi.hsyncstart = m_OriginalMode.hsyncstart; |
| tmpmi.htotal = m_OriginalMode.htotal; |
| tmpmi.privsize = m_OriginalMode.privsize; |
| tmpmi.vdisplay = m_OriginalMode.vdisplay; |
| tmpmi.vsyncend = m_OriginalMode.vsyncend; |
| tmpmi.vsyncstart = m_OriginalMode.vsyncstart; |
| tmpmi.vtotal = m_OriginalMode.vtotal; |
| |
| XF86VidModeSwitchToMode(m_X11Display,m_X11Screen,&tmpmi); |
| } |
| #endif |
| |
| XDestroyWindow( m_X11Display, m_X11Window ); |
| XFreeColormap( m_X11Display, m_X11ColorMap ); |
| |
| if(m_X11Visual) |
| delete m_X11Visual; |
| } |
| |
| /***************************************************************************** |
| Global code |
| *****************************************************************************/ |
| |
| static Bool WaitForMapNotify( Display *d, XEvent *e, char *arg ) |
| { |
| return (e->type == MapNotify) && (e->xmap.window == (Window)arg); |
| } |
| |
| /*!*************************************************************************** |
| @function main |
| @input argc count of args from OS |
| @input argv array of args from OS |
| @returns result code to OS |
| @description Main function of the program |
| *****************************************************************************/ |
| int main(int argc, char **argv) |
| { |
| PVRShellInit init; |
| |
| // Initialise the demo, process the command line, create the OS initialiser. |
| if(!init.Init()) |
| return EXIT_ERR_CODE; |
| |
| init.CommandLine((argc-1),&argv[1]); |
| |
| // Initialise/run/shutdown |
| while(init.Run()); |
| |
| return EXIT_NOERR_CODE; |
| } |
| |
| /// @endcond |
| |
| /***************************************************************************** |
| End of file (PVRShellOS.cpp) |
| *****************************************************************************/ |
| |