1 ///////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/display.cpp
3 // Author: Paul Cornett
4 // Created: 2014-04-17
5 // Copyright: (c) 2014 Paul Cornett
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 #include "wx/wxprec.h"
10
11 #if wxUSE_DISPLAY
12 #include "wx/display.h"
13 #include "wx/display_impl.h"
14 #endif
15 #include "wx/utils.h" // wxClientDisplayRect
16
17 #include <gtk/gtk.h>
18 #ifdef GDK_WINDOWING_X11
19 #include <gdk/gdkx.h>
20 #endif
21 #include "wx/gtk/private/gtk2-compat.h"
22
23 GtkWidget* wxGetRootWindow();
24
25 //-----------------------------------------------------------------------------
26
27 #if !(wxUSE_LIBHILDON || wxUSE_LIBHILDON2)
28
29 void wxGetWorkAreaX11(Screen* screen, int& x, int& y, int& width, int& height);
30
31 #ifndef __WXGTK3__
wx_gdk_screen_get_primary_monitor(GdkScreen * screen)32 static inline int wx_gdk_screen_get_primary_monitor(GdkScreen* screen)
33 {
34 int monitor = 0;
35 #if GTK_CHECK_VERSION(2,20,0)
36 if (gtk_check_version(2,20,0) == NULL)
37 monitor = gdk_screen_get_primary_monitor(screen);
38 #endif
39 return monitor;
40 }
41 #define gdk_screen_get_primary_monitor wx_gdk_screen_get_primary_monitor
42 #endif // !__WXGTK3__
43
44 static inline void
wx_gdk_screen_get_monitor_workarea(GdkScreen * screen,int monitor,GdkRectangle * dest)45 wx_gdk_screen_get_monitor_workarea(GdkScreen* screen, int monitor, GdkRectangle* dest)
46 {
47 #if GTK_CHECK_VERSION(3,4,0)
48 if (gtk_check_version(3,4,0) == NULL)
49 gdk_screen_get_monitor_workarea(screen, monitor, dest);
50 else
51 #endif
52 {
53 gdk_screen_get_monitor_geometry(screen, monitor, dest);
54 #ifdef GDK_WINDOWING_X11
55 #ifdef __WXGTK3__
56 if (GDK_IS_X11_SCREEN(screen))
57 #endif
58 {
59 GdkRectangle rect = { 0 };
60 wxGetWorkAreaX11(GDK_SCREEN_XSCREEN(screen),
61 rect.x, rect.y, rect.width, rect.height);
62 // in case _NET_WORKAREA result is too large
63 if (rect.width && rect.height)
64 gdk_rectangle_intersect(dest, &rect, dest);
65 }
66 #endif // GDK_WINDOWING_X11
67 }
68 }
69 #define gdk_screen_get_monitor_workarea wx_gdk_screen_get_monitor_workarea
70
71 #endif // !(wxUSE_LIBHILDON || wxUSE_LIBHILDON2)
72
wxClientDisplayRect(int * x,int * y,int * width,int * height)73 void wxClientDisplayRect(int* x, int* y, int* width, int* height)
74 {
75 #if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
76 GdkRectangle rect = { 0, 0, 672, 396 };
77 #else
78 GdkRectangle rect;
79 GdkWindow* window = gtk_widget_get_window(wxGetRootWindow());
80 GdkScreen* screen = gdk_window_get_screen(window);
81 int monitor = gdk_screen_get_monitor_at_window(screen, window);
82 gdk_screen_get_monitor_workarea(screen, monitor, &rect);
83 #endif
84 if (x)
85 *x = rect.x;
86 if (y)
87 *y = rect.y;
88 if (width)
89 *width = rect.width;
90 if (height)
91 *height = rect.height;
92 }
93 //-----------------------------------------------------------------------------
94
95 #if wxUSE_DISPLAY
96 class wxDisplayFactoryGTK: public wxDisplayFactory
97 {
98 public:
99 virtual wxDisplayImpl* CreateDisplay(unsigned n);
100 virtual unsigned GetCount();
101 virtual int GetFromPoint(const wxPoint& pt);
102 };
103
104 class wxDisplayImplGTK: public wxDisplayImpl
105 {
106 typedef wxDisplayImpl base_type;
107 public:
108 wxDisplayImplGTK(unsigned i);
109 virtual wxRect GetGeometry() const;
110 virtual wxRect GetClientArea() const;
111 virtual wxString GetName() const;
112 virtual bool IsPrimary() const;
113 virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const;
114 virtual wxVideoMode GetCurrentMode() const;
115 virtual bool ChangeMode(const wxVideoMode& mode);
116
117 GdkScreen* const m_screen;
118 };
119
GetScreen()120 static inline GdkScreen* GetScreen()
121 {
122 return gtk_widget_get_screen(wxGetRootWindow());
123 }
124 //-----------------------------------------------------------------------------
125
CreateDisplay(unsigned n)126 wxDisplayImpl* wxDisplayFactoryGTK::CreateDisplay(unsigned n)
127 {
128 return new wxDisplayImplGTK(n);
129 }
130
GetCount()131 unsigned wxDisplayFactoryGTK::GetCount()
132 {
133 return gdk_screen_get_n_monitors(GetScreen());
134 }
135
GetFromPoint(const wxPoint & pt)136 int wxDisplayFactoryGTK::GetFromPoint(const wxPoint& pt)
137 {
138 GdkScreen* screen = GetScreen();
139 int monitor = gdk_screen_get_monitor_at_point(screen, pt.x, pt.y);
140 GdkRectangle rect;
141 gdk_screen_get_monitor_geometry(screen, monitor, &rect);
142 if (!wxRect(rect.x, rect.y, rect.width, rect.height).Contains(pt))
143 monitor = wxNOT_FOUND;
144 return monitor;
145 }
146 //-----------------------------------------------------------------------------
147
wxDisplayImplGTK(unsigned i)148 wxDisplayImplGTK::wxDisplayImplGTK(unsigned i)
149 : base_type(i)
150 , m_screen(GetScreen())
151 {
152 }
153
GetGeometry() const154 wxRect wxDisplayImplGTK::GetGeometry() const
155 {
156 GdkRectangle rect;
157 gdk_screen_get_monitor_geometry(m_screen, m_index, &rect);
158 return wxRect(rect.x, rect.y, rect.width, rect.height);
159 }
160
GetClientArea() const161 wxRect wxDisplayImplGTK::GetClientArea() const
162 {
163 GdkRectangle rect;
164 gdk_screen_get_monitor_workarea(m_screen, m_index, &rect);
165 return wxRect(rect.x, rect.y, rect.width, rect.height);
166 }
167
GetName() const168 wxString wxDisplayImplGTK::GetName() const
169 {
170 return wxString();
171 }
172
IsPrimary() const173 bool wxDisplayImplGTK::IsPrimary() const
174 {
175 return gdk_screen_get_primary_monitor(m_screen) == int(m_index);
176 }
177
178 wxArrayVideoModes wxXF86VidMode_GetModes(const wxVideoMode& mode, Display* pDisplay, int nScreen);
179 wxVideoMode wxXF86VidMode_GetCurrentMode(Display* display, int nScreen);
180 bool wxXF86VidMode_ChangeMode(const wxVideoMode& mode, Display* display, int nScreen);
181 wxArrayVideoModes wxX11_GetModes(const wxDisplayImpl* impl, const wxVideoMode& modeMatch, Display* display);
182
GetModes(const wxVideoMode & mode) const183 wxArrayVideoModes wxDisplayImplGTK::GetModes(const wxVideoMode& mode) const
184 {
185 wxArrayVideoModes modes;
186 #ifdef GDK_WINDOWING_X11
187 #ifdef __WXGTK3__
188 if (GDK_IS_X11_SCREEN(m_screen))
189 #endif
190 {
191 Display* display = GDK_DISPLAY_XDISPLAY(gdk_screen_get_display(m_screen));
192 #ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
193 int nScreen = gdk_x11_screen_get_screen_number(m_screen);
194 modes = wxXF86VidMode_GetModes(mode, display, nScreen);
195 #else
196 modes = wxX11_GetModes(this, mode, display);
197 #endif
198 }
199 #endif // GDK_WINDOWING_X11
200 return modes;
201 }
202
GetCurrentMode() const203 wxVideoMode wxDisplayImplGTK::GetCurrentMode() const
204 {
205 wxVideoMode mode;
206 #if defined(GDK_WINDOWING_X11) && defined(HAVE_X11_EXTENSIONS_XF86VMODE_H)
207 #ifdef __WXGTK3__
208 if (GDK_IS_X11_SCREEN(m_screen))
209 #endif
210 {
211 Display* display = GDK_DISPLAY_XDISPLAY(gdk_screen_get_display(m_screen));
212 int nScreen = gdk_x11_screen_get_screen_number(m_screen);
213 mode = wxXF86VidMode_GetCurrentMode(display, nScreen);
214 }
215 #endif
216 return mode;
217 }
218
ChangeMode(const wxVideoMode & mode)219 bool wxDisplayImplGTK::ChangeMode(const wxVideoMode& mode)
220 {
221 bool success = false;
222 #if defined(GDK_WINDOWING_X11) && defined(HAVE_X11_EXTENSIONS_XF86VMODE_H)
223 #ifdef __WXGTK3__
224 if (GDK_IS_X11_SCREEN(m_screen))
225 #endif
226 {
227 Display* display = GDK_DISPLAY_XDISPLAY(gdk_screen_get_display(m_screen));
228 int nScreen = gdk_x11_screen_get_screen_number(m_screen);
229 success = wxXF86VidMode_ChangeMode(mode, display, nScreen);
230 }
231 #else
232 wxUnusedVar(mode);
233 #endif
234 return success;
235 }
236
CreateFactory()237 wxDisplayFactory* wxDisplay::CreateFactory()
238 {
239 return new wxDisplayFactoryGTK;
240 }
241 #endif // wxUSE_DISPLAY
242