Line data Source code
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 _VCL_GTKFRAME_HXX
21 : #define _VCL_GTKFRAME_HXX
22 :
23 : #include <prex.h>
24 : #include <cairo.h>
25 : #include <gdk/gdk.h>
26 : #include <gdk/gdkx.h>
27 : #include <gtk/gtk.h>
28 : #if GTK_CHECK_VERSION(3,0,0)
29 : # include <gtk/gtkx.h>
30 : #endif
31 : #include <gdk/gdkkeysyms.h>
32 : #include <postx.h>
33 :
34 : #include <salframe.hxx>
35 : #include <vcl/sysdata.hxx>
36 : #include <unx/saltype.h>
37 :
38 : #include "tools/link.hxx"
39 :
40 : #include <basebmp/bitmapdevice.hxx>
41 : #include <basebmp/scanlineformats.hxx>
42 : #include <com/sun/star/awt/XTopWindow.hpp>
43 :
44 : #include <list>
45 : #include <vector>
46 :
47 : class GtkSalGraphics;
48 : class GtkSalDisplay;
49 :
50 : #if GTK_CHECK_VERSION(3,0,0)
51 : typedef XLIB_Window GdkNativeWindow;
52 : #define GDK_WINDOW_XWINDOW(o) GDK_WINDOW_XID(o)
53 : #define gdk_set_sm_client_id(i) gdk_x11_set_sm_client_id(i)
54 : #define gdk_window_foreign_new_for_display(a,b) gdk_x11_window_foreign_new_for_display(a,b)
55 : #endif
56 :
57 : #if !(GLIB_MAJOR_VERSION > 2 || GLIB_MINOR_VERSION >= 26)
58 : typedef void GDBusConnection;
59 : #endif
60 :
61 : class GtkSalFrame : public SalFrame
62 : {
63 : static const int nMaxGraphics = 2;
64 :
65 : struct GraphicsHolder
66 : {
67 : GtkSalGraphics* pGraphics;
68 : bool bInUse;
69 0 : GraphicsHolder()
70 : : pGraphics( NULL ),
71 0 : bInUse( false )
72 0 : {}
73 : ~GraphicsHolder();
74 : };
75 :
76 : struct IMHandler
77 : {
78 : //--------------------------------------------------------
79 : // Not all GTK Input Methods swallow key release
80 : // events. Since they swallow the key press events and we
81 : // are left with the key release events, we need to
82 : // manually swallow those. To do this, we keep a list of
83 : // the previous 10 key press events in each GtkSalFrame
84 : // and when we get a key release that matches one of the
85 : // key press events in our list, we swallow it.
86 : struct PreviousKeyPress
87 : {
88 : GdkWindow *window;
89 : gint8 send_event;
90 : guint32 time;
91 : guint state;
92 : guint keyval;
93 : guint16 hardware_keycode;
94 : guint8 group;
95 :
96 0 : PreviousKeyPress (GdkEventKey *event)
97 : : window (NULL),
98 : send_event (0),
99 : time (0),
100 : state (0),
101 : keyval (0),
102 : hardware_keycode (0),
103 0 : group (0)
104 : {
105 0 : if (event)
106 : {
107 0 : window = event->window;
108 0 : send_event = event->send_event;
109 0 : time = event->time;
110 0 : state = event->state;
111 0 : keyval = event->keyval;
112 0 : hardware_keycode = event->hardware_keycode;
113 0 : group = event->group;
114 : }
115 0 : }
116 :
117 0 : PreviousKeyPress( const PreviousKeyPress& rPrev )
118 : : window( rPrev.window ),
119 : send_event( rPrev.send_event ),
120 : time( rPrev.time ),
121 : state( rPrev.state ),
122 : keyval( rPrev.keyval ),
123 : hardware_keycode( rPrev.hardware_keycode ),
124 0 : group( rPrev.group )
125 0 : {}
126 :
127 0 : bool operator== (GdkEventKey *event) const
128 : {
129 : return (event != NULL)
130 0 : && (event->window == window)
131 0 : && (event->send_event == send_event)
132 : // ignore non-Gdk state bits, e.g., these used by IBus
133 0 : && ((event->state & GDK_MODIFIER_MASK) == (state & GDK_MODIFIER_MASK))
134 0 : && (event->keyval == keyval)
135 0 : && (event->hardware_keycode == hardware_keycode)
136 0 : && (event->group == group)
137 0 : && (event->time - time < 300)
138 : ;
139 : }
140 : };
141 :
142 :
143 : GtkSalFrame* m_pFrame;
144 : std::list< PreviousKeyPress > m_aPrevKeyPresses;
145 : int m_nPrevKeyPresses; // avoid using size()
146 : GtkIMContext* m_pIMContext;
147 : bool m_bFocused;
148 : bool m_bPreeditJustChanged;
149 : SalExtTextInputEvent m_aInputEvent;
150 : std::vector< sal_uInt16 > m_aInputFlags;
151 :
152 : IMHandler( GtkSalFrame* );
153 : ~IMHandler();
154 :
155 : void createIMContext();
156 : void deleteIMContext();
157 : void updateIMSpotLocation();
158 : void setInputContext( SalInputContext* pContext );
159 : void endExtTextInput( sal_uInt16 nFlags );
160 : bool handleKeyEvent( GdkEventKey* pEvent );
161 : void focusChanged( bool bFocusIn );
162 :
163 : void doCallEndExtTextInput();
164 : void sendEmptyCommit();
165 :
166 : static void signalIMCommit( GtkIMContext*, gchar*, gpointer );
167 : static gboolean signalIMDeleteSurrounding( GtkIMContext*, gint, gint, gpointer );
168 : static void signalIMPreeditChanged( GtkIMContext*, gpointer );
169 : static void signalIMPreeditEnd( GtkIMContext*, gpointer );
170 : static void signalIMPreeditStart( GtkIMContext*, gpointer );
171 : static gboolean signalIMRetrieveSurrounding( GtkIMContext*, gpointer );
172 : };
173 : friend struct IMHandler;
174 :
175 : SalX11Screen m_nXScreen;
176 : GtkWidget* m_pWindow;
177 : int m_nDuringRender;
178 : GdkWindow* m_pForeignParent;
179 : GdkNativeWindow m_aForeignParentWindow;
180 : GdkWindow* m_pForeignTopLevel;
181 : GdkNativeWindow m_aForeignTopLevelWindow;
182 : Pixmap m_hBackgroundPixmap;
183 : sal_uLong m_nStyle;
184 : SalExtStyle m_nExtStyle;
185 : GtkFixed* m_pFixedContainer;
186 : GtkSalFrame* m_pParent;
187 : std::list< GtkSalFrame* > m_aChildren;
188 : GdkWindowState m_nState;
189 : SystemEnvData m_aSystemData;
190 : GraphicsHolder m_aGraphics[ nMaxGraphics ];
191 : sal_uInt16 m_nKeyModifiers;
192 : GdkCursor *m_pCurrentCursor;
193 : GdkVisibilityState m_nVisibility;
194 : PointerStyle m_ePointerStyle;
195 : int m_nSavedScreenSaverTimeout;
196 : guint m_nGSMCookie;
197 : int m_nWorkArea;
198 : bool m_bFullscreen;
199 : bool m_bDefaultPos;
200 : bool m_bDefaultSize;
201 : bool m_bSendModChangeOnRelease;
202 : bool m_bWindowIsGtkPlug;
203 : bool m_bSetFocusOnMap;
204 : OUString m_aTitle;
205 : OUString m_sWMClass;
206 :
207 : IMHandler* m_pIMHandler;
208 :
209 : Size m_aMaxSize;
210 : Size m_aMinSize;
211 : Rectangle m_aRestorePosSize;
212 :
213 : #if GTK_CHECK_VERSION(3,0,0)
214 : cairo_region_t* m_pRegion;
215 : #else
216 : GdkRegion* m_pRegion;
217 : #endif
218 :
219 : SalMenu* m_pSalMenu;
220 :
221 : #if defined(ENABLE_DBUS) && defined(ENABLE_GIO)
222 : friend void ensure_dbus_setup(GdkWindow* gdkWindow, GtkSalFrame* pSalFrame);
223 : friend void on_registrar_available (GDBusConnection*, const gchar*, const gchar*, gpointer);
224 : friend void on_registrar_unavailable (GDBusConnection*, const gchar*, gpointer);
225 : #endif
226 : guint m_nWatcherId;
227 :
228 : void Init( SalFrame* pParent, sal_uLong nStyle );
229 : void Init( SystemParentData* pSysData );
230 : void InitCommon();
231 :
232 : // signals
233 : static gboolean signalButton( GtkWidget*, GdkEventButton*, gpointer );
234 : static void signalStyleSet( GtkWidget*, GtkStyle* pPrevious, gpointer );
235 : static gboolean signalDraw( GtkWidget*, cairo_t *cr, gpointer );
236 : static gboolean signalExpose( GtkWidget*, GdkEventExpose*, gpointer );
237 : static gboolean signalFocus( GtkWidget*, GdkEventFocus*, gpointer );
238 : static gboolean signalMap( GtkWidget*, GdkEvent*, gpointer );
239 : static gboolean signalUnmap( GtkWidget*, GdkEvent*, gpointer );
240 : static gboolean signalConfigure( GtkWidget*, GdkEventConfigure*, gpointer );
241 : static gboolean signalMotion( GtkWidget*, GdkEventMotion*, gpointer );
242 : static gboolean signalKey( GtkWidget*, GdkEventKey*, gpointer );
243 : static gboolean signalDelete( GtkWidget*, GdkEvent*, gpointer );
244 : static gboolean signalState( GtkWidget*, GdkEvent*, gpointer );
245 : static gboolean signalScroll( GtkWidget*, GdkEvent*, gpointer );
246 : static gboolean signalCrossing( GtkWidget*, GdkEventCrossing*, gpointer );
247 : static gboolean signalVisibility( GtkWidget*, GdkEventVisibility*, gpointer );
248 : static void signalDestroy( GtkWidget*, gpointer );
249 :
250 : void Center();
251 : void SetDefaultSize();
252 : void setAutoLock( bool bLock );
253 : void setScreenSaverTimeout( int nTimeout );
254 :
255 : void doKeyCallback( guint state,
256 : guint keyval,
257 : guint16 hardware_keycode,
258 : guint8 group,
259 : guint32 time,
260 : sal_Unicode aOrigCode,
261 : bool bDown,
262 : bool bSendRelease
263 : );
264 :
265 :
266 : GdkNativeWindow findTopLevelSystemWindow( GdkNativeWindow aWindow );
267 :
268 : static int m_nFloats;
269 :
270 0 : bool isFloatGrabWindow() const
271 : {
272 : return
273 0 : (m_nStyle & SAL_FRAME_STYLE_FLOAT) && // only a float can be floatgrab
274 0 : !(m_nStyle & SAL_FRAME_STYLE_TOOLTIP) && // tool tips are not
275 0 : !(m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) && // toolbars are also not
276 0 : !(m_nStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE); // focusable floats are not
277 : }
278 :
279 0 : bool isChild( bool bPlug = true, bool bSysChild = true )
280 : {
281 0 : sal_uLong nMask = 0;
282 0 : if( bPlug )
283 0 : nMask |= SAL_FRAME_STYLE_PLUG;
284 0 : if( bSysChild )
285 0 : nMask |= SAL_FRAME_STYLE_SYSTEMCHILD;
286 0 : return (m_nStyle & nMask) != 0;
287 : }
288 :
289 : void resizeWindow( long nWidth, long nHeight );
290 : void moveWindow( long nX, long nY );
291 :
292 : Size calcDefaultSize();
293 :
294 : void setMinMaxSize();
295 : void createNewWindow( XLIB_Window aParent, bool bXEmbed, SalX11Screen nXScreen );
296 : void askForXEmbedFocus( sal_Int32 nTimecode );
297 :
298 : void AllocateFrame();
299 :
300 : void updateWMClass();
301 : void SetScreen( unsigned int nNewScreen, int eType, Rectangle *pSize = NULL );
302 :
303 : DECL_LINK( ImplDelayedFullScreenHdl, void* );
304 : public:
305 : #if GTK_CHECK_VERSION(3,0,0)
306 : basebmp::BitmapDeviceSharedPtr m_aFrame;
307 : #endif
308 : GtkSalFrame( SalFrame* pParent, sal_uLong nStyle );
309 : GtkSalFrame( SystemParentData* pSysData );
310 :
311 : guint m_nMenuExportId;
312 : guint m_nActionGroupExportId;
313 : guint m_nHudAwarenessId;
314 :
315 : // dispatches an event, returns true if dispatched
316 : // and false else; if true was returned the event should
317 : // be swallowed
318 : bool Dispatch( const XEvent* pEvent );
319 : void grabPointer( sal_Bool bGrab, sal_Bool bOwnerEvents = sal_False );
320 :
321 : GtkSalDisplay* getDisplay();
322 : GdkDisplay* getGdkDisplay();
323 0 : GtkWidget* getWindow() const { return m_pWindow; }
324 0 : GtkFixed* getFixedContainer() const { return m_pFixedContainer; }
325 0 : GdkWindow* getForeignParent() const { return m_pForeignParent; }
326 0 : GdkNativeWindow getForeignParentWindow() const { return m_aForeignParentWindow; }
327 0 : GdkWindow* getForeignTopLevel() const { return m_pForeignTopLevel; }
328 0 : GdkNativeWindow getForeignTopLevelWindow() const { return m_aForeignTopLevelWindow; }
329 : GdkVisibilityState getVisibilityState() const
330 : { return m_nVisibility; }
331 0 : Pixmap getBackgroundPixmap() const { return m_hBackgroundPixmap; }
332 0 : SalX11Screen getXScreenNumber() const { return m_nXScreen; }
333 0 : int GetDisplayScreen() const { return maGeometry.nDisplayScreenNumber; }
334 : void updateScreenNumber();
335 :
336 : #if GTK_CHECK_VERSION(3,0,0)
337 : // only for gtk3 ...
338 : void pushIgnoreDamage();
339 : void popIgnoreDamage();
340 : bool isDuringRender();
341 : void renderArea( cairo_t *cr, cairo_rectangle_t *src );
342 : #endif
343 : virtual ~GtkSalFrame();
344 :
345 : // SalGraphics or NULL, but two Graphics for all SalFrames
346 : // must be returned
347 : virtual SalGraphics* GetGraphics();
348 : virtual void ReleaseGraphics( SalGraphics* pGraphics );
349 :
350 : // Event must be destroyed, when Frame is destroyed
351 : // When Event is called, SalInstance::Yield() must be returned
352 : virtual sal_Bool PostEvent( void* pData );
353 :
354 : virtual void SetTitle( const OUString& rTitle );
355 : virtual void SetIcon( sal_uInt16 nIcon );
356 : virtual void SetMenu( SalMenu *pSalMenu );
357 : virtual SalMenu* GetMenu( void );
358 : virtual void DrawMenuBar();
359 : void EnsureAppMenuWatch();
360 :
361 : virtual void SetExtendedFrameStyle( SalExtStyle nExtStyle );
362 : // Before the window is visible, a resize event
363 : // must be sent with the correct size
364 : virtual void Show( sal_Bool bVisible, sal_Bool bNoActivate = sal_False );
365 : virtual void Enable( sal_Bool bEnable );
366 : // Set ClientSize and Center the Window to the desktop
367 : // and send/post a resize message
368 : virtual void SetMinClientSize( long nWidth, long nHeight );
369 : virtual void SetMaxClientSize( long nWidth, long nHeight );
370 : virtual void SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags );
371 : virtual void GetClientSize( long& rWidth, long& rHeight );
372 : virtual void GetWorkArea( Rectangle& rRect );
373 : virtual SalFrame* GetParent() const;
374 : virtual void SetWindowState( const SalFrameState* pState );
375 : virtual sal_Bool GetWindowState( SalFrameState* pState );
376 : virtual void ShowFullScreen( sal_Bool bFullScreen, sal_Int32 nDisplay );
377 : // Enable/Disable ScreenSaver, SystemAgents, ...
378 : virtual void StartPresentation( sal_Bool bStart );
379 : // Show Window over all other Windows
380 : virtual void SetAlwaysOnTop( sal_Bool bOnTop );
381 :
382 : // Window to top and grab focus
383 : virtual void ToTop( sal_uInt16 nFlags );
384 :
385 : // this function can call with the same
386 : // pointer style
387 : virtual void SetPointer( PointerStyle ePointerStyle );
388 : virtual void CaptureMouse( sal_Bool bMouse );
389 : virtual void SetPointerPos( long nX, long nY );
390 :
391 : // flush output buffer
392 : using SalFrame::Flush;
393 : virtual void Flush();
394 : // flush output buffer, wait till outstanding operations are done
395 : virtual void Sync();
396 :
397 : virtual void SetInputContext( SalInputContext* pContext );
398 : virtual void EndExtTextInput( sal_uInt16 nFlags );
399 :
400 : virtual OUString GetKeyName( sal_uInt16 nKeyCode );
401 : virtual sal_Bool MapUnicodeToKeyCode( sal_Unicode aUnicode, LanguageType aLangType, KeyCode& rKeyCode );
402 :
403 : // returns the input language used for the last key stroke
404 : // may be LANGUAGE_DONTKNOW if not supported by the OS
405 : virtual LanguageType GetInputLanguage();
406 :
407 : virtual void UpdateSettings( AllSettings& rSettings );
408 :
409 : virtual void Beep();
410 :
411 : // returns system data (most prominent: window handle)
412 : virtual const SystemEnvData* GetSystemData() const;
413 :
414 :
415 : // get current modifier and button mask
416 : virtual SalPointerState GetPointerState();
417 :
418 : virtual SalIndicatorState GetIndicatorState();
419 :
420 : virtual void SimulateKeyPress( sal_uInt16 nKeyCode );
421 :
422 : // set new parent window
423 : virtual void SetParent( SalFrame* pNewParent );
424 : // reparent window to act as a plugin; implementation
425 : // may choose to use a new system window internally
426 : // return false to indicate failure
427 : virtual bool SetPluginParent( SystemParentData* pNewParent );
428 :
429 : virtual void SetScreenNumber( unsigned int );
430 : virtual void SetApplicationID( const OUString &rWMClass );
431 :
432 : // shaped system windows
433 : // set clip region to none (-> rectangular windows, normal state)
434 : virtual void ResetClipRegion();
435 : // start setting the clipregion consisting of nRects rectangles
436 : virtual void BeginSetClipRegion( sal_uLong nRects );
437 : // add a rectangle to the clip region
438 : virtual void UnionClipRegion( long nX, long nY, long nWidth, long nHeight );
439 : // done setting up the clipregion
440 : virtual void EndSetClipRegion();
441 :
442 : static GtkSalFrame *getFromWindow( GtkWindow *pWindow );
443 :
444 : virtual void damaged (const basegfx::B2IBox& rDamageRect);
445 : };
446 :
447 : #define OOO_TYPE_FIXED ooo_fixed_get_type()
448 :
449 : extern "C" {
450 :
451 : GType ooo_fixed_get_type( void );
452 :
453 : } // extern "C"
454 :
455 : #endif //_VCL_GTKFRAME_HXX
456 :
457 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|