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