xref: /trunk/main/vcl/inc/unx/gtk/gtkframe.hxx (revision 605bd593b0f7b92e079dee47a9ef4285cec2902a)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _VCL_GTKFRAME_HXX
25 #define _VCL_GTKFRAME_HXX
26 
27 #include <tools/prex.h>
28 #include <gtk/gtk.h>
29 #include <gdk/gdk.h>
30 #include <gdk/gdkx.h>
31 #include <gdk/gdkkeysyms.h>
32 #include <tools/postx.h>
33 
34 #include <salframe.hxx>
35 #include <vcl/sysdata.hxx>
36 
37 #include "tools/link.hxx"
38 
39 #include <list>
40 #include <vector>
41 
42 class GtkSalGraphics;
43 class GtkSalDisplay;
44 
45 class GtkSalFrame : public SalFrame
46 {
47     static const int nMaxGraphics = 2;
48 
49     struct GraphicsHolder
50     {
51         GtkSalGraphics*     pGraphics;
52         bool                bInUse;
GraphicsHolderGtkSalFrame::GraphicsHolder53         GraphicsHolder()
54                 : pGraphics( NULL ),
55                   bInUse( false )
56         {}
57         ~GraphicsHolder();
58     };
59 
60     struct IMHandler
61     {
62         //--------------------------------------------------------
63         // Not all GTK Input Methods swallow key release
64         // events.  Since they swallow the key press events and we
65         // are left with the key release events, we need to
66         // manually swallow those.  To do this, we keep a list of
67         // the previous 10 key press events in each GtkSalFrame
68         // and when we get a key release that matches one of the
69         // key press events in our list, we swallow it.
70         struct PreviousKeyPress
71         {
72             GdkWindow *window;
73             gint8   send_event;
74             guint32 time;
75             guint   state;
76             guint   keyval;
77             guint16 hardware_keycode;
78             guint8  group;
79 
PreviousKeyPressGtkSalFrame::IMHandler::PreviousKeyPress80             PreviousKeyPress (GdkEventKey *event)
81             :   window (NULL),
82                 send_event (0),
83                 time (0),
84                 state (0),
85                 keyval (0),
86                 hardware_keycode (0),
87                 group (0)
88             {
89                 if (event)
90                 {
91                     window              = event->window;
92                     send_event          = event->send_event;
93                     time                = event->time;
94                     state               = event->state;
95                     keyval              = event->keyval;
96                     hardware_keycode    = event->hardware_keycode;
97                     group               = event->group;
98                 }
99             }
100 
PreviousKeyPressGtkSalFrame::IMHandler::PreviousKeyPress101             PreviousKeyPress( const PreviousKeyPress& rPrev )
102             :   window( rPrev.window ),
103                 send_event( rPrev.send_event ),
104                 time( rPrev.time ),
105                 state( rPrev.state ),
106                 keyval( rPrev.keyval ),
107                 hardware_keycode( rPrev.hardware_keycode ),
108                 group( rPrev.group )
109             {}
110 
operator ==GtkSalFrame::IMHandler::PreviousKeyPress111             bool operator== (GdkEventKey *event) const
112             {
113                 return (event != NULL)
114                     && (event->window == window)
115                     && (event->send_event == send_event)
116                     && (event->state == state)
117                     && (event->keyval == keyval)
118                     && (event->hardware_keycode == hardware_keycode)
119                     && (event->group == group)
120                     && (event->time - time < 3)
121                     ;
122             }
123         };
124 
125 
126         GtkSalFrame*                    m_pFrame;
127         std::list< PreviousKeyPress >   m_aPrevKeyPresses;
128         int                             m_nPrevKeyPresses; // avoid using size()
129         GtkIMContext*                   m_pIMContext;
130         bool                            m_bFocused;
131         bool                            m_bPreeditJustChanged;
132         SalExtTextInputEvent            m_aInputEvent;
133         std::vector< sal_uInt16 >           m_aInputFlags;
134 
135         IMHandler( GtkSalFrame* );
136         ~IMHandler();
137 
138         void            createIMContext();
139         void            deleteIMContext();
140         void            updateIMSpotLocation();
141         void            setInputContext( SalInputContext* pContext );
142         void            endExtTextInput( sal_uInt16 nFlags );
143         bool            handleKeyEvent( GdkEventKey* pEvent );
144         void            focusChanged( bool bFocusIn );
145 
146         void            doCallEndExtTextInput();
147         void            sendEmptyCommit();
148 
149 
150         static void         signalIMCommit( GtkIMContext*, gchar*, gpointer );
151         static gboolean     signalIMDeleteSurrounding( GtkIMContext*, gint, gint, gpointer );
152         static void         signalIMPreeditChanged( GtkIMContext*, gpointer );
153         static void         signalIMPreeditEnd( GtkIMContext*, gpointer );
154         static void         signalIMPreeditStart( GtkIMContext*, gpointer );
155         static gboolean     signalIMRetrieveSurrounding( GtkIMContext*, gpointer );
156     };
157     friend struct IMHandler;
158 
159     int                             m_nScreen;
160     GtkWidget*                      m_pWindow;
161     GdkWindow*                      m_pForeignParent;
162     GdkNativeWindow                 m_aForeignParentWindow;
163     GdkWindow*                      m_pForeignTopLevel;
164     GdkNativeWindow                 m_aForeignTopLevelWindow;
165     Pixmap                          m_hBackgroundPixmap;
166     sal_uLong                     m_nStyle;
167     SalExtStyle                     m_nExtStyle;
168     GtkFixed*                       m_pFixedContainer;
169     GtkSalFrame*                    m_pParent;
170     std::list< GtkSalFrame* >       m_aChildren;
171     GdkWindowState                  m_nState;
172     SystemEnvData                   m_aSystemData;
173     GraphicsHolder                  m_aGraphics[ nMaxGraphics ];
174     sal_uInt16                          m_nKeyModifiers;
175     GdkCursor                      *m_pCurrentCursor;
176     GdkVisibilityState              m_nVisibility;
177     PointerStyle                    m_ePointerStyle;
178     int                             m_nSavedScreenSaverTimeout;
179     guint                           m_nGSMCookie;
180     int                             m_nWorkArea;
181     bool                            m_bFullscreen;
182     bool                            m_bSingleAltPress;
183     bool                            m_bDefaultPos;
184     bool                            m_bDefaultSize;
185     bool                            m_bSendModChangeOnRelease;
186     bool                            m_bWindowIsGtkPlug;
187     bool                            m_bSetFocusOnMap;
188     String                          m_aTitle;
189 
190     IMHandler*                      m_pIMHandler;
191 
192     Size                            m_aMaxSize;
193     Size                            m_aMinSize;
194     Rectangle                       m_aRestorePosSize;
195 
196     GdkRegion*                      m_pRegion;
197 
198     void Init( SalFrame* pParent, sal_uLong nStyle );
199     void Init( SystemParentData* pSysData );
200     void InitCommon();
201 
202     // signals
203     static gboolean     signalButton( GtkWidget*, GdkEventButton*, gpointer );
204     static void         signalStyleSet( GtkWidget*, GtkStyle* pPrevious, gpointer );
205     static gboolean     signalExpose( GtkWidget*, GdkEventExpose*, gpointer );
206     static gboolean     signalFocus( GtkWidget*, GdkEventFocus*, gpointer );
207     static gboolean     signalMap( GtkWidget*, GdkEvent*, gpointer );
208     static gboolean     signalUnmap( GtkWidget*, GdkEvent*, gpointer );
209     static gboolean     signalConfigure( GtkWidget*, GdkEventConfigure*, gpointer );
210     static gboolean     signalMotion( GtkWidget*, GdkEventMotion*, gpointer );
211     static gboolean     signalKey( GtkWidget*, GdkEventKey*, gpointer );
212     static gboolean     signalDelete( GtkWidget*, GdkEvent*, gpointer );
213     static gboolean     signalState( GtkWidget*, GdkEvent*, gpointer );
214     static gboolean     signalScroll( GtkWidget*, GdkEvent*, gpointer );
215     static gboolean     signalCrossing( GtkWidget*, GdkEventCrossing*, gpointer );
216     static gboolean     signalVisibility( GtkWidget*, GdkEventVisibility*, gpointer );
217     static void         signalDestroy( GtkObject*, gpointer );
218 
219     void            Center();
220     void            SetDefaultSize();
221     void            setAutoLock( bool bLock );
222     void            setScreenSaverTimeout( int nTimeout );
223 
224     void            doKeyCallback( guint state,
225                                    guint keyval,
226                                    guint16 hardware_keycode,
227                                    guint8 group,
228                                    guint32 time,
229                                    sal_Unicode aOrigCode,
230                                    bool bDown,
231                                    bool bSendRelease
232                                    );
233 
234 
235     GdkNativeWindow findTopLevelSystemWindow( GdkNativeWindow aWindow );
236 
237     static int m_nFloats;
238 
isFloatGrabWindow() const239     bool isFloatGrabWindow() const
240     {
241         return
242             (m_nStyle & SAL_FRAME_STYLE_FLOAT) &&                // only a float can be floatgrab
243             !(m_nStyle & SAL_FRAME_STYLE_TOOLTIP) &&             // tool tips are not
244             !(m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) && // toolbars are also not
245             !(m_nStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE);       // focusable floats are not
246     }
247 
isChild(bool bPlug=true,bool bSysChild=true)248     bool isChild( bool bPlug = true, bool bSysChild = true )
249     {
250         sal_uLong nMask = 0;
251         if( bPlug )
252             nMask |= SAL_FRAME_STYLE_PLUG;
253         if( bSysChild )
254             nMask |= SAL_FRAME_STYLE_SYSTEMCHILD;
255         return (m_nStyle & nMask) != 0;
256     }
257 
258     void resizeWindow( long nWidth, long nHeight );
259     void moveWindow( long nX, long nY );
260 
261     Size calcDefaultSize();
262 
263     void setMinMaxSize();
264     void createNewWindow( XLIB_Window aParent, bool bXEmbed, int nScreen );
265     void askForXEmbedFocus( sal_Int32 nTimecode );
266 
267     DECL_LINK( ImplDelayedFullScreenHdl, void* );
268 public:
269     GtkSalFrame( SalFrame* pParent, sal_uLong nStyle );
270     GtkSalFrame( SystemParentData* pSysData );
271 
272     // Dispatches an XEvent; true means handled and swallowed.
273     bool dispatchXEvent( const XEvent* pEvent );
274 
275     // Legacy wrapper: true means continue, false means swallowed.
276     bool Dispatch( const XEvent* pEvent );
277     void grabPointer( sal_Bool bGrab, sal_Bool bOwnerEvents = sal_False );
278 
279     GtkSalDisplay*  getDisplay();
280     GdkDisplay*     getGdkDisplay();
getWindow() const281     GtkWidget*  getWindow() const { return m_pWindow; }
getGdkWindow() const282     GdkWindow*  getGdkWindow() const { return m_pWindow ? gtk_widget_get_window( m_pWindow ) : NULL; }
getXWindow() const283     XLIB_Window getXWindow() const
284     {
285         GdkWindow* pWin = getGdkWindow();
286         return pWin ? GDK_WINDOW_XWINDOW( pWin ) : None;
287     }
getFixedContainer() const288     GtkFixed*   getFixedContainer() const { return m_pFixedContainer; }
getForeignParent() const289     GdkWindow*  getForeignParent() const { return m_pForeignParent; }
getForeignParentWindow() const290     GdkNativeWindow getForeignParentWindow() const { return m_aForeignParentWindow; }
getForeignTopLevel() const291     GdkWindow*  getForeignTopLevel() const { return m_pForeignTopLevel; }
getForeignTopLevelWindow() const292     GdkNativeWindow getForeignTopLevelWindow() const { return m_aForeignTopLevelWindow; }
getVisibilityState() const293     GdkVisibilityState getVisibilityState() const
294     { return m_nVisibility; }
getBackgroundPixmap() const295     Pixmap getBackgroundPixmap() const { return m_hBackgroundPixmap; }
getScreenNumber() const296     int getScreenNumber() const { return m_nScreen; }
297     void updateScreenNumber();
298 
299     void moveToScreen( int nScreen );
300 
301     virtual ~GtkSalFrame();
302 
303     // SalGraphics or NULL, but two Graphics for all SalFrames
304     // must be returned
305     virtual SalGraphics*        GetGraphics();
306     virtual void                ReleaseGraphics( SalGraphics* pGraphics );
307 
308     // Event must be destroyed, when Frame is destroyed
309     // When Event is called, SalInstance::Yield() must be returned
310     virtual sal_Bool                PostEvent( void* pData );
311 
312     virtual void                SetTitle( const XubString& rTitle );
313     virtual void                SetIcon( sal_uInt16 nIcon );
314     virtual void                SetMenu( SalMenu *pSalMenu );
315     virtual void                DrawMenuBar();
316 
317     virtual void                SetExtendedFrameStyle( SalExtStyle nExtStyle );
318     // Before the window is visible, a resize event
319     // must be sent with the correct size
320     virtual void                Show( sal_Bool bVisible, sal_Bool bNoActivate = sal_False );
321     virtual void                Enable( sal_Bool bEnable );
322     // Set ClientSize and Center the Window to the desktop
323     // and send/post a resize message
324     virtual void                SetMinClientSize( long nWidth, long nHeight );
325     virtual void                SetMaxClientSize( long nWidth, long nHeight );
326     virtual void                SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags );
327     virtual void                GetClientSize( long& rWidth, long& rHeight );
328     virtual void                GetWorkArea( Rectangle& rRect );
329     virtual SalFrame*           GetParent() const;
330     virtual void                SetWindowState( const SalFrameState* pState );
331     virtual sal_Bool                GetWindowState( SalFrameState* pState );
332     virtual void                ShowFullScreen( sal_Bool bFullScreen, sal_Int32 nDisplay );
333     // Enable/Disable ScreenSaver, SystemAgents, ...
334     virtual void                StartPresentation( sal_Bool bStart );
335     // Show Window over all other Windows
336     virtual void                SetAlwaysOnTop( sal_Bool bOnTop );
337 
338     // Window to top and grab focus
339     virtual void                ToTop( sal_uInt16 nFlags );
340 
341     // this function can call with the same
342     // pointer style
343     virtual void                SetPointer( PointerStyle ePointerStyle );
344     virtual void                CaptureMouse( sal_Bool bMouse );
345     virtual void                SetPointerPos( long nX, long nY );
346 
347     // flush output buffer
348     using SalFrame::Flush;
349     virtual void                Flush();
350     // flush output buffer, wait till outstanding operations are done
351     virtual void                Sync();
352 
353     virtual void                SetInputContext( SalInputContext* pContext );
354     virtual void                EndExtTextInput( sal_uInt16 nFlags );
355 
356     virtual String              GetKeyName( sal_uInt16 nKeyCode );
357     virtual String              GetSymbolKeyName( const XubString& rFontName, sal_uInt16 nKeyCode );
358     virtual sal_Bool            MapUnicodeToKeyCode( sal_Unicode aUnicode, LanguageType aLangType, KeyCode& rKeyCode );
359 
360     // returns the input language used for the last key stroke
361     // may be LANGUAGE_DONTKNOW if not supported by the OS
362     virtual LanguageType        GetInputLanguage();
363 
364     virtual SalBitmap*          SnapShot();
365 
366     virtual void                UpdateSettings( AllSettings& rSettings );
367 
368     virtual void                Beep( SoundType eSoundType );
369 
370     // returns system data (most prominent: window handle)
371     virtual const SystemEnvData*    GetSystemData() const;
372 
373 
374     // get current modifier and button mask
375     virtual SalPointerState     GetPointerState();
376 
377     // set new parent window
378     virtual void                SetParent( SalFrame* pNewParent );
379     // reparent window to act as a plugin; implementation
380     // may choose to use a new system window internally
381     // return false to indicate failure
382     virtual bool                SetPluginParent( SystemParentData* pNewParent );
383 
384     virtual void                SetBackgroundBitmap( SalBitmap* );
385 
386     virtual void                SetScreenNumber( unsigned int );
387 
388     // shaped system windows
389     // set clip region to none (-> rectangular windows, normal state)
390     virtual void                    ResetClipRegion();
391     // start setting the clipregion consisting of nRects rectangles
392     virtual void                    BeginSetClipRegion( sal_uLong nRects );
393     // add a rectangle to the clip region
394     virtual void                    UnionClipRegion( long nX, long nY, long nWidth, long nHeight );
395     // done setting up the clipregion
396     virtual void                    EndSetClipRegion();
397 
398     static GtkSalFrame         *getFromWindow( GtkWindow *pWindow );
399 };
400 
401 
402 #define OOO_TYPE_FIXED ooo_fixed_get_type()
403 
404 extern "C" {
405 
406 GType ooo_fixed_get_type( void );
407 
408 } // extern "C"
409 
410 #endif //_VCL_GTKFRAME_HXX
411