From 5e6e7aa7698b0b64dda557d51fe83f06bab07263 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 4 Oct 2018 23:01:27 +0200 Subject: [PATCH] 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. --- src/gtk/display.cpp | 284 ++++++++++++++++++++++++++------------------ 1 file changed, 171 insertions(+), 113 deletions(-) diff --git a/src/gtk/display.cpp b/src/gtk/display.cpp index b9eedf910b..a9ddf52d83 100644 --- a/src/gtk/display.cpp +++ b/src/gtk/display.cpp @@ -21,71 +21,20 @@ #include #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() {