/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#include <tools/debug.hxx>

#include <unotools/localedatawrapper.hxx>

#include <vcl/i18nhelp.hxx>
#include <vcl/unohelp.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/wrkwin.hxx>
#include <vcl/floatwin.hxx>
#include <vcl/dialog.hxx>
#include <vcl/help.hxx>
#include <vcl/dockwin.hxx>
#include <vcl/menu.hxx>

#include <svdata.hxx>
#include <dbggui.hxx>
#include <salwtype.hxx>
#include <salframe.hxx>
#include <accmgr.hxx>
#include <print.h>
#include <window.h>
#include <helpwin.hxx>
#include <brdwin.hxx>
#include <salgdi.hxx>
#include <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 sal_Bool ImplHandleMouseFloatMode( Window* pChild, const Point& rMousePos,
                                      sal_uInt16 nCode, sal_uInt16 nSVEvent,
                                      sal_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
         */
        sal_uInt16          nHitTest = IMPL_FLOATWIN_HITTEST_OUTSIDE;
        FloatingWindow* pFloat = pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( pChild, rMousePos, nHitTest );
        FloatingWindow* pLastLevelFloat;
        sal_uLong           nPopupFlags;
        if ( nSVEvent == EVENT_MOUSEMOVE )
        {
            if ( bMouseLeave )
                return sal_True;

            if ( !pFloat || (nHitTest & IMPL_FLOATWIN_HITTEST_RECT) )
            {
                if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp )
                    ImplDestroyHelpWindow( true );
                pChild->ImplGetFrame()->SetPointer( POINTER_ARROW );
                return sal_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 sal_False;
//                        else
                            return sal_True;
                    }
                    else if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
                    {
                        if ( !(pFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOMOUSERECTCLOSE) )
                            pFloat->ImplSetMouseDown();
                        return sal_True;
                    }
                }
                else
                {
                    if ( pFloat )
                    {
                        if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
                        {
                            if ( pFloat->ImplIsMouseDown() )
                                pFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
                            return sal_True;
                        }
                    }
                    else
                    {
                        pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
                        nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
                        if ( !(nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) )
                        {
                            pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
                            return sal_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 sal_True;
                        pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
                        if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
                            return sal_False;
                        else
                            return sal_True;
                    }
                    else
                        return sal_True;
                }
            }
        }
    }

    return sal_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 ) ) )
    {
        sal_uInt16 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 = sal_True;
                pChild->RequestHelp( aHelpEvent );
                pSVData->maHelpData.mbRequestingHelp = sal_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 sal_Bool ImplCallCommand( Window* pChild, sal_uInt16 nEvt, void* pData = NULL,
                             sal_Bool bMouse = sal_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 );
    sal_Bool            bPreNotify = (ImplCallPreNotify( aNCmdEvt ) != 0);
    if ( aDelData.IsDelete() )
        return sal_False;
    if ( !bPreNotify )
    {
        pChild->ImplGetWindowImpl()->mbCommand = sal_False;
        pChild->Command( aCEvt );

        if( aDelData.IsDelete() )
            return sal_False;
        pChild->ImplNotifyKeyMouseCommandEventListeners( aNCmdEvt );
        if ( aDelData.IsDelete() )
            return sal_False;
        if ( pChild->ImplGetWindowImpl()->mbCommand )
            return sal_True;
    }

    return sal_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, sal_True, &pEv->aChildPos );
    }
    delete pEv;

    return 0;
}

