1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #ifndef INCLUDED_VCL_INC_UNX_GTK_GTKDATA_HXX
21 #define INCLUDED_VCL_INC_UNX_GTK_GTKDATA_HXX
22
23 #define GLIB_DISABLE_DEPRECATION_WARNINGS
24 #include <gtk/gtk.h>
25 #include <gdk/gdk.h>
26 #if GTK_CHECK_VERSION(4,0,0)
27 #include <gdk/x11/gdkx.h>
28 #else
29 #include <gdk/gdkx.h>
30 #endif
31
32 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
33 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
34 #include <unx/gendata.hxx>
35 #include <unx/saldisp.hxx>
36 #include <unx/gtk/gtksys.hxx>
37 #include <vcl/ptrstyle.hxx>
38 #include <osl/conditn.hxx>
39 #include <saltimer.hxx>
40 #include <o3tl/enumarray.hxx>
41
42 #include <vector>
43
44 namespace com::sun::star::accessibility { class XAccessibleEventListener; }
45
46 class GtkSalDisplay;
47 class DocumentFocusListener;
48
49 #if !GTK_CHECK_VERSION(4,0,0)
50 typedef GdkWindow GdkSurface;
51 typedef GdkWindowState GdkToplevelState;
52 #endif
53
main_loop_run(GMainLoop * pLoop)54 inline void main_loop_run(GMainLoop* pLoop)
55 {
56 #if !GTK_CHECK_VERSION(4, 0, 0)
57 gdk_threads_leave();
58 #endif
59 g_main_loop_run(pLoop);
60 #if !GTK_CHECK_VERSION(4, 0, 0)
61 gdk_threads_enter();
62 #endif
63 }
64
css_provider_load_from_data(GtkCssProvider * css_provider,const gchar * data,gssize length)65 inline void css_provider_load_from_data(GtkCssProvider *css_provider,
66 const gchar *data,
67 gssize length)
68 {
69 #if GTK_CHECK_VERSION(4, 0, 0)
70 gtk_css_provider_load_from_data(css_provider, data, length);
71 #else
72 gtk_css_provider_load_from_data(css_provider, data, length, nullptr);
73 #endif
74 }
75
widget_get_toplevel(GtkWidget * pWidget)76 inline GtkWidget* widget_get_toplevel(GtkWidget* pWidget)
77 {
78 #if GTK_CHECK_VERSION(4, 0, 0)
79 GtkRoot* pRoot = gtk_widget_get_root(pWidget);
80 return pRoot ? GTK_WIDGET(pRoot) : pWidget;
81 #else
82 return gtk_widget_get_toplevel(pWidget);
83 #endif
84 }
85
image_get_icon_name(GtkImage * pImage)86 inline const char* image_get_icon_name(GtkImage *pImage)
87 {
88 #if GTK_CHECK_VERSION(4, 0, 0)
89 return gtk_image_get_icon_name(pImage);
90 #else
91 const gchar* icon_name;
92 gtk_image_get_icon_name(pImage, &icon_name, nullptr);
93 return icon_name;
94 #endif
95 }
96
widget_get_first_child(GtkWidget * pWidget)97 inline GtkWidget* widget_get_first_child(GtkWidget *pWidget)
98 {
99 #if GTK_CHECK_VERSION(4, 0, 0)
100 return gtk_widget_get_first_child(pWidget);
101 #else
102 GList* pChildren = gtk_container_get_children(GTK_CONTAINER(pWidget));
103 GList* pChild = g_list_first(pChildren);
104 GtkWidget* pRet = pChild ? static_cast<GtkWidget*>(pChild->data) : nullptr;
105 g_list_free(pChildren);
106 return pRet;
107 #endif
108 }
109
style_context_get_color(GtkStyleContext * pStyle,GdkRGBA * pColor)110 inline void style_context_get_color(GtkStyleContext *pStyle, GdkRGBA *pColor)
111 {
112 #if GTK_CHECK_VERSION(4, 0, 0)
113 return gtk_style_context_get_color(pStyle, pColor);
114 #else
115 return gtk_style_context_get_color(pStyle, gtk_style_context_get_state(pStyle), pColor);
116 #endif
117 }
118
widget_get_surface(GtkWidget * pWidget)119 inline GdkSurface* widget_get_surface(GtkWidget* pWidget)
120 {
121 #if GTK_CHECK_VERSION(4,0,0)
122 return gtk_native_get_surface(gtk_widget_get_native(pWidget));
123 #else
124 return gtk_widget_get_window(pWidget);
125 #endif
126 }
127
widget_set_cursor(GtkWidget * pWidget,GdkCursor * pCursor)128 inline void widget_set_cursor(GtkWidget *pWidget, GdkCursor *pCursor)
129 {
130 #if GTK_CHECK_VERSION(4, 0, 0)
131 gtk_widget_set_cursor(pWidget, pCursor);
132 #else
133 gdk_window_set_cursor(gtk_widget_get_window(pWidget), pCursor);
134 #endif
135 }
136
surface_create_similar_surface(GdkSurface * pSurface,cairo_content_t eContent,int nWidth,int nHeight)137 inline cairo_surface_t * surface_create_similar_surface(GdkSurface *pSurface,
138 cairo_content_t eContent,
139 int nWidth,
140 int nHeight)
141 {
142 #if GTK_CHECK_VERSION(4, 0, 0)
143 return gdk_surface_create_similar_surface(pSurface, eContent, nWidth, nHeight);
144 #else
145 return gdk_window_create_similar_surface(pSurface, eContent, nWidth, nHeight);
146 #endif
147 }
148
im_context_set_client_widget(GtkIMContext * pIMContext,GtkWidget * pWidget)149 inline void im_context_set_client_widget(GtkIMContext *pIMContext, GtkWidget *pWidget)
150 {
151 #if GTK_CHECK_VERSION(4, 0, 0)
152 gtk_im_context_set_client_widget(pIMContext, pWidget);
153 #else
154 gtk_im_context_set_client_window(pIMContext, pWidget ? gtk_widget_get_window(pWidget) : nullptr);
155 #endif
156 }
157
158 #if GTK_CHECK_VERSION(4, 0, 0)
159 typedef double gtk_coord;
160 #else
161 typedef int gtk_coord;
162 #endif
163
surface_get_device_position(GdkSurface * pSurface,GdkDevice * pDevice,double & x,double & y,GdkModifierType * pMask)164 inline bool surface_get_device_position(GdkSurface* pSurface,
165 GdkDevice* pDevice,
166 double& x,
167 double& y,
168 GdkModifierType* pMask)
169 {
170 #if GTK_CHECK_VERSION(4, 0, 0)
171 return gdk_surface_get_device_position(pSurface, pDevice,
172 &x, &y,
173 pMask);
174 #else
175 int nX(x), nY(y);
176 bool bRet = gdk_window_get_device_position(pSurface, pDevice,
177 &nX, &nY,
178 pMask);
179 x = nX;
180 y = nY;
181 return bRet;
182 #endif
183 }
184
surface_create_gl_context(GdkSurface * pSurface)185 inline GdkGLContext* surface_create_gl_context(GdkSurface* pSurface)
186 {
187 #if GTK_CHECK_VERSION(4, 0, 0)
188 return gdk_surface_create_gl_context(pSurface, nullptr);
189 #else
190 return gdk_window_create_gl_context(pSurface, nullptr);
191 #endif
192 }
193
194 #if !GTK_CHECK_VERSION(4, 0, 0)
195 typedef GtkClipboard GdkClipboard;
196 #endif
197
198 int getButtonPriority(const OString &rType);
199
200 class GtkSalTimer final : public SalTimer
201 {
202 struct SalGtkTimeoutSource *m_pTimeout;
203 public:
204 GtkSalTimer();
205 virtual ~GtkSalTimer() override;
206 virtual void Start( sal_uInt64 nMS ) override;
207 virtual void Stop() override;
208 bool Expired();
209
210 sal_uLong m_nTimeoutMS;
211 };
212
213 class DocumentFocusListener :
214 public ::cppu::WeakImplHelper< css::accessibility::XAccessibleEventListener >
215 {
216
217 o3tl::sorted_vector< css::uno::Reference< css::uno::XInterface > > m_aRefList;
218
219 public:
220 /// @throws lang::IndexOutOfBoundsException
221 /// @throws uno::RuntimeException
222 void attachRecursive(
223 const css::uno::Reference< css::accessibility::XAccessible >& xAccessible
224 );
225
226 /// @throws lang::IndexOutOfBoundsException
227 /// @throws uno::RuntimeException
228 void attachRecursive(
229 const css::uno::Reference< css::accessibility::XAccessible >& xAccessible,
230 const css::uno::Reference< css::accessibility::XAccessibleContext >& xContext
231 );
232
233 /// @throws lang::IndexOutOfBoundsException
234 /// @throws uno::RuntimeException
235 void attachRecursive(
236 const css::uno::Reference< css::accessibility::XAccessible >& xAccessible,
237 const css::uno::Reference< css::accessibility::XAccessibleContext >& xContext,
238 const css::uno::Reference< css::accessibility::XAccessibleStateSet >& xStateSet
239 );
240
241 /// @throws lang::IndexOutOfBoundsException
242 /// @throws uno::RuntimeException
243 void detachRecursive(
244 const css::uno::Reference< css::accessibility::XAccessible >& xAccessible
245 );
246
247 /// @throws lang::IndexOutOfBoundsException
248 /// @throws uno::RuntimeException
249 void detachRecursive(
250 const css::uno::Reference< css::accessibility::XAccessibleContext >& xContext
251 );
252
253 /// @throws lang::IndexOutOfBoundsException
254 /// @throws uno::RuntimeException
255 void detachRecursive(
256 const css::uno::Reference< css::accessibility::XAccessibleContext >& xContext,
257 const css::uno::Reference< css::accessibility::XAccessibleStateSet >& xStateSet
258 );
259
260 /// @throws lang::IndexOutOfBoundsException
261 /// @throws uno::RuntimeException
262 static css::uno::Reference< css::accessibility::XAccessible > getAccessible(const css::lang::EventObject& aEvent );
263
264 // XEventListener
265 virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
266
267 // XAccessibleEventListener
268 virtual void SAL_CALL notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) override;
269 };
270
271 class GtkSalData final : public GenericUnixSalData
272 {
273 GSource* m_pUserEvent;
274 osl::Mutex m_aDispatchMutex;
275 osl::Condition m_aDispatchCondition;
276 std::exception_ptr m_aException;
277
278 rtl::Reference<DocumentFocusListener> m_xDocumentFocusListener;
279
280 public:
281 GtkSalData( SalInstance *pInstance );
282 virtual ~GtkSalData() override;
283
284 DocumentFocusListener & GetDocumentFocusListener();
285
286 void Init();
287 virtual void Dispose() override;
288
289 static void initNWF();
290 static void deInitNWF();
291
292 void TriggerUserEventProcessing();
293 void TriggerAllUserEventsProcessed();
294
295 bool Yield( bool bWait, bool bHandleAllCurrentEvents );
296 inline GdkDisplay *GetGdkDisplay();
297
298 virtual void ErrorTrapPush() override;
299 virtual bool ErrorTrapPop( bool bIgnoreError = true ) override;
300
301 inline GtkSalDisplay *GetGtkDisplay() const;
setException(const std::exception_ptr & exception)302 void setException(const std::exception_ptr& exception) { m_aException = exception; }
303 };
304
305 class GtkSalFrame;
306
307 class GtkSalDisplay : public SalGenericDisplay
308 {
309 GtkSalSystem* m_pSys;
310 GdkDisplay* m_pGdkDisplay;
311 o3tl::enumarray<PointerStyle, GdkCursor*> m_aCursors;
312 bool m_bStartupCompleted;
313
314 GdkCursor* getFromSvg( OUString const & name, int nXHot, int nYHot );
315
316 public:
317 GtkSalDisplay( GdkDisplay* pDisplay );
318 virtual ~GtkSalDisplay() override;
319
GetGdkDisplay() const320 GdkDisplay* GetGdkDisplay() const { return m_pGdkDisplay; }
321
getSystem() const322 GtkSalSystem* getSystem() const { return m_pSys; }
323
324 GtkWidget* findGtkWidgetForNativeHandle(sal_uIntPtr hWindow) const;
325
326 virtual void deregisterFrame( SalFrame* pFrame ) override;
327 GdkCursor *getCursor( PointerStyle ePointerStyle );
328 virtual int CaptureMouse( SalFrame* pFrame );
329
GetDefaultXScreen()330 SalX11Screen GetDefaultXScreen() { return m_pSys->GetDisplayDefaultXScreen(); }
331 Size GetScreenSize( int nDisplayScreen );
332
startupNotificationCompleted()333 void startupNotificationCompleted() { m_bStartupCompleted = true; }
334
335 #if !GTK_CHECK_VERSION(4,0,0)
336 void screenSizeChanged( GdkScreen const * );
337 void monitorsChanged( GdkScreen const * );
338 #endif
339
340 virtual void TriggerUserEventProcessing() override;
341 virtual void TriggerAllUserEventsProcessed() override;
342 };
343
GetGtkSalData()344 inline GtkSalData* GetGtkSalData()
345 {
346 return static_cast<GtkSalData*>(ImplGetSVData()->mpSalData);
347 }
GetGdkDisplay()348 inline GdkDisplay *GtkSalData::GetGdkDisplay()
349 {
350 return GetGtkDisplay()->GetGdkDisplay();
351 }
352
GetGtkDisplay() const353 GtkSalDisplay *GtkSalData::GetGtkDisplay() const
354 {
355 return static_cast<GtkSalDisplay *>(GetDisplay());
356 }
357
358 #endif // INCLUDED_VCL_INC_UNX_GTK_GTKDATA_HXX
359
360 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
361