From 0e212a65eb600d217b98a4e68c7abf952f6c8f3f Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Thu, 17 Apr 2014 17:36:10 +0000 Subject: [PATCH] Add a separate GTK-specific wxDisplay implementation. This separates the GTK implementation from Unix/X11, except for the wxVideoMode stuff, and _NET_WORKAREA when GTK < 3.4. wxDisplay and wxClientDisplayRect() should now work as well as they can with Wayland. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76365 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- Makefile.in | 40 ++++++ build/bakefiles/files.bkl | 1 + src/gtk/display.cpp | 239 +++++++++++++++++++++++++++++++++++ src/unix/displayx11.cpp | 257 +++++++++++++------------------------- 4 files changed, 369 insertions(+), 168 deletions(-) create mode 100644 src/gtk/display.cpp diff --git a/Makefile.in b/Makefile.in index 67573fec2b..59a2986ae0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -5234,6 +5234,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___LOWLEVEL_SRC_OBJECTS = \ monodll_gtk_cursor.o \ monodll_gtk_dataobj.o \ monodll_gtk_dc.o \ + monodll_gtk_display.o \ monodll_gtk_dnd.o \ monodll_gtk_evtloop.o \ monodll_filectrl.o \ @@ -5272,6 +5273,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_3___LOWLEVEL_SRC_OBJECTS = \ monodll_gtk_cursor.o \ monodll_gtk_dataobj.o \ monodll_gtk_dc.o \ + monodll_gtk_display.o \ monodll_gtk_dnd.o \ monodll_gtk_evtloop.o \ monodll_filectrl.o \ @@ -6182,6 +6184,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___LOWLEVEL_SRC_OBJECTS_1 = \ monodll_gtk_cursor.o \ monodll_gtk_dataobj.o \ monodll_gtk_dc.o \ + monodll_gtk_display.o \ monodll_gtk_dnd.o \ monodll_gtk_evtloop.o \ monodll_filectrl.o \ @@ -6220,6 +6223,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_3___LOWLEVEL_SRC_OBJECTS_1 = \ monodll_gtk_cursor.o \ monodll_gtk_dataobj.o \ monodll_gtk_dc.o \ + monodll_gtk_display.o \ monodll_gtk_dnd.o \ monodll_gtk_evtloop.o \ monodll_filectrl.o \ @@ -7483,6 +7487,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___LOWLEVEL_SRC_OBJECTS_2 = \ monolib_gtk_cursor.o \ monolib_gtk_dataobj.o \ monolib_gtk_dc.o \ + monolib_gtk_display.o \ monolib_gtk_dnd.o \ monolib_gtk_evtloop.o \ monolib_filectrl.o \ @@ -7521,6 +7526,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_3___LOWLEVEL_SRC_OBJECTS_2 = \ monolib_gtk_cursor.o \ monolib_gtk_dataobj.o \ monolib_gtk_dc.o \ + monolib_gtk_display.o \ monolib_gtk_dnd.o \ monolib_gtk_evtloop.o \ monolib_filectrl.o \ @@ -8431,6 +8437,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___LOWLEVEL_SRC_OBJECTS_3 = \ monolib_gtk_cursor.o \ monolib_gtk_dataobj.o \ monolib_gtk_dc.o \ + monolib_gtk_display.o \ monolib_gtk_dnd.o \ monolib_gtk_evtloop.o \ monolib_filectrl.o \ @@ -8469,6 +8476,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_3___LOWLEVEL_SRC_OBJECTS_3 = \ monolib_gtk_cursor.o \ monolib_gtk_dataobj.o \ monolib_gtk_dc.o \ + monolib_gtk_display.o \ monolib_gtk_dnd.o \ monolib_gtk_evtloop.o \ monolib_filectrl.o \ @@ -9905,6 +9913,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___LOWLEVEL_SRC_OBJECTS_4 = \ coredll_gtk_cursor.o \ coredll_gtk_dataobj.o \ coredll_gtk_dc.o \ + coredll_gtk_display.o \ coredll_gtk_dnd.o \ coredll_gtk_evtloop.o \ coredll_filectrl.o \ @@ -9943,6 +9952,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_3___LOWLEVEL_SRC_OBJECTS_4 = \ coredll_gtk_cursor.o \ coredll_gtk_dataobj.o \ coredll_gtk_dc.o \ + coredll_gtk_display.o \ coredll_gtk_dnd.o \ coredll_gtk_evtloop.o \ coredll_filectrl.o \ @@ -10853,6 +10863,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___LOWLEVEL_SRC_OBJECTS_5 = \ coredll_gtk_cursor.o \ coredll_gtk_dataobj.o \ coredll_gtk_dc.o \ + coredll_gtk_display.o \ coredll_gtk_dnd.o \ coredll_gtk_evtloop.o \ coredll_filectrl.o \ @@ -10891,6 +10902,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_3___LOWLEVEL_SRC_OBJECTS_5 = \ coredll_gtk_cursor.o \ coredll_gtk_dataobj.o \ coredll_gtk_dc.o \ + coredll_gtk_display.o \ coredll_gtk_dnd.o \ coredll_gtk_evtloop.o \ coredll_filectrl.o \ @@ -11582,6 +11594,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___LOWLEVEL_SRC_OBJECTS_6 = \ corelib_gtk_cursor.o \ corelib_gtk_dataobj.o \ corelib_gtk_dc.o \ + corelib_gtk_display.o \ corelib_gtk_dnd.o \ corelib_gtk_evtloop.o \ corelib_filectrl.o \ @@ -11620,6 +11633,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_3___LOWLEVEL_SRC_OBJECTS_6 = \ corelib_gtk_cursor.o \ corelib_gtk_dataobj.o \ corelib_gtk_dc.o \ + corelib_gtk_display.o \ corelib_gtk_dnd.o \ corelib_gtk_evtloop.o \ corelib_filectrl.o \ @@ -12530,6 +12544,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___LOWLEVEL_SRC_OBJECTS_7 = \ corelib_gtk_cursor.o \ corelib_gtk_dataobj.o \ corelib_gtk_dc.o \ + corelib_gtk_display.o \ corelib_gtk_dnd.o \ corelib_gtk_evtloop.o \ corelib_filectrl.o \ @@ -12568,6 +12583,7 @@ COND_TOOLKIT_GTK_TOOLKIT_VERSION_3___LOWLEVEL_SRC_OBJECTS_7 = \ corelib_gtk_cursor.o \ corelib_gtk_dataobj.o \ corelib_gtk_dc.o \ + corelib_gtk_display.o \ corelib_gtk_dnd.o \ corelib_gtk_evtloop.o \ corelib_filectrl.o \ @@ -19431,6 +19447,12 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@monodll_gtk_dc.o: $(srcdir)/src/gtk/dc.cpp $(MONODLL_ODEP) @COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/gtk/dc.cpp +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@monodll_gtk_display.o: $(srcdir)/src/gtk/display.cpp $(MONODLL_ODEP) +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/gtk/display.cpp + +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@monodll_gtk_display.o: $(srcdir)/src/gtk/display.cpp $(MONODLL_ODEP) +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/gtk/display.cpp + @COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@monodll_gtk_dnd.o: $(srcdir)/src/gtk/dnd.cpp $(MONODLL_ODEP) @COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/gtk/dnd.cpp @@ -25302,6 +25324,12 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@monolib_gtk_dc.o: $(srcdir)/src/gtk/dc.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/gtk/dc.cpp +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@monolib_gtk_display.o: $(srcdir)/src/gtk/display.cpp $(MONOLIB_ODEP) +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/gtk/display.cpp + +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@monolib_gtk_display.o: $(srcdir)/src/gtk/display.cpp $(MONOLIB_ODEP) +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/gtk/display.cpp + @COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@monolib_gtk_dnd.o: $(srcdir)/src/gtk/dnd.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/gtk/dnd.cpp @@ -31335,6 +31363,12 @@ coredll_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(COREDLL_ODEP) @COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@coredll_gtk_dc.o: $(srcdir)/src/gtk/dc.cpp $(COREDLL_ODEP) @COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/gtk/dc.cpp +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@coredll_gtk_display.o: $(srcdir)/src/gtk/display.cpp $(COREDLL_ODEP) +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/gtk/display.cpp + +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@coredll_gtk_display.o: $(srcdir)/src/gtk/display.cpp $(COREDLL_ODEP) +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/gtk/display.cpp + @COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@coredll_gtk_dnd.o: $(srcdir)/src/gtk/dnd.cpp $(COREDLL_ODEP) @COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/gtk/dnd.cpp @@ -35712,6 +35746,12 @@ corelib_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(CORELIB_ODEP) @COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@corelib_gtk_dc.o: $(srcdir)/src/gtk/dc.cpp $(CORELIB_ODEP) @COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/gtk/dc.cpp +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@corelib_gtk_display.o: $(srcdir)/src/gtk/display.cpp $(CORELIB_ODEP) +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/gtk/display.cpp + +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@corelib_gtk_display.o: $(srcdir)/src/gtk/display.cpp $(CORELIB_ODEP) +@COND_TOOLKIT_GTK_TOOLKIT_VERSION_3_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/gtk/display.cpp + @COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@corelib_gtk_dnd.o: $(srcdir)/src/gtk/dnd.cpp $(CORELIB_ODEP) @COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/gtk/dnd.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index e077460543..0ed0288e96 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -1108,6 +1108,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/gtk/cursor.cpp src/gtk/dataobj.cpp src/gtk/dc.cpp + src/gtk/display.cpp src/gtk/dnd.cpp src/gtk/evtloop.cpp src/gtk/filectrl.cpp diff --git a/src/gtk/display.cpp b/src/gtk/display.cpp new file mode 100644 index 0000000000..8ab5cd9382 --- /dev/null +++ b/src/gtk/display.cpp @@ -0,0 +1,239 @@ +/////////////////////////////////////////////////////////////////////////// +// Name: src/gtk/display.cpp +// Author: Paul Cornett +// Created: 2014-04-17 +// Copyright: (c) 2014 Paul Cornett +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#include "wx/wxprec.h" + +#if wxUSE_DISPLAY + #include "wx/display.h" + #include "wx/display_impl.h" +#endif +#include "wx/utils.h" // wxClientDisplayRect + +#include +#ifdef GDK_WINDOWING_X11 + #include +#endif + +GtkWidget* wxGetRootWindow(); + +//----------------------------------------------------------------------------- + +#if !(wxUSE_LIBHILDON || wxUSE_LIBHILDON2) + +void wxGetWorkAreaX11(Screen* screen, int& x, int& y, int& width, int& height); + +#ifndef __WXGTK3__ +static inline int wx_gdk_screen_get_primary_monitor(GdkScreen* screen) +{ + int monitor = 0; +#if GTK_CHECK_VERSION(2,20,0) + if (gtk_check_version(2,20,0) == NULL) + 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) +{ +#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 GDK_WINDOWING_X11 +#ifdef __WXGTK3__ + if (GDK_IS_X11_SCREEN(screen)) +#endif + { + GdkRectangle rect; + wxGetWorkAreaX11(GDK_SCREEN_XSCREEN(screen), + rect.x, rect.y, rect.width, rect.height); + // in case _NET_WORKAREA result is too large + gdk_rectangle_intersect(dest, &rect, dest); + } +#endif // GDK_WINDOWING_X11 + } +} +#define gdk_screen_get_monitor_workarea wx_gdk_screen_get_monitor_workarea + +#endif // !(wxUSE_LIBHILDON || wxUSE_LIBHILDON2) + +void wxClientDisplayRect(int* x, int* y, int* width, int* height) +{ +#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2 + GdkRectangle rect = { 0, 0, 672, 396 }; +#else + GdkRectangle rect; + GdkWindow* window = gtk_widget_get_window(wxGetRootWindow()); + GdkScreen* screen = gdk_window_get_screen(window); + int monitor = gdk_screen_get_monitor_at_window(screen, window); + gdk_screen_get_monitor_workarea(screen, monitor, &rect); +#endif + if (x) + *x = rect.x; + if (y) + *y = rect.y; + if (width) + *width = rect.width; + if (height) + *height = rect.height; +} +//----------------------------------------------------------------------------- + +#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; +}; + +class wxDisplayImplGTK: public wxDisplayImpl +{ + typedef wxDisplayImpl base_type; +public: + wxDisplayImplGTK(unsigned i); + virtual wxRect GetGeometry() const wxOVERRIDE; + virtual wxRect GetClientArea() const wxOVERRIDE; + virtual wxString GetName() const wxOVERRIDE; + 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; + + GdkScreen* const m_screen; +}; + +static inline GdkScreen* GetScreen() +{ + return gtk_widget_get_screen(wxGetRootWindow()); +} +//----------------------------------------------------------------------------- + +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) +{ + GdkScreen* screen = GetScreen(); + int monitor = gdk_screen_get_monitor_at_point(screen, pt.x, pt.y); + GdkRectangle rect; + 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; +} +//----------------------------------------------------------------------------- + +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); +} + +wxString wxDisplayImplGTK::GetName() const +{ + return wxString(); +} + +bool wxDisplayImplGTK::IsPrimary() const +{ + return gdk_screen_get_primary_monitor(m_screen) == int(m_index); +} + +wxArrayVideoModes wxXF86VidMode_GetModes(const wxVideoMode& mode, Display* pDisplay, int nScreen); +wxVideoMode wxXF86VidMode_GetCurrentMode(Display* display, int nScreen); +bool wxXF86VidMode_ChangeMode(const wxVideoMode& mode, Display* display, int nScreen); +wxArrayVideoModes wxX11_GetModes(const wxDisplayImpl* impl, const wxVideoMode& modeMatch, Display* display); + +wxArrayVideoModes wxDisplayImplGTK::GetModes(const wxVideoMode& mode) const +{ + wxArrayVideoModes modes; +#ifdef GDK_WINDOWING_X11 +#ifdef __WXGTK3__ + if (GDK_IS_X11_SCREEN(m_screen)) +#endif + { + Display* display = GDK_DISPLAY_XDISPLAY(gdk_screen_get_display(m_screen)); +#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H + int nScreen = gdk_x11_screen_get_screen_number(m_screen); + modes = wxXF86VidMode_GetModes(mode, display, nScreen); +#else + modes = wxX11_GetModes(this, mode, display); +#endif + } +#endif // GDK_WINDOWING_X11 + return modes; +} + +wxVideoMode wxDisplayImplGTK::GetCurrentMode() const +{ + wxVideoMode mode; +#if defined(GDK_WINDOWING_X11) && defined(HAVE_X11_EXTENSIONS_XF86VMODE_H) +#ifdef __WXGTK3__ + if (GDK_IS_X11_SCREEN(m_screen)) +#endif + { + Display* display = GDK_DISPLAY_XDISPLAY(gdk_screen_get_display(m_screen)); + int nScreen = gdk_x11_screen_get_screen_number(m_screen); + mode = wxXF86VidMode_GetCurrentMode(display, nScreen); + } +#endif + return mode; +} + +bool wxDisplayImplGTK::ChangeMode(const wxVideoMode& mode) +{ + bool success = false; +#if defined(GDK_WINDOWING_X11) && defined(HAVE_X11_EXTENSIONS_XF86VMODE_H) +#ifdef __WXGTK3__ + if (GDK_IS_X11_SCREEN(m_screen)) +#endif + { + Display* display = GDK_DISPLAY_XDISPLAY(gdk_screen_get_display(m_screen)); + int nScreen = gdk_x11_screen_get_screen_number(m_screen); + success = wxXF86VidMode_ChangeMode(mode, display, nScreen); + } +#else + wxUnusedVar(mode); +#endif + return success; +} + +wxDisplayFactory* wxDisplay::CreateFactory() +{ + return new wxDisplayFactoryGTK; +} +#endif // wxUSE_DISPLAY diff --git a/src/unix/displayx11.cpp b/src/unix/displayx11.cpp index ef91c848ac..d29d9c2f65 100644 --- a/src/unix/displayx11.cpp +++ b/src/unix/displayx11.cpp @@ -23,55 +23,35 @@ #pragma hdrstop #endif -#if wxUSE_DISPLAY - -#include "wx/display.h" - #ifndef WX_PRECOMP - #include "wx/dynarray.h" - #include "wx/gdicmn.h" - #include "wx/string.h" #include "wx/utils.h" #include "wx/intl.h" #include "wx/log.h" #endif /* WX_PRECOMP */ +#ifdef __WXGTK20__ + #include // GDK_WINDOWING_X11 +#endif +#if !defined(__WXGTK20__) || defined(GDK_WINDOWING_X11) + #include + #include +#endif + +#if wxUSE_DISPLAY + +#include "wx/display.h" #include "wx/display_impl.h" -#ifdef __WXGTK20__ - #include - #include - - // define the struct with the same fields as XineramaScreenInfo (except for - // screen number which we don't need) but which we can use without - // including Xinerama headers - struct ScreenInfo - { - short x_org; - short y_org; - short width; - short height; - }; -#else // use raw Xinerama functions - /* These must be included after the wx files. Otherwise the Data macro in - * Xlibint.h conflicts with a function declaration in wx/list.h. */ - extern "C" - { - #include - #include +#ifndef __WXGTK20__ #include - } typedef XineramaScreenInfo ScreenInfo; -#endif // GTK+/Xinerama // ---------------------------------------------------------------------------- // helper class storing information about all screens // ---------------------------------------------------------------------------- -// the base class provides access to ScreenInfo array, derived class -// initializes it using either GTK+ or Xinerama functions class ScreensInfoBase { public: @@ -84,36 +64,6 @@ protected: int m_num; }; -#ifdef __WXGTK20__ - -class ScreensInfo : public ScreensInfoBase -{ -public: - ScreensInfo() - { - GdkScreen * const screen = gdk_screen_get_default(); - - m_num = gdk_screen_get_n_monitors(screen); - m_screens = new ScreenInfo[m_num]; - for ( int i = 0; i < m_num; i++ ) - { - GdkRectangle rect; - gdk_screen_get_monitor_geometry(screen, i, &rect); - m_screens[i].x_org = rect.x; - m_screens[i].y_org = rect.y; - m_screens[i].width = rect.width; - m_screens[i].height = rect.height; - } - } - - ~ScreensInfo() - { - delete [] m_screens; - } -}; - -#else // Xinerama - class ScreensInfo : public ScreensInfoBase { public: @@ -128,8 +78,6 @@ public: } }; -#endif // GTK+/Xinerama - // ---------------------------------------------------------------------------- // display and display factory classes // ---------------------------------------------------------------------------- @@ -211,11 +159,14 @@ wxDisplayImpl *wxDisplayFactoryX11::CreateDisplay(unsigned n) return n < screens.GetCount() ? new wxDisplayImplX11(n, screens[n]) : NULL; } +#endif // !__WXGTK20__ // ============================================================================ // wxDisplayImplX11 implementation // ============================================================================ +#if !defined(__WXGTK20__) || defined(GDK_WINDOWING_X11) + #ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H #include @@ -234,13 +185,8 @@ wxDisplayImpl *wxDisplayFactoryX11::CreateDisplay(unsigned n) #define wxCVM2(v, dc, display, nScreen) wxVideoMode(v.hdisplay, v.vdisplay, DefaultDepth(display, nScreen), wxCRR2(v,dc)) #define wxCVM(v, display, nScreen) wxCVM2(v, v.dotclock, display, nScreen) -wxArrayVideoModes wxDisplayImplX11::GetModes(const wxVideoMode& mode) const +wxArrayVideoModes wxXF86VidMode_GetModes(const wxVideoMode& mode, Display* display, int nScreen) { - //Convenience... - Display* display = (Display*) wxGetDisplay(); //default display - int nScreen = DefaultScreen(display); //default screen of (default) display... - - //Some variables.. XF86VidModeModeInfo** ppXModes; //Enumerated Modes (Don't forget XFree() :)) int nNumModes; //Number of modes enumerated.... @@ -269,10 +215,8 @@ wxArrayVideoModes wxDisplayImplX11::GetModes(const wxVideoMode& mode) const return Modes; } -wxVideoMode wxDisplayImplX11::GetCurrentMode() const +wxVideoMode wxXF86VidMode_GetCurrentMode(Display* display, int nScreen) { - Display* display = static_cast(wxGetDisplay()); - int nScreen = DefaultScreen(display); XF86VidModeModeLine VM; int nDotClock; XF86VidModeGetModeLine(display, nScreen, &nDotClock, &VM); @@ -280,10 +224,8 @@ wxVideoMode wxDisplayImplX11::GetCurrentMode() const return wxCVM2(VM, nDotClock, display, nScreen); } -bool wxDisplayImplX11::ChangeMode(const wxVideoMode& mode) +bool wxXF86VidMode_ChangeMode(const wxVideoMode& mode, Display* display, int nScreen) { - Display* display = static_cast(wxGetDisplay()); - int nScreen = DefaultScreen(display); XF86VidModeModeInfo** ppXModes; //Enumerated Modes (Don't forget XFree() :)) int nNumModes; //Number of modes enumerated.... @@ -326,18 +268,42 @@ bool wxDisplayImplX11::ChangeMode(const wxVideoMode& mode) return bRet; } -#else // !HAVE_X11_EXTENSIONS_XF86VMODE_H - +#ifndef __WXGTK20__ wxArrayVideoModes wxDisplayImplX11::GetModes(const wxVideoMode& modeMatch) const +{ + Display* display = static_cast(wxGetDisplay()); + int nScreen = DefaultScreen(display); + return wxXF86VidMode_GetModes(modeMatch, display, nScreen); +} + +wxVideoMode wxDisplayImplX11::GetCurrentMode() const +{ + Display* display = static_cast(wxGetDisplay()); + int nScreen = DefaultScreen(display); + return wxXF86VidMode_GetCurrentMode(display, nScreen); +} + +bool wxDisplayImplX11::ChangeMode(const wxVideoMode& mode) +{ + Display* display = static_cast(wxGetDisplay()); + int nScreen = DefaultScreen(display); + return wxXF86VidMode_ChangeMode(mode, display, nScreen); +} +#endif // !__WXGTK20__ + +#else // !HAVE_X11_EXTENSIONS_XF86VMODE_H + +wxArrayVideoModes wxX11_GetModes(const wxDisplayImpl* impl, const wxVideoMode& modeMatch, Display* display) { int count_return; - int* depths = XListDepths((Display*)wxGetDisplay(), 0, &count_return); + int* depths = XListDepths(display, 0, &count_return); wxArrayVideoModes modes; if ( depths ) { + const wxRect rect = impl->GetGeometry(); for ( int x = 0; x < count_return; ++x ) { - wxVideoMode mode(m_rect.GetWidth(), m_rect.GetHeight(), depths[x]); + wxVideoMode mode(rect.width, rect.height, depths[x]); if ( mode.Matches(modeMatch) ) { modes.Add(mode); @@ -349,6 +315,13 @@ wxArrayVideoModes wxDisplayImplX11::GetModes(const wxVideoMode& modeMatch) const return modes; } +#ifndef __WXGTK20__ +wxArrayVideoModes wxDisplayImplX11::GetModes(const wxVideoMode& modeMatch) const +{ + Display* display = static_cast(wxGetDisplay()); + return wxX11_GetModes(this, modeMatch, display); +} + wxVideoMode wxDisplayImplX11::GetCurrentMode() const { // Not implemented @@ -360,118 +333,67 @@ bool wxDisplayImplX11::ChangeMode(const wxVideoMode& WXUNUSED(mode)) // Not implemented return false; } - +#endif // !__WXGTK20__ #endif // !HAVE_X11_EXTENSIONS_XF86VMODE_H +#endif // !defined(__WXGTK20__) || defined(GDK_WINDOWING_X11) // ============================================================================ // wxDisplay::CreateFactory() // ============================================================================ +#ifndef __WXGTK20__ /* static */ wxDisplayFactory *wxDisplay::CreateFactory() { - // GTK+ screen functions are always available, no need to check for them -#ifndef __WXGTK20__ if ( !XineramaIsActive((Display*)wxGetDisplay()) ) return new wxDisplayFactorySingle; -#endif return new wxDisplayFactoryX11; } +#endif #endif /* wxUSE_DISPLAY */ -#include "wx/utils.h" -#ifdef __WXGTK20__ - #include // for GDK_WINDOWING_X11 -#endif - -#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2 || !defined(GDK_WINDOWING_X11) - -void wxClientDisplayRect(int *x, int *y, int *width, int *height) +#if !defined(__WXGTK20__) || defined(GDK_WINDOWING_X11) +void wxGetWorkAreaX11(Screen* screen, int& x, int& y, int& width, int& height) { - // TODO: don't hardcode display size - if ( x ) - *x = 0; - if ( y ) - *y = 0; - if ( width ) - *width = 672; - if ( height ) - *height = 396; + Display* display = DisplayOfScreen(screen); + Atom property = XInternAtom(display, "_NET_WORKAREA", true); + if (property) + { + Atom actual_type; + int actual_format; + unsigned long nitems; + unsigned long bytes_after; + unsigned char* data = NULL; + Status status = XGetWindowProperty( + display, RootWindowOfScreen(screen), property, + 0, 4, false, XA_CARDINAL, + &actual_type, &actual_format, &nitems, &bytes_after, &data); + if (status == Success && actual_type == XA_CARDINAL && + actual_format == 32 && nitems == 4) + { + const long* p = (long*)data; + x = p[0]; + y = p[1]; + width = p[2]; + height = p[3]; + } + if (data) + XFree(data); + } } +#endif // !defined(__WXGTK20__) || defined(GDK_WINDOWING_X11) -#else // !wxUSE_LIBHILDON || !wxUSE_LIBHILDON2 +#ifndef __WXGTK20__ -#include "wx/log.h" - -#include -#include - -// TODO: make this a full-fledged class and move to a public header -class wxX11Ptr -{ -public: - wxX11Ptr(void *ptr = NULL) : m_ptr(ptr) { } - ~wxX11Ptr() { if ( m_ptr ) XFree(m_ptr); } - -private: - void *m_ptr; - - wxDECLARE_NO_COPY_CLASS(wxX11Ptr); -}; - -// NB: this function is implemented using X11 and not GDK calls as it's shared -// by wxGTK[12], wxX11 and wxMotif ports void wxClientDisplayRect(int *x, int *y, int *width, int *height) { Display * const dpy = wxGetX11Display(); wxCHECK_RET( dpy, wxT("can't be called before initializing the GUI") ); wxRect rectClient; - - const Atom atomWorkArea = XInternAtom(dpy, "_NET_WORKAREA", True); - if ( atomWorkArea ) - { - long *workareas = NULL; - unsigned long numItems; - unsigned long bytesRemaining; - Atom actualType; - int format; - - if ( XGetWindowProperty - ( - dpy, - XDefaultRootWindow(dpy), - atomWorkArea, - 0, // offset of data to retrieve - 4, // number of items to retrieve - False, // don't delete property - XA_CARDINAL, // type of the items to get - &actualType, - &format, - &numItems, - &bytesRemaining, - (unsigned char **)&workareas - ) == Success && workareas ) - { - wxX11Ptr x11ptr(workareas); // ensure it will be freed - - // check that we retrieved the property of the expected type and - // that we did get back 4 longs (32 is the format for long), as - // requested - if ( actualType != XA_CARDINAL || - format != 32 || - numItems != 4 ) - { - wxLogDebug(wxT("XGetWindowProperty(\"_NET_WORKAREA\") failed")); - } - else - { - rectClient = wxRect(workareas[0], workareas[1], - workareas[2], workareas[3]); - } - } - } + wxGetWorkAreaX11(DefaultScreenOfDisplay(dpy), + rectClient.x, rectClient.y, rectClient.width, rectClient.height); // Although _NET_WORKAREA is supposed to return the client size of the // screen, not all implementations are conforming, apparently, see #14419, @@ -505,5 +427,4 @@ void wxClientDisplayRect(int *x, int *y, int *width, int *height) if ( height ) *height = rectClient.height; } - -#endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON +#endif // !__WXGTK20__