long ImplHandleMouseEvent( Window* pWindow, sal_uInt16 nSVEvent, sal_Bool bMouseLeave,
                           long nX, long nY, sal_uLong nMsgTime,
                           sal_uInt16 nCode, sal_uInt16 nMode )
{
    ImplSVData* pSVData = ImplGetSVData();
    Point       aMousePos( nX, nY );
    Window*     pChild;
    long        nRet;
    sal_uInt16      nClicks;
    ImplFrameData* pWinFrameData = pWindow->ImplGetFrameData();
    sal_uInt16      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, sal_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 = sal_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 = sal_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  = sal_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 );

                                sal_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  = sal_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 = sal_True;
                pMouseMoveWin->ImplGetWinData()->mbMouseOver = sal_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 = sal_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 = sal_True;

        // MouseLeave
        if ( !pChild )
            return 0;
    }
    else
    {
        // mouse click
        if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
        {
            const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
            sal_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  = sal_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 = sal_True;
            }
            return 1;
        }
        else
            pChild->ImplRemoveDel( &aDelData );
    }

    // call handler
    sal_Bool bDrag = sal_False;
    sal_Bool bCallHelpRequest = sal_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 = sal_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 = sal_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 = sal_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 = sal_False;
                    pChild->MouseMove( aMEvt );
                    if ( pOldHelpTextWin != pSVData->maHelpData.mpHelpWin )
                        bCallHelpRequest = sal_False;
                }
            }
        }
        else if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
        {
            if ( pSVData->maWinData.mpTrackWin &&
                 !(pSVData->maWinData.mnTrackFlags & STARTTRACK_MOUSEBUTTONDOWN) )
                nRet = 1;
            else
            {
                pChild->ImplGetWindowImpl()->mbMouseButtonDown = sal_False;
                pChild->MouseButtonDown( aMEvt );
            }
        }
        else
        {
            if ( pSVData->maWinData.mpTrackWin )
            {
                pChild->EndTracking();
                nRet = 1;
            }
            else
            {
                pChild->ImplGetWindowImpl()->mbMouseButtonUp = sal_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 = sal_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) )
            {
                sal_uInt16 nMiddleAction = pChild->GetSettings().GetMouseSettings().GetMiddleButtonAction();
                if ( nMiddleAction == MOUSE_MIDDLE_AUTOSCROLL )
                    nRet = !ImplCallCommand( pChild, COMMAND_STARTAUTOSCROLL, NULL, sal_True, &aChildPos );
                else if ( nMiddleAction == MOUSE_MIDDLE_PASTESELECTION )
                    nRet = !ImplCallCommand( pChild, COMMAND_PASTESELECTION, NULL, sal_True, &aChildPos );
            }
            else
            {
                // ContextMenu
                const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
                if ( (nCode == rMSettings.GetContextMenuCode()) &&
                     (nClicks == rMSettings.GetContextMenuClicks()) )
                {
                    sal_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, sal_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, sal_uInt16 nSVEvent,
                           sal_uInt16 nKeyCode, sal_uInt16 nCharCode, sal_uInt16 nRepeat, sal_Bool bForward )
{
    ImplSVData* pSVData = ImplGetSVData();
    KeyCode     aKeyCode( nKeyCode, nKeyCode );
    sal_uInt16      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 sal_False)
    // becasue those are coming back from the listener itself and MUST be processed
    KeyEvent aKeyEvent( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
    if( bForward )
    {
        sal_uInt16 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 = (sal_uInt16) aSep.GetChar(0);
        }
    }

	sal_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 )
        {
            sal_uInt16 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) )
                    {
                        sal_uInt16 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) )
            {
                sal_uInt16 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 );
    sal_Bool        bKeyPreNotify = (ImplCallPreNotify( aNotifyEvt ) != 0);
    long        nRet = 1;

    if ( !bKeyPreNotify && !aDelData.IsDelete() )
    {
        if ( nSVEvent == EVENT_KEYINPUT )
        {
            pChild->ImplGetWindowImpl()->mbKeyInput = sal_False;
            pChild->KeyInput( aKeyEvt );
        }
        else
        {
            pChild->ImplGetWindowImpl()->mbKeyUp = sal_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 )
        {
            sal_uInt16 nCode = aKeyCode.GetCode();

            // #101999# is focus in or below toolbox
            sal_Bool bToolboxFocus=sal_False;
            if( (nCode == KEY_F1) && aKeyCode.IsShift() )
            {
                Window *pWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
                while( pWin )
                {
                    if( pWin->ImplGetWindowImpl()->mbToolBox )
                    {
                        bToolboxFocus = sal_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, sal_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( sal_True );
				pSVData->maHelpData.mbSetKeyboardHelp = sal_True;
                pChild->RequestHelp( aHelpEvent );
				pSVData->maHelpData.mbSetKeyboardHelp = sal_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 );
        sal_Bool        bPreNotify = (ImplCallPreNotify( aNEvt ) != 0);
        if ( aChildDelData.IsDelete() )
            return 1;

        if ( !bPreNotify )
        {
            if ( nSVEvent == EVENT_KEYINPUT )
            {
                pChild->ImplGetWindowImpl()->mbKeyInput = sal_False;
                pChild->KeyInput( aKEvt );
            }
            else
            {
                pChild->ImplGetWindowImpl()->mbKeyUp = sal_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 sal_uInt16* pTextAttr,
                                    sal_uLong nCursorPos, sal_uInt16 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 = sal_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
    sal_Bool        bOnlyCursor = sal_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 = sal_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 sal_uInt16[rText.Len()];
        memcpy( pWinData->mpExtOldAttrAry, pTextAttr, rText.Len()*sizeof( sal_uInt16 ) );
    }
    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 = sal_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 sal_Bool ImplCallWheelCommand( Window* pWindow, const Point& rPos,
                                  const CommandWheelData* pWheelData )
{
    Point               aCmdMousePos = pWindow->ImplFrameToOutput( rPos );
    CommandEvent        aCEvt( aCmdMousePos, COMMAND_WHEEL, sal_True, pWheelData );
    NotifyEvent         aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt );
    ImplDelData         aDelData( pWindow );
    sal_Bool                bPreNotify = (ImplCallPreNotify( aNCmdEvt ) != 0);
    if ( aDelData.IsDelete() )
        return sal_False;
    if ( !bPreNotify )
    {
        pWindow->ImplGetWindowImpl()->mbCommand = sal_False;
        pWindow->Command( aCEvt );
        if ( aDelData.IsDelete() )
            return sal_False;
        if ( pWindow->ImplGetWindowImpl()->mbCommand )
            return sal_True;
    }
    return sal_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;

    sal_uInt16 nMode;
    sal_uInt16 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 );
    sal_Bool                bRet = sal_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 ) )
    {
        sal_uInt16 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 )
        {
            sal_uLong nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
            if ( nPopupFlags & FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE )
            {
                pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
            }
        }
    }

    return !bRet;
}

