diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h index 841293e09e4..e0b483d07fe 100644 --- a/intern/ghost/GHOST_ISystem.h +++ b/intern/ghost/GHOST_ISystem.h @@ -253,6 +253,7 @@ public: GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height, GHOST_TWindowState state, GHOST_TDrawingContextType type, const bool stereoVisual = false, + const bool exclusive = false, const GHOST_TUns16 numOfAASamples = 0, const GHOST_TEmbedderWindowID parentWindow = 0) = 0; diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index 4cf0dbfb820..a2d3e9b91fb 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -305,7 +305,10 @@ public: */ virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds, GHOST_TInt32 mouse_ungrab_xy[2]) { return GHOST_kSuccess; } - + /** */ + virtual GHOST_TSuccess beginFullScreen() const = 0; + virtual GHOST_TSuccess endFullScreen() const = 0; + virtual float getNativePixelSize(void) = 0; diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp index 080619bc0ac..5405fe7efe8 100644 --- a/intern/ghost/intern/GHOST_System.cpp +++ b/intern/ghost/intern/GHOST_System.cpp @@ -152,7 +152,7 @@ GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting& setting success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, setting); if (success == GHOST_kSuccess) { //GHOST_PRINT("GHOST_System::beginFullScreen(): creating full-screen window\n"); - success = createFullScreenWindow((GHOST_Window **)window, stereoVisual, numOfAASamples); + success = createFullScreenWindow((GHOST_Window **)window, setting, stereoVisual, numOfAASamples); if (success == GHOST_kSuccess) { m_windowManager->beginFullScreen(*window, stereoVisual); } @@ -347,26 +347,22 @@ GHOST_TSuccess GHOST_System::exit() return GHOST_kSuccess; } - -GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window, const bool stereoVisual, const GHOST_TUns16 numOfAASamples) +GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings, + const bool stereoVisual, const GHOST_TUns16 numOfAASamples) { - GHOST_TSuccess success; + /* note: don't use getCurrentDisplaySetting() because on X11 we may + * be zoomed in and the desktop may be bigger then the viewport. */ GHOST_ASSERT(m_displayManager, "GHOST_System::createFullScreenWindow(): invalid display manager"); - GHOST_DisplaySetting settings; - - success = m_displayManager->getCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, settings); - if (success) { - //GHOST_PRINT("GHOST_System::createFullScreenWindow(): creating full-screen window\n"); - *window = (GHOST_Window *)createWindow( - STR_String(""), - 0, 0, settings.xPixels, settings.yPixels, - GHOST_kWindowStateFullScreen, - GHOST_kDrawingContextTypeOpenGL, - stereoVisual, - numOfAASamples); - success = *window == 0 ? GHOST_kFailure : GHOST_kSuccess; - } - return success; + //GHOST_PRINT("GHOST_System::createFullScreenWindow(): creating full-screen window\n"); + *window = (GHOST_Window *)createWindow( + STR_String(""), + 0, 0, settings.xPixels, settings.yPixels, + GHOST_kWindowStateNormal, + GHOST_kDrawingContextTypeOpenGL, + stereoVisual, + true, /* exclusive */ + numOfAASamples); + return (*window == NULL) ? GHOST_kFailure : GHOST_kSuccess; } diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h index 928bbe6a31b..0d18dfe532f 100644 --- a/intern/ghost/intern/GHOST_System.h +++ b/intern/ghost/intern/GHOST_System.h @@ -330,7 +330,7 @@ protected: * \param window The window created. * \return Indication of success. */ - virtual GHOST_TSuccess createFullScreenWindow(GHOST_Window **window, + virtual GHOST_TSuccess createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings, const bool stereoVisual, const GHOST_TUns16 numOfAASamples = 0); /** The display manager (platform dependant). */ diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 48fb8375303..d00265fbd9b 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -278,6 +278,8 @@ getAllDisplayDimensions( * \param state The state of the window when opened. * \param type The type of drawing context installed in this window. * \param stereoVisual Stereo visual for quad buffered stereo. + * \param exclusive Use to show the window ontop and ignore others + * (used fullscreen). * \param numOfAASamples Number of samples used for AA (zero if no AA) * \param parentWindow Parent (embedder) window * \return The new window (or 0 if creation failed). @@ -292,7 +294,8 @@ createWindow( GHOST_TUns32 height, GHOST_TWindowState state, GHOST_TDrawingContextType type, - bool stereoVisual, + const bool stereoVisual, + const bool exclusive, const GHOST_TUns16 numOfAASamples, const GHOST_TEmbedderWindowID parentWindow) { @@ -305,7 +308,9 @@ createWindow( window = new GHOST_WindowX11(this, m_display, title, left, top, width, height, - state, parentWindow, type, stereoVisual, numOfAASamples); + state, parentWindow, type, + stereoVisual, exclusive, + numOfAASamples); if (window) { /* Both are now handle in GHOST_WindowX11.cpp diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h index a11aea240be..6a492f64b41 100644 --- a/intern/ghost/intern/GHOST_SystemX11.h +++ b/intern/ghost/intern/GHOST_SystemX11.h @@ -137,7 +137,9 @@ public: * \param height The height the window. * \param state The state of the window when opened. * \param type The type of drawing context installed in this window. - * \param stereoVisual Create a stereo visual for quad buffered stereo. + * \param stereoVisual Create a stereo visual for quad buffered stereo. + * \param exclusive Use to show the window ontop and ignore others + * (used fullscreen). * \param parentWindow Parent (embedder) window * \return The new window (or 0 if creation failed). */ @@ -151,6 +153,7 @@ public: GHOST_TWindowState state, GHOST_TDrawingContextType type, const bool stereoVisual, + const bool exclusive = false, const GHOST_TUns16 numOfAASamples = 0, const GHOST_TEmbedderWindowID parentWindow = 0 ); diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index ca12abe7324..6c2d7350cd9 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -45,6 +45,7 @@ GHOST_Window::GHOST_Window( GHOST_TWindowState state, GHOST_TDrawingContextType type, const bool stereoVisual, + const bool exclusive, const GHOST_TUns16 numOfAASamples) : m_drawingContextType(type), diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index f7c67bf7be6..588de0911e3 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -80,6 +80,8 @@ public: * \param state The state the window is initially opened with. * \param type The type of drawing context installed in this window. * \param stereoVisual Stereo visual for quad buffered stereo. + * \param exclusive Use to show the window ontop and ignore others + * (used fullscreen). * \param numOfAASamples Number of samples used for AA (zero if no AA) */ GHOST_Window( @@ -88,6 +90,7 @@ public: GHOST_TWindowState state, GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, const bool stereoVisual = false, + const bool exclusive = false, const GHOST_TUns16 numOfAASamples = 0); /** diff --git a/intern/ghost/intern/GHOST_WindowManager.cpp b/intern/ghost/intern/GHOST_WindowManager.cpp index daf1c2f2d22..1f20e01ca73 100644 --- a/intern/ghost/intern/GHOST_WindowManager.cpp +++ b/intern/ghost/intern/GHOST_WindowManager.cpp @@ -130,12 +130,12 @@ GHOST_TSuccess GHOST_WindowManager::beginFullScreen(GHOST_IWindow *window, m_fullScreenWindow = window; m_activeWindowBeforeFullScreen = getActiveWindow(); setActiveWindow(m_fullScreenWindow); + m_fullScreenWindow->beginFullScreen(); success = GHOST_kSuccess; } return success; } - GHOST_TSuccess GHOST_WindowManager::endFullScreen(void) { GHOST_TSuccess success = GHOST_kFailure; @@ -143,6 +143,7 @@ GHOST_TSuccess GHOST_WindowManager::endFullScreen(void) if (m_fullScreenWindow != 0) { //GHOST_PRINT("GHOST_WindowManager::endFullScreen(): deleting full-screen window\n"); setWindowInactive(m_fullScreenWindow); + m_fullScreenWindow->endFullScreen(); delete m_fullScreenWindow; //GHOST_PRINT("GHOST_WindowManager::endFullScreen(): done\n"); m_fullScreenWindow = 0; diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 8184475b610..05ab24492c2 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -165,9 +165,10 @@ GHOST_WindowX11( const GHOST_TEmbedderWindowID parentWindow, GHOST_TDrawingContextType type, const bool stereoVisual, + const bool exclusive, const GHOST_TUns16 numOfAASamples ) : - GHOST_Window(width, height, state, type, stereoVisual, numOfAASamples), + GHOST_Window(width, height, state, type, stereoVisual, exclusive, numOfAASamples), m_context(NULL), m_display(display), m_normal_state(GHOST_kWindowStateNormal), @@ -254,6 +255,7 @@ GHOST_WindowX11( * This seems pretty much a legacy feature as we are in rgba mode anyway. */ XSetWindowAttributes xattributes; + unsigned int xattributes_valuemask = (CWBorderPixel | CWColormap | CWEventMask); memset(&xattributes, 0, sizeof(xattributes)); xattributes.colormap = XCreateColormap(m_display, @@ -274,6 +276,11 @@ GHOST_WindowX11( PointerMotionMask | FocusChangeMask | PropertyChangeMask | KeymapStateMask; + if (exclusive) { + xattributes_valuemask |= CWOverrideRedirect; + xattributes.override_redirect = True; + } + /* create the window! */ if (parentWindow == 0) { m_window = XCreateWindow(m_display, @@ -286,7 +293,7 @@ GHOST_WindowX11( m_visual->depth, InputOutput, m_visual->visual, - CWBorderPixel | CWColormap | CWEventMask, + xattributes_valuemask, &xattributes ); } @@ -315,7 +322,7 @@ GHOST_WindowX11( m_visual->depth, InputOutput, m_visual->visual, - CWBorderPixel | CWColormap | CWEventMask, + xattributes_valuemask, &xattributes ); @@ -486,7 +493,12 @@ GHOST_WindowX11( GHOST_PRINT("Created window\n"); } - XMapWindow(m_display, m_window); + if (exclusive) { + XMapRaised(m_display, m_window); + } + else { + XMapWindow(m_display, m_window); + } GHOST_PRINT("Mapped window\n"); XFlush(m_display); @@ -1498,3 +1510,44 @@ setWindowCustomCursorShape( return GHOST_kSuccess; } + + +GHOST_TSuccess +GHOST_WindowX11:: +beginFullScreen() const +{ + { + Window root_return; + int x_return, y_return; + unsigned int w_return, h_return, border_w_return, depth_return; + + XGetGeometry(m_display, m_window, &root_return, &x_return, &y_return, + &w_return, &h_return, &border_w_return, &depth_return); + + m_system->setCursorPosition(w_return / 2, h_return / 2); + } + + + /* Grab Keyboard & Mouse */ + int err; + + err = XGrabKeyboard(m_display, m_window, False, + GrabModeAsync, GrabModeAsync, CurrentTime); + if (err != GrabSuccess) printf("XGrabKeyboard failed %d\n", err); + + err = XGrabPointer(m_display, m_window, False, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime); + if (err != GrabSuccess) printf("XGrabPointer failed %d\n", err); + + return GHOST_kSuccess; +} + +GHOST_TSuccess +GHOST_WindowX11:: +endFullScreen() const +{ + XUngrabKeyboard(m_display, CurrentTime); + XUngrabPointer(m_display, CurrentTime); + + return GHOST_kSuccess; +} diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h index 10d44987647..c009512a831 100644 --- a/intern/ghost/intern/GHOST_WindowX11.h +++ b/intern/ghost/intern/GHOST_WindowX11.h @@ -87,6 +87,7 @@ public: const GHOST_TEmbedderWindowID parentWindow, GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, const bool stereoVisual = false, + const bool exclusive = false, const GHOST_TUns16 numOfAASamples = 0 ); @@ -308,6 +309,12 @@ protected: int bg_color ); + GHOST_TSuccess + beginFullScreen() const; + + GHOST_TSuccess + endFullScreen() const; + private: /// Force use of public constructor. diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 89d11515bb3..f3f4c31149a 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -386,6 +386,7 @@ bool GPG_Application::startFullScreen( fSystem->beginFullScreen(setting, &m_mainWindow, stereoVisual, samples); m_mainWindow->setCursorVisibility(false); + /* note that X11 ignores this (it uses a window internally for fullscreen) */ m_mainWindow->setState(GHOST_kWindowStateFullScreen); success = initEngine(m_mainWindow, stereoMode);