Separate GTK+ 4 wxDisplay implementation from previous versions

This makes the code more readable, even though it almost doubles its
size -- but the corresponding reduction in the number of preprocessor
checks is still worth it.
This commit is contained in:
Vadim Zeitlin
2018-10-04 23:01:27 +02:00
parent e0ba727dec
commit 5e6e7aa769

View File

@@ -21,71 +21,20 @@
#include <gdk/gdkx.h>
#endif
// This file is not used at all when using Win32.
#if !defined(GDK_WINDOWING_WIN32)
GdkWindow* wxGetTopLevelGDK();
//-----------------------------------------------------------------------------
#ifndef __WXGTK4__
#ifndef __WXGTK3__
static inline int wx_gdk_screen_get_primary_monitor(GdkScreen* screen)
{
int monitor = 0;
#if GTK_CHECK_VERSION(2,20,0)
if (wx_is_at_least_gtk2(20))
monitor = gdk_screen_get_primary_monitor(screen);
#endif
return monitor;
}
#define gdk_screen_get_primary_monitor wx_gdk_screen_get_primary_monitor
#endif // !__WXGTK3__
static inline void
wx_gdk_screen_get_monitor_workarea(GdkScreen* screen, int monitor, GdkRectangle* dest)
{
wxGCC_WARNING_SUPPRESS(deprecated-declarations)
#if GTK_CHECK_VERSION(3,4,0)
if (gtk_check_version(3,4,0) == NULL)
gdk_screen_get_monitor_workarea(screen, monitor, dest);
else
#endif
{
gdk_screen_get_monitor_geometry(screen, monitor, dest);
#ifdef wxGTK_HAVE_X11_DISPLAY
#ifdef __WXGTK3__
if (GDK_IS_X11_SCREEN(screen))
#endif
{
GdkRectangle rect = { 0, 0, 0, 0 };
wxGetWorkAreaX11(GDK_SCREEN_XSCREEN(screen),
rect.x, rect.y, rect.width, rect.height);
// in case _NET_WORKAREA result is too large
if (rect.width && rect.height)
gdk_rectangle_intersect(dest, &rect, dest);
}
#endif // wxGTK_HAVE_X11_DISPLAY
}
wxGCC_WARNING_RESTORE()
}
#define gdk_screen_get_monitor_workarea wx_gdk_screen_get_monitor_workarea
#endif // !__WXGTK4__
// There are 2 quite different implementations here: one for GTK+ 4 and the
// other one for the previous versions.
#ifdef __WXGTK4__
static inline GdkDisplay* GetDisplay()
{
return gdk_window_get_display(wxGetTopLevelGDK());
}
#else
static inline GdkScreen* GetScreen()
{
return gdk_window_get_screen(wxGetTopLevelGDK());
}
#endif
//-----------------------------------------------------------------------------
// This class is always defined as it's used for the main display even when
// wxUSE_DISPLAY == 0.
@@ -104,15 +53,9 @@ public:
virtual bool ChangeMode(const wxVideoMode& mode) wxOVERRIDE;
#endif // wxUSE_DISPLAY
#ifdef __WXGTK4__
GdkMonitor* const m_monitor;
#else
GdkScreen* const m_screen;
#endif
};
//-----------------------------------------------------------------------------
// This class is only defined when we're built with full display support.
#if wxUSE_DISPLAY
class wxDisplayFactoryGTK: public wxDisplayFactory
@@ -130,20 +73,13 @@ wxDisplayImpl* wxDisplayFactoryGTK::CreateDisplay(unsigned n)
unsigned wxDisplayFactoryGTK::GetCount()
{
#ifdef __WXGTK4__
return gdk_display_get_n_monitors(GetDisplay());
#else
wxGCC_WARNING_SUPPRESS(deprecated-declarations)
return gdk_screen_get_n_monitors(GetScreen());
wxGCC_WARNING_RESTORE()
#endif
return gdk_display_get_n_monitors(::GetDisplay());
}
int wxDisplayFactoryGTK::GetFromPoint(const wxPoint& pt)
{
GdkRectangle rect;
#ifdef __WXGTK4__
GdkDisplay* display = GetDisplay();
GdkDisplay* display = ::GetDisplay();
GdkMonitor* monitor = gdk_display_get_monitor_at_point(display, pt.x, pt.y);
gdk_monitor_get_geometry(monitor, &rect);
if (wxRect(rect.x, rect.y, rect.width, rect.height).Contains(pt))
@@ -155,76 +91,195 @@ int wxDisplayFactoryGTK::GetFromPoint(const wxPoint& pt)
}
}
return wxNOT_FOUND;
#else
GdkScreen* screen = GetScreen();
wxGCC_WARNING_SUPPRESS(deprecated-declarations)
int monitor = gdk_screen_get_monitor_at_point(screen, pt.x, pt.y);
gdk_screen_get_monitor_geometry(screen, monitor, &rect);
wxGCC_WARNING_RESTORE()
if (!wxRect(rect.x, rect.y, rect.width, rect.height).Contains(pt))
monitor = wxNOT_FOUND;
return monitor;
#endif
}
#endif // wxUSE_DISPLAY
//-----------------------------------------------------------------------------
wxDisplayImplGTK::wxDisplayImplGTK(unsigned i)
: base_type(i)
#ifdef __WXGTK4__
, m_monitor(gdk_display_get_monitor(GetDisplay(), i))
#else
, m_screen(GetScreen())
#endif
{
}
wxRect wxDisplayImplGTK::GetGeometry() const
{
GdkRectangle rect;
#ifdef __WXGTK4__
gdk_monitor_get_geometry(m_monitor, &rect);
#else
wxGCC_WARNING_SUPPRESS(deprecated-declarations)
gdk_screen_get_monitor_geometry(m_screen, m_index, &rect);
wxGCC_WARNING_RESTORE()
#endif
return wxRect(rect.x, rect.y, rect.width, rect.height);
}
wxRect wxDisplayImplGTK::GetClientArea() const
{
GdkRectangle rect;
#ifdef __WXGTK4__
gdk_monitor_get_workarea(m_monitor, &rect);
#else
wxGCC_WARNING_SUPPRESS(deprecated-declarations)
gdk_screen_get_monitor_workarea(m_screen, m_index, &rect);
wxGCC_WARNING_RESTORE()
#endif
return wxRect(rect.x, rect.y, rect.width, rect.height);
}
#if wxUSE_DISPLAY
bool wxDisplayImplGTK::IsPrimary() const
{
#ifdef __WXGTK4__
return gdk_monitor_is_primary(m_monitor) != 0;
#else
wxGCC_WARNING_SUPPRESS(deprecated-declarations)
return gdk_screen_get_primary_monitor(m_screen) == int(m_index);
wxGCC_WARNING_RESTORE()
}
wxArrayVideoModes
wxDisplayImplGTK::GetModes(const wxVideoMode& WXUNUSED(mode)) const
{
return wxArrayVideoModes();
}
wxVideoMode wxDisplayImplGTK::GetCurrentMode() const
{
return wxVideoMode();
}
bool wxDisplayImplGTK::ChangeMode(const wxVideoMode& WXUNUSED(mode))
{
return false;
}
#endif // wxUSE_DISPLAY
#else // !__WXGTK4__
#ifdef __WXGTK3__
static inline bool gdk_is_x11_screen(GdkScreen* screen)
{
return GDK_IS_X11_SCREEN(screen);
}
#else // !__WXGTK3__
static inline int wx_gdk_screen_get_primary_monitor(GdkScreen* screen)
{
int monitor = 0;
#if GTK_CHECK_VERSION(2,20,0)
if (wx_is_at_least_gtk2(20))
monitor = gdk_screen_get_primary_monitor(screen);
#endif
return monitor;
}
#define gdk_screen_get_primary_monitor wx_gdk_screen_get_primary_monitor
static inline bool gdk_is_x11_screen(GdkScreen* WXUNUSED(screen))
{
return true;
}
#endif // __WXGTK3__/!__WXGTK3__
static inline void
wx_gdk_screen_get_monitor_workarea(GdkScreen* screen, int monitor, GdkRectangle* dest)
{
wxGCC_WARNING_SUPPRESS(deprecated-declarations)
#if GTK_CHECK_VERSION(3,4,0)
if (gtk_check_version(3,4,0) == NULL)
gdk_screen_get_monitor_workarea(screen, monitor, dest);
else
#endif
{
gdk_screen_get_monitor_geometry(screen, monitor, dest);
#ifdef wxGTK_HAVE_X11_DISPLAY
if ( gdk_is_x11_screen(screen) )
{
GdkRectangle rect = { 0, 0, 0, 0 };
wxGetWorkAreaX11(GDK_SCREEN_XSCREEN(screen),
rect.x, rect.y, rect.width, rect.height);
// in case _NET_WORKAREA result is too large
if (rect.width && rect.height)
gdk_rectangle_intersect(dest, &rect, dest);
}
#endif // wxGTK_HAVE_X11_DISPLAY
}
wxGCC_WARNING_RESTORE()
}
#define gdk_screen_get_monitor_workarea wx_gdk_screen_get_monitor_workarea
static inline GdkScreen* GetScreen()
{
return gdk_window_get_screen(wxGetTopLevelGDK());
}
class wxDisplayImplGTK : public wxDisplayImpl
{
typedef wxDisplayImpl base_type;
public:
wxDisplayImplGTK(unsigned i);
virtual wxRect GetGeometry() const wxOVERRIDE;
virtual wxRect GetClientArea() const wxOVERRIDE;
#if wxUSE_DISPLAY
virtual bool IsPrimary() const wxOVERRIDE;
virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const wxOVERRIDE;
virtual wxVideoMode GetCurrentMode() const wxOVERRIDE;
virtual bool ChangeMode(const wxVideoMode& mode) wxOVERRIDE;
#endif // wxUSE_DISPLAY
GdkScreen* const m_screen;
};
#if wxUSE_DISPLAY
class wxDisplayFactoryGTK: public wxDisplayFactory
{
public:
virtual wxDisplayImpl* CreateDisplay(unsigned n) wxOVERRIDE;
virtual unsigned GetCount() wxOVERRIDE;
virtual int GetFromPoint(const wxPoint& pt) wxOVERRIDE;
};
wxGCC_WARNING_SUPPRESS(deprecated-declarations)
wxDisplayImpl* wxDisplayFactoryGTK::CreateDisplay(unsigned n)
{
return new wxDisplayImplGTK(n);
}
unsigned wxDisplayFactoryGTK::GetCount()
{
return gdk_screen_get_n_monitors(GetScreen());
}
int wxDisplayFactoryGTK::GetFromPoint(const wxPoint& pt)
{
GdkRectangle rect;
GdkScreen* screen = GetScreen();
int monitor = gdk_screen_get_monitor_at_point(screen, pt.x, pt.y);
gdk_screen_get_monitor_geometry(screen, monitor, &rect);
if (!wxRect(rect.x, rect.y, rect.width, rect.height).Contains(pt))
monitor = wxNOT_FOUND;
return monitor;
}
#endif // wxUSE_DISPLAY
wxDisplayImplGTK::wxDisplayImplGTK(unsigned i)
: base_type(i)
, m_screen(GetScreen())
{
}
wxRect wxDisplayImplGTK::GetGeometry() const
{
GdkRectangle rect;
gdk_screen_get_monitor_geometry(m_screen, m_index, &rect);
return wxRect(rect.x, rect.y, rect.width, rect.height);
}
wxRect wxDisplayImplGTK::GetClientArea() const
{
GdkRectangle rect;
gdk_screen_get_monitor_workarea(m_screen, m_index, &rect);
return wxRect(rect.x, rect.y, rect.width, rect.height);
}
#if wxUSE_DISPLAY
bool wxDisplayImplGTK::IsPrimary() const
{
return gdk_screen_get_primary_monitor(m_screen) == int(m_index);
}
wxArrayVideoModes wxDisplayImplGTK::GetModes(const wxVideoMode& mode) const
{
wxArrayVideoModes modes;
#ifdef wxGTK_HAVE_X11_DISPLAY
#ifdef __WXGTK3__
if (GDK_IS_X11_SCREEN(m_screen))
#endif
if ( gdk_is_x11_screen(m_screen) )
{
Display* display = GDK_DISPLAY_XDISPLAY(gdk_screen_get_display(m_screen));
#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
@@ -244,9 +299,7 @@ wxVideoMode wxDisplayImplGTK::GetCurrentMode() const
{
wxVideoMode mode;
#if defined(wxGTK_HAVE_X11_DISPLAY) && defined(HAVE_X11_EXTENSIONS_XF86VMODE_H)
#ifdef __WXGTK3__
if (GDK_IS_X11_SCREEN(m_screen))
#endif
if ( gdk_is_x11_screen(m_screen) )
{
Display* display = GDK_DISPLAY_XDISPLAY(gdk_screen_get_display(m_screen));
int nScreen = gdk_x11_screen_get_screen_number(m_screen);
@@ -260,9 +313,7 @@ bool wxDisplayImplGTK::ChangeMode(const wxVideoMode& mode)
{
bool success = false;
#if defined(wxGTK_HAVE_X11_DISPLAY) && defined(HAVE_X11_EXTENSIONS_XF86VMODE_H)
#ifdef __WXGTK3__
if (GDK_IS_X11_SCREEN(m_screen))
#endif
if ( gdk_is_x11_screen(m_screen) )
{
Display* display = GDK_DISPLAY_XDISPLAY(gdk_screen_get_display(m_screen));
int nScreen = gdk_x11_screen_get_screen_number(m_screen);
@@ -273,7 +324,14 @@ bool wxDisplayImplGTK::ChangeMode(const wxVideoMode& mode)
#endif
return success;
}
//-----------------------------------------------------------------------------
wxGCC_WARNING_RESTORE()
#endif // wxUSE_DISPLAY
#endif // __WXGTK4__/!__WXGTK4__
#if wxUSE_DISPLAY
wxDisplayFactory* wxDisplay::CreateFactory()
{