// -----------------------------------------------------------------------
#define IMPL_PAINT_CHECKRTL         ((sal_uInt16)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, sal_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 = sal_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
                    {
                        WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pWindow);
                        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 = sal_True;
        }
    }

    pWindow->ImplGetWindowImpl()->mpFrameData->mbNeedSysWindow = (nNewWidth < IMPL_MIN_NEEDSYSWIN) ||
                                            (nNewHeight < IMPL_MIN_NEEDSYSWIN);
    sal_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 = sal_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, sal_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
    sal_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 )
        {
            sal_Bool bHandled = sal_False;
            if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInputEnabled() &&
                 ! ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInModalMode() )
            {
                if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsEnabled() )
                {
                    ImplGetWindowImpl()->mpFrameData->mpFocusWin->GrabFocus();
                    bHandled = sal_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 = sal_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( true );

                // Deaktivate rufen
                Window* pOldFocusWindow = pFocusWin;
                if ( pOldFocusWindow )
                {
                    Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
                    Window* pOldRealWindow = pOldOverlapWindow->ImplGetWindow();

                    pOldOverlapWindow->ImplGetWindowImpl()->mbActive = sal_False;
                    pOldOverlapWindow->Deactivate();
                    if ( pOldRealWindow != pOldOverlapWindow )
                    {
                        pOldRealWindow->ImplGetWindowImpl()->mbActive = sal_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 = sal_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 = sal_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( true );
    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 sal_uInt16 ImplGetMouseMoveMode( SalMouseEvent* pEvent )
{
    sal_uInt16 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 sal_uInt16 ImplGetMouseButtonMode( SalMouseEvent* pEvent )
{
    sal_uInt16 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, sal_True,
                                 pEvent->mnX, pEvent->mnY,
                                 pEvent->mnTime, pEvent->mnCode,
                                 ImplGetMouseMoveMode( pEvent ) );
}

// -----------------------------------------------------------------------

inline long ImplHandleSalMouseMove( Window* pWindow, SalMouseEvent* pEvent )
{
    return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, sal_False,
                                 pEvent->mnX, pEvent->mnY,
                                 pEvent->mnTime, pEvent->mnCode,
                                 ImplGetMouseMoveMode( pEvent ) );
}

// -----------------------------------------------------------------------

inline long ImplHandleSalMouseButtonDown( Window* pWindow, SalMouseEvent* pEvent )
{
    return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONDOWN, sal_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, sal_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 sal_False;
}

// -----------------------------------------------------------------------

static long ImplHandleMenuEvent( Window* pWindow, SalMenuEvent* pEvent, sal_uInt16 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
    sal_uInt16 nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
#else
    sal_uInt16 nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
#endif
    sal_uInt16 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, sal_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, sal_uInt16 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
    {
        sal_uInt16 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( sal_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 sal_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,
						      sal_uLong nStart,
						      sal_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*/,
                          sal_uInt16 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, sal_True );
            }
            break;
        case SALEVENT_EXTERNALKEYINPUT:
            {
            KeyEvent* pKeyEvt = (KeyEvent*) pEvent;
            nRet = ImplHandleKey( pWindow, EVENT_KEYINPUT,
                pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), sal_False );
            }
            break;
        case SALEVENT_KEYUP:
            {
            SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
            nRet = ImplHandleKey( pWindow, EVENT_KEYUP,
                pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, sal_True );
            }
            break;
        case SALEVENT_EXTERNALKEYUP:
            {
            KeyEvent* pKeyEvt = (KeyEvent*) pEvent;
            nRet = ImplHandleKey( pWindow, EVENT_KEYUP,
                pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), sal_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 sal_False;
					}
					else
					{
						bInQueryExit = false;
						return sal_True;
					}
				}
                return sal_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)", (sal_uLong)nEvent );
            break;
#endif
    }

    return nRet;
}
