Created
July 15, 2014 00:28
-
-
Save mikesart/63ce0e64f85ce10b5a50 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//----------------------------------------------------------------------------- | |
// Purpose: Returns bounds of the usable workspace area, including multiple monitors | |
//----------------------------------------------------------------------------- | |
void CLinuxSurface::GetWorkspaceBounds( int &x0, int &y0, int &x1, int &y1, VPANEL panel ) | |
{ | |
// Build list of monitors | |
CUtlVector<XineramaScreenInfo> monitors; | |
GetMonitorList(monitors); | |
// Get the bounds of the window we're dealing with. | |
int px = 0, py = 0, pw = 0, pt = 0; | |
if ( panel ) | |
{ | |
panel = GetContextPanelForChildPanel( panel ); | |
if ( panel ) | |
{ | |
g_pIPanel->GetPos( panel, px, py ); | |
g_pIPanel->GetSize( panel, pw, pt ); | |
} | |
} | |
// Work out which monitor best matches the window. | |
int iBestMonitor = 0; | |
int nBestIntersection = 0; | |
for ( int i = 0; i < monitors.Count(); i++ ) | |
{ | |
XineramaScreenInfo &monitorInfo = monitors[i]; | |
// Work out how much the monitor and the rectangle intersect. | |
int nIntersectX = MIN( px + pw, monitorInfo.x_org + monitorInfo.width ) - MAX( px, monitorInfo.x_org ); | |
int nIntersectY = MIN( py + pt, monitorInfo.y_org + monitorInfo.height ) - MAX( py, monitorInfo.y_org ); | |
// both intersections should be turned into 0 if they are negative | |
nIntersectX = nIntersectX > 0 ? nIntersectX : 0; | |
nIntersectY = nIntersectY > 0 ? nIntersectY : 0; | |
int nIntersection = nIntersectX * nIntersectY; | |
if ( nIntersection > nBestIntersection ) | |
{ | |
nBestIntersection = nIntersection; | |
iBestMonitor = i; | |
} | |
// "xrandr --primary" has the effect of setting the specified | |
// output as the first monitor returned by XineramaQueryScreens. | |
// So we use monitor 0 as the primary if there is no | |
// intersection. | |
} | |
// we've found the best monitor, return it | |
XineramaScreenInfo &monitorInfo = monitors[iBestMonitor]; | |
x0 = monitorInfo.x_org; | |
x1 = monitorInfo.x_org + monitorInfo.width; | |
y0 = monitorInfo.y_org; | |
y1 = monitorInfo.y_org + monitorInfo.height; | |
} | |
//----------------------------------------------------------------------------- | |
// Purpose: Returns the bounds of each monitor | |
//----------------------------------------------------------------------------- | |
bool CLinuxSurface::GetMonitorList(CUtlVector<XineramaScreenInfo >& monitorList) | |
{ | |
// Check to see if Xinerama is supported. If so, we will use | |
// that to enumerate the monitors. | |
int event_base = 0; | |
int error_base = 0; | |
int major, minor; | |
int screencount; | |
XineramaScreenInfo *xinerama = NULL; | |
if ( XineramaQueryExtension(m_pXDisplay, &event_base, &error_base) && | |
XineramaQueryVersion(m_pXDisplay, &major, &minor) && | |
XineramaIsActive(m_pXDisplay) && | |
((major != 0) || (minor != 0))) | |
{ | |
xinerama = XineramaQueryScreens(m_pXDisplay, &screencount); | |
} | |
if ( !xinerama ) | |
{ | |
// No Xinerama, just return the bounds of the entire display. | |
XineramaScreenInfo screenInfo; | |
screenInfo.screen_number = 0; | |
screenInfo.x_org = screenInfo.y_org = 0; | |
screenInfo.width = DisplayWidth(m_pXDisplay, m_XScreen); | |
screenInfo.height = DisplayHeight(m_pXDisplay, m_XScreen); | |
WaitForX(m_pXDisplay, false); | |
monitorList.AddToTail(screenInfo); | |
return true; | |
} | |
// Copy the returned screen info into the supplied vector. | |
for (int i=0; i<screencount; i++) | |
{ | |
monitorList.AddToTail(xinerama[i]); | |
} | |
XFree(xinerama); | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment