Permalink
Browse files

X11: support multiple xserver screens

  • Loading branch information...
1 parent 0b80d65 commit c7c6cb2253abe2a5e91c5d05cfba2f17b05f7f84 @elupus committed Jul 15, 2012
@@ -277,7 +277,7 @@ bool CVDPAU::MakePixmapGL()
};
GLXFBConfig *fbConfigs;
- fbConfigs = glXChooseFBConfig(m_Display, DefaultScreen(m_Display), doubleVisAttributes, &num);
+ fbConfigs = glXChooseFBConfig(m_Display, g_Windowing.GetVisual()->screen, doubleVisAttributes, &num);
if (fbConfigs==NULL)
{
CLog::Log(LOGERROR, "GLX Error: MakePixmap: No compatible framebuffers found");
@@ -328,10 +328,10 @@ bool CVDPAU::MakePixmap(int width, int height)
// Get our window attribs.
XWindowAttributes wndattribs;
- XGetWindowAttributes(m_Display, DefaultRootWindow(m_Display), &wndattribs); // returns a status but I don't know what success is
+ XGetWindowAttributes(m_Display, g_Windowing.GetWindow(), &wndattribs); // returns a status but I don't know what success is
m_Pixmap = XCreatePixmap(m_Display,
- DefaultRootWindow(m_Display),
+ g_Windowing.GetWindow(),
OutWidth,
OutHeight,
wndattribs.depth);
@@ -343,7 +343,7 @@ bool CVDPAU::MakePixmap(int width, int height)
XGCValues values = {};
GC xgc;
- values.foreground = BlackPixel (m_Display, DefaultScreen (m_Display));
+ values.foreground = BlackPixel (m_Display, g_Windowing.GetVisual()->screen);
xgc = XCreateGC(m_Display, m_Pixmap, GCForeground, &values);
XFillRectangle(m_Display, m_Pixmap, xgc, 0, 0, OutWidth, OutHeight);
XFreeGC(m_Display, xgc);
@@ -755,7 +755,7 @@ void CVDPAU::InitVDPAUProcs()
return;
}
- int mScreen = DefaultScreen(m_Display);
+ int mScreen = g_Windowing.GetVisual()->screen;
VdpStatus vdp_st;
// Create Device
View
@@ -95,6 +95,7 @@ struct RESOLUTION_INFO
CStdString strMode;
CStdString strOutput;
CStdString strId;
+ int iInternal; /* internal to windowing layer */
public:
RESOLUTION_INFO(int width = 1280, int height = 720, float aspect = 0, const CStdString &mode = "")
{
@@ -105,6 +106,7 @@ struct RESOLUTION_INFO
bFullScreen = true;
fRefreshRate = 0;
dwFlags = iSubtitles = iScreen = 0;
+ iInternal = 0;
}
float DisplayRatio() const
{
@@ -117,5 +119,6 @@ struct RESOLUTION_INFO
iSubtitles = res.iSubtitles; dwFlags = res.dwFlags;
fPixelRatio = res.fPixelRatio; fRefreshRate = res.fRefreshRate;
strMode = res.strMode; strOutput = res.strOutput; strId = res.strId;
+ iInternal = res.iInternal;
}
};
@@ -47,14 +47,15 @@ static bool SetOutputMode(RESOLUTION_INFO& res)
{
#if defined(HAS_XRANDR)
XOutput out;
- XMode mode = g_xrandr.GetCurrentMode(res.strOutput);
+ XMode mode = g_xrandr.GetCurrentMode(res.iInternal, res.strOutput);
/* mode matches so we are done */
if(res.strId == mode.id)
return false;
/* set up mode */
out.name = res.strOutput;
+ out.screen = res.iInternal;
mode.w = res.iWidth;
mode.h = res.iHeight;
mode.hz = res.fRefreshRate;
@@ -294,7 +295,7 @@ bool CWinSystemX11::CreateNewWindow(const CStdString& name, bool fullScreen, RES
XSetWindowAttributes swa = {0};
#if defined(HAS_XRANDR)
- XOutput out = g_xrandr.GetOutput(res.strOutput);
+ XOutput out = g_xrandr.GetOutput(m_visual->screen, res.strOutput);
if(out.isConnected)
{
x = out.x;
@@ -440,6 +441,15 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
OnLostDevice();
}
+ if(res.iInternal != m_visual->screen)
+ {
+ CreateNewWindow("", fullScreen, res, NULL);
+ m_bFullScreen = fullScreen;
+ m_outputName = res.strOutput;
+ m_outputIndex = res.iScreen;
+ return true;
+ }
+
XSetWindowAttributes attr = {0};
if(fullScreen)
attr.border_pixel = 0;
@@ -449,7 +459,7 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
int x = 0, y = 0;
#if defined(HAS_XRANDR)
- XOutput out = g_xrandr.GetOutput(res.strOutput);
+ XOutput out = g_xrandr.GetOutput(res.iInternal, res.strOutput);
if(out.isConnected)
{
x = out.x;
@@ -528,19 +538,20 @@ void CWinSystemX11::UpdateResolutions()
#if defined(HAS_XRANDR)
// add desktop modes
- g_xrandr.Query(true);
+ g_xrandr.Query(XScreenCount(m_dpy), true);
std::vector<XOutput> outs = g_xrandr.GetModes();
if(outs.size() > 0)
{
for(unsigned i = 0; i < outs.size(); ++i)
{
XOutput out = outs[i];
- XMode mode = g_xrandr.GetCurrentMode(out.name);
+ XMode mode = g_xrandr.GetCurrentMode(out.screen, out.name);
RESOLUTION_INFO res;
UpdateDesktopResolution(res, i, mode.w, mode.h, mode.hz);
res.strId = mode.id;
res.strOutput = out.name;
+ res.iInternal = out.screen;
g_settings.m_ResInfo.push_back(res);
}
}
@@ -551,6 +562,7 @@ void CWinSystemX11::UpdateResolutions()
int x11screen = DefaultScreen(m_dpy);
int w = DisplayWidth(m_dpy, x11screen);
int h = DisplayHeight(m_dpy, x11screen);
+ res.iInternal = x11screen;
UpdateDesktopResolution(res, 0, w, h, 0.0);
g_settings.m_ResInfo.push_back(res);
}
@@ -588,6 +600,7 @@ void CWinSystemX11::UpdateResolutions()
res.strOutput = out.name;
res.strId = mode.id;
res.iScreen = outiter - outs.begin();
+ res.iInternal = out.screen;
res.iSubtitles = (int)(0.95*mode.h);
res.fRefreshRate = mode.hz;
res.bFullScreen = true;
@@ -628,6 +641,8 @@ int CWinSystemX11::GetCurrentScreen()
for(unsigned i = 0; i < outs.size(); ++i)
{
XOutput out = outs[i];
+ if(out.screen != m_visual->screen)
+ continue;
int w = std::max(0, std::min(m_nLeft + m_nWidth , out.x + out.w) - std::max(m_nLeft, out.x));
int h = std::max(0, std::min(m_nTop + m_nHeight, out.y + out.h) - std::max(m_nTop , out.y));
@@ -742,7 +757,7 @@ void CWinSystemX11::NotifyXRREvent()
CLog::Log(LOGDEBUG, "%s - notify display reset event", __FUNCTION__);
#if defined(HAS_XRANDR)
- g_xrandr.Query(true);
+ g_xrandr.Query(XScreenCount(m_dpy), true);
#endif
OnResetDevice();
}
@@ -73,6 +73,7 @@ class CWinSystemX11 : public CWinSystemBase
// Local to WinSystemX11 only
Display* GetDisplay() { return m_dpy; }
GLXWindow GetWindow() { return m_glWindow; }
+ XVisualInfo* GetVisual() { return m_visual; }
void NotifyXRREvent();
protected:
@@ -237,14 +237,13 @@ bool CWinSystemX11GL::CreateNewWindow(const CStdString& name, bool fullScreen, R
DestroyWindow();
- m_visual = glXChooseVisual(m_dpy, DefaultScreen(m_dpy), att);
+ m_visual = glXChooseVisual(m_dpy, res.iInternal, att);
if(m_visual == NULL)
{
CLog::Log(LOGERROR, "CWinSystemX11GL::CreateNewWindow - failed to create visual");
return false;
}
-
if(!CWinSystemX11::CreateNewWindow(name, fullScreen, res, userFunction))
return false;
@@ -264,7 +263,7 @@ bool CWinSystemX11GL::CreateNewWindow(const CStdString& name, bool fullScreen, R
m_glWindow = m_wmWindow;
m_glxext = " ";
- m_glxext += (const char*)glXQueryExtensionsString(m_dpy, DefaultScreen(m_dpy));
+ m_glxext += (const char*)glXQueryExtensionsString(m_dpy, m_visual->screen);
m_glxext += " ";
CLog::Log(LOGDEBUG, "GLX_EXTENSIONS:%s", m_glxext.c_str());
@@ -36,14 +36,12 @@
using namespace std;
-CXRandR::CXRandR(bool query)
+CXRandR::CXRandR()
{
m_bInit = false;
- if (query)
- Query();
}
-bool CXRandR::Query(bool force)
+bool CXRandR::Query(int screens, bool force)
{
if (!force)
if (m_bInit)
@@ -55,11 +53,21 @@ bool CXRandR::Query(bool force)
return false;
m_outputs.clear();
- m_current.clear();
+ // query all screens
+ for(int screennum=0; screennum<screens; ++screennum)
+ {
+ if(!Query(screennum))
+ return false;
+ }
+ return true;
+}
+bool CXRandR::Query(int screennum)
+{
CStdString cmd;
cmd = getenv("XBMC_BIN_HOME");
cmd += "/xbmc-xrandr";
+ cmd.AppendFormat(" -q --screen %d", screennum);
FILE* file = popen(cmd.c_str(),"r");
if (!file)
@@ -79,11 +87,6 @@ bool CXRandR::Query(bool force)
pclose(file);
TiXmlElement *pRootElement = xmlDoc.RootElement();
- if (strcasecmp(pRootElement->Value(), "screen") != 0)
- {
- // TODO ERROR
- return false;
- }
for (TiXmlElement* output = pRootElement->FirstChildElement("output"); output; output = output->NextSiblingElement("output"))
{
@@ -92,6 +95,7 @@ bool CXRandR::Query(bool force)
xoutput.name.TrimLeft(" \n\r\t");
xoutput.name.TrimRight(" \n\r\t");
xoutput.isConnected = (strcasecmp(output->Attribute("connected"), "true") == 0);
+ xoutput.screen = screennum;
xoutput.w = (output->Attribute("w") != NULL ? atoi(output->Attribute("w")) : 0);
xoutput.h = (output->Attribute("h") != NULL ? atoi(output->Attribute("h")) : 0);
xoutput.x = (output->Attribute("x") != NULL ? atoi(output->Attribute("x")) : 0);
@@ -142,7 +146,8 @@ bool CXRandR::SetMode(XOutput output, XMode mode)
XOutput outputFound;
for (size_t i = 0; i < m_outputs.size(); i++)
{
- if (m_outputs[i].name == output.name)
+ if (m_outputs[i].name == output.name
+ && m_outputs[i].screen == output.screen)
{
isOutputFound = true;
outputFound = m_outputs[i];
@@ -215,7 +220,7 @@ bool CXRandR::SetMode(XOutput output, XMode mode)
char cmd[255];
if (getenv("XBMC_BIN_HOME"))
- snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --output %s --mode %s", getenv("XBMC_BIN_HOME"), outputFound.name.c_str(), modeFound.id.c_str());
+ snprintf(cmd, sizeof(cmd), "%s/xbmc-xrandr --screen %d --output %s --mode %s", getenv("XBMC_BIN_HOME"), outputFound.screen, outputFound.name.c_str(), modeFound.id.c_str());
else
return false;
CLog::Log(LOGINFO, "XRANDR: %s", cmd);
@@ -229,13 +234,14 @@ bool CXRandR::SetMode(XOutput output, XMode mode)
return true;
}
-XMode CXRandR::GetCurrentMode(CStdString outputName)
+XMode CXRandR::GetCurrentMode(int screen, CStdString outputName)
{
XMode result;
for (unsigned int j = 0; j < m_outputs.size(); j++)
{
- if (m_outputs[j].name == outputName || outputName == "")
+ if ((m_outputs[j].name == outputName || outputName == "")
+ && (m_outputs[j].screen == screen))
{
for (unsigned int i = 0; i < m_outputs[j].modes.size(); i++)
{
@@ -300,12 +306,13 @@ void CXRandR::LoadCustomModeLinesToAllOutputs(void)
}
}
-XOutput CXRandR::GetOutput(CStdString outputName)
+XOutput CXRandR::GetOutput(int screen, CStdString outputName)
{
XOutput result;
for (unsigned int i = 0; i < m_outputs.size(); ++i)
{
- if (m_outputs[i].name == outputName)
+ if ((m_outputs[i].name == outputName || outputName == "")
+ && (m_outputs[i].screen == screen))
{
result = m_outputs[i];
break;
@@ -76,9 +76,11 @@ class XOutput
name="";
isConnected=false;
w=h=x=y=wmm=hmm=0;
+ screen=0;
}
CStdString name;
bool isConnected;
+ int screen;
int w;
int h;
int x;
@@ -91,15 +93,16 @@ class XOutput
class CXRandR
{
public:
- CXRandR(bool query=false);
- bool Query(bool force=false);
+ CXRandR();
+ bool Query(int screens, bool force);
std::vector<XOutput> GetModes(void);
- XMode GetCurrentMode(CStdString outputName);
- XOutput GetOutput(CStdString outputName);
+ XMode GetCurrentMode(int screen, CStdString outputName);
+ XOutput GetOutput(int screen, CStdString outputName);
bool SetMode(XOutput output, XMode mode);
void LoadCustomModeLinesToAllOutputs(void);
private:
+ bool Query(int screen);
bool m_bInit;
std::vector<XOutput> m_outputs;
};

0 comments on commit c7c6cb2

Please sign in to comment.