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