1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef _VCL_GTKFRAME_HXX
21 #define _VCL_GTKFRAME_HXX
28 #if GTK_CHECK_VERSION(3,0,0)
29 # include <gtk/gtkx.h>
31 #include <gdk/gdkkeysyms.h>
34 #include <salframe.hxx>
35 #include <vcl/sysdata.hxx>
36 #include <unx/saltype.h>
38 #include "tools/link.hxx"
40 #include <basebmp/bitmapdevice.hxx>
41 #include <basebmp/scanlineformats.hxx>
42 #include <com/sun/star/awt/XTopWindow.hpp>
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)
57 #if !(GLIB_MAJOR_VERSION > 2 || GLIB_MINOR_VERSION >= 26)
58 typedef void GDBusConnection
;
61 class GtkSalFrame
: public SalFrame
63 static const int nMaxGraphics
= 2;
67 GtkSalGraphics
* pGraphics
;
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
93 guint16 hardware_keycode
;
96 PreviousKeyPress (GdkEventKey
*event
)
102 hardware_keycode (0),
107 window
= event
->window
;
108 send_event
= event
->send_event
;
110 state
= event
->state
;
111 keyval
= event
->keyval
;
112 hardware_keycode
= event
->hardware_keycode
;
113 group
= event
->group
;
117 PreviousKeyPress( const PreviousKeyPress
& rPrev
)
118 : window( rPrev
.window
),
119 send_event( rPrev
.send_event
),
121 state( rPrev
.state
),
122 keyval( rPrev
.keyval
),
123 hardware_keycode( rPrev
.hardware_keycode
),
127 bool operator== (GdkEventKey
*event
) const
129 return (event
!= NULL
)
130 && (event
->window
== window
)
131 && (event
->send_event
== send_event
)
132 // ignore non-Gdk state bits, e.g., these used by IBus
133 && ((event
->state
& GDK_MODIFIER_MASK
) == (state
& GDK_MODIFIER_MASK
))
134 && (event
->keyval
== keyval
)
135 && (event
->hardware_keycode
== hardware_keycode
)
136 && (event
->group
== group
)
137 && (event
->time
- time
< 300)
143 GtkSalFrame
* m_pFrame
;
144 std::list
< PreviousKeyPress
> m_aPrevKeyPresses
;
145 int m_nPrevKeyPresses
; // avoid using size()
146 GtkIMContext
* m_pIMContext
;
148 bool m_bPreeditJustChanged
;
149 SalExtTextInputEvent m_aInputEvent
;
150 std::vector
< sal_uInt16
> m_aInputFlags
;
152 IMHandler( GtkSalFrame
* );
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
);
163 void doCallEndExtTextInput();
164 void sendEmptyCommit();
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
);
173 friend struct IMHandler
;
175 SalX11Screen m_nXScreen
;
176 GtkWidget
* m_pWindow
;
178 GdkWindow
* m_pForeignParent
;
179 GdkNativeWindow m_aForeignParentWindow
;
180 GdkWindow
* m_pForeignTopLevel
;
181 GdkNativeWindow m_aForeignTopLevelWindow
;
182 Pixmap m_hBackgroundPixmap
;
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
;
201 bool m_bSendModChangeOnRelease
;
202 bool m_bWindowIsGtkPlug
;
203 bool m_bSetFocusOnMap
;
207 IMHandler
* m_pIMHandler
;
211 Rectangle m_aRestorePosSize
;
213 #if GTK_CHECK_VERSION(3,0,0)
214 cairo_region_t
* m_pRegion
;
216 GdkRegion
* m_pRegion
;
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
);
228 void Init( SalFrame
* pParent
, sal_uLong nStyle
);
229 void Init( SystemParentData
* pSysData
);
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
);
251 void SetDefaultSize();
252 void setAutoLock( bool bLock
);
253 void setScreenSaverTimeout( int nTimeout
);
255 void doKeyCallback( guint state
,
257 guint16 hardware_keycode
,
260 sal_Unicode aOrigCode
,
266 GdkNativeWindow
findTopLevelSystemWindow( GdkNativeWindow aWindow
);
268 static int m_nFloats
;
270 bool isFloatGrabWindow() const
273 (m_nStyle
& SAL_FRAME_STYLE_FLOAT
) && // only a float can be floatgrab
274 !(m_nStyle
& SAL_FRAME_STYLE_TOOLTIP
) && // tool tips are not
275 !(m_nStyle
& SAL_FRAME_STYLE_OWNERDRAWDECORATION
) && // toolbars are also not
276 !(m_nStyle
& SAL_FRAME_STYLE_FLOAT_FOCUSABLE
); // focusable floats are not
279 bool isChild( bool bPlug
= true, bool bSysChild
= true )
283 nMask
|= SAL_FRAME_STYLE_PLUG
;
285 nMask
|= SAL_FRAME_STYLE_SYSTEMCHILD
;
286 return (m_nStyle
& nMask
) != 0;
289 void resizeWindow( long nWidth
, long nHeight
);
290 void moveWindow( long nX
, long nY
);
292 Size
calcDefaultSize();
294 void setMinMaxSize();
295 void createNewWindow( XLIB_Window aParent
, bool bXEmbed
, SalX11Screen nXScreen
);
296 void askForXEmbedFocus( sal_Int32 nTimecode
);
298 void AllocateFrame();
300 void updateWMClass();
301 void SetScreen( unsigned int nNewScreen
, int eType
, Rectangle
*pSize
= NULL
);
303 DECL_LINK( ImplDelayedFullScreenHdl
, void* );
305 #if GTK_CHECK_VERSION(3,0,0)
306 basebmp::BitmapDeviceSharedPtr m_aFrame
;
308 GtkSalFrame( SalFrame
* pParent
, sal_uLong nStyle
);
309 GtkSalFrame( SystemParentData
* pSysData
);
311 guint m_nMenuExportId
;
312 guint m_nActionGroupExportId
;
313 guint m_nHudAwarenessId
;
315 // dispatches an event, returns true if dispatched
316 // and false else; if true was returned the event should
318 bool Dispatch( const XEvent
* pEvent
);
319 void grabPointer( sal_Bool bGrab
, sal_Bool bOwnerEvents
= sal_False
);
321 GtkSalDisplay
* getDisplay();
322 GdkDisplay
* getGdkDisplay();
323 GtkWidget
* getWindow() const { return m_pWindow
; }
324 GtkFixed
* getFixedContainer() const { return m_pFixedContainer
; }
325 GdkWindow
* getForeignParent() const { return m_pForeignParent
; }
326 GdkNativeWindow
getForeignParentWindow() const { return m_aForeignParentWindow
; }
327 GdkWindow
* getForeignTopLevel() const { return m_pForeignTopLevel
; }
328 GdkNativeWindow
getForeignTopLevelWindow() const { return m_aForeignTopLevelWindow
; }
329 GdkVisibilityState
getVisibilityState() const
330 { return m_nVisibility
; }
331 Pixmap
getBackgroundPixmap() const { return m_hBackgroundPixmap
; }
332 SalX11Screen
getXScreenNumber() const { return m_nXScreen
; }
333 int GetDisplayScreen() const { return maGeometry
.nDisplayScreenNumber
; }
334 void updateScreenNumber();
336 #if GTK_CHECK_VERSION(3,0,0)
338 void pushIgnoreDamage();
339 void popIgnoreDamage();
340 bool isDuringRender();
341 void renderArea( cairo_t
*cr
, cairo_rectangle_t
*src
);
343 virtual ~GtkSalFrame();
345 // SalGraphics or NULL, but two Graphics for all SalFrames
347 virtual SalGraphics
* GetGraphics();
348 virtual void ReleaseGraphics( SalGraphics
* pGraphics
);
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
);
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();
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
);
382 // Window to top and grab focus
383 virtual void ToTop( sal_uInt16 nFlags
);
385 // this function can call with the same
387 virtual void SetPointer( PointerStyle ePointerStyle
);
388 virtual void CaptureMouse( sal_Bool bMouse
);
389 virtual void SetPointerPos( long nX
, long nY
);
391 // flush output buffer
392 using SalFrame::Flush
;
393 virtual void Flush();
394 // flush output buffer, wait till outstanding operations are done
397 virtual void SetInputContext( SalInputContext
* pContext
);
398 virtual void EndExtTextInput( sal_uInt16 nFlags
);
400 virtual OUString
GetKeyName( sal_uInt16 nKeyCode
);
401 virtual sal_Bool
MapUnicodeToKeyCode( sal_Unicode aUnicode
, LanguageType aLangType
, KeyCode
& rKeyCode
);
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();
407 virtual void UpdateSettings( AllSettings
& rSettings
);
411 // returns system data (most prominent: window handle)
412 virtual const SystemEnvData
* GetSystemData() const;
415 // get current modifier and button mask
416 virtual SalPointerState
GetPointerState();
418 virtual SalIndicatorState
GetIndicatorState();
420 virtual void SimulateKeyPress( sal_uInt16 nKeyCode
);
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
);
429 virtual void SetScreenNumber( unsigned int );
430 virtual void SetApplicationID( const OUString
&rWMClass
);
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();
442 static GtkSalFrame
*getFromWindow( GtkWindow
*pWindow
);
444 virtual void damaged (const basegfx::B2IBox
& rDamageRect
);
447 #define OOO_TYPE_FIXED ooo_fixed_get_type()
451 GType
ooo_fixed_get_type( void );
455 #endif //_VCL_GTKFRAME_HXX
457 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */