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
This commit is contained in:
Paul Cornett
2014-04-17 17:36:10 +00:00
parent 5a6d62d823
commit 0e212a65eb
4 changed files with 369 additions and 168 deletions

239
src/gtk/display.cpp Normal file
View File

@@ -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 <gtk/gtk.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#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