Skip to content
This repository
Browse code

X11: refresh window after having received xrandr event

  • Loading branch information...
commit 7ed3a94403dff461a3b32ab8d486f06fcfebea71 1 parent e9cb3ab
Rainer Hochecker authored
68 xbmc/windowing/X11/WinSystemX11.cpp
@@ -35,6 +35,8 @@
35 35 #include <X11/Xlib.h>
36 36 #include "cores/VideoRenderers/RenderManager.h"
37 37 #include "utils/TimeUtils.h"
  38 +#include "settings/AdvancedSettings.h"
  39 +#include "settings/GUISettings.h"
38 40
39 41 #if defined(HAS_XRANDR)
40 42 #include <X11/extensions/Xrandr.h>
@@ -52,6 +54,7 @@ CWinSystemX11::CWinSystemX11() : CWinSystemBase()
52 54 m_wmWindow = 0;
53 55 m_bWasFullScreenBeforeMinimize = false;
54 56 m_dpyLostTime = 0;
  57 + m_internalModeSwitch = false;
55 58
56 59 XSetErrorHandler(XErrorHandler);
57 60 }
@@ -178,6 +181,45 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n
178 181 return false;
179 182 }
180 183
  184 +void CWinSystemX11::RefreshWindow()
  185 +{
  186 + // save current mode if this is not an internal request
  187 + if (!m_internalModeSwitch)
  188 + {
  189 + CLog::Log(LOGNOTICE, "CWinSystemX11::RefreshWindow - external or initial xrandr event");
  190 + m_xrandrOut = g_xrandr.GetCurrentOutput();
  191 + m_xrandrMode = g_xrandr.GetCurrentMode(m_xrandrOut.name);
  192 + }
  193 + m_internalModeSwitch = false;
  194 +
  195 + g_xrandr.Query(true);
  196 + XOutput out = g_xrandr.GetCurrentOutput();
  197 + XMode mode = g_xrandr.GetCurrentMode(out.name);
  198 +
  199 + RESOLUTION_INFO res;
  200 + unsigned int i;
  201 + bool found(false);
  202 + for (i = RES_DESKTOP; i < g_settings.m_ResInfo.size(); ++i)
  203 + {
  204 + if (g_settings.m_ResInfo[i].strId == mode.id)
  205 + {
  206 + found = true;
  207 + break;
  208 + }
  209 + }
  210 +
  211 + if (!found)
  212 + {
  213 + CLog::Log(LOGERROR, "CWinSystemX11::RefreshWindow - could not find resolution");
  214 + return;
  215 + }
  216 +
  217 + g_graphicsContext.SetVideoResolution((RESOLUTION)i, true);
  218 + g_guiSettings.SetInt("window.width", mode.w);
  219 + g_guiSettings.SetInt("window.height", mode.h);
  220 + g_settings.Save();
  221 +}
  222 +
181 223 bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
182 224 {
183 225 m_nWidth = res.iWidth;
@@ -193,13 +235,32 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
193 235 mode.hz = res.fRefreshRate;
194 236 mode.id = res.strId;
195 237
196   - if(m_bFullScreen)
  238 + XOutput currout = g_xrandr.GetCurrentOutput();
  239 + XMode currmode = g_xrandr.GetCurrentMode(currout.name);
  240 +
  241 + if (m_xrandrOut.name.empty())
  242 + {
  243 + m_xrandrOut = currout;
  244 + m_xrandrMode = currmode;
  245 + }
  246 +
  247 + if(!m_bFullScreen)
197 248 {
  249 + // reset to mode we had before internal mode switch
  250 + out = m_xrandrOut;
  251 + mode = m_xrandrMode;
  252 + }
  253 +
  254 + // only call xrandr if mode changes
  255 + if (currout.name != out.name || currmode.w != mode.w || currmode.h != mode.h ||
  256 + currmode.hz != mode.hz || currmode.id != mode.id)
  257 + {
  258 + CLog::Log(LOGNOTICE, "CWinSystemX11::SetFullScreen - calling xrandr");
198 259 OnLostDevice();
  260 + m_internalModeSwitch = true;
199 261 g_xrandr.SetMode(out, mode);
200 262 }
201   - else
202   - g_xrandr.RestoreState();
  263 +
203 264 #endif
204 265
205 266 int options = SDL_OPENGL;
@@ -493,6 +554,7 @@ void CWinSystemX11::CheckDisplayEvents()
493 554 if (bGotEvent || bTimeout)
494 555 {
495 556 CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__);
  557 + RefreshWindow();
496 558
497 559 CSingleLock lock(m_resourceSection);
498 560
5 xbmc/windowing/X11/WinSystemX11.h
@@ -27,6 +27,7 @@
27 27 #include "utils/Stopwatch.h"
28 28 #include <GL/glx.h>
29 29 #include "threads/CriticalSection.h"
  30 +#include "XRandR.h"
30 31
31 32 class IDispResource;
32 33
@@ -60,6 +61,7 @@ class CWinSystemX11 : public CWinSystemBase
60 61 // Local to WinSystemX11 only
61 62 Display* GetDisplay() { return m_dpy; }
62 63 GLXWindow GetWindow() { return m_glWindow; }
  64 + void RefreshWindow();
63 65
64 66 protected:
65 67 bool RefreshGlxContext();
@@ -76,6 +78,9 @@ class CWinSystemX11 : public CWinSystemBase
76 78 CCriticalSection m_resourceSection;
77 79 std::vector<IDispResource*> m_resources;
78 80 uint64_t m_dpyLostTime;
  81 + XOutput m_xrandrOut;
  82 + XMode m_xrandrMode;
  83 + bool m_internalModeSwitch;
79 84
80 85 private:
81 86 bool IsSuitableVisual(XVisualInfo *vInfo);

0 comments on commit 7ed3a94

Please sign in to comment.
Something went wrong with that request. Please try again.