summaryrefslogtreecommitdiff
path: root/vcl/source/window/winproc.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/window/winproc.cxx')
-rw-r--r--vcl/source/window/winproc.cxx2618
1 files changed, 2618 insertions, 0 deletions
diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx
new file mode 100644
index 000000000000..c964ad0d739b
--- /dev/null
+++ b/vcl/source/window/winproc.cxx
@@ -0,0 +1,2618 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_vcl.hxx"
+
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#include <vcl/salwtype.hxx>
+#include <vcl/salframe.hxx>
+#include <tools/debug.hxx>
+#ifndef _INTN_HXX
+//#include <tools/intn.hxx>
+#endif
+#include <vcl/i18nhelp.hxx>
+#include <vcl/unohelp.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <vcl/svdata.hxx>
+#include <vcl/dbggui.hxx>
+#include <vcl/windata.hxx>
+#include <vcl/timer.hxx>
+#include <vcl/event.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/cursor.hxx>
+#include <vcl/accmgr.hxx>
+#include <vcl/print.h>
+#include <vcl/window.h>
+#include <vcl/wrkwin.hxx>
+#include <vcl/floatwin.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/help.hxx>
+#include <vcl/helpwin.hxx>
+#include <vcl/brdwin.hxx>
+#include <vcl/dockwin.hxx>
+#include <vcl/salgdi.hxx>
+#include <vcl/menu.hxx>
+
+#include <vcl/dndlcon.hxx>
+#include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
+#include <com/sun/star/awt/MouseEvent.hpp>
+
+#if OSL_DEBUG_LEVEL > 1
+char dbgbuffer[1024];
+#ifndef WNT
+#include <stdio.h>
+#define MyOutputDebugString(s) (fprintf(stderr, s ))
+#else
+extern void MyOutputDebugString( char *s);
+#endif
+#endif
+
+
+// =======================================================================
+
+#define IMPL_MIN_NEEDSYSWIN 49
+
+// =======================================================================
+
+long ImplCallPreNotify( NotifyEvent& rEvt )
+{
+ long nRet = Application::CallEventHooks( rEvt );
+ if ( !nRet )
+ nRet = rEvt.GetWindow()->PreNotify( rEvt );
+ return nRet;
+}
+
+// =======================================================================
+
+long ImplCallEvent( NotifyEvent& rEvt )
+{
+ long nRet = ImplCallPreNotify( rEvt );
+ if ( !nRet )
+ {
+ Window* pWindow = rEvt.GetWindow();
+ switch ( rEvt.GetType() )
+ {
+ case EVENT_MOUSEBUTTONDOWN:
+ pWindow->MouseButtonDown( *rEvt.GetMouseEvent() );
+ break;
+ case EVENT_MOUSEBUTTONUP:
+ pWindow->MouseButtonUp( *rEvt.GetMouseEvent() );
+ break;
+ case EVENT_MOUSEMOVE:
+ pWindow->MouseMove( *rEvt.GetMouseEvent() );
+ break;
+ case EVENT_KEYINPUT:
+ pWindow->KeyInput( *rEvt.GetKeyEvent() );
+ break;
+ case EVENT_KEYUP:
+ pWindow->KeyUp( *rEvt.GetKeyEvent() );
+ break;
+ case EVENT_GETFOCUS:
+ pWindow->GetFocus();
+ break;
+ case EVENT_LOSEFOCUS:
+ pWindow->LoseFocus();
+ break;
+ case EVENT_COMMAND:
+ pWindow->Command( *rEvt.GetCommandEvent() );
+ break;
+ }
+ }
+
+ return nRet;
+}
+
+// =======================================================================
+
+static BOOL ImplHandleMouseFloatMode( Window* pChild, const Point& rMousePos,
+ USHORT nCode, USHORT nSVEvent,
+ BOOL bMouseLeave )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maWinData.mpFirstFloat && !pSVData->maWinData.mpCaptureWin &&
+ !pSVData->maWinData.mpFirstFloat->ImplIsFloatPopupModeWindow( pChild ) )
+ {
+ /*
+ * #93895# since floats are system windows, coordinates have
+ * to be converted to float relative for the hittest
+ */
+ USHORT nHitTest = IMPL_FLOATWIN_HITTEST_OUTSIDE;
+ FloatingWindow* pFloat = pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( pChild, rMousePos, nHitTest );
+ FloatingWindow* pLastLevelFloat;
+ ULONG nPopupFlags;
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ if ( bMouseLeave )
+ return TRUE;
+
+ if ( !pFloat || (nHitTest & IMPL_FLOATWIN_HITTEST_RECT) )
+ {
+ if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp )
+ ImplDestroyHelpWindow( true );
+ pChild->ImplGetFrame()->SetPointer( POINTER_ARROW );
+ return TRUE;
+ }
+ }
+ else
+ {
+ if ( nCode & MOUSE_LEFT )
+ {
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ if ( !pFloat )
+ {
+ pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+// Erstmal ausgebaut als Hack fuer Bug 53378
+// if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
+// return FALSE;
+// else
+ return TRUE;
+ }
+ else if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
+ {
+ if ( !(pFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOMOUSERECTCLOSE) )
+ pFloat->ImplSetMouseDown();
+ return TRUE;
+ }
+ }
+ else
+ {
+ if ( pFloat )
+ {
+ if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
+ {
+ if ( pFloat->ImplIsMouseDown() )
+ pFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
+ return TRUE;
+ }
+ }
+ else
+ {
+ pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
+ if ( !(nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) )
+ {
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ return TRUE;
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( !pFloat )
+ {
+ pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
+ if ( nPopupFlags & FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE )
+ {
+ if ( (nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) &&
+ (nSVEvent == EVENT_MOUSEBUTTONUP) )
+ return TRUE;
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
+ return FALSE;
+ else
+ return TRUE;
+ }
+ else
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleMouseHelpRequest( Window* pChild, const Point& rMousePos )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( !pSVData->maHelpData.mpHelpWin ||
+ !( pSVData->maHelpData.mpHelpWin->IsWindowOrChild( pChild ) ||
+ pChild->IsWindowOrChild( pSVData->maHelpData.mpHelpWin ) ) )
+ {
+ USHORT nHelpMode = 0;
+ if ( pSVData->maHelpData.mbQuickHelp )
+ nHelpMode = HELPMODE_QUICK;
+ if ( pSVData->maHelpData.mbBalloonHelp )
+ nHelpMode |= HELPMODE_BALLOON;
+ if ( nHelpMode )
+ {
+ if ( pChild->IsInputEnabled() && ! pChild->IsInModalMode() )
+ {
+ HelpEvent aHelpEvent( rMousePos, nHelpMode );
+ pSVData->maHelpData.mbRequestingHelp = TRUE;
+ pChild->RequestHelp( aHelpEvent );
+ pSVData->maHelpData.mbRequestingHelp = FALSE;
+ }
+ // #104172# do not kill keyboard activated tooltips
+ else if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp)
+ {
+ ImplDestroyHelpWindow( true );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSetMousePointer( Window* pChild )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->maHelpData.mbExtHelpMode )
+ pChild->ImplGetFrame()->SetPointer( POINTER_HELP );
+ else
+ pChild->ImplGetFrame()->SetPointer( pChild->ImplGetMousePointer() );
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplCallCommand( Window* pChild, USHORT nEvt, void* pData = NULL,
+ BOOL bMouse = FALSE, Point* pPos = NULL )
+{
+ Point aPos;
+ if ( pPos )
+ aPos = *pPos;
+ else
+ {
+ if( bMouse )
+ aPos = pChild->GetPointerPosPixel();
+ else
+ {
+ // simulate mouseposition at center of window
+ Size aSize( pChild->GetOutputSizePixel() );
+ aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
+ }
+ }
+
+ CommandEvent aCEvt( aPos, nEvt, bMouse, pData );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pChild, &aCEvt );
+ ImplDelData aDelData( pChild );
+ BOOL bPreNotify = (ImplCallPreNotify( aNCmdEvt ) != 0);
+ if ( aDelData.IsDelete() )
+ return FALSE;
+ if ( !bPreNotify )
+ {
+ pChild->ImplGetWindowImpl()->mbCommand = FALSE;
+ pChild->Command( aCEvt );
+
+ if( aDelData.IsDelete() )
+ return FALSE;
+ pChild->ImplNotifyKeyMouseCommandEventListeners( aNCmdEvt );
+ if ( aDelData.IsDelete() )
+ return FALSE;
+ if ( pChild->ImplGetWindowImpl()->mbCommand )
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+/* #i34277# delayed context menu activation;
+* necessary if there already was a popup menu running.
+*/
+
+struct ContextMenuEvent
+{
+ Window* pWindow;
+ ImplDelData aDelData;
+ Point aChildPos;
+};
+
+static long ContextMenuEventLink( void* pCEvent, void* )
+{
+ ContextMenuEvent* pEv = (ContextMenuEvent*)pCEvent;
+
+ if( ! pEv->aDelData.IsDelete() )
+ {
+ pEv->pWindow->ImplRemoveDel( &pEv->aDelData );
+ ImplCallCommand( pEv->pWindow, COMMAND_CONTEXTMENU, NULL, TRUE, &pEv->aChildPos );
+ }
+ delete pEv;
+
+ return 0;
+}
+
+long ImplHandleMouseEvent( Window* pWindow, USHORT nSVEvent, BOOL bMouseLeave,
+ long nX, long nY, ULONG nMsgTime,
+ USHORT nCode, USHORT nMode )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ Point aMousePos( nX, nY );
+ Window* pChild;
+ long nRet;
+ USHORT nClicks;
+ ImplFrameData* pWinFrameData = pWindow->ImplGetFrameData();
+ USHORT nOldCode = pWinFrameData->mnMouseCode;
+
+ // we need a mousemove event, befor we get a mousebuttondown or a
+ // mousebuttonup event
+ if ( (nSVEvent == EVENT_MOUSEBUTTONDOWN) ||
+ (nSVEvent == EVENT_MOUSEBUTTONUP) )
+ {
+ if ( (nSVEvent == EVENT_MOUSEBUTTONUP) && pSVData->maHelpData.mbExtHelpMode )
+ Help::EndExtHelp();
+ if ( pSVData->maHelpData.mpHelpWin )
+ {
+ if( pWindow->ImplGetWindow() == pSVData->maHelpData.mpHelpWin )
+ {
+ ImplDestroyHelpWindow( false );
+ return 1; // pWindow is dead now - avoid crash!
+ }
+ else
+ ImplDestroyHelpWindow( true );
+ }
+
+ if ( (pWinFrameData->mnLastMouseX != nX) ||
+ (pWinFrameData->mnLastMouseY != nY) )
+ {
+ ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, FALSE, nX, nY, nMsgTime, nCode, nMode );
+ }
+ }
+
+ // update frame data
+ pWinFrameData->mnBeforeLastMouseX = pWinFrameData->mnLastMouseX;
+ pWinFrameData->mnBeforeLastMouseY = pWinFrameData->mnLastMouseY;
+ pWinFrameData->mnLastMouseX = nX;
+ pWinFrameData->mnLastMouseY = nY;
+ pWinFrameData->mnMouseCode = nCode;
+ pWinFrameData->mnMouseMode = nMode & ~(MOUSE_SYNTHETIC | MOUSE_MODIFIERCHANGED);
+ if ( bMouseLeave )
+ {
+ pWinFrameData->mbMouseIn = FALSE;
+ if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp )
+ {
+ ImplDelData aDelData( pWindow );
+
+ ImplDestroyHelpWindow( true );
+
+ if ( aDelData.IsDelete() )
+ return 1; // pWindow is dead now - avoid crash! (#122045#)
+ }
+ }
+ else
+ pWinFrameData->mbMouseIn = TRUE;
+
+ DBG_ASSERT( !pSVData->maWinData.mpTrackWin ||
+ (pSVData->maWinData.mpTrackWin == pSVData->maWinData.mpCaptureWin),
+ "ImplHandleMouseEvent: TrackWin != CaptureWin" );
+
+ // AutoScrollMode
+ if ( pSVData->maWinData.mpAutoScrollWin && (nSVEvent == EVENT_MOUSEBUTTONDOWN) )
+ {
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+ return 1;
+ }
+
+ // find mouse window
+ if ( pSVData->maWinData.mpCaptureWin )
+ {
+ pChild = pSVData->maWinData.mpCaptureWin;
+
+ DBG_ASSERT( pWindow == pChild->ImplGetFrameWindow(),
+ "ImplHandleMouseEvent: mouse event is not sent to capture window" );
+
+ // java client cannot capture mouse correctly
+ if ( pWindow != pChild->ImplGetFrameWindow() )
+ return 0;
+
+ if ( bMouseLeave )
+ return 0;
+ }
+ else
+ {
+ if ( bMouseLeave )
+ pChild = NULL;
+ else
+ pChild = pWindow->ImplFindWindow( aMousePos );
+ }
+
+ // test this because mouse events are buffered in the remote version
+ // and size may not be in sync
+ if ( !pChild && !bMouseLeave )
+ return 0;
+
+ // Ein paar Test ausfuehren und Message abfangen oder Status umsetzen
+ if ( pChild )
+ {
+ if( pChild->ImplIsAntiparallel() )
+ {
+ // - RTL - re-mirror frame pos at pChild
+ pChild->ImplReMirror( aMousePos );
+ }
+ // no mouse messages to system object windows ?
+ // !!!KA: Is it OK to comment this out? !!!
+// if ( pChild->ImplGetWindowImpl()->mpSysObj )
+// return 0;
+
+ // no mouse messages to disabled windows
+ // #106845# if the window was disabed during capturing we have to pass the mouse events to release capturing
+ if ( pSVData->maWinData.mpCaptureWin != pChild && (!pChild->IsEnabled() || !pChild->IsInputEnabled() || pChild->IsInModalMode() ) )
+ {
+ ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave );
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ ImplHandleMouseHelpRequest( pChild, aMousePos );
+ if( pWinFrameData->mpMouseMoveWin != pChild )
+ nMode |= MOUSE_ENTERWINDOW;
+ }
+
+ // Call the hook also, if Window is disabled
+ Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
+ MouseEvent aMEvt( aChildPos, pWinFrameData->mnClickCount, nMode, nCode, nCode );
+ NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
+ Application::CallEventHooks( aNEvt );
+
+ if( pChild->IsCallHandlersOnInputDisabled() )
+ {
+ pWinFrameData->mpMouseMoveWin = pChild;
+ pChild->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
+ }
+
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ Sound::Beep( SOUND_DISABLE, pChild );
+ return 1;
+ }
+ else
+ {
+ // Set normal MousePointer for disabled windows
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ ImplSetMousePointer( pChild );
+
+ return 0;
+ }
+ }
+
+ // End ExtTextInput-Mode, if the user click in the same TopLevel Window
+ if ( pSVData->maWinData.mpExtTextInputWin &&
+ ((nSVEvent == EVENT_MOUSEBUTTONDOWN) ||
+ (nSVEvent == EVENT_MOUSEBUTTONUP)) )
+ pSVData->maWinData.mpExtTextInputWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
+ }
+
+ // determine mouse event data
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ // Testen, ob MouseMove an das gleiche Fenster geht und sich der
+ // Status nicht geaendert hat
+ if ( pChild )
+ {
+ Point aChildMousePos = pChild->ImplFrameToOutput( aMousePos );
+ if ( !bMouseLeave &&
+ (pChild == pWinFrameData->mpMouseMoveWin) &&
+ (aChildMousePos.X() == pWinFrameData->mnLastMouseWinX) &&
+ (aChildMousePos.Y() == pWinFrameData->mnLastMouseWinY) &&
+ (nOldCode == pWinFrameData->mnMouseCode) )
+ {
+ // Mouse-Pointer neu setzen, da er sich geaendet haben
+ // koennte, da ein Modus umgesetzt wurde
+ ImplSetMousePointer( pChild );
+ return 0;
+ }
+
+ pWinFrameData->mnLastMouseWinX = aChildMousePos.X();
+ pWinFrameData->mnLastMouseWinY = aChildMousePos.Y();
+ }
+
+ // mouse click
+ nClicks = pWinFrameData->mnClickCount;
+
+ // Gegebenenfalls den Start-Drag-Handler rufen.
+ // Achtung: Muss vor Move gerufen werden, da sonst bei schnellen
+ // Mausbewegungen die Applikationen in den Selektionszustand gehen.
+ Window* pMouseDownWin = pWinFrameData->mpMouseDownWin;
+ if ( pMouseDownWin )
+ {
+ // Testen, ob StartDrag-Modus uebereinstimmt. Wir vergleichen nur
+ // den Status der Maustasten, damit man mit Mod1 z.B. sofort
+ // in den Kopiermodus gehen kann.
+ const MouseSettings& rMSettings = pMouseDownWin->GetSettings().GetMouseSettings();
+ if ( (nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
+ (rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) )
+ {
+ if ( !pMouseDownWin->ImplGetFrameData()->mbStartDragCalled )
+ {
+ long nDragW = rMSettings.GetStartDragWidth();
+ long nDragH = rMSettings.GetStartDragWidth();
+ //long nMouseX = nX;
+ //long nMouseY = nY;
+ long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
+ long nMouseY = aMousePos.Y();
+ if ( !(((nMouseX-nDragW) <= pMouseDownWin->ImplGetFrameData()->mnFirstMouseX) &&
+ ((nMouseX+nDragW) >= pMouseDownWin->ImplGetFrameData()->mnFirstMouseX)) ||
+ !(((nMouseY-nDragH) <= pMouseDownWin->ImplGetFrameData()->mnFirstMouseY) &&
+ ((nMouseY+nDragH) >= pMouseDownWin->ImplGetFrameData()->mnFirstMouseY)) )
+ {
+ pMouseDownWin->ImplGetFrameData()->mbStartDragCalled = TRUE;
+
+ // Check if drag source provides it's own recognizer
+ if( pMouseDownWin->ImplGetFrameData()->mbInternalDragGestureRecognizer )
+ {
+ // query DropTarget from child window
+ ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > xDragGestureRecognizer =
+ ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > ( pMouseDownWin->ImplGetWindowImpl()->mxDNDListenerContainer,
+ ::com::sun::star::uno::UNO_QUERY );
+
+ if( xDragGestureRecognizer.is() )
+ {
+ // retrieve mouse position relative to mouse down window
+ Point relLoc = pMouseDownWin->ImplFrameToOutput( Point(
+ pMouseDownWin->ImplGetFrameData()->mnFirstMouseX,
+ pMouseDownWin->ImplGetFrameData()->mnFirstMouseY ) );
+
+ // create a uno mouse event out of the available data
+ ::com::sun::star::awt::MouseEvent aMouseEvent(
+ static_cast < ::com::sun::star::uno::XInterface * > ( 0 ),
+#ifdef MACOSX
+ nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3),
+#else
+ nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2),
+#endif
+ nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE),
+ nMouseX,
+ nMouseY,
+ nClicks,
+ sal_False );
+
+ ULONG nCount = Application::ReleaseSolarMutex();
+
+ // FIXME: where do I get Action from ?
+ ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSource > xDragSource = pMouseDownWin->GetDragSource();
+
+ if( xDragSource.is() )
+ {
+ static_cast < DNDListenerContainer * > ( xDragGestureRecognizer.get() )->fireDragGestureEvent( 0,
+ relLoc.X(), relLoc.Y(), xDragSource, ::com::sun::star::uno::makeAny( aMouseEvent ) );
+ }
+
+ Application::AcquireSolarMutex( nCount );
+ }
+ }
+ }
+ }
+ }
+ else
+ pMouseDownWin->ImplGetFrameData()->mbStartDragCalled = TRUE;
+ }
+
+ // test for mouseleave and mouseenter
+ Window* pMouseMoveWin = pWinFrameData->mpMouseMoveWin;
+ if ( pChild != pMouseMoveWin )
+ {
+ if ( pMouseMoveWin )
+ {
+ Point aLeaveMousePos = pMouseMoveWin->ImplFrameToOutput( aMousePos );
+ MouseEvent aMLeaveEvt( aLeaveMousePos, nClicks, nMode | MOUSE_LEAVEWINDOW, nCode, nCode );
+ NotifyEvent aNLeaveEvt( EVENT_MOUSEMOVE, pMouseMoveWin, &aMLeaveEvt );
+ ImplDelData aDelData;
+ ImplDelData aDelData2;
+ pWinFrameData->mbInMouseMove = TRUE;
+ pMouseMoveWin->ImplGetWinData()->mbMouseOver = FALSE;
+ pMouseMoveWin->ImplAddDel( &aDelData );
+ // Durch MouseLeave kann auch dieses Fenster zerstoert
+ // werden
+ if ( pChild )
+ pChild->ImplAddDel( &aDelData2 );
+ if ( !ImplCallPreNotify( aNLeaveEvt ) )
+ {
+ pMouseMoveWin->MouseMove( aMLeaveEvt );
+ // #82968#
+ if( !aDelData.IsDelete() )
+ aNLeaveEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNLeaveEvt );
+ }
+
+ pWinFrameData->mpMouseMoveWin = NULL;
+ pWinFrameData->mbInMouseMove = FALSE;
+
+ if ( pChild )
+ {
+ if ( aDelData2.IsDelete() )
+ pChild = NULL;
+ else
+ pChild->ImplRemoveDel( &aDelData2 );
+ }
+ if ( aDelData.IsDelete() )
+ return 1;
+ pMouseMoveWin->ImplRemoveDel( &aDelData );
+ }
+
+ nMode |= MOUSE_ENTERWINDOW;
+ }
+ pWinFrameData->mpMouseMoveWin = pChild;
+ if( pChild )
+ pChild->ImplGetWinData()->mbMouseOver = TRUE;
+
+ // MouseLeave
+ if ( !pChild )
+ return 0;
+ }
+ else
+ {
+ // mouse click
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
+ ULONG nDblClkTime = rMSettings.GetDoubleClickTime();
+ long nDblClkW = rMSettings.GetDoubleClickWidth();
+ long nDblClkH = rMSettings.GetDoubleClickHeight();
+ //long nMouseX = nX;
+ //long nMouseY = nY;
+ long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
+ long nMouseY = aMousePos.Y();
+
+ if ( (pChild == pChild->ImplGetFrameData()->mpMouseDownWin) &&
+ (nCode == pChild->ImplGetFrameData()->mnFirstMouseCode) &&
+ ((nMsgTime-pChild->ImplGetFrameData()->mnMouseDownTime) < nDblClkTime) &&
+ ((nMouseX-nDblClkW) <= pChild->ImplGetFrameData()->mnFirstMouseX) &&
+ ((nMouseX+nDblClkW) >= pChild->ImplGetFrameData()->mnFirstMouseX) &&
+ ((nMouseY-nDblClkH) <= pChild->ImplGetFrameData()->mnFirstMouseY) &&
+ ((nMouseY+nDblClkH) >= pChild->ImplGetFrameData()->mnFirstMouseY) )
+ {
+ pChild->ImplGetFrameData()->mnClickCount++;
+ pChild->ImplGetFrameData()->mbStartDragCalled = TRUE;
+ }
+ else
+ {
+ pChild->ImplGetFrameData()->mpMouseDownWin = pChild;
+ pChild->ImplGetFrameData()->mnClickCount = 1;
+ pChild->ImplGetFrameData()->mnFirstMouseX = nMouseX;
+ pChild->ImplGetFrameData()->mnFirstMouseY = nMouseY;
+ pChild->ImplGetFrameData()->mnFirstMouseCode = nCode;
+ pChild->ImplGetFrameData()->mbStartDragCalled = !((nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
+ (rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)));
+ }
+ pChild->ImplGetFrameData()->mnMouseDownTime = nMsgTime;
+ }
+ nClicks = pChild->ImplGetFrameData()->mnClickCount;
+
+ pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
+ }
+
+ DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild == NULL" );
+
+ // create mouse event
+ Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
+ MouseEvent aMEvt( aChildPos, nClicks, nMode, nCode, nCode );
+
+ // tracking window gets the mouse events
+ if ( pSVData->maWinData.mpTrackWin )
+ pChild = pSVData->maWinData.mpTrackWin;
+
+ // handle FloatingMode
+ if ( !pSVData->maWinData.mpTrackWin && pSVData->maWinData.mpFirstFloat )
+ {
+ ImplDelData aDelData;
+ pChild->ImplAddDel( &aDelData );
+ if ( ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave ) )
+ {
+ if ( !aDelData.IsDelete() )
+ {
+ pChild->ImplRemoveDel( &aDelData );
+ pChild->ImplGetFrameData()->mbStartDragCalled = TRUE;
+ }
+ return 1;
+ }
+ else
+ pChild->ImplRemoveDel( &aDelData );
+ }
+
+ // call handler
+ BOOL bDrag = FALSE;
+ BOOL bCallHelpRequest = TRUE;
+ DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild is NULL" );
+
+ ImplDelData aDelData;
+ NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
+ pChild->ImplAddDel( &aDelData );
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ pChild->ImplGetFrameData()->mbInMouseMove = TRUE;
+
+ // bring window into foreground on mouseclick
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ if( !pSVData->maWinData.mpFirstFloat && // totop for floating windows in popup would change the focus and would close them immediately
+ !(pChild->ImplGetFrameWindow()->GetStyle() & WB_OWNERDRAWDECORATION) ) // ownerdrawdecorated windows must never grab focus
+ pChild->ToTop();
+ if ( aDelData.IsDelete() )
+ return 1;
+ }
+
+ if ( ImplCallPreNotify( aNEvt ) || aDelData.IsDelete() )
+ nRet = 1;
+ else
+ {
+ nRet = 0;
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ if ( pSVData->maWinData.mpTrackWin )
+ {
+ TrackingEvent aTEvt( aMEvt );
+ pChild->Tracking( aTEvt );
+ if ( !aDelData.IsDelete() )
+ {
+ // When ScrollRepeat, we restart the timer
+ if ( pSVData->maWinData.mpTrackTimer &&
+ (pSVData->maWinData.mnTrackFlags & STARTTRACK_SCROLLREPEAT) )
+ pSVData->maWinData.mpTrackTimer->Start();
+ }
+ bCallHelpRequest = FALSE;
+ nRet = 1;
+ }
+ else
+ {
+ // Auto-ToTop
+ if ( !pSVData->maWinData.mpCaptureWin &&
+ (pChild->GetSettings().GetMouseSettings().GetOptions() & MOUSE_OPTION_AUTOFOCUS) )
+ pChild->ToTop( TOTOP_NOGRABFOCUS );
+
+ if( aDelData.IsDelete() )
+ bCallHelpRequest = FALSE;
+ else
+ {
+ // if the MouseMove handler changes the help window's visibility
+ // the HelpRequest handler should not be called anymore
+ Window* pOldHelpTextWin = pSVData->maHelpData.mpHelpWin;
+ pChild->ImplGetWindowImpl()->mbMouseMove = FALSE;
+ pChild->MouseMove( aMEvt );
+ if ( pOldHelpTextWin != pSVData->maHelpData.mpHelpWin )
+ bCallHelpRequest = FALSE;
+ }
+ }
+ }
+ else if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ if ( pSVData->maWinData.mpTrackWin &&
+ !(pSVData->maWinData.mnTrackFlags & STARTTRACK_MOUSEBUTTONDOWN) )
+ nRet = 1;
+ else
+ {
+ pChild->ImplGetWindowImpl()->mbMouseButtonDown = FALSE;
+ pChild->MouseButtonDown( aMEvt );
+ }
+ }
+ else
+ {
+ if ( pSVData->maWinData.mpTrackWin )
+ {
+ pChild->EndTracking();
+ nRet = 1;
+ }
+ else
+ {
+ pChild->ImplGetWindowImpl()->mbMouseButtonUp = FALSE;
+ pChild->MouseButtonUp( aMEvt );
+ }
+ }
+
+ // #82968#
+ if ( !aDelData.IsDelete() )
+ aNEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
+ }
+
+ if ( aDelData.IsDelete() )
+ return 1;
+
+
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ pChild->ImplGetWindowImpl()->mpFrameData->mbInMouseMove = FALSE;
+
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ if ( bCallHelpRequest && !pSVData->maHelpData.mbKeyboardHelp )
+ ImplHandleMouseHelpRequest( pChild, pChild->OutputToScreenPixel( aMEvt.GetPosPixel() ) );
+ nRet = 1;
+ }
+ else if ( !nRet )
+ {
+ if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
+ {
+ if ( !pChild->ImplGetWindowImpl()->mbMouseButtonDown )
+ nRet = 1;
+ }
+ else
+ {
+ if ( !pChild->ImplGetWindowImpl()->mbMouseButtonUp )
+ nRet = 1;
+ }
+ }
+
+ pChild->ImplRemoveDel( &aDelData );
+
+ if ( nSVEvent == EVENT_MOUSEMOVE )
+ {
+ // set new mouse pointer
+ if ( !bMouseLeave )
+ ImplSetMousePointer( pChild );
+ }
+ else if ( (nSVEvent == EVENT_MOUSEBUTTONDOWN) || (nSVEvent == EVENT_MOUSEBUTTONUP) )
+ {
+ if ( !bDrag )
+ {
+ // Command-Events
+ if ( /*(nRet == 0) &&*/ (nClicks == 1) && (nSVEvent == EVENT_MOUSEBUTTONDOWN) &&
+ (nCode == MOUSE_MIDDLE) )
+ {
+ USHORT nMiddleAction = pChild->GetSettings().GetMouseSettings().GetMiddleButtonAction();
+ if ( nMiddleAction == MOUSE_MIDDLE_AUTOSCROLL )
+ nRet = !ImplCallCommand( pChild, COMMAND_STARTAUTOSCROLL, NULL, TRUE, &aChildPos );
+ else if ( nMiddleAction == MOUSE_MIDDLE_PASTESELECTION )
+ nRet = !ImplCallCommand( pChild, COMMAND_PASTESELECTION, NULL, TRUE, &aChildPos );
+ }
+ else
+ {
+ // ContextMenu
+ const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
+ if ( (nCode == rMSettings.GetContextMenuCode()) &&
+ (nClicks == rMSettings.GetContextMenuClicks()) )
+ {
+ BOOL bContextMenu;
+ if ( rMSettings.GetContextMenuDown() )
+ bContextMenu = (nSVEvent == EVENT_MOUSEBUTTONDOWN);
+ else
+ bContextMenu = (nSVEvent == EVENT_MOUSEBUTTONUP);
+ if ( bContextMenu )
+ {
+ if( pSVData->maAppData.mpActivePopupMenu )
+ {
+ /* #i34277# there already is a context menu open
+ * that was probably just closed with EndPopupMode.
+ * We need to give the eventual corresponding
+ * PopupMenu::Execute a chance to end properly.
+ * Therefore delay context menu command and
+ * issue only after popping one frame of the
+ * Yield stack.
+ */
+ ContextMenuEvent* pEv = new ContextMenuEvent;
+ pEv->pWindow = pChild;
+ pEv->aChildPos = aChildPos;
+ pChild->ImplAddDel( &pEv->aDelData );
+ Application::PostUserEvent( Link( pEv, ContextMenuEventLink ) );
+ }
+ else
+ nRet = ! ImplCallCommand( pChild, COMMAND_CONTEXTMENU, NULL, TRUE, &aChildPos );
+ }
+ }
+ }
+ }
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static Window* ImplGetKeyInputWindow( Window* pWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // determine last input time
+ pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
+
+ // #127104# workaround for destroyed windows
+ if( pWindow->ImplGetWindowImpl() == NULL )
+ return 0;
+
+ // find window - is every time the window which has currently the
+ // focus or the last time the focus.
+ // the first floating window always has the focus
+ Window* pChild = pSVData->maWinData.mpFirstFloat;
+ if( !pChild || ( pChild->ImplGetWindowImpl()->mbFloatWin && !((FloatingWindow *)pChild)->GrabsFocus() ) )
+ pChild = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
+ else
+ {
+ // allow floaters to forward keyinput to some member
+ pChild = pChild->GetPreferredKeyInputWindow();
+ }
+
+ // no child - than no input
+ if ( !pChild )
+ return 0;
+
+ // We call also KeyInput if we haven't the focus, because on Unix
+ // system this is often the case when a Lookup Choise Window has
+ // the focus - because this windows send the KeyInput directly to
+ // the window without resetting the focus
+ DBG_ASSERTWARNING( pChild == pSVData->maWinData.mpFocusWin,
+ "ImplHandleKey: Keyboard-Input is sent to a frame without focus" );
+
+ // no keyinput to disabled windows
+ if ( !pChild->IsEnabled() || !pChild->IsInputEnabled() || pChild->IsInModalMode() )
+ return 0;
+
+ return pChild;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleKey( Window* pWindow, USHORT nSVEvent,
+ USHORT nKeyCode, USHORT nCharCode, USHORT nRepeat, BOOL bForward )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ KeyCode aKeyCode( nKeyCode, nKeyCode );
+ USHORT nEvCode = aKeyCode.GetCode();
+
+ // allow application key listeners to remove the key event
+ // but make sure we're not forwarding external KeyEvents, (ie where bForward is FALSE)
+ // becasue those are coming back from the listener itself and MUST be processed
+ KeyEvent aKeyEvent( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
+ if( bForward )
+ {
+ USHORT nVCLEvent;
+ switch( nSVEvent )
+ {
+ case EVENT_KEYINPUT:
+ nVCLEvent = VCLEVENT_WINDOW_KEYINPUT;
+ break;
+ case EVENT_KEYUP:
+ nVCLEvent = VCLEVENT_WINDOW_KEYUP;
+ break;
+ default:
+ nVCLEvent = 0;
+ break;
+ }
+ if( nVCLEvent && pSVData->mpApp->HandleKey( nVCLEvent, pWindow, &aKeyEvent ) )
+ return 1;
+ }
+
+ // #i1820# use locale specific decimal separator
+ if( nEvCode == KEY_DECIMAL )
+ {
+ if( Application::GetSettings().GetMiscSettings().GetEnableLocalizedDecimalSep() )
+ {
+ String aSep( pWindow->GetSettings().GetLocaleDataWrapper().getNumDecimalSep() );
+ nCharCode = (USHORT) aSep.GetChar(0);
+ }
+ }
+
+ BOOL bCtrlF6 = (aKeyCode.GetCode() == KEY_F6) && aKeyCode.IsMod1();
+
+ // determine last input time
+ pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
+
+ // handle tracking window
+ if ( nSVEvent == EVENT_KEYINPUT )
+ {
+#ifdef DBG_UTIL
+ // #105224# use Ctrl-Alt-Shift-D, Ctrl-Shift-D must be useable by app
+ if ( aKeyCode.IsShift() && aKeyCode.IsMod1() && (aKeyCode.IsMod2() || aKeyCode.IsMod3()) && (aKeyCode.GetCode() == KEY_D) )
+ {
+ DBGGUI_START();
+ return 1;
+ }
+#endif
+
+ if ( pSVData->maHelpData.mbExtHelpMode )
+ {
+ Help::EndExtHelp();
+ if ( nEvCode == KEY_ESCAPE )
+ return 1;
+ }
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow( false );
+
+ // AutoScrollMode
+ if ( pSVData->maWinData.mpAutoScrollWin )
+ {
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+ if ( nEvCode == KEY_ESCAPE )
+ return 1;
+ }
+
+ if ( pSVData->maWinData.mpTrackWin )
+ {
+ USHORT nOrigCode = aKeyCode.GetCode();
+
+ if ( (nOrigCode == KEY_ESCAPE) && !(pSVData->maWinData.mnTrackFlags & STARTTRACK_NOKEYCANCEL) )
+ {
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL | ENDTRACK_KEY );
+ if ( pSVData->maWinData.mpFirstFloat )
+ {
+ FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ if ( !(pLastLevelFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOKEYCLOSE) )
+ {
+ USHORT nEscCode = aKeyCode.GetCode();
+
+ if ( nEscCode == KEY_ESCAPE )
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ }
+ }
+ return 1;
+ }
+ else if ( nOrigCode == KEY_RETURN )
+ {
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_KEY );
+ return 1;
+ }
+ else if ( !(pSVData->maWinData.mnTrackFlags & STARTTRACK_KEYINPUT) )
+ return 1;
+ }
+
+ // handle FloatingMode
+ if ( pSVData->maWinData.mpFirstFloat )
+ {
+ FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ if ( !(pLastLevelFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOKEYCLOSE) )
+ {
+ USHORT nCode = aKeyCode.GetCode();
+
+ if ( (nCode == KEY_ESCAPE) || bCtrlF6)
+ {
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ if( !bCtrlF6 )
+ return 1;
+ }
+ }
+ }
+
+ // test for accel
+ if ( pSVData->maAppData.mpAccelMgr )
+ {
+ if ( pSVData->maAppData.mpAccelMgr->IsAccelKey( aKeyCode, nRepeat ) )
+ return 1;
+ }
+ }
+
+ // find window
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ if ( !pChild )
+ return 0;
+
+ // --- RTL --- mirror cursor keys
+ if( (aKeyCode.GetCode() == KEY_LEFT || aKeyCode.GetCode() == KEY_RIGHT) &&
+ pChild->ImplHasMirroredGraphics() && pChild->IsRTLEnabled() )
+ aKeyCode = KeyCode( aKeyCode.GetCode() == KEY_LEFT ? KEY_RIGHT : KEY_LEFT, aKeyCode.GetModifier() );
+
+ // call handler
+ ImplDelData aDelData;
+ pChild->ImplAddDel( &aDelData );
+
+ KeyEvent aKeyEvt( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
+ NotifyEvent aNotifyEvt( nSVEvent, pChild, &aKeyEvt );
+ BOOL bKeyPreNotify = (ImplCallPreNotify( aNotifyEvt ) != 0);
+ long nRet = 1;
+
+ if ( !bKeyPreNotify && !aDelData.IsDelete() )
+ {
+ if ( nSVEvent == EVENT_KEYINPUT )
+ {
+ pChild->ImplGetWindowImpl()->mbKeyInput = FALSE;
+ pChild->KeyInput( aKeyEvt );
+ }
+ else
+ {
+ pChild->ImplGetWindowImpl()->mbKeyUp = FALSE;
+ pChild->KeyUp( aKeyEvt );
+ }
+ // #82968#
+ if( !aDelData.IsDelete() )
+ aNotifyEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNotifyEvt );
+ }
+
+ if ( aDelData.IsDelete() )
+ return 1;
+
+ pChild->ImplRemoveDel( &aDelData );
+
+ if ( nSVEvent == EVENT_KEYINPUT )
+ {
+ if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyInput )
+ {
+ USHORT nCode = aKeyCode.GetCode();
+
+ // #101999# is focus in or below toolbox
+ BOOL bToolboxFocus=FALSE;
+ if( (nCode == KEY_F1) && aKeyCode.IsShift() )
+ {
+ Window *pWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
+ while( pWin )
+ {
+ if( pWin->ImplGetWindowImpl()->mbToolBox )
+ {
+ bToolboxFocus = TRUE;
+ break;
+ }
+ else
+ pWin = pWin->GetParent();
+ }
+ }
+
+ // ContextMenu
+ if ( (nCode == KEY_CONTEXTMENU) || ((nCode == KEY_F10) && aKeyCode.IsShift() && !aKeyCode.IsMod1() && !aKeyCode.IsMod2() ) )
+ nRet = !ImplCallCommand( pChild, COMMAND_CONTEXTMENU, NULL, FALSE );
+ else if ( ( (nCode == KEY_F2) && aKeyCode.IsShift() ) || ( (nCode == KEY_F1) && aKeyCode.IsMod1() ) ||
+ // #101999# no active help when focus in toolbox, simulate BallonHelp instead
+ ( (nCode == KEY_F1) && aKeyCode.IsShift() && bToolboxFocus ) )
+ {
+ // TipHelp via Keyboard (Shift-F2 or Ctrl-F1)
+ // simulate mouseposition at center of window
+
+ Size aSize = pChild->GetOutputSize();
+ Point aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
+ aPos = pChild->OutputToScreenPixel( aPos );
+
+ HelpEvent aHelpEvent( aPos, HELPMODE_BALLOON );
+ aHelpEvent.SetKeyboardActivated( TRUE );
+ pSVData->maHelpData.mbSetKeyboardHelp = TRUE;
+ pChild->RequestHelp( aHelpEvent );
+ pSVData->maHelpData.mbSetKeyboardHelp = FALSE;
+ }
+ else if ( (nCode == KEY_F1) || (nCode == KEY_HELP) )
+ {
+ if ( !aKeyCode.GetModifier() )
+ {
+ if ( pSVData->maHelpData.mbContextHelp )
+ {
+ Point aMousePos = pChild->OutputToScreenPixel( pChild->GetPointerPosPixel() );
+ HelpEvent aHelpEvent( aMousePos, HELPMODE_CONTEXT );
+ pChild->RequestHelp( aHelpEvent );
+ }
+ else
+ nRet = 0;
+ }
+ else if ( aKeyCode.IsShift() )
+ {
+ if ( pSVData->maHelpData.mbExtHelp )
+ Help::StartExtHelp();
+ else
+ nRet = 0;
+ }
+ }
+ else
+ {
+ if ( ImplCallHotKey( aKeyCode ) )
+ nRet = 1;
+ else
+ nRet = 0;
+ }
+ }
+ }
+ else
+ {
+ if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyUp )
+ nRet = 0;
+ }
+
+ // #105591# send keyinput to parent if we are a floating window and the key was not pocessed yet
+ if( !nRet && pWindow->ImplGetWindowImpl()->mbFloatWin && pWindow->GetParent() && (pWindow->ImplGetWindowImpl()->mpFrame != pWindow->GetParent()->ImplGetWindowImpl()->mpFrame) )
+ {
+ pChild = pWindow->GetParent();
+
+ // call handler
+ ImplDelData aChildDelData( pChild );
+ KeyEvent aKEvt( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
+ NotifyEvent aNEvt( nSVEvent, pChild, &aKEvt );
+ BOOL bPreNotify = (ImplCallPreNotify( aNEvt ) != 0);
+ if ( aChildDelData.IsDelete() )
+ return 1;
+
+ if ( !bPreNotify )
+ {
+ if ( nSVEvent == EVENT_KEYINPUT )
+ {
+ pChild->ImplGetWindowImpl()->mbKeyInput = FALSE;
+ pChild->KeyInput( aKEvt );
+ }
+ else
+ {
+ pChild->ImplGetWindowImpl()->mbKeyUp = FALSE;
+ pChild->KeyUp( aKEvt );
+ }
+ // #82968#
+ if( !aChildDelData.IsDelete() )
+ aNEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
+ if ( aChildDelData.IsDelete() )
+ return 1;
+ }
+
+ if( bPreNotify || !pChild->ImplGetWindowImpl()->mbKeyInput )
+ nRet = 1;
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleExtTextInput( Window* pWindow,
+ const XubString& rText,
+ const USHORT* pTextAttr,
+ ULONG nCursorPos, USHORT nCursorFlags )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ Window* pChild = NULL;
+
+ int nTries = 200;
+ while( nTries-- )
+ {
+ pChild = pSVData->maWinData.mpExtTextInputWin;
+ if ( !pChild )
+ {
+ pChild = ImplGetKeyInputWindow( pWindow );
+ if ( !pChild )
+ return 0;
+ }
+ if( !pChild->ImplGetWindowImpl()->mpFrameData->mnFocusId )
+ break;
+ Application::Yield();
+ }
+
+ // If it is the first ExtTextInput call, we inform the information
+ // and allocate the data, which we must store in this mode
+ ImplWinData* pWinData = pChild->ImplGetWinData();
+ if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
+ {
+ pChild->ImplGetWindowImpl()->mbExtTextInput = TRUE;
+ if ( !pWinData->mpExtOldText )
+ pWinData->mpExtOldText = new UniString;
+ else
+ pWinData->mpExtOldText->Erase();
+ if ( pWinData->mpExtOldAttrAry )
+ {
+ delete [] pWinData->mpExtOldAttrAry;
+ pWinData->mpExtOldAttrAry = NULL;
+ }
+ pSVData->maWinData.mpExtTextInputWin = pChild;
+ ImplCallCommand( pChild, COMMAND_STARTEXTTEXTINPUT );
+ }
+
+ // be aware of being recursively called in StartExtTextInput
+ if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
+ return 0;
+
+ // Test for changes
+ BOOL bOnlyCursor = FALSE;
+ xub_StrLen nMinLen = Min( pWinData->mpExtOldText->Len(), rText.Len() );
+ xub_StrLen nDeltaStart = 0;
+ while ( nDeltaStart < nMinLen )
+ {
+ if ( pWinData->mpExtOldText->GetChar( nDeltaStart ) != rText.GetChar( nDeltaStart ) )
+ break;
+ nDeltaStart++;
+ }
+ if ( pWinData->mpExtOldAttrAry || pTextAttr )
+ {
+ if ( !pWinData->mpExtOldAttrAry || !pTextAttr )
+ nDeltaStart = 0;
+ else
+ {
+ xub_StrLen i = 0;
+ while ( i < nDeltaStart )
+ {
+ if ( pWinData->mpExtOldAttrAry[i] != pTextAttr[i] )
+ {
+ nDeltaStart = i;
+ break;
+ }
+ i++;
+ }
+ }
+ }
+ if ( (nDeltaStart >= nMinLen) &&
+ (pWinData->mpExtOldText->Len() == rText.Len()) )
+ bOnlyCursor = TRUE;
+
+ // Call Event and store the information
+ CommandExtTextInputData aData( rText, pTextAttr,
+ (xub_StrLen)nCursorPos, nCursorFlags,
+ nDeltaStart, pWinData->mpExtOldText->Len(),
+ bOnlyCursor );
+ *pWinData->mpExtOldText = rText;
+ if ( pWinData->mpExtOldAttrAry )
+ {
+ delete [] pWinData->mpExtOldAttrAry;
+ pWinData->mpExtOldAttrAry = NULL;
+ }
+ if ( pTextAttr )
+ {
+ pWinData->mpExtOldAttrAry = new USHORT[rText.Len()];
+ memcpy( pWinData->mpExtOldAttrAry, pTextAttr, rText.Len()*sizeof( USHORT ) );
+ }
+ return !ImplCallCommand( pChild, COMMAND_EXTTEXTINPUT, &aData );
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleEndExtTextInput( Window* /* pWindow */ )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ Window* pChild = pSVData->maWinData.mpExtTextInputWin;
+ long nRet = 0;
+
+ if ( pChild )
+ {
+ pChild->ImplGetWindowImpl()->mbExtTextInput = FALSE;
+ pSVData->maWinData.mpExtTextInputWin = NULL;
+ ImplWinData* pWinData = pChild->ImplGetWinData();
+ if ( pWinData->mpExtOldText )
+ {
+ delete pWinData->mpExtOldText;
+ pWinData->mpExtOldText = NULL;
+ }
+ if ( pWinData->mpExtOldAttrAry )
+ {
+ delete [] pWinData->mpExtOldAttrAry;
+ pWinData->mpExtOldAttrAry = NULL;
+ }
+ nRet = !ImplCallCommand( pChild, COMMAND_ENDEXTTEXTINPUT );
+ }
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleExtTextInputPos( Window* pWindow,
+ Rectangle& rRect, long& rInputWidth,
+ bool * pVertical )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ Window* pChild = pSVData->maWinData.mpExtTextInputWin;
+
+ if ( !pChild )
+ pChild = ImplGetKeyInputWindow( pWindow );
+ else
+ {
+ // Test, if the Window is related to the frame
+ if ( !pWindow->ImplIsWindowOrChild( pChild ) )
+ pChild = ImplGetKeyInputWindow( pWindow );
+ }
+
+ if ( pChild )
+ {
+ ImplCallCommand( pChild, COMMAND_CURSORPOS );
+ const Rectangle* pRect = pChild->GetCursorRect();
+ if ( pRect )
+ rRect = pChild->ImplLogicToDevicePixel( *pRect );
+ else
+ {
+ Cursor* pCursor = pChild->GetCursor();
+ if ( pCursor )
+ {
+ Point aPos = pChild->ImplLogicToDevicePixel( pCursor->GetPos() );
+ Size aSize = pChild->LogicToPixel( pCursor->GetSize() );
+ if ( !aSize.Width() )
+ aSize.Width() = pChild->GetSettings().GetStyleSettings().GetCursorSize();
+ rRect = Rectangle( aPos, aSize );
+ }
+ else
+ rRect = Rectangle( Point( pChild->GetOutOffXPixel(), pChild->GetOutOffYPixel() ), Size() );
+ }
+ rInputWidth = pChild->ImplLogicWidthToDevicePixel( pChild->GetCursorExtTextInputWidth() );
+ if ( !rInputWidth )
+ rInputWidth = rRect.GetWidth();
+ }
+ if (pVertical != 0)
+ *pVertical
+ = pChild != 0 && pChild->GetInputContext().GetFont().IsVertical();
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleInputContextChange( Window* pWindow, LanguageType eNewLang )
+{
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ CommandInputContextData aData( eNewLang );
+ return !ImplCallCommand( pChild, COMMAND_INPUTCONTEXTCHANGE, &aData );
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplCallWheelCommand( Window* pWindow, const Point& rPos,
+ const CommandWheelData* pWheelData )
+{
+ Point aCmdMousePos = pWindow->ImplFrameToOutput( rPos );
+ CommandEvent aCEvt( aCmdMousePos, COMMAND_WHEEL, TRUE, pWheelData );
+ NotifyEvent aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt );
+ ImplDelData aDelData( pWindow );
+ BOOL bPreNotify = (ImplCallPreNotify( aNCmdEvt ) != 0);
+ if ( aDelData.IsDelete() )
+ return FALSE;
+ if ( !bPreNotify )
+ {
+ pWindow->ImplGetWindowImpl()->mbCommand = FALSE;
+ pWindow->Command( aCEvt );
+ if ( aDelData.IsDelete() )
+ return FALSE;
+ if ( pWindow->ImplGetWindowImpl()->mbCommand )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleWheelEvent( Window* pWindow, const SalWheelMouseEvent& rEvt )
+{
+ ImplDelData aDogTag( pWindow );
+
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pSVData->maWinData.mpAutoScrollWin )
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow( true );
+ if( aDogTag.IsDelete() )
+ return 0;
+
+ USHORT nMode;
+ USHORT nCode = rEvt.mnCode;
+ bool bHorz = rEvt.mbHorz;
+ bool bPixel = rEvt.mbDeltaIsPixel;
+ if ( nCode & KEY_MOD1 )
+ nMode = COMMAND_WHEEL_ZOOM;
+ else if ( nCode & KEY_MOD2 )
+ nMode = COMMAND_WHEEL_DATAZOOM;
+ else
+ {
+ nMode = COMMAND_WHEEL_SCROLL;
+ // #i85450# interpret shift-wheel as horizontal wheel action
+ if( (nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)) == KEY_SHIFT )
+ bHorz = true;
+ }
+
+ CommandWheelData aWheelData( rEvt.mnDelta, rEvt.mnNotchDelta, rEvt.mnScrollLines, nMode, nCode, bHorz, bPixel );
+ Point aMousePos( rEvt.mnX, rEvt.mnY );
+ BOOL bRet = TRUE;
+
+ // first check any floating window ( eg. drop down listboxes)
+ bool bIsFloat = false;
+ Window *pMouseWindow = NULL;
+ if ( pSVData->maWinData.mpFirstFloat && !pSVData->maWinData.mpCaptureWin &&
+ !pSVData->maWinData.mpFirstFloat->ImplIsFloatPopupModeWindow( pWindow ) )
+ {
+ USHORT nHitTest = IMPL_FLOATWIN_HITTEST_OUTSIDE;
+ pMouseWindow = pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( pWindow, aMousePos, nHitTest );
+ }
+ // then try the window directly beneath the mouse
+ if( !pMouseWindow )
+ pMouseWindow = pWindow->ImplFindWindow( aMousePos );
+ else
+ {
+ // transform coordinates to float window frame coordinates
+ pMouseWindow = pMouseWindow->ImplFindWindow(
+ pMouseWindow->OutputToScreenPixel(
+ pMouseWindow->AbsoluteScreenToOutputPixel(
+ pWindow->OutputToAbsoluteScreenPixel(
+ pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
+ bIsFloat = true;
+ }
+
+ if ( pMouseWindow &&
+ pMouseWindow->IsEnabled() && pMouseWindow->IsInputEnabled() && ! pMouseWindow->IsInModalMode() )
+ {
+ // transform coordinates to float window frame coordinates
+ Point aRelMousePos( pMouseWindow->OutputToScreenPixel(
+ pMouseWindow->AbsoluteScreenToOutputPixel(
+ pWindow->OutputToAbsoluteScreenPixel(
+ pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
+ bRet = ImplCallWheelCommand( pMouseWindow, aRelMousePos, &aWheelData );
+ }
+
+ // if the commad was not handled try the focus window
+ if ( bRet )
+ {
+ Window* pFocusWindow = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
+ if ( pFocusWindow && (pFocusWindow != pMouseWindow) &&
+ (pFocusWindow == pSVData->maWinData.mpFocusWin) )
+ {
+ // no wheel-messages to disabled windows
+ if ( pFocusWindow->IsEnabled() && pFocusWindow->IsInputEnabled() && ! pFocusWindow->IsInModalMode() )
+ {
+ // transform coordinates to focus window frame coordinates
+ Point aRelMousePos( pFocusWindow->OutputToScreenPixel(
+ pFocusWindow->AbsoluteScreenToOutputPixel(
+ pWindow->OutputToAbsoluteScreenPixel(
+ pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
+ bRet = ImplCallWheelCommand( pFocusWindow, aRelMousePos, &aWheelData );
+ }
+ }
+ }
+
+ // close floaters
+ if( ! bIsFloat && pSVData->maWinData.mpFirstFloat )
+ {
+ FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ if( pLastLevelFloat )
+ {
+ ULONG nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
+ if ( nPopupFlags & FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE )
+ {
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ }
+ }
+ }
+
+ return !bRet;
+}
+
+// -----------------------------------------------------------------------
+#define IMPL_PAINT_CHECKRTL ((USHORT)0x0020)
+
+static void ImplHandlePaint( Window* pWindow, const Rectangle& rBoundRect, bool bImmediateUpdate )
+{
+ // give up background save when sytem paints arrive
+ Window* pSaveBackWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFirstBackWin;
+ while ( pSaveBackWin )
+ {
+ Window* pNext = pSaveBackWin->ImplGetWindowImpl()->mpOverlapData->mpNextBackWin;
+ Rectangle aRect( Point( pSaveBackWin->GetOutOffXPixel(), pSaveBackWin->GetOutOffYPixel() ),
+ Size( pSaveBackWin->GetOutputWidthPixel(), pSaveBackWin->GetOutputHeightPixel() ) );
+ if ( aRect.IsOver( rBoundRect ) )
+ pSaveBackWin->ImplDeleteOverlapBackground();
+ pSaveBackWin = pNext;
+ }
+
+ // system paint events must be checked for re-mirroring
+ pWindow->ImplGetWindowImpl()->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
+
+ // trigger paint for all windows that live in the new paint region
+ Region aRegion( rBoundRect );
+ pWindow->ImplInvalidateOverlapFrameRegion( aRegion );
+ if( bImmediateUpdate )
+ {
+ // #i87663# trigger possible pending resize notifications
+ // (GetSizePixel does that for us)
+ pWindow->GetSizePixel();
+ // force drawing inmmediately
+ pWindow->Update();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void KillOwnPopups( Window* pWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ Window *pParent = pWindow->ImplGetWindowImpl()->mpFrameWindow;
+ Window *pChild = pSVData->maWinData.mpFirstFloat;
+ if ( pChild && pParent->ImplIsWindowOrChild( pChild, TRUE ) )
+ {
+ if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) )
+ pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplHandleResize( Window* pWindow, long nNewWidth, long nNewHeight )
+{
+ if( pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE) )
+ {
+ KillOwnPopups( pWindow );
+ if( pWindow->ImplGetWindow() != ImplGetSVData()->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow( true );
+ }
+
+ if (
+ (nNewWidth > 0 && nNewHeight > 0) ||
+ pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize
+ )
+ {
+ if ( (nNewWidth != pWindow->GetOutputWidthPixel()) || (nNewHeight != pWindow->GetOutputHeightPixel()) )
+ {
+ pWindow->mnOutWidth = nNewWidth;
+ pWindow->mnOutHeight = nNewHeight;
+ pWindow->ImplGetWindowImpl()->mbWaitSystemResize = FALSE;
+ if ( pWindow->IsReallyVisible() )
+ pWindow->ImplSetClipFlag();
+ if ( pWindow->IsVisible() || pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize ||
+ ( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow ) ) // propagate resize for system border windows
+ {
+ bool bStartTimer = true;
+ // use resize buffering for user resizes
+ // ownerdraw decorated windows and floating windows can be resized immediately (i.e. synchronously)
+ if( pWindow->ImplGetWindowImpl()->mbFrame && (pWindow->GetStyle() & WB_SIZEABLE)
+ && !(pWindow->GetStyle() & WB_OWNERDRAWDECORATION) // synchronous resize for ownerdraw decorated windows (toolbars)
+ && !pWindow->ImplGetWindowImpl()->mbFloatWin ) // synchronous resize for floating windows, #i43799#
+ {
+ if( pWindow->ImplGetWindowImpl()->mpClientWindow )
+ {
+ // #i42750# presentation wants to be informed about resize
+ // as early as possible
+ WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pWindow->ImplGetWindowImpl()->mpClientWindow);
+ if( pWorkWindow && pWorkWindow->IsPresentationMode() )
+ bStartTimer = false;
+ }
+ }
+ else
+ bStartTimer = false;
+
+ if( bStartTimer )
+ pWindow->ImplGetWindowImpl()->mpFrameData->maResizeTimer.Start();
+ else
+ pWindow->ImplCallResize(); // otherwise menues cannot be positioned
+ }
+ else
+ pWindow->ImplGetWindowImpl()->mbCallResize = TRUE;
+ }
+ }
+
+ pWindow->ImplGetWindowImpl()->mpFrameData->mbNeedSysWindow = (nNewWidth < IMPL_MIN_NEEDSYSWIN) ||
+ (nNewHeight < IMPL_MIN_NEEDSYSWIN);
+ BOOL bMinimized = (nNewWidth <= 0) || (nNewHeight <= 0);
+ if( bMinimized != pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized )
+ pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplNotifyIconifiedState( bMinimized );
+ pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized = bMinimized;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleMove( Window* pWindow )
+{
+ if( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplIsFloatingWindow() && pWindow->IsReallyVisible() )
+ {
+ static_cast<FloatingWindow*>(pWindow)->EndPopupMode( FLOATWIN_POPUPMODEEND_TEAROFF );
+ pWindow->ImplCallMove();
+ }
+
+ if( pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE) )
+ {
+ KillOwnPopups( pWindow );
+ if( pWindow->ImplGetWindow() != ImplGetSVData()->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow( true );
+ }
+
+ if ( pWindow->IsVisible() )
+ pWindow->ImplCallMove();
+ else
+ pWindow->ImplGetWindowImpl()->mbCallMove = TRUE; // make sure the framepos will be updated on the next Show()
+
+ if ( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow )
+ pWindow->ImplGetWindowImpl()->mpClientWindow->ImplCallMove(); // notify client to update geometry
+
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleMoveResize( Window* pWindow, long nNewWidth, long nNewHeight )
+{
+ ImplHandleMove( pWindow );
+ ImplHandleResize( pWindow, nNewWidth, nNewHeight );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplActivateFloatingWindows( Window* pWindow, BOOL bActive )
+{
+ // Zuerst alle ueberlappenden Fenster ueberpruefen
+ Window* pTempWindow = pWindow->ImplGetWindowImpl()->mpFirstOverlap;
+ while ( pTempWindow )
+ {
+ if ( !pTempWindow->GetActivateMode() )
+ {
+ if ( (pTempWindow->GetType() == WINDOW_BORDERWINDOW) &&
+ (pTempWindow->ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) )
+ ((ImplBorderWindow*)pTempWindow)->SetDisplayActive( bActive );
+ }
+
+ ImplActivateFloatingWindows( pTempWindow, bActive );
+ pTempWindow = pTempWindow->ImplGetWindowImpl()->mpNext;
+ }
+}
+
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( Window, ImplAsyncFocusHdl, void*, EMPTYARG )
+{
+ ImplGetWindowImpl()->mpFrameData->mnFocusId = 0;
+
+ // Wenn Status erhalten geblieben ist, weil wir den Focus in der
+ // zwischenzeit schon wiederbekommen haben, brauchen wir auch
+ // nichts machen
+ BOOL bHasFocus = ImplGetWindowImpl()->mpFrameData->mbHasFocus || ImplGetWindowImpl()->mpFrameData->mbSysObjFocus;
+
+ // Dann die zeitverzoegerten Funktionen ausfuehren
+ if ( bHasFocus )
+ {
+ // Alle FloatingFenster deaktiv zeichnen
+ if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
+ ImplActivateFloatingWindows( this, bHasFocus );
+
+ if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin )
+ {
+ BOOL bHandled = FALSE;
+ if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInputEnabled() &&
+ ! ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInModalMode() )
+ {
+ if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsEnabled() )
+ {
+ ImplGetWindowImpl()->mpFrameData->mpFocusWin->GrabFocus();
+ bHandled = TRUE;
+ }
+ else if( ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplHasDlgCtrl() )
+ {
+ // #109094# if the focus is restored to a disabled dialog control (was disabled meanwhile)
+ // try to move it to the next control
+ ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplDlgCtrlNextWindow();
+ bHandled = TRUE;
+ }
+ }
+ if ( !bHandled )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+ Window* pTopLevelWindow = ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplGetFirstOverlapWindow();
+ if ( ( ! pTopLevelWindow->IsInputEnabled() || pTopLevelWindow->IsInModalMode() )
+ && pSVData->maWinData.mpLastExecuteDlg )
+ pSVData->maWinData.mpLastExecuteDlg->ToTop( TOTOP_RESTOREWHENMIN | TOTOP_GRABFOCUSONLY);
+ else
+ pTopLevelWindow->GrabFocus();
+ }
+ }
+ else
+ GrabFocus();
+ }
+ else
+ {
+ Window* pFocusWin = ImplGetWindowImpl()->mpFrameData->mpFocusWin;
+ if ( pFocusWin )
+ {
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( pSVData->maWinData.mpFocusWin == pFocusWin )
+ {
+ // FocusWindow umsetzen
+ Window* pOverlapWindow = pFocusWin->ImplGetFirstOverlapWindow();
+ pOverlapWindow->ImplGetWindowImpl()->mpLastFocusWindow = pFocusWin;
+ pSVData->maWinData.mpFocusWin = NULL;
+
+ if ( pFocusWin->ImplGetWindowImpl()->mpCursor )
+ pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide();
+
+ // Deaktivate rufen
+ Window* pOldFocusWindow = pFocusWin;
+ if ( pOldFocusWindow )
+ {
+ Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
+ Window* pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
+
+ pOldOverlapWindow->ImplGetWindowImpl()->mbActive = FALSE;
+ pOldOverlapWindow->Deactivate();
+ if ( pOldRealWindow != pOldOverlapWindow )
+ {
+ pOldRealWindow->ImplGetWindowImpl()->mbActive = FALSE;
+ pOldRealWindow->Deactivate();
+ }
+ }
+
+ // TrackingMode is ended in ImplHandleLoseFocus
+// To avoid problems with the Unix IME
+// pFocusWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
+
+ // XXX #102010# hack for accessibility: do not close the menu,
+ // even after focus lost
+ static const char* pEnv = getenv("SAL_FLOATWIN_NOAPPFOCUSCLOSE");
+ if( !(pEnv && *pEnv) )
+ {
+ NotifyEvent aNEvt( EVENT_LOSEFOCUS, pFocusWin );
+ if ( !ImplCallPreNotify( aNEvt ) )
+ pFocusWin->LoseFocus();
+ pFocusWin->ImplCallDeactivateListeners( NULL );
+ GetpApp()->FocusChanged();
+ }
+ // XXX
+ }
+ }
+
+ // Alle FloatingFenster deaktiv zeichnen
+ if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
+ ImplActivateFloatingWindows( this, bHasFocus );
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleGetFocus( Window* pWindow )
+{
+ pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = TRUE;
+
+ // Focus-Events zeitverzoegert ausfuehren, damit bei SystemChildFenstern
+ // nicht alles flackert, wenn diese den Focus bekommen
+ if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
+ {
+ bool bCallDirect = ImplGetSVData()->mbIsTestTool;
+ pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
+ if( ! bCallDirect )
+ Application::PostUserEvent( pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId, LINK( pWindow, Window, ImplAsyncFocusHdl ) );
+ Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
+ if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
+ pFocusWin->ImplGetWindowImpl()->mpCursor->ImplShow();
+ if( bCallDirect )
+ pWindow->ImplAsyncFocusHdl( NULL );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleLoseFocus( Window* pWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // Wenn Frame den Focus verliert, brechen wir auch ein AutoScroll ab
+ if ( pSVData->maWinData.mpAutoScrollWin )
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+
+ // Wenn Frame den Focus verliert, brechen wir auch ein Tracking ab
+ if ( pSVData->maWinData.mpTrackWin )
+ {
+ if ( pSVData->maWinData.mpTrackWin->ImplGetWindowImpl()->mpFrameWindow == pWindow )
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
+ }
+
+ // handle FloatingMode
+ // hier beenden wir immer den PopupModus, auch dann, wenn NOFOCUSCLOSE
+ // gesetzt ist, damit wir nicht beim Wechsel noch Fenster stehen lassen
+ if ( pSVData->maWinData.mpFirstFloat )
+ {
+ if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) )
+ pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ }
+
+ pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = FALSE;
+
+ // Focus-Events zeitverzoegert ausfuehren, damit bei SystemChildFenstern
+ // nicht alles flackert, wenn diese den Focus bekommen
+ bool bCallDirect = ImplGetSVData()->mbIsTestTool;
+ if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
+ {
+ pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
+ if( ! bCallDirect )
+ Application::PostUserEvent( pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId, LINK( pWindow, Window, ImplAsyncFocusHdl ) );
+ }
+
+ Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
+ if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
+ pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide();
+ if( bCallDirect )
+ pWindow->ImplAsyncFocusHdl( NULL );
+}
+
+// -----------------------------------------------------------------------
+struct DelayedCloseEvent
+{
+ Window* pWindow;
+ ImplDelData aDelData;
+};
+
+static long DelayedCloseEventLink( void* pCEvent, void* )
+{
+ DelayedCloseEvent* pEv = (DelayedCloseEvent*)pCEvent;
+
+ if( ! pEv->aDelData.IsDelete() )
+ {
+ pEv->pWindow->ImplRemoveDel( &pEv->aDelData );
+ // dispatch to correct window type
+ if( pEv->pWindow->IsSystemWindow() )
+ ((SystemWindow*)pEv->pWindow)->Close();
+ else if( pEv->pWindow->ImplIsDockingWindow() )
+ ((DockingWindow*)pEv->pWindow)->Close();
+ }
+ delete pEv;
+
+ return 0;
+}
+
+void ImplHandleClose( Window* pWindow )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ bool bWasPopup = false;
+ if( pWindow->ImplIsFloatingWindow() &&
+ static_cast<FloatingWindow*>(pWindow)->ImplIsInPrivatePopupMode() )
+ {
+ bWasPopup = true;
+ }
+
+ // on Close stop all floating modes and end popups
+ if ( pSVData->maWinData.mpFirstFloat )
+ {
+ FloatingWindow* pLastLevelFloat;
+ pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
+ pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
+ }
+ if ( pSVData->maHelpData.mbExtHelpMode )
+ Help::EndExtHelp();
+ if ( pSVData->maHelpData.mpHelpWin )
+ ImplDestroyHelpWindow( false );
+ // AutoScrollMode
+ if ( pSVData->maWinData.mpAutoScrollWin )
+ pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
+
+ if ( pSVData->maWinData.mpTrackWin )
+ pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL | ENDTRACK_KEY );
+
+ if( ! bWasPopup )
+ {
+ Window *pWin = pWindow->ImplGetWindow();
+ // check whether close is allowed
+ if ( !pWin->IsEnabled() || !pWin->IsInputEnabled() || pWin->IsInModalMode() )
+ Sound::Beep( SOUND_DISABLE, pWin );
+ else
+ {
+ DelayedCloseEvent* pEv = new DelayedCloseEvent;
+ pEv->pWindow = pWin;
+ pWin->ImplAddDel( &pEv->aDelData );
+ Application::PostUserEvent( Link( pEv, DelayedCloseEventLink ) );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleUserEvent( ImplSVEvent* pSVEvent )
+{
+ if ( pSVEvent )
+ {
+ if ( pSVEvent->mbCall && !pSVEvent->maDelData.IsDelete() )
+ {
+ if ( pSVEvent->mpWindow )
+ {
+ pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) );
+ if ( pSVEvent->mpLink )
+ pSVEvent->mpLink->Call( pSVEvent->mpData );
+ else
+ pSVEvent->mpWindow->UserEvent( pSVEvent->mnEvent, pSVEvent->mpData );
+ }
+ else
+ {
+ if ( pSVEvent->mpLink )
+ pSVEvent->mpLink->Call( pSVEvent->mpData );
+ else
+ GetpApp()->UserEvent( pSVEvent->mnEvent, pSVEvent->mpData );
+ }
+ }
+
+ delete pSVEvent->mpLink;
+ delete pSVEvent;
+ }
+}
+
+// =======================================================================
+
+static USHORT ImplGetMouseMoveMode( SalMouseEvent* pEvent )
+{
+ USHORT nMode = 0;
+ if ( !pEvent->mnCode )
+ nMode |= MOUSE_SIMPLEMOVE;
+ if ( (pEvent->mnCode & MOUSE_LEFT) && !(pEvent->mnCode & KEY_MOD1) )
+ nMode |= MOUSE_DRAGMOVE;
+ if ( (pEvent->mnCode & MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) )
+ nMode |= MOUSE_DRAGCOPY;
+ return nMode;
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplGetMouseButtonMode( SalMouseEvent* pEvent )
+{
+ USHORT nMode = 0;
+ if ( pEvent->mnButton == MOUSE_LEFT )
+ nMode |= MOUSE_SIMPLECLICK;
+ if ( (pEvent->mnButton == MOUSE_LEFT) && !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT)) )
+ nMode |= MOUSE_SELECT;
+ if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) &&
+ !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_SHIFT)) )
+ nMode |= MOUSE_MULTISELECT;
+ if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_SHIFT) &&
+ !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_MOD1)) )
+ nMode |= MOUSE_RANGESELECT;
+ return nMode;
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplHandleSalMouseLeave( Window* pWindow, SalMouseEvent* pEvent )
+{
+ return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, TRUE,
+ pEvent->mnX, pEvent->mnY,
+ pEvent->mnTime, pEvent->mnCode,
+ ImplGetMouseMoveMode( pEvent ) );
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplHandleSalMouseMove( Window* pWindow, SalMouseEvent* pEvent )
+{
+ return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, FALSE,
+ pEvent->mnX, pEvent->mnY,
+ pEvent->mnTime, pEvent->mnCode,
+ ImplGetMouseMoveMode( pEvent ) );
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplHandleSalMouseButtonDown( Window* pWindow, SalMouseEvent* pEvent )
+{
+ return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONDOWN, FALSE,
+ pEvent->mnX, pEvent->mnY,
+ pEvent->mnTime,
+#ifdef MACOSX
+ pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)),
+#else
+ pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
+#endif
+ ImplGetMouseButtonMode( pEvent ) );
+}
+
+// -----------------------------------------------------------------------
+
+inline long ImplHandleSalMouseButtonUp( Window* pWindow, SalMouseEvent* pEvent )
+{
+ return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONUP, FALSE,
+ pEvent->mnX, pEvent->mnY,
+ pEvent->mnTime,
+#ifdef MACOSX
+ pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)),
+#else
+ pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
+#endif
+ ImplGetMouseButtonMode( pEvent ) );
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleSalMouseActivate( Window* /*pWindow*/, SalMouseActivateEvent* /*pEvent*/ )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleMenuEvent( Window* pWindow, SalMenuEvent* pEvent, USHORT nEvent )
+{
+ // Find SystemWindow and its Menubar and let it dispatch the command
+ long nRet = 0;
+ Window *pWin = pWindow->ImplGetWindowImpl()->mpFirstChild;
+ while ( pWin )
+ {
+ if ( pWin->ImplGetWindowImpl()->mbSysWin )
+ break;
+ pWin = pWin->ImplGetWindowImpl()->mpNext;
+ }
+ if( pWin )
+ {
+ MenuBar *pMenuBar = ((SystemWindow*) pWin)->GetMenuBar();
+ if( pMenuBar )
+ {
+ switch( nEvent )
+ {
+ case SALEVENT_MENUACTIVATE:
+ nRet = pMenuBar->HandleMenuActivateEvent( (Menu*) pEvent->mpMenu ) ? 1 : 0;
+ break;
+ case SALEVENT_MENUDEACTIVATE:
+ nRet = pMenuBar->HandleMenuDeActivateEvent( (Menu*) pEvent->mpMenu ) ? 1 : 0;
+ break;
+ case SALEVENT_MENUHIGHLIGHT:
+ nRet = pMenuBar->HandleMenuHighlightEvent( (Menu*) pEvent->mpMenu, pEvent->mnId ) ? 1 : 0;
+ break;
+ case SALEVENT_MENUBUTTONCOMMAND:
+ nRet = pMenuBar->HandleMenuButtonEvent( (Menu*) pEvent->mpMenu, pEvent->mnId ) ? 1 : 0;
+ break;
+ case SALEVENT_MENUCOMMAND:
+ nRet = pMenuBar->HandleMenuCommandEvent( (Menu*) pEvent->mpMenu, pEvent->mnId ) ? 1 : 0;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSalKeyMod( Window* pWindow, SalKeyModEvent* pEvent )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ Window* pTrackWin = pSVData->maWinData.mpTrackWin;
+ if ( pTrackWin )
+ pWindow = pTrackWin;
+#ifdef MACOSX
+ USHORT nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
+#else
+ USHORT nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
+#endif
+ USHORT nNewCode = pEvent->mnCode;
+ if ( nOldCode != nNewCode )
+ {
+#ifdef MACOSX
+ nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
+#else
+ nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
+#endif
+ pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplCallMouseMove( nNewCode, TRUE );
+ }
+
+ // #105224# send commandevent to allow special treatment of Ctrl-LeftShift/Ctrl-RightShift etc.
+
+ // find window
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ if ( !pChild )
+ return;
+
+ // send modkey events only if useful data is available
+ if( pEvent->mnModKeyCode != 0 )
+ {
+ CommandModKeyData data( pEvent->mnModKeyCode );
+ ImplCallCommand( pChild, COMMAND_MODKEYCHANGE, &data );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleInputLanguageChange( Window* pWindow )
+{
+ // find window
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ if ( !pChild )
+ return;
+
+ ImplCallCommand( pChild, COMMAND_INPUTLANGUAGECHANGE );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSalSettings( Window* pWindow, USHORT nEvent )
+{
+ // Application Notification werden nur fuer das erste Window ausgeloest
+ ImplSVData* pSVData = ImplGetSVData();
+ if ( pWindow != pSVData->maWinData.mpFirstFrame )
+ return;
+
+ Application* pApp = GetpApp();
+ if ( !pApp )
+ return;
+
+ if ( nEvent == SALEVENT_SETTINGSCHANGED )
+ {
+ AllSettings aSettings = pApp->GetSettings();
+ pApp->MergeSystemSettings( aSettings );
+ pApp->SystemSettingsChanging( aSettings, pWindow );
+ pApp->SetSettings( aSettings );
+ }
+ else
+ {
+ USHORT nType;
+ switch ( nEvent )
+ {
+ case SALEVENT_VOLUMECHANGED:
+ nType = 0;
+ break;
+ case SALEVENT_PRINTERCHANGED:
+ ImplDeletePrnQueueList();
+ nType = DATACHANGED_PRINTER;
+ break;
+ case SALEVENT_DISPLAYCHANGED:
+ nType = DATACHANGED_DISPLAY;
+ break;
+ case SALEVENT_FONTCHANGED:
+ OutputDevice::ImplUpdateAllFontData( TRUE );
+ nType = DATACHANGED_FONTS;
+ break;
+ case SALEVENT_DATETIMECHANGED:
+ nType = DATACHANGED_DATETIME;
+ break;
+ case SALEVENT_KEYBOARDCHANGED:
+ nType = 0;
+ break;
+ default:
+ nType = 0;
+ break;
+ }
+
+ if ( nType )
+ {
+ DataChangedEvent aDCEvt( nType );
+ pApp->DataChanged( aDCEvt );
+ pApp->NotifyAllWindows( aDCEvt );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSalExtTextInputPos( Window* pWindow, SalExtTextInputPosEvent* pEvt )
+{
+ Rectangle aCursorRect;
+ ImplHandleExtTextInputPos( pWindow, aCursorRect, pEvt->mnExtWidth, &pEvt->mbVertical );
+ if ( aCursorRect.IsEmpty() )
+ {
+ pEvt->mnX = -1;
+ pEvt->mnY = -1;
+ pEvt->mnWidth = -1;
+ pEvt->mnHeight = -1;
+ }
+ else
+ {
+ pEvt->mnX = aCursorRect.Left();
+ pEvt->mnY = aCursorRect.Top();
+ pEvt->mnWidth = aCursorRect.GetWidth();
+ pEvt->mnHeight = aCursorRect.GetHeight();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleShowDialog( Window* pWindow, int nDialogId )
+{
+ if( ! pWindow )
+ return FALSE;
+
+ if( pWindow->GetType() == WINDOW_BORDERWINDOW )
+ {
+ Window* pWrkWin = pWindow->GetWindow( WINDOW_CLIENT );
+ if( pWrkWin )
+ pWindow = pWrkWin;
+ }
+ CommandDialogData aCmdData( nDialogId );
+ return ImplCallCommand( pWindow, COMMAND_SHOWDIALOG, &aCmdData );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSurroundingTextRequest( Window *pWindow,
+ XubString& rText,
+ Selection &rSelRange )
+{
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+
+ if ( !pChild )
+ {
+ rText = XubString::EmptyString();
+ rSelRange.setMin( 0 );
+ rSelRange.setMax( 0 );
+ }
+ else
+ {
+
+ rText = pChild->GetSurroundingText();
+ Selection aSel = pChild->GetSurroundingTextSelection();
+ rSelRange.setMin( aSel.Min() );
+ rSelRange.setMax( aSel.Max() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSalSurroundingTextRequest( Window *pWindow,
+ SalSurroundingTextRequestEvent *pEvt )
+{
+ Selection aSelRange;
+ ImplHandleSurroundingTextRequest( pWindow, pEvt->maText, aSelRange );
+
+ aSelRange.Justify();
+
+ if( aSelRange.Min() < 0 )
+ pEvt->mnStart = 0;
+ else if( aSelRange.Min() > pEvt->maText.Len() )
+ pEvt->mnStart = pEvt->maText.Len();
+ else
+ pEvt->mnStart = aSelRange.Min();
+
+ if( aSelRange.Max() < 0 )
+ pEvt->mnStart = 0;
+ else if( aSelRange.Max() > pEvt->maText.Len() )
+ pEvt->mnEnd = pEvt->maText.Len();
+ else
+ pEvt->mnEnd = aSelRange.Max();
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSurroundingTextSelectionChange( Window *pWindow,
+ ULONG nStart,
+ ULONG nEnd )
+{
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ if( pChild )
+ {
+ CommandSelectionChangeData data( nStart, nEnd );
+ ImplCallCommand( pChild, COMMAND_SELECTIONCHANGE, &data );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleStartReconversion( Window *pWindow )
+{
+ Window* pChild = ImplGetKeyInputWindow( pWindow );
+ if( pChild )
+ ImplCallCommand( pChild, COMMAND_PREPARERECONVERSION );
+}
+
+// -----------------------------------------------------------------------
+
+long ImplWindowFrameProc( Window* pWindow, SalFrame* /*pFrame*/,
+ USHORT nEvent, const void* pEvent )
+{
+ DBG_TESTSOLARMUTEX();
+
+ long nRet = 0;
+
+ // #119709# for some unknown reason it is possible to receive events (in this case key events)
+ // although the corresponding VCL window must have been destroyed already
+ // at least ImplGetWindowImpl() was NULL in these cases, so check this here
+ if( pWindow->ImplGetWindowImpl() == NULL )
+ return 0;
+
+ switch ( nEvent )
+ {
+ case SALEVENT_MOUSEMOVE:
+ nRet = ImplHandleSalMouseMove( pWindow, (SalMouseEvent*)pEvent );
+ break;
+ case SALEVENT_EXTERNALMOUSEMOVE:
+ {
+ MouseEvent* pMouseEvt = (MouseEvent*) pEvent;
+ SalMouseEvent aSalMouseEvent;
+
+ aSalMouseEvent.mnTime = Time::GetSystemTicks();
+ aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
+ aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
+ aSalMouseEvent.mnButton = 0;
+ aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
+
+ nRet = ImplHandleSalMouseMove( pWindow, &aSalMouseEvent );
+ }
+ break;
+ case SALEVENT_MOUSELEAVE:
+ nRet = ImplHandleSalMouseLeave( pWindow, (SalMouseEvent*)pEvent );
+ break;
+ case SALEVENT_MOUSEBUTTONDOWN:
+ nRet = ImplHandleSalMouseButtonDown( pWindow, (SalMouseEvent*)pEvent );
+ break;
+ case SALEVENT_EXTERNALMOUSEBUTTONDOWN:
+ {
+ MouseEvent* pMouseEvt = (MouseEvent*) pEvent;
+ SalMouseEvent aSalMouseEvent;
+
+ aSalMouseEvent.mnTime = Time::GetSystemTicks();
+ aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
+ aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
+ aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
+ aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
+
+ nRet = ImplHandleSalMouseButtonDown( pWindow, &aSalMouseEvent );
+ }
+ break;
+ case SALEVENT_MOUSEBUTTONUP:
+ nRet = ImplHandleSalMouseButtonUp( pWindow, (SalMouseEvent*)pEvent );
+ break;
+ case SALEVENT_EXTERNALMOUSEBUTTONUP:
+ {
+ MouseEvent* pMouseEvt = (MouseEvent*) pEvent;
+ SalMouseEvent aSalMouseEvent;
+
+ aSalMouseEvent.mnTime = Time::GetSystemTicks();
+ aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
+ aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
+ aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
+ aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
+
+ nRet = ImplHandleSalMouseButtonUp( pWindow, &aSalMouseEvent );
+ }
+ break;
+ case SALEVENT_MOUSEACTIVATE:
+ nRet = ImplHandleSalMouseActivate( pWindow, (SalMouseActivateEvent*)pEvent );
+ break;
+ case SALEVENT_KEYINPUT:
+ {
+ SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
+ nRet = ImplHandleKey( pWindow, EVENT_KEYINPUT,
+ pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, TRUE );
+ }
+ break;
+ case SALEVENT_EXTERNALKEYINPUT:
+ {
+ KeyEvent* pKeyEvt = (KeyEvent*) pEvent;
+ nRet = ImplHandleKey( pWindow, EVENT_KEYINPUT,
+ pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), FALSE );
+ }
+ break;
+ case SALEVENT_KEYUP:
+ {
+ SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
+ nRet = ImplHandleKey( pWindow, EVENT_KEYUP,
+ pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, TRUE );
+ }
+ break;
+ case SALEVENT_EXTERNALKEYUP:
+ {
+ KeyEvent* pKeyEvt = (KeyEvent*) pEvent;
+ nRet = ImplHandleKey( pWindow, EVENT_KEYUP,
+ pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), FALSE );
+ }
+ break;
+ case SALEVENT_KEYMODCHANGE:
+ ImplHandleSalKeyMod( pWindow, (SalKeyModEvent*)pEvent );
+ break;
+
+ case SALEVENT_INPUTLANGUAGECHANGE:
+ ImplHandleInputLanguageChange( pWindow );
+ break;
+
+ case SALEVENT_MENUACTIVATE:
+ case SALEVENT_MENUDEACTIVATE:
+ case SALEVENT_MENUHIGHLIGHT:
+ case SALEVENT_MENUCOMMAND:
+ case SALEVENT_MENUBUTTONCOMMAND:
+ nRet = ImplHandleMenuEvent( pWindow, (SalMenuEvent*)pEvent, nEvent );
+ break;
+
+ case SALEVENT_WHEELMOUSE:
+ nRet = ImplHandleWheelEvent( pWindow, *(const SalWheelMouseEvent*)pEvent);
+ break;
+
+ case SALEVENT_PAINT:
+ {
+ SalPaintEvent* pPaintEvt = (SalPaintEvent*)pEvent;
+
+ if( Application::GetSettings().GetLayoutRTL() )
+ {
+ // --- RTL --- (mirror paint rect)
+ SalFrame* pSalFrame = pWindow->ImplGetWindowImpl()->mpFrame;
+ pPaintEvt->mnBoundX = pSalFrame->maGeometry.nWidth-pPaintEvt->mnBoundWidth-pPaintEvt->mnBoundX;
+ }
+
+ Rectangle aBoundRect( Point( pPaintEvt->mnBoundX, pPaintEvt->mnBoundY ),
+ Size( pPaintEvt->mnBoundWidth, pPaintEvt->mnBoundHeight ) );
+ ImplHandlePaint( pWindow, aBoundRect, pPaintEvt->mbImmediateUpdate );
+ }
+ break;
+
+ case SALEVENT_MOVE:
+ ImplHandleMove( pWindow );
+ break;
+
+ case SALEVENT_RESIZE:
+ {
+ long nNewWidth;
+ long nNewHeight;
+ pWindow->ImplGetWindowImpl()->mpFrame->GetClientSize( nNewWidth, nNewHeight );
+ ImplHandleResize( pWindow, nNewWidth, nNewHeight );
+ }
+ break;
+
+ case SALEVENT_MOVERESIZE:
+ {
+ SalFrameGeometry g = pWindow->ImplGetWindowImpl()->mpFrame->GetGeometry();
+ ImplHandleMoveResize( pWindow, g.nWidth, g.nHeight );
+ }
+ break;
+
+ case SALEVENT_CLOSEPOPUPS:
+ {
+ KillOwnPopups( pWindow );
+ }
+ break;
+
+ case SALEVENT_GETFOCUS:
+ ImplHandleGetFocus( pWindow );
+ break;
+ case SALEVENT_LOSEFOCUS:
+ ImplHandleLoseFocus( pWindow );
+ break;
+
+ case SALEVENT_CLOSE:
+ ImplHandleClose( pWindow );
+ break;
+
+ case SALEVENT_SHUTDOWN:
+ {
+ static bool bInQueryExit = false;
+ if( !bInQueryExit )
+ {
+ bInQueryExit = true;
+ if ( GetpApp()->QueryExit() )
+ {
+ // Message-Schleife beenden
+ Application::Quit();
+ return FALSE;
+ }
+ else
+ {
+ bInQueryExit = false;
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+
+ case SALEVENT_SETTINGSCHANGED:
+ case SALEVENT_VOLUMECHANGED:
+ case SALEVENT_PRINTERCHANGED:
+ case SALEVENT_DISPLAYCHANGED:
+ case SALEVENT_FONTCHANGED:
+ case SALEVENT_DATETIMECHANGED:
+ case SALEVENT_KEYBOARDCHANGED:
+ ImplHandleSalSettings( pWindow, nEvent );
+ break;
+
+ case SALEVENT_USEREVENT:
+ ImplHandleUserEvent( (ImplSVEvent*)pEvent );
+ break;
+
+ case SALEVENT_EXTTEXTINPUT:
+ {
+ SalExtTextInputEvent* pEvt = (SalExtTextInputEvent*)pEvent;
+ nRet = ImplHandleExtTextInput( pWindow,
+ pEvt->maText, pEvt->mpTextAttr,
+ pEvt->mnCursorPos, pEvt->mnCursorFlags );
+ }
+ break;
+ case SALEVENT_ENDEXTTEXTINPUT:
+ nRet = ImplHandleEndExtTextInput( pWindow );
+ break;
+ case SALEVENT_EXTTEXTINPUTPOS:
+ ImplHandleSalExtTextInputPos( pWindow, (SalExtTextInputPosEvent*)pEvent );
+ break;
+ case SALEVENT_INPUTCONTEXTCHANGE:
+ nRet = ImplHandleInputContextChange( pWindow, ((SalInputContextChangeEvent*)pEvent)->meLanguage );
+ break;
+ case SALEVENT_SHOWDIALOG:
+ {
+ int nDialogID = static_cast<int>(reinterpret_cast<sal_IntPtr>(pEvent));
+ nRet = ImplHandleShowDialog( pWindow, nDialogID );
+ }
+ break;
+ case SALEVENT_SURROUNDINGTEXTREQUEST:
+ ImplHandleSalSurroundingTextRequest( pWindow, (SalSurroundingTextRequestEvent*)pEvent );
+ break;
+ case SALEVENT_SURROUNDINGTEXTSELECTIONCHANGE:
+ {
+ SalSurroundingTextSelectionChangeEvent* pEvt
+ = (SalSurroundingTextSelectionChangeEvent*)pEvent;
+ ImplHandleSurroundingTextSelectionChange( pWindow,
+ pEvt->mnStart,
+ pEvt->mnEnd );
+ }
+ case SALEVENT_STARTRECONVERSION:
+ ImplHandleStartReconversion( pWindow );
+ break;
+#ifdef DBG_UTIL
+ default:
+ DBG_ERROR1( "ImplWindowFrameProc(): unknown event (%lu)", (ULONG)nEvent );
+ break;
+#endif
+ }
+
+ return nRet;
+}