Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #ifndef _VCL_GTKFRAME_HXX
30 : : #define _VCL_GTKFRAME_HXX
31 : :
32 : : #include <tools/prex.h>
33 : : #include <cairo/cairo.h>
34 : : #include <gdk/gdk.h>
35 : : #include <gdk/gdkx.h>
36 : : #include <gtk/gtk.h>
37 : : #if GTK_CHECK_VERSION(3,0,0)
38 : : # include <gtk/gtkx.h>
39 : : #endif
40 : : #include <gdk/gdkkeysyms.h>
41 : : #include <tools/postx.h>
42 : :
43 : : #include <salframe.hxx>
44 : : #include <vcl/sysdata.hxx>
45 : : #include <unx/saltype.h>
46 : :
47 : : #include "tools/link.hxx"
48 : :
49 : : #include <basebmp/bitmapdevice.hxx>
50 : : #include <basebmp/scanlineformats.hxx>
51 : : #include <com/sun/star/awt/XTopWindow.hpp>
52 : :
53 : : #include <list>
54 : : #include <vector>
55 : :
56 : : class GtkSalGraphics;
57 : : class GtkSalDisplay;
58 : :
59 : : #if GTK_CHECK_VERSION(3,0,0)
60 : : typedef XLIB_Window GdkNativeWindow;
61 : : #define GDK_WINDOW_XWINDOW(o) GDK_WINDOW_XID(o)
62 : : #define gdk_set_sm_client_id(i) gdk_x11_set_sm_client_id(i)
63 : : #define gdk_window_foreign_new_for_display(a,b) gdk_x11_window_foreign_new_for_display(a,b)
64 : : #endif
65 : :
66 : : class GtkSalFrame : public SalFrame
67 : : {
68 : : static const int nMaxGraphics = 2;
69 : :
70 : : struct GraphicsHolder
71 : : {
72 : : GtkSalGraphics* pGraphics;
73 : : bool bInUse;
74 : 0 : GraphicsHolder()
75 : : : pGraphics( NULL ),
76 : 0 : bInUse( false )
77 : 0 : {}
78 : : ~GraphicsHolder();
79 : : };
80 : :
81 : : struct IMHandler
82 : : {
83 : : //--------------------------------------------------------
84 : : // Not all GTK Input Methods swallow key release
85 : : // events. Since they swallow the key press events and we
86 : : // are left with the key release events, we need to
87 : : // manually swallow those. To do this, we keep a list of
88 : : // the previous 10 key press events in each GtkSalFrame
89 : : // and when we get a key release that matches one of the
90 : : // key press events in our list, we swallow it.
91 : : struct PreviousKeyPress
92 : : {
93 : : GdkWindow *window;
94 : : gint8 send_event;
95 : : guint32 time;
96 : : guint state;
97 : : guint keyval;
98 : : guint16 hardware_keycode;
99 : : guint8 group;
100 : :
101 : 0 : PreviousKeyPress (GdkEventKey *event)
102 : : : window (NULL),
103 : : send_event (0),
104 : : time (0),
105 : : state (0),
106 : : keyval (0),
107 : : hardware_keycode (0),
108 : 0 : group (0)
109 : : {
110 : 0 : if (event)
111 : : {
112 : 0 : window = event->window;
113 : 0 : send_event = event->send_event;
114 : 0 : time = event->time;
115 : 0 : state = event->state;
116 : 0 : keyval = event->keyval;
117 : 0 : hardware_keycode = event->hardware_keycode;
118 : 0 : group = event->group;
119 : : }
120 : 0 : }
121 : :
122 : 0 : PreviousKeyPress( const PreviousKeyPress& rPrev )
123 : : : window( rPrev.window ),
124 : : send_event( rPrev.send_event ),
125 : : time( rPrev.time ),
126 : : state( rPrev.state ),
127 : : keyval( rPrev.keyval ),
128 : : hardware_keycode( rPrev.hardware_keycode ),
129 : 0 : group( rPrev.group )
130 : 0 : {}
131 : :
132 : 0 : bool operator== (GdkEventKey *event) const
133 : : {
134 : : return (event != NULL)
135 : : && (event->window == window)
136 : : && (event->send_event == send_event)
137 : : // ignore non-Gdk state bits, e.g., these used by IBus
138 : : && ((event->state & GDK_MODIFIER_MASK) == (state & GDK_MODIFIER_MASK))
139 : : && (event->keyval == keyval)
140 : : && (event->hardware_keycode == hardware_keycode)
141 : : && (event->group == group)
142 : 0 : && (event->time - time < 300)
143 : : ;
144 : : }
145 : : };
146 : :
147 : :
148 : : GtkSalFrame* m_pFrame;
149 : : std::list< PreviousKeyPress > m_aPrevKeyPresses;
150 : : int m_nPrevKeyPresses; // avoid using size()
151 : : GtkIMContext* m_pIMContext;
152 : : bool m_bFocused;
153 : : bool m_bPreeditJustChanged;
154 : : SalExtTextInputEvent m_aInputEvent;
155 : : std::vector< sal_uInt16 > m_aInputFlags;
156 : :
157 : : IMHandler( GtkSalFrame* );
158 : : ~IMHandler();
159 : :
160 : : void createIMContext();
161 : : void deleteIMContext();
162 : : void updateIMSpotLocation();
163 : : void setInputContext( SalInputContext* pContext );
164 : : void endExtTextInput( sal_uInt16 nFlags );
165 : : bool handleKeyEvent( GdkEventKey* pEvent );
166 : : void focusChanged( bool bFocusIn );
167 : :
168 : : void doCallEndExtTextInput();
169 : : void sendEmptyCommit();
170 : :
171 : : static void signalIMCommit( GtkIMContext*, gchar*, gpointer );
172 : : static gboolean signalIMDeleteSurrounding( GtkIMContext*, gint, gint, gpointer );
173 : : static void signalIMPreeditChanged( GtkIMContext*, gpointer );
174 : : static void signalIMPreeditEnd( GtkIMContext*, gpointer );
175 : : static void signalIMPreeditStart( GtkIMContext*, gpointer );
176 : : static gboolean signalIMRetrieveSurrounding( GtkIMContext*, gpointer );
177 : : };
178 : : friend struct IMHandler;
179 : :
180 : : SalX11Screen m_nXScreen;
181 : : GtkWidget* m_pWindow;
182 : : int m_nDuringRender;
183 : : GdkWindow* m_pForeignParent;
184 : : GdkNativeWindow m_aForeignParentWindow;
185 : : GdkWindow* m_pForeignTopLevel;
186 : : GdkNativeWindow m_aForeignTopLevelWindow;
187 : : Pixmap m_hBackgroundPixmap;
188 : : sal_uLong m_nStyle;
189 : : SalExtStyle m_nExtStyle;
190 : : GtkFixed* m_pFixedContainer;
191 : : GtkSalFrame* m_pParent;
192 : : std::list< GtkSalFrame* > m_aChildren;
193 : : GdkWindowState m_nState;
194 : : SystemEnvData m_aSystemData;
195 : : GraphicsHolder m_aGraphics[ nMaxGraphics ];
196 : : sal_uInt16 m_nKeyModifiers;
197 : : GdkCursor *m_pCurrentCursor;
198 : : GdkVisibilityState m_nVisibility;
199 : : PointerStyle m_ePointerStyle;
200 : : int m_nSavedScreenSaverTimeout;
201 : : guint m_nGSMCookie;
202 : : int m_nWorkArea;
203 : : bool m_bFullscreen;
204 : : bool m_bDefaultPos;
205 : : bool m_bDefaultSize;
206 : : bool m_bSendModChangeOnRelease;
207 : : bool m_bWindowIsGtkPlug;
208 : : bool m_bSetFocusOnMap;
209 : : rtl::OUString m_aTitle;
210 : : rtl::OUString m_sWMClass;
211 : :
212 : : IMHandler* m_pIMHandler;
213 : :
214 : : Size m_aMaxSize;
215 : : Size m_aMinSize;
216 : : Rectangle m_aRestorePosSize;
217 : :
218 : : #if GTK_CHECK_VERSION(3,0,0)
219 : : cairo_region_t* m_pRegion;
220 : : #else
221 : : GdkRegion* m_pRegion;
222 : : #endif
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 : : // dispatches an event, returns true if dispatched
308 : : // and false else; if true was returned the event should
309 : : // be swallowed
310 : : bool Dispatch( const XEvent* pEvent );
311 : : void grabPointer( sal_Bool bGrab, sal_Bool bOwnerEvents = sal_False );
312 : :
313 : : GtkSalDisplay* getDisplay();
314 : : GdkDisplay* getGdkDisplay();
315 : 0 : GtkWidget* getWindow() const { return m_pWindow; }
316 : 0 : GtkFixed* getFixedContainer() const { return m_pFixedContainer; }
317 : 0 : GdkWindow* getForeignParent() const { return m_pForeignParent; }
318 : 0 : GdkNativeWindow getForeignParentWindow() const { return m_aForeignParentWindow; }
319 : 0 : GdkWindow* getForeignTopLevel() const { return m_pForeignTopLevel; }
320 : 0 : GdkNativeWindow getForeignTopLevelWindow() const { return m_aForeignTopLevelWindow; }
321 : : GdkVisibilityState getVisibilityState() const
322 : : { return m_nVisibility; }
323 : 0 : Pixmap getBackgroundPixmap() const { return m_hBackgroundPixmap; }
324 : 0 : SalX11Screen getXScreenNumber() const { return m_nXScreen; }
325 : 0 : int GetDisplayScreen() const { return maGeometry.nDisplayScreenNumber; }
326 : : void updateScreenNumber();
327 : :
328 : : #if GTK_CHECK_VERSION(3,0,0)
329 : : // only for gtk3 ...
330 : : void pushIgnoreDamage();
331 : : void popIgnoreDamage();
332 : : bool isDuringRender();
333 : : void renderArea( cairo_t *cr, cairo_rectangle_t *src );
334 : : #endif
335 : : virtual ~GtkSalFrame();
336 : :
337 : : // SalGraphics or NULL, but two Graphics for all SalFrames
338 : : // must be returned
339 : : virtual SalGraphics* GetGraphics();
340 : : virtual void ReleaseGraphics( SalGraphics* pGraphics );
341 : :
342 : : // Event must be destroyed, when Frame is destroyed
343 : : // When Event is called, SalInstance::Yield() must be returned
344 : : virtual sal_Bool PostEvent( void* pData );
345 : :
346 : : virtual void SetTitle( const rtl::OUString& rTitle );
347 : : virtual void SetIcon( sal_uInt16 nIcon );
348 : : virtual void SetMenu( SalMenu *pSalMenu );
349 : : virtual void DrawMenuBar();
350 : :
351 : : virtual void SetExtendedFrameStyle( SalExtStyle nExtStyle );
352 : : // Before the window is visible, a resize event
353 : : // must be sent with the correct size
354 : : virtual void Show( sal_Bool bVisible, sal_Bool bNoActivate = sal_False );
355 : : virtual void Enable( sal_Bool bEnable );
356 : : // Set ClientSize and Center the Window to the desktop
357 : : // and send/post a resize message
358 : : virtual void SetMinClientSize( long nWidth, long nHeight );
359 : : virtual void SetMaxClientSize( long nWidth, long nHeight );
360 : : virtual void SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags );
361 : : virtual void GetClientSize( long& rWidth, long& rHeight );
362 : : virtual void GetWorkArea( Rectangle& rRect );
363 : : virtual SalFrame* GetParent() const;
364 : : virtual void SetWindowState( const SalFrameState* pState );
365 : : virtual sal_Bool GetWindowState( SalFrameState* pState );
366 : : virtual void ShowFullScreen( sal_Bool bFullScreen, sal_Int32 nDisplay );
367 : : // Enable/Disable ScreenSaver, SystemAgents, ...
368 : : virtual void StartPresentation( sal_Bool bStart );
369 : : // Show Window over all other Windows
370 : : virtual void SetAlwaysOnTop( sal_Bool bOnTop );
371 : :
372 : : // Window to top and grab focus
373 : : virtual void ToTop( sal_uInt16 nFlags );
374 : :
375 : : // this function can call with the same
376 : : // pointer style
377 : : virtual void SetPointer( PointerStyle ePointerStyle );
378 : : virtual void CaptureMouse( sal_Bool bMouse );
379 : : virtual void SetPointerPos( long nX, long nY );
380 : :
381 : : // flush output buffer
382 : : using SalFrame::Flush;
383 : : virtual void Flush();
384 : : // flush output buffer, wait till outstanding operations are done
385 : : virtual void Sync();
386 : :
387 : : virtual void SetInputContext( SalInputContext* pContext );
388 : : virtual void EndExtTextInput( sal_uInt16 nFlags );
389 : :
390 : : virtual rtl::OUString GetKeyName( sal_uInt16 nKeyCode );
391 : : virtual sal_Bool MapUnicodeToKeyCode( sal_Unicode aUnicode, LanguageType aLangType, KeyCode& rKeyCode );
392 : :
393 : : // returns the input language used for the last key stroke
394 : : // may be LANGUAGE_DONTKNOW if not supported by the OS
395 : : virtual LanguageType GetInputLanguage();
396 : :
397 : : virtual void UpdateSettings( AllSettings& rSettings );
398 : :
399 : : // returns system data (most prominent: window handle)
400 : : virtual const SystemEnvData* GetSystemData() const;
401 : :
402 : :
403 : : // get current modifier and button mask
404 : : virtual SalPointerState GetPointerState();
405 : :
406 : : virtual SalIndicatorState GetIndicatorState();
407 : :
408 : : virtual void SimulateKeyPress( sal_uInt16 nKeyCode );
409 : :
410 : : // set new parent window
411 : : virtual void SetParent( SalFrame* pNewParent );
412 : : // reparent window to act as a plugin; implementation
413 : : // may choose to use a new system window internally
414 : : // return false to indicate failure
415 : : virtual bool SetPluginParent( SystemParentData* pNewParent );
416 : :
417 : : virtual void SetBackgroundBitmap( SalBitmap* );
418 : :
419 : : virtual void SetScreenNumber( unsigned int );
420 : : virtual void SetApplicationID( const rtl::OUString &rWMClass );
421 : :
422 : : // shaped system windows
423 : : // set clip region to none (-> rectangular windows, normal state)
424 : : virtual void ResetClipRegion();
425 : : // start setting the clipregion consisting of nRects rectangles
426 : : virtual void BeginSetClipRegion( sal_uLong nRects );
427 : : // add a rectangle to the clip region
428 : : virtual void UnionClipRegion( long nX, long nY, long nWidth, long nHeight );
429 : : // done setting up the clipregion
430 : : virtual void EndSetClipRegion();
431 : :
432 : : static GtkSalFrame *getFromWindow( GtkWindow *pWindow );
433 : :
434 : : virtual void damaged (const basegfx::B2IBox& rDamageRect);
435 : : };
436 : :
437 : : #define OOO_TYPE_FIXED ooo_fixed_get_type()
438 : :
439 : : extern "C" {
440 : :
441 : : GType ooo_fixed_get_type( void );
442 : :
443 : : } // extern "C"
444 : :
445 : : #endif //_VCL_GTKFRAME_HXX
446 : :
447 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|