Permalink
Browse files

X11: refresh window after having received xrandr event

  • Loading branch information...
1 parent e9cb3ab commit 7ed3a94403dff461a3b32ab8d486f06fcfebea71 @FernetMenta committed Dec 21, 2011
Showing with 70 additions and 3 deletions.
  1. +65 −3 xbmc/windowing/X11/WinSystemX11.cpp
  2. +5 −0 xbmc/windowing/X11/WinSystemX11.h
View
68 xbmc/windowing/X11/WinSystemX11.cpp
@@ -35,6 +35,8 @@
#include <X11/Xlib.h>
#include "cores/VideoRenderers/RenderManager.h"
#include "utils/TimeUtils.h"
+#include "settings/AdvancedSettings.h"
+#include "settings/GUISettings.h"
#if defined(HAS_XRANDR)
#include <X11/extensions/Xrandr.h>
@@ -52,6 +54,7 @@ CWinSystemX11::CWinSystemX11() : CWinSystemBase()
m_wmWindow = 0;
m_bWasFullScreenBeforeMinimize = false;
m_dpyLostTime = 0;
+ m_internalModeSwitch = false;
XSetErrorHandler(XErrorHandler);
}
@@ -178,6 +181,45 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n
return false;
}
+void CWinSystemX11::RefreshWindow()
+{
+ // save current mode if this is not an internal request
+ if (!m_internalModeSwitch)
+ {
+ CLog::Log(LOGNOTICE, "CWinSystemX11::RefreshWindow - external or initial xrandr event");
+ m_xrandrOut = g_xrandr.GetCurrentOutput();
+ m_xrandrMode = g_xrandr.GetCurrentMode(m_xrandrOut.name);
+ }
+ m_internalModeSwitch = false;
+
+ g_xrandr.Query(true);
+ XOutput out = g_xrandr.GetCurrentOutput();
+ XMode mode = g_xrandr.GetCurrentMode(out.name);
+
+ RESOLUTION_INFO res;
+ unsigned int i;
+ bool found(false);
+ for (i = RES_DESKTOP; i < g_settings.m_ResInfo.size(); ++i)
+ {
+ if (g_settings.m_ResInfo[i].strId == mode.id)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution");
+ return;
+ }
+
+ g_graphicsContext.SetVideoResolution((RESOLUTION)i, true);
+ g_guiSettings.SetInt("window.width", mode.w);
+ g_guiSettings.SetInt("window.height", mode.h);
+ g_settings.Save();
+}
+
bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
{
m_nWidth = res.iWidth;
@@ -193,13 +235,32 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
mode.hz = res.fRefreshRate;
mode.id = res.strId;
- if(m_bFullScreen)
+ XOutput currout = g_xrandr.GetCurrentOutput();
+ XMode currmode = g_xrandr.GetCurrentMode(currout.name);
+
+ if (m_xrandrOut.name.empty())
+ {
+ m_xrandrOut = currout;
+ m_xrandrMode = currmode;
+ }
+
+ if(!m_bFullScreen)
{
+ // reset to mode we had before internal mode switch
+ out = m_xrandrOut;
+ mode = m_xrandrMode;
+ }
+
+ // only call xrandr if mode changes
+ if (currout.name != out.name || currmode.w != mode.w || currmode.h != mode.h ||
+ currmode.hz != mode.hz || currmode.id != mode.id)
+ {
+ CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr");
OnLostDevice();
+ m_internalModeSwitch = true;
g_xrandr.SetMode(out, mode);
}
- else
- g_xrandr.RestoreState();
+
#endif
int options = SDL_OPENGL;
@@ -493,6 +554,7 @@ void CWinSystemX11::CheckDisplayEvents()
if (bGotEvent || bTimeout)
{
CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__);
+ RefreshWindow();
CSingleLock lock(m_resourceSection);
View
5 xbmc/windowing/X11/WinSystemX11.h
@@ -27,6 +27,7 @@
#include "utils/Stopwatch.h"
#include <GL/glx.h>
#include "threads/CriticalSection.h"
+#include "XRandR.h"
class IDispResource;
@@ -60,6 +61,7 @@ class CWinSystemX11 : public CWinSystemBase
// Local to WinSystemX11 only
Display* GetDisplay() { return m_dpy; }
GLXWindow GetWindow() { return m_glWindow; }
+ void RefreshWindow();
protected:
bool RefreshGlxContext();
@@ -76,6 +78,9 @@ class CWinSystemX11 : public CWinSystemBase
CCriticalSection m_resourceSection;
std::vector<IDispResource*> m_resources;
uint64_t m_dpyLostTime;
+ XOutput m_xrandrOut;
+ XMode m_xrandrMode;
+ bool m_internalModeSwitch;
private:
bool IsSuitableVisual(XVisualInfo *vInfo);

0 comments on commit 7ed3a94

Please sign in to comment.