Kaydet (Commit) b1c3f00d authored tarafından David Tardon's avatar David Tardon

rhbz#809019 count mirrored monitors as one

Change-Id: I I I184541e99ab4e04b8534dd0341bc2f3630094e9c
üst bcbf4b06
...@@ -151,6 +151,8 @@ public: ...@@ -151,6 +151,8 @@ public:
GdkDisplay* GetGdkDisplay() const { return m_pGdkDisplay; } GdkDisplay* GetGdkDisplay() const { return m_pGdkDisplay; }
bool IsX11Display() const { return m_bX11Display; } bool IsX11Display() const { return m_bX11Display; }
GtkSalSystem* getSystem() const { return m_pSys; }
virtual void deregisterFrame( SalFrame* pFrame ); virtual void deregisterFrame( SalFrame* pFrame );
GdkCursor *getCursor( PointerStyle ePointerStyle ); GdkCursor *getCursor( PointerStyle ePointerStyle );
virtual int CaptureMouse( SalFrame* pFrame ); virtual int CaptureMouse( SalFrame* pFrame );
......
...@@ -36,7 +36,11 @@ ...@@ -36,7 +36,11 @@
class GtkSalSystem : public SalGenericSystem class GtkSalSystem : public SalGenericSystem
{ {
typedef std::deque<std::pair<GdkScreen*, int> > ScreenMonitors_t;
GdkDisplay *mpDisplay; GdkDisplay *mpDisplay;
// Number of monitors for every active screen.
ScreenMonitors_t maScreenMonitors;
public: public:
GtkSalSystem(); GtkSalSystem();
virtual ~GtkSalSystem(); virtual ~GtkSalSystem();
...@@ -56,10 +60,11 @@ public: ...@@ -56,10 +60,11 @@ public:
{ return getXScreenFromDisplayScreen( GetDisplayDefaultScreen() ); } { return getXScreenFromDisplayScreen( GetDisplayDefaultScreen() ); }
int GetDisplayXScreenCount(); int GetDisplayXScreenCount();
SalX11Screen getXScreenFromDisplayScreen(unsigned int nDisplayScreen); SalX11Screen getXScreenFromDisplayScreen(unsigned int nDisplayScreen);
void countScreenMonitors();
// We have a 'screen' number that is combined from screen-idx + monitor-idx // We have a 'screen' number that is combined from screen-idx + monitor-idx
static int getScreenIdxFromPtr (GdkDisplay *pDisplay, GdkScreen *pScreen); int getScreenIdxFromPtr (GdkScreen *pScreen);
static int getScreenMonitorIdx (GdkDisplay *pDisplay, GdkScreen *pScreen, int nX, int nY); int getScreenMonitorIdx (GdkScreen *pScreen, int nX, int nY);
static GdkScreen *getScreenMonitorFromIdx (GdkDisplay *pDisplay, int nIdx, gint &nMonitor); GdkScreen *getScreenMonitorFromIdx (int nIdx, gint &nMonitor);
}; };
#endif // _VCL_GTKSYS_HXX_ #endif // _VCL_GTKSYS_HXX_
......
...@@ -197,12 +197,14 @@ GdkFilterReturn GtkSalDisplay::filterGdkEvent( GdkXEvent* sys_event, ...@@ -197,12 +197,14 @@ GdkFilterReturn GtkSalDisplay::filterGdkEvent( GdkXEvent* sys_event,
void GtkSalDisplay::screenSizeChanged( GdkScreen* pScreen ) void GtkSalDisplay::screenSizeChanged( GdkScreen* pScreen )
{ {
m_pSys->countScreenMonitors();
if (pScreen) if (pScreen)
emitDisplayChanged(); emitDisplayChanged();
} }
void GtkSalDisplay::monitorsChanged( GdkScreen* pScreen ) void GtkSalDisplay::monitorsChanged( GdkScreen* pScreen )
{ {
m_pSys->countScreenMonitors();
if (pScreen) if (pScreen)
emitDisplayChanged(); emitDisplayChanged();
} }
......
...@@ -49,6 +49,7 @@ SalSystem *GtkInstance::CreateSalSystem() ...@@ -49,6 +49,7 @@ SalSystem *GtkInstance::CreateSalSystem()
GtkSalSystem::GtkSalSystem() : SalGenericSystem() GtkSalSystem::GtkSalSystem() : SalGenericSystem()
{ {
mpDisplay = gdk_display_get_default(); mpDisplay = gdk_display_get_default();
countScreenMonitors();
} }
GtkSalSystem::~GtkSalSystem() GtkSalSystem::~GtkSalSystem()
...@@ -61,6 +62,52 @@ GtkSalSystem::GetDisplayXScreenCount() ...@@ -61,6 +62,52 @@ GtkSalSystem::GetDisplayXScreenCount()
return gdk_display_get_n_screens (mpDisplay); return gdk_display_get_n_screens (mpDisplay);
} }
namespace
{
struct GdkRectangleEqual
{
bool operator()(GdkRectangle const& rLeft, GdkRectangle const& rRight)
{
return
rLeft.x == rRight.x
&& rLeft.y == rRight.y
&& rLeft.width == rRight.width
&& rLeft.height == rRight.height
;
}
};
}
void
GtkSalSystem::countScreenMonitors()
{
maScreenMonitors.clear();
for (gint i = 0; i < gdk_display_get_n_screens(mpDisplay); i++)
{
GdkScreen* const pScreen(gdk_display_get_screen(mpDisplay, i));
gint nMonitors(pScreen ? gdk_screen_get_n_monitors(pScreen) : 0);
if (nMonitors > 1)
{
std::vector<GdkRectangle> aGeometries;
aGeometries.reserve(nMonitors);
for (gint j(0); j != nMonitors; ++j)
{
GdkRectangle aGeometry;
gdk_screen_get_monitor_geometry(pScreen, j, &aGeometry);
aGeometries.push_back(aGeometry);
}
GdkRectangleEqual aCmp;
std::sort(aGeometries.begin(), aGeometries.end(), aCmp);
const std::vector<GdkRectangle>::iterator aUniqueEnd(
std::unique(aGeometries.begin(), aGeometries.end(), aCmp));
nMonitors = std::distance(aGeometries.begin(), aUniqueEnd);
}
maScreenMonitors.push_back(std::make_pair(pScreen, nMonitors));
}
}
// Including gdkx.h kills us with the Window / XWindow conflict // Including gdkx.h kills us with the Window / XWindow conflict
extern "C" { extern "C" {
GType gdk_x11_display_get_type (void); GType gdk_x11_display_get_type (void);
...@@ -73,7 +120,7 @@ GtkSalSystem::getXScreenFromDisplayScreen(unsigned int nScreen) ...@@ -73,7 +120,7 @@ GtkSalSystem::getXScreenFromDisplayScreen(unsigned int nScreen)
gint nMonitor; gint nMonitor;
GdkScreen *pScreen = NULL; GdkScreen *pScreen = NULL;
pScreen = getScreenMonitorFromIdx (mpDisplay, nScreen, nMonitor); pScreen = getScreenMonitorFromIdx (nScreen, nMonitor);
if (!pScreen) if (!pScreen)
return SalX11Screen (0); return SalX11Screen (0);
#if GTK_CHECK_VERSION(3,0,0) #if GTK_CHECK_VERSION(3,0,0)
...@@ -84,16 +131,16 @@ GtkSalSystem::getXScreenFromDisplayScreen(unsigned int nScreen) ...@@ -84,16 +131,16 @@ GtkSalSystem::getXScreenFromDisplayScreen(unsigned int nScreen)
} }
GdkScreen * GdkScreen *
GtkSalSystem::getScreenMonitorFromIdx (GdkDisplay *pDisplay, int nIdx, gint &nMonitor) GtkSalSystem::getScreenMonitorFromIdx (int nIdx, gint &nMonitor)
{ {
GdkScreen *pScreen = NULL; GdkScreen *pScreen = NULL;
for (gint i = 0; i < gdk_display_get_n_screens (pDisplay); i++) for (ScreenMonitors_t::const_iterator aIt(maScreenMonitors.begin()), aEnd(maScreenMonitors.end()); aIt != aEnd; ++aIt)
{ {
pScreen = gdk_display_get_screen (pDisplay, i); pScreen = aIt->first;
if (!pScreen) if (!pScreen)
break; break;
if (nIdx >= gdk_screen_get_n_monitors (pScreen)) if (nIdx >= aIt->second)
nIdx -= gdk_screen_get_n_monitors (pScreen); nIdx -= aIt->second;
else else
break; break;
} }
...@@ -102,32 +149,34 @@ GtkSalSystem::getScreenMonitorFromIdx (GdkDisplay *pDisplay, int nIdx, gint &nMo ...@@ -102,32 +149,34 @@ GtkSalSystem::getScreenMonitorFromIdx (GdkDisplay *pDisplay, int nIdx, gint &nMo
} }
int int
GtkSalSystem::getScreenIdxFromPtr (GdkDisplay *pDisplay, GdkScreen *pScreen) GtkSalSystem::getScreenIdxFromPtr (GdkScreen *pScreen)
{ {
int nIdx = 0; int nIdx = 0;
for (gint i = 0; i < gdk_display_get_n_screens (pDisplay); i++) for (ScreenMonitors_t::const_iterator aIt(maScreenMonitors.begin()), aEnd(maScreenMonitors.end()); aIt != aEnd; ++aIt)
{ {
GdkScreen *pCmp = gdk_display_get_screen (pDisplay, i); if (aIt->first == pScreen)
if (pCmp == pScreen)
return nIdx; return nIdx;
nIdx += gdk_screen_get_n_monitors (pCmp); nIdx += aIt->second;
} }
g_warning ("failed to find screen %p", pScreen); g_warning ("failed to find screen %p", pScreen);
return 0; return 0;
} }
int GtkSalSystem::getScreenMonitorIdx (GdkDisplay *pDisplay, int GtkSalSystem::getScreenMonitorIdx (GdkScreen *pScreen,
GdkScreen *pScreen,
int nX, int nY) int nX, int nY)
{ {
return getScreenIdxFromPtr (pDisplay, pScreen) + // TODO: this will fail horribly for exotic combinations like two
// monitors in mirror mode and one extra. Hopefully such
// abominations are not used (or, even better, not possible) in
// practice .-)
return getScreenIdxFromPtr (pScreen) +
gdk_screen_get_monitor_at_point (pScreen, nX, nY); gdk_screen_get_monitor_at_point (pScreen, nX, nY);
} }
unsigned int GtkSalSystem::GetDisplayScreenCount() unsigned int GtkSalSystem::GetDisplayScreenCount()
{ {
gint nMonitor; gint nMonitor;
(void)getScreenMonitorFromIdx (mpDisplay, G_MAXINT, nMonitor); (void)getScreenMonitorFromIdx (G_MAXINT, nMonitor);
return G_MAXINT - nMonitor; return G_MAXINT - nMonitor;
} }
...@@ -183,7 +232,7 @@ static int _get_primary_monitor (GdkScreen *pScreen) ...@@ -183,7 +232,7 @@ static int _get_primary_monitor (GdkScreen *pScreen)
unsigned int GtkSalSystem::GetDisplayDefaultScreen() unsigned int GtkSalSystem::GetDisplayDefaultScreen()
{ {
GdkScreen *pDefault = gdk_display_get_default_screen (mpDisplay); GdkScreen *pDefault = gdk_display_get_default_screen (mpDisplay);
int idx = getScreenIdxFromPtr (mpDisplay, pDefault); int idx = getScreenIdxFromPtr (pDefault);
return idx + _get_primary_monitor (pDefault); return idx + _get_primary_monitor (pDefault);
} }
...@@ -192,7 +241,7 @@ Rectangle GtkSalSystem::GetDisplayScreenPosSizePixel (unsigned int nScreen) ...@@ -192,7 +241,7 @@ Rectangle GtkSalSystem::GetDisplayScreenPosSizePixel (unsigned int nScreen)
gint nMonitor; gint nMonitor;
GdkScreen *pScreen; GdkScreen *pScreen;
GdkRectangle aRect; GdkRectangle aRect;
pScreen = getScreenMonitorFromIdx (mpDisplay, nScreen, nMonitor); pScreen = getScreenMonitorFromIdx (nScreen, nMonitor);
if (!pScreen) if (!pScreen)
return Rectangle(); return Rectangle();
gdk_screen_get_monitor_geometry (pScreen, nMonitor, &aRect); gdk_screen_get_monitor_geometry (pScreen, nMonitor, &aRect);
...@@ -212,7 +261,7 @@ rtl::OUString GtkSalSystem::GetDisplayScreenName(unsigned int nScreen) ...@@ -212,7 +261,7 @@ rtl::OUString GtkSalSystem::GetDisplayScreenName(unsigned int nScreen)
gchar *pStr; gchar *pStr;
gint nMonitor; gint nMonitor;
GdkScreen *pScreen; GdkScreen *pScreen;
pScreen = getScreenMonitorFromIdx (mpDisplay, nScreen, nMonitor); pScreen = getScreenMonitorFromIdx (nScreen, nMonitor);
if (!pScreen) if (!pScreen)
return rtl::OUString(); return rtl::OUString();
......
...@@ -593,7 +593,7 @@ void GtkSalFrame::updateScreenNumber() ...@@ -593,7 +593,7 @@ void GtkSalFrame::updateScreenNumber()
int nScreen = 0; int nScreen = 0;
GdkScreen *pScreen = gtk_widget_get_screen( m_pWindow ); GdkScreen *pScreen = gtk_widget_get_screen( m_pWindow );
if( pScreen ) if( pScreen )
nScreen = GtkSalSystem::getScreenMonitorIdx( getGdkDisplay(), pScreen, maGeometry.nX, maGeometry.nY ); nScreen = getDisplay()->getSystem()->getScreenMonitorIdx( pScreen, maGeometry.nX, maGeometry.nY );
maGeometry.nDisplayScreenNumber = nScreen; maGeometry.nDisplayScreenNumber = nScreen;
} }
...@@ -1862,7 +1862,7 @@ void GtkSalFrame::SetScreen( unsigned int nNewScreen, int eType, Rectangle *pSiz ...@@ -1862,7 +1862,7 @@ void GtkSalFrame::SetScreen( unsigned int nNewScreen, int eType, Rectangle *pSiz
gint nMonitor; gint nMonitor;
GdkScreen *pScreen = NULL; GdkScreen *pScreen = NULL;
pScreen = GtkSalSystem::getScreenMonitorFromIdx( getGdkDisplay(), nNewScreen, nMonitor ); pScreen = getDisplay()->getSystem()->getScreenMonitorFromIdx( nNewScreen, nMonitor );
// Heavy lifting, need to move screen ... // Heavy lifting, need to move screen ...
if( pScreen != gtk_widget_get_screen( m_pWindow )) if( pScreen != gtk_widget_get_screen( m_pWindow ))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment