xref: /aoo42x/main/vcl/source/window/winproc.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <tools/debug.hxx>
32 
33 #include <unotools/localedatawrapper.hxx>
34 
35 #include <vcl/i18nhelp.hxx>
36 #include <vcl/unohelp.hxx>
37 #include <vcl/timer.hxx>
38 #include <vcl/event.hxx>
39 #include <vcl/sound.hxx>
40 #include <vcl/settings.hxx>
41 #include <vcl/svapp.hxx>
42 #include <vcl/cursor.hxx>
43 #include <vcl/wrkwin.hxx>
44 #include <vcl/floatwin.hxx>
45 #include <vcl/dialog.hxx>
46 #include <vcl/help.hxx>
47 #include <vcl/dockwin.hxx>
48 #include <vcl/menu.hxx>
49 
50 #include <svdata.hxx>
51 #include <dbggui.hxx>
52 #include <salwtype.hxx>
53 #include <salframe.hxx>
54 #include <accmgr.hxx>
55 #include <print.h>
56 #include <window.h>
57 #include <helpwin.hxx>
58 #include <brdwin.hxx>
59 #include <salgdi.hxx>
60 #include <dndlcon.hxx>
61 
62 #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
63 #include <com/sun/star/awt/MouseEvent.hpp>
64 
65 #if OSL_DEBUG_LEVEL > 1
66 char dbgbuffer[1024];
67 #ifndef WNT
68 #include <stdio.h>
69 #define MyOutputDebugString(s) (fprintf(stderr, s ))
70 #else
71 extern void MyOutputDebugString( char *s);
72 #endif
73 #endif
74 
75 
76 // =======================================================================
77 
78 #define IMPL_MIN_NEEDSYSWIN         49
79 
80 // =======================================================================
81 
82 long ImplCallPreNotify( NotifyEvent& rEvt )
83 {
84     long nRet = Application::CallEventHooks( rEvt );
85     if ( !nRet )
86         nRet = rEvt.GetWindow()->PreNotify( rEvt );
87     return nRet;
88 }
89 
90 // =======================================================================
91 
92 long ImplCallEvent( NotifyEvent& rEvt )
93 {
94     long nRet = ImplCallPreNotify( rEvt );
95     if ( !nRet )
96     {
97         Window* pWindow = rEvt.GetWindow();
98         switch ( rEvt.GetType() )
99         {
100             case EVENT_MOUSEBUTTONDOWN:
101                 pWindow->MouseButtonDown( *rEvt.GetMouseEvent() );
102                 break;
103             case EVENT_MOUSEBUTTONUP:
104                 pWindow->MouseButtonUp( *rEvt.GetMouseEvent() );
105                 break;
106             case EVENT_MOUSEMOVE:
107                 pWindow->MouseMove( *rEvt.GetMouseEvent() );
108                 break;
109             case EVENT_KEYINPUT:
110                 pWindow->KeyInput( *rEvt.GetKeyEvent() );
111                 break;
112             case EVENT_KEYUP:
113                 pWindow->KeyUp( *rEvt.GetKeyEvent() );
114                 break;
115             case EVENT_GETFOCUS:
116                 pWindow->GetFocus();
117                 break;
118             case EVENT_LOSEFOCUS:
119                 pWindow->LoseFocus();
120                 break;
121             case EVENT_COMMAND:
122                 pWindow->Command( *rEvt.GetCommandEvent() );
123                 break;
124         }
125     }
126 
127     return nRet;
128 }
129 
130 // =======================================================================
131 
132 static sal_Bool ImplHandleMouseFloatMode( Window* pChild, const Point& rMousePos,
133                                       sal_uInt16 nCode, sal_uInt16 nSVEvent,
134                                       sal_Bool bMouseLeave )
135 {
136     ImplSVData* pSVData = ImplGetSVData();
137 
138     if ( pSVData->maWinData.mpFirstFloat && !pSVData->maWinData.mpCaptureWin &&
139          !pSVData->maWinData.mpFirstFloat->ImplIsFloatPopupModeWindow( pChild ) )
140     {
141         /*
142          *  #93895# since floats are system windows, coordinates have
143          *  to be converted to float relative for the hittest
144          */
145         sal_uInt16          nHitTest = IMPL_FLOATWIN_HITTEST_OUTSIDE;
146         FloatingWindow* pFloat = pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( pChild, rMousePos, nHitTest );
147         FloatingWindow* pLastLevelFloat;
148         sal_uLong           nPopupFlags;
149         if ( nSVEvent == EVENT_MOUSEMOVE )
150         {
151             if ( bMouseLeave )
152                 return sal_True;
153 
154             if ( !pFloat || (nHitTest & IMPL_FLOATWIN_HITTEST_RECT) )
155             {
156                 if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp )
157                     ImplDestroyHelpWindow( true );
158                 pChild->ImplGetFrame()->SetPointer( POINTER_ARROW );
159                 return sal_True;
160             }
161         }
162         else
163         {
164             if ( nCode & MOUSE_LEFT )
165             {
166                 if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
167                 {
168                     if ( !pFloat )
169                     {
170                         pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
171                         nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
172                         pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
173 // Erstmal ausgebaut als Hack fuer Bug 53378
174 //                        if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
175 //                            return sal_False;
176 //                        else
177                             return sal_True;
178                     }
179                     else if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
180                     {
181                         if ( !(pFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOMOUSERECTCLOSE) )
182                             pFloat->ImplSetMouseDown();
183                         return sal_True;
184                     }
185                 }
186                 else
187                 {
188                     if ( pFloat )
189                     {
190                         if ( nHitTest & IMPL_FLOATWIN_HITTEST_RECT )
191                         {
192                             if ( pFloat->ImplIsMouseDown() )
193                                 pFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
194                             return sal_True;
195                         }
196                     }
197                     else
198                     {
199                         pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
200                         nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
201                         if ( !(nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) )
202                         {
203                             pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
204                             return sal_True;
205                         }
206                     }
207                 }
208             }
209             else
210             {
211                 if ( !pFloat )
212                 {
213                     pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
214                     nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
215                     if ( nPopupFlags & FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE )
216                     {
217                         if ( (nPopupFlags & FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE) &&
218                              (nSVEvent == EVENT_MOUSEBUTTONUP) )
219                             return sal_True;
220                         pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
221                         if ( nPopupFlags & FLOATWIN_POPUPMODE_PATHMOUSECANCELCLICK )
222                             return sal_False;
223                         else
224                             return sal_True;
225                     }
226                     else
227                         return sal_True;
228                 }
229             }
230         }
231     }
232 
233     return sal_False;
234 }
235 
236 // -----------------------------------------------------------------------
237 
238 static void ImplHandleMouseHelpRequest( Window* pChild, const Point& rMousePos )
239 {
240     ImplSVData* pSVData = ImplGetSVData();
241     if ( !pSVData->maHelpData.mpHelpWin ||
242 	     !( pSVData->maHelpData.mpHelpWin->IsWindowOrChild( pChild ) ||
243 	       pChild->IsWindowOrChild( pSVData->maHelpData.mpHelpWin ) ) )
244     {
245         sal_uInt16 nHelpMode = 0;
246         if ( pSVData->maHelpData.mbQuickHelp )
247             nHelpMode = HELPMODE_QUICK;
248         if ( pSVData->maHelpData.mbBalloonHelp )
249             nHelpMode |= HELPMODE_BALLOON;
250         if ( nHelpMode )
251         {
252             if ( pChild->IsInputEnabled() && ! pChild->IsInModalMode() )
253             {
254                 HelpEvent aHelpEvent( rMousePos, nHelpMode );
255                 pSVData->maHelpData.mbRequestingHelp = sal_True;
256                 pChild->RequestHelp( aHelpEvent );
257                 pSVData->maHelpData.mbRequestingHelp = sal_False;
258             }
259             // #104172# do not kill keyboard activated tooltips
260             else if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp)
261             {
262                 ImplDestroyHelpWindow( true );
263             }
264         }
265     }
266 }
267 
268 // -----------------------------------------------------------------------
269 
270 static void ImplSetMousePointer( Window* pChild )
271 {
272     ImplSVData* pSVData = ImplGetSVData();
273     if ( pSVData->maHelpData.mbExtHelpMode )
274         pChild->ImplGetFrame()->SetPointer( POINTER_HELP );
275     else
276         pChild->ImplGetFrame()->SetPointer( pChild->ImplGetMousePointer() );
277 }
278 
279 // -----------------------------------------------------------------------
280 
281 static sal_Bool ImplCallCommand( Window* pChild, sal_uInt16 nEvt, void* pData = NULL,
282                              sal_Bool bMouse = sal_False, Point* pPos = NULL )
283 {
284     Point aPos;
285     if ( pPos )
286         aPos = *pPos;
287     else
288 	{
289 		if( bMouse )
290 			aPos = pChild->GetPointerPosPixel();
291 		else
292 		{
293 			// simulate mouseposition at center of window
294 			Size aSize( pChild->GetOutputSizePixel() );
295 			aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
296 		}
297 	}
298 
299     CommandEvent    aCEvt( aPos, nEvt, bMouse, pData );
300     NotifyEvent     aNCmdEvt( EVENT_COMMAND, pChild, &aCEvt );
301     ImplDelData     aDelData( pChild );
302     sal_Bool            bPreNotify = (ImplCallPreNotify( aNCmdEvt ) != 0);
303     if ( aDelData.IsDelete() )
304         return sal_False;
305     if ( !bPreNotify )
306     {
307         pChild->ImplGetWindowImpl()->mbCommand = sal_False;
308         pChild->Command( aCEvt );
309 
310         if( aDelData.IsDelete() )
311             return sal_False;
312         pChild->ImplNotifyKeyMouseCommandEventListeners( aNCmdEvt );
313         if ( aDelData.IsDelete() )
314             return sal_False;
315         if ( pChild->ImplGetWindowImpl()->mbCommand )
316             return sal_True;
317     }
318 
319     return sal_False;
320 }
321 
322 // -----------------------------------------------------------------------
323 
324 /*  #i34277# delayed context menu activation;
325 *   necessary if there already was a popup menu running.
326 */
327 
328 struct ContextMenuEvent
329 {
330     Window*         pWindow;
331     ImplDelData     aDelData;
332     Point           aChildPos;
333 };
334 
335 static long ContextMenuEventLink( void* pCEvent, void* )
336 {
337     ContextMenuEvent* pEv = (ContextMenuEvent*)pCEvent;
338 
339     if( ! pEv->aDelData.IsDelete() )
340     {
341         pEv->pWindow->ImplRemoveDel( &pEv->aDelData );
342         ImplCallCommand( pEv->pWindow, COMMAND_CONTEXTMENU, NULL, sal_True, &pEv->aChildPos );
343     }
344     delete pEv;
345 
346     return 0;
347 }
348 
349 long ImplHandleMouseEvent( Window* pWindow, sal_uInt16 nSVEvent, sal_Bool bMouseLeave,
350                            long nX, long nY, sal_uLong nMsgTime,
351                            sal_uInt16 nCode, sal_uInt16 nMode )
352 {
353     ImplSVData* pSVData = ImplGetSVData();
354     Point       aMousePos( nX, nY );
355     Window*     pChild;
356     long        nRet;
357     sal_uInt16      nClicks;
358     ImplFrameData* pWinFrameData = pWindow->ImplGetFrameData();
359     sal_uInt16      nOldCode = pWinFrameData->mnMouseCode;
360 
361     // we need a mousemove event, befor we get a mousebuttondown or a
362     // mousebuttonup event
363     if ( (nSVEvent == EVENT_MOUSEBUTTONDOWN) ||
364          (nSVEvent == EVENT_MOUSEBUTTONUP) )
365     {
366         if ( (nSVEvent == EVENT_MOUSEBUTTONUP) && pSVData->maHelpData.mbExtHelpMode )
367             Help::EndExtHelp();
368         if ( pSVData->maHelpData.mpHelpWin )
369         {
370             if( pWindow->ImplGetWindow() == pSVData->maHelpData.mpHelpWin )
371             {
372                 ImplDestroyHelpWindow( false );
373                 return 1; // pWindow is dead now - avoid crash!
374             }
375             else
376                 ImplDestroyHelpWindow( true );
377         }
378 
379         if ( (pWinFrameData->mnLastMouseX != nX) ||
380              (pWinFrameData->mnLastMouseY != nY) )
381         {
382             ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, sal_False, nX, nY, nMsgTime, nCode, nMode );
383         }
384     }
385 
386     // update frame data
387     pWinFrameData->mnBeforeLastMouseX = pWinFrameData->mnLastMouseX;
388     pWinFrameData->mnBeforeLastMouseY = pWinFrameData->mnLastMouseY;
389     pWinFrameData->mnLastMouseX = nX;
390     pWinFrameData->mnLastMouseY = nY;
391     pWinFrameData->mnMouseCode  = nCode;
392     pWinFrameData->mnMouseMode  = nMode & ~(MOUSE_SYNTHETIC | MOUSE_MODIFIERCHANGED);
393     if ( bMouseLeave )
394     {
395         pWinFrameData->mbMouseIn = sal_False;
396         if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp )
397         {
398             ImplDelData aDelData( pWindow );
399 
400             ImplDestroyHelpWindow( true );
401 
402             if ( aDelData.IsDelete() )
403                 return 1; // pWindow is dead now - avoid crash! (#122045#)
404         }
405     }
406     else
407         pWinFrameData->mbMouseIn = sal_True;
408 
409     DBG_ASSERT( !pSVData->maWinData.mpTrackWin ||
410                 (pSVData->maWinData.mpTrackWin == pSVData->maWinData.mpCaptureWin),
411                 "ImplHandleMouseEvent: TrackWin != CaptureWin" );
412 
413     // AutoScrollMode
414     if ( pSVData->maWinData.mpAutoScrollWin && (nSVEvent == EVENT_MOUSEBUTTONDOWN) )
415     {
416         pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
417         return 1;
418     }
419 
420     // find mouse window
421     if ( pSVData->maWinData.mpCaptureWin )
422     {
423         pChild = pSVData->maWinData.mpCaptureWin;
424 
425 		DBG_ASSERT( pWindow == pChild->ImplGetFrameWindow(),
426                     "ImplHandleMouseEvent: mouse event is not sent to capture window" );
427 
428         // java client cannot capture mouse correctly
429         if ( pWindow != pChild->ImplGetFrameWindow() )
430             return 0;
431 
432         if ( bMouseLeave )
433             return 0;
434     }
435     else
436     {
437         if ( bMouseLeave )
438             pChild = NULL;
439         else
440             pChild = pWindow->ImplFindWindow( aMousePos );
441     }
442 
443     // test this because mouse events are buffered in the remote version
444     // and size may not be in sync
445     if ( !pChild && !bMouseLeave )
446         return 0;
447 
448     // Ein paar Test ausfuehren und Message abfangen oder Status umsetzen
449     if ( pChild )
450     {
451         if( pChild->ImplIsAntiparallel() )
452         {
453             // - RTL - re-mirror frame pos at pChild
454             pChild->ImplReMirror( aMousePos );
455         }
456         // no mouse messages to system object windows ?
457 		// !!!KA: Is it OK to comment this out? !!!
458 //        if ( pChild->ImplGetWindowImpl()->mpSysObj )
459 //            return 0;
460 
461         // no mouse messages to disabled windows
462         // #106845# if the window was disabed during capturing we have to pass the mouse events to release capturing
463         if ( pSVData->maWinData.mpCaptureWin != pChild && (!pChild->IsEnabled() || !pChild->IsInputEnabled() || pChild->IsInModalMode() ) )
464         {
465             ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave );
466             if ( nSVEvent == EVENT_MOUSEMOVE )
467             {
468                 ImplHandleMouseHelpRequest( pChild, aMousePos );
469                 if( pWinFrameData->mpMouseMoveWin != pChild )
470                     nMode |= MOUSE_ENTERWINDOW;
471             }
472 
473             // Call the hook also, if Window is disabled
474             Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
475             MouseEvent aMEvt( aChildPos, pWinFrameData->mnClickCount, nMode, nCode, nCode );
476             NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
477             Application::CallEventHooks( aNEvt );
478 
479             if( pChild->IsCallHandlersOnInputDisabled() )
480             {
481                 pWinFrameData->mpMouseMoveWin = pChild;
482                 pChild->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
483             }
484 
485             if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
486             {
487                 Sound::Beep( SOUND_DISABLE, pChild );
488                 return 1;
489             }
490             else
491             {
492                 // Set normal MousePointer for disabled windows
493                 if ( nSVEvent == EVENT_MOUSEMOVE )
494                     ImplSetMousePointer( pChild );
495 
496                 return 0;
497             }
498         }
499 
500         // End ExtTextInput-Mode, if the user click in the same TopLevel Window
501         if ( pSVData->maWinData.mpExtTextInputWin &&
502              ((nSVEvent == EVENT_MOUSEBUTTONDOWN) ||
503               (nSVEvent == EVENT_MOUSEBUTTONUP)) )
504             pSVData->maWinData.mpExtTextInputWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
505     }
506 
507     // determine mouse event data
508     if ( nSVEvent == EVENT_MOUSEMOVE )
509     {
510         // Testen, ob MouseMove an das gleiche Fenster geht und sich der
511         // Status nicht geaendert hat
512         if ( pChild )
513         {
514             Point aChildMousePos = pChild->ImplFrameToOutput( aMousePos );
515             if ( !bMouseLeave &&
516                  (pChild == pWinFrameData->mpMouseMoveWin) &&
517                  (aChildMousePos.X() == pWinFrameData->mnLastMouseWinX) &&
518                  (aChildMousePos.Y() == pWinFrameData->mnLastMouseWinY) &&
519                  (nOldCode == pWinFrameData->mnMouseCode) )
520             {
521                 // Mouse-Pointer neu setzen, da er sich geaendet haben
522                 // koennte, da ein Modus umgesetzt wurde
523                 ImplSetMousePointer( pChild );
524                 return 0;
525             }
526 
527             pWinFrameData->mnLastMouseWinX = aChildMousePos.X();
528             pWinFrameData->mnLastMouseWinY = aChildMousePos.Y();
529         }
530 
531         // mouse click
532         nClicks = pWinFrameData->mnClickCount;
533 
534         // Gegebenenfalls den Start-Drag-Handler rufen.
535         // Achtung: Muss vor Move gerufen werden, da sonst bei schnellen
536         // Mausbewegungen die Applikationen in den Selektionszustand gehen.
537         Window* pMouseDownWin = pWinFrameData->mpMouseDownWin;
538         if ( pMouseDownWin )
539         {
540             // Testen, ob StartDrag-Modus uebereinstimmt. Wir vergleichen nur
541             // den Status der Maustasten, damit man mit Mod1 z.B. sofort
542             // in den Kopiermodus gehen kann.
543             const MouseSettings& rMSettings = pMouseDownWin->GetSettings().GetMouseSettings();
544             if ( (nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
545                  (rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) )
546             {
547                 if ( !pMouseDownWin->ImplGetFrameData()->mbStartDragCalled )
548                 {
549                     long nDragW  = rMSettings.GetStartDragWidth();
550                     long nDragH  = rMSettings.GetStartDragWidth();
551                     //long nMouseX = nX;
552                     //long nMouseY = nY;
553                     long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
554                     long nMouseY = aMousePos.Y();
555                     if ( !(((nMouseX-nDragW) <= pMouseDownWin->ImplGetFrameData()->mnFirstMouseX) &&
556                            ((nMouseX+nDragW) >= pMouseDownWin->ImplGetFrameData()->mnFirstMouseX)) ||
557                          !(((nMouseY-nDragH) <= pMouseDownWin->ImplGetFrameData()->mnFirstMouseY) &&
558                            ((nMouseY+nDragH) >= pMouseDownWin->ImplGetFrameData()->mnFirstMouseY)) )
559                     {
560                         pMouseDownWin->ImplGetFrameData()->mbStartDragCalled  = sal_True;
561 
562                         // Check if drag source provides it's own recognizer
563                         if( pMouseDownWin->ImplGetFrameData()->mbInternalDragGestureRecognizer )
564                         {
565                             // query DropTarget from child window
566                             ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > xDragGestureRecognizer =
567                                 ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > ( pMouseDownWin->ImplGetWindowImpl()->mxDNDListenerContainer,
568                                     ::com::sun::star::uno::UNO_QUERY );
569 
570                             if( xDragGestureRecognizer.is() )
571                             {
572                                 // retrieve mouse position relative to mouse down window
573                                 Point relLoc = pMouseDownWin->ImplFrameToOutput( Point(
574                                     pMouseDownWin->ImplGetFrameData()->mnFirstMouseX,
575                                     pMouseDownWin->ImplGetFrameData()->mnFirstMouseY ) );
576 
577                                 // create a uno mouse event out of the available data
578                                 ::com::sun::star::awt::MouseEvent aMouseEvent(
579                                     static_cast < ::com::sun::star::uno::XInterface * > ( 0 ),
580 #ifdef MACOSX
581 				    nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3),
582 #else
583                                     nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2),
584 #endif
585                                     nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE),
586                                     nMouseX,
587                                     nMouseY,
588                                     nClicks,
589                                     sal_False );
590 
591                                 sal_uLong nCount = Application::ReleaseSolarMutex();
592 
593                                 // FIXME: where do I get Action from ?
594                                 ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSource > xDragSource = pMouseDownWin->GetDragSource();
595 
596                                 if( xDragSource.is() )
597                                 {
598                                     static_cast < DNDListenerContainer * > ( xDragGestureRecognizer.get() )->fireDragGestureEvent( 0,
599                                         relLoc.X(), relLoc.Y(), xDragSource, ::com::sun::star::uno::makeAny( aMouseEvent ) );
600                                 }
601 
602                                 Application::AcquireSolarMutex( nCount );
603                             }
604                         }
605                     }
606                 }
607             }
608             else
609                 pMouseDownWin->ImplGetFrameData()->mbStartDragCalled  = sal_True;
610         }
611 
612         // test for mouseleave and mouseenter
613         Window* pMouseMoveWin = pWinFrameData->mpMouseMoveWin;
614         if ( pChild != pMouseMoveWin )
615         {
616             if ( pMouseMoveWin )
617             {
618                 Point       aLeaveMousePos = pMouseMoveWin->ImplFrameToOutput( aMousePos );
619                 MouseEvent  aMLeaveEvt( aLeaveMousePos, nClicks, nMode | MOUSE_LEAVEWINDOW, nCode, nCode );
620                 NotifyEvent aNLeaveEvt( EVENT_MOUSEMOVE, pMouseMoveWin, &aMLeaveEvt );
621                 ImplDelData aDelData;
622                 ImplDelData aDelData2;
623                 pWinFrameData->mbInMouseMove = sal_True;
624                 pMouseMoveWin->ImplGetWinData()->mbMouseOver = sal_False;
625                 pMouseMoveWin->ImplAddDel( &aDelData );
626                 // Durch MouseLeave kann auch dieses Fenster zerstoert
627                 // werden
628                 if ( pChild )
629                     pChild->ImplAddDel( &aDelData2 );
630                 if ( !ImplCallPreNotify( aNLeaveEvt ) )
631                 {
632                     pMouseMoveWin->MouseMove( aMLeaveEvt );
633                     // #82968#
634                     if( !aDelData.IsDelete() )
635                         aNLeaveEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNLeaveEvt );
636                 }
637 
638                 pWinFrameData->mpMouseMoveWin = NULL;
639                 pWinFrameData->mbInMouseMove = sal_False;
640 
641                 if ( pChild )
642                 {
643                     if ( aDelData2.IsDelete() )
644                         pChild = NULL;
645                     else
646                         pChild->ImplRemoveDel( &aDelData2 );
647                 }
648                 if ( aDelData.IsDelete() )
649                     return 1;
650                 pMouseMoveWin->ImplRemoveDel( &aDelData );
651             }
652 
653             nMode |= MOUSE_ENTERWINDOW;
654         }
655         pWinFrameData->mpMouseMoveWin = pChild;
656         if( pChild )
657             pChild->ImplGetWinData()->mbMouseOver = sal_True;
658 
659         // MouseLeave
660         if ( !pChild )
661             return 0;
662     }
663     else
664     {
665         // mouse click
666         if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
667         {
668             const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
669             sal_uLong   nDblClkTime = rMSettings.GetDoubleClickTime();
670             long    nDblClkW    = rMSettings.GetDoubleClickWidth();
671             long    nDblClkH    = rMSettings.GetDoubleClickHeight();
672             //long    nMouseX     = nX;
673             //long    nMouseY     = nY;
674             long nMouseX = aMousePos.X();   // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
675             long nMouseY = aMousePos.Y();
676 
677             if ( (pChild == pChild->ImplGetFrameData()->mpMouseDownWin) &&
678                  (nCode == pChild->ImplGetFrameData()->mnFirstMouseCode) &&
679                  ((nMsgTime-pChild->ImplGetFrameData()->mnMouseDownTime) < nDblClkTime) &&
680                  ((nMouseX-nDblClkW) <= pChild->ImplGetFrameData()->mnFirstMouseX) &&
681                  ((nMouseX+nDblClkW) >= pChild->ImplGetFrameData()->mnFirstMouseX) &&
682                  ((nMouseY-nDblClkH) <= pChild->ImplGetFrameData()->mnFirstMouseY) &&
683                  ((nMouseY+nDblClkH) >= pChild->ImplGetFrameData()->mnFirstMouseY) )
684             {
685                 pChild->ImplGetFrameData()->mnClickCount++;
686                 pChild->ImplGetFrameData()->mbStartDragCalled  = sal_True;
687             }
688             else
689             {
690                 pChild->ImplGetFrameData()->mpMouseDownWin     = pChild;
691                 pChild->ImplGetFrameData()->mnClickCount       = 1;
692                 pChild->ImplGetFrameData()->mnFirstMouseX      = nMouseX;
693                 pChild->ImplGetFrameData()->mnFirstMouseY      = nMouseY;
694                 pChild->ImplGetFrameData()->mnFirstMouseCode   = nCode;
695                 pChild->ImplGetFrameData()->mbStartDragCalled  = !((nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
696                                                             (rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)));
697             }
698             pChild->ImplGetFrameData()->mnMouseDownTime = nMsgTime;
699         }
700         nClicks = pChild->ImplGetFrameData()->mnClickCount;
701 
702         pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
703     }
704 
705     DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild == NULL" );
706 
707     // create mouse event
708     Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
709     MouseEvent aMEvt( aChildPos, nClicks, nMode, nCode, nCode );
710 
711     // tracking window gets the mouse events
712     if ( pSVData->maWinData.mpTrackWin )
713         pChild = pSVData->maWinData.mpTrackWin;
714 
715     // handle FloatingMode
716     if ( !pSVData->maWinData.mpTrackWin && pSVData->maWinData.mpFirstFloat )
717     {
718         ImplDelData aDelData;
719         pChild->ImplAddDel( &aDelData );
720         if ( ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave ) )
721         {
722             if ( !aDelData.IsDelete() )
723             {
724                 pChild->ImplRemoveDel( &aDelData );
725                 pChild->ImplGetFrameData()->mbStartDragCalled = sal_True;
726             }
727             return 1;
728         }
729         else
730             pChild->ImplRemoveDel( &aDelData );
731     }
732 
733     // call handler
734     sal_Bool bDrag = sal_False;
735     sal_Bool bCallHelpRequest = sal_True;
736     DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild is NULL" );
737 
738     ImplDelData aDelData;
739     NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
740     pChild->ImplAddDel( &aDelData );
741     if ( nSVEvent == EVENT_MOUSEMOVE )
742         pChild->ImplGetFrameData()->mbInMouseMove = sal_True;
743 
744     // bring window into foreground on mouseclick
745     if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
746     {
747         if( !pSVData->maWinData.mpFirstFloat && // totop for floating windows in popup would change the focus and would close them immediately
748             !(pChild->ImplGetFrameWindow()->GetStyle() & WB_OWNERDRAWDECORATION) )    // ownerdrawdecorated windows must never grab focus
749             pChild->ToTop();
750         if ( aDelData.IsDelete() )
751             return 1;
752     }
753 
754     if ( ImplCallPreNotify( aNEvt ) || aDelData.IsDelete() )
755         nRet = 1;
756     else
757     {
758         nRet = 0;
759         if ( nSVEvent == EVENT_MOUSEMOVE )
760         {
761             if ( pSVData->maWinData.mpTrackWin )
762             {
763                 TrackingEvent aTEvt( aMEvt );
764                 pChild->Tracking( aTEvt );
765                 if ( !aDelData.IsDelete() )
766                 {
767                     // When ScrollRepeat, we restart the timer
768                     if ( pSVData->maWinData.mpTrackTimer &&
769                          (pSVData->maWinData.mnTrackFlags & STARTTRACK_SCROLLREPEAT) )
770                         pSVData->maWinData.mpTrackTimer->Start();
771                 }
772                 bCallHelpRequest = sal_False;
773                 nRet = 1;
774             }
775             else
776             {
777                 // Auto-ToTop
778                 if ( !pSVData->maWinData.mpCaptureWin &&
779                      (pChild->GetSettings().GetMouseSettings().GetOptions() & MOUSE_OPTION_AUTOFOCUS) )
780                     pChild->ToTop( TOTOP_NOGRABFOCUS );
781 
782                 if( aDelData.IsDelete() )
783                     bCallHelpRequest = sal_False;
784                 else
785                 {
786                     // if the MouseMove handler changes the help window's visibility
787                     // the HelpRequest handler should not be called anymore
788                     Window* pOldHelpTextWin = pSVData->maHelpData.mpHelpWin;
789                     pChild->ImplGetWindowImpl()->mbMouseMove = sal_False;
790                     pChild->MouseMove( aMEvt );
791                     if ( pOldHelpTextWin != pSVData->maHelpData.mpHelpWin )
792                         bCallHelpRequest = sal_False;
793                 }
794             }
795         }
796         else if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
797         {
798             if ( pSVData->maWinData.mpTrackWin &&
799                  !(pSVData->maWinData.mnTrackFlags & STARTTRACK_MOUSEBUTTONDOWN) )
800                 nRet = 1;
801             else
802             {
803                 pChild->ImplGetWindowImpl()->mbMouseButtonDown = sal_False;
804                 pChild->MouseButtonDown( aMEvt );
805             }
806         }
807         else
808         {
809             if ( pSVData->maWinData.mpTrackWin )
810             {
811                 pChild->EndTracking();
812                 nRet = 1;
813             }
814             else
815             {
816                 pChild->ImplGetWindowImpl()->mbMouseButtonUp = sal_False;
817                 pChild->MouseButtonUp( aMEvt );
818             }
819         }
820 
821         // #82968#
822         if ( !aDelData.IsDelete() )
823             aNEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
824     }
825 
826     if ( aDelData.IsDelete() )
827         return 1;
828 
829 
830     if ( nSVEvent == EVENT_MOUSEMOVE )
831         pChild->ImplGetWindowImpl()->mpFrameData->mbInMouseMove = sal_False;
832 
833     if ( nSVEvent == EVENT_MOUSEMOVE )
834     {
835         if ( bCallHelpRequest && !pSVData->maHelpData.mbKeyboardHelp )
836             ImplHandleMouseHelpRequest( pChild, pChild->OutputToScreenPixel( aMEvt.GetPosPixel() ) );
837         nRet = 1;
838     }
839     else if ( !nRet )
840     {
841         if ( nSVEvent == EVENT_MOUSEBUTTONDOWN )
842         {
843             if ( !pChild->ImplGetWindowImpl()->mbMouseButtonDown )
844                 nRet = 1;
845         }
846         else
847         {
848             if ( !pChild->ImplGetWindowImpl()->mbMouseButtonUp )
849                 nRet = 1;
850         }
851     }
852 
853     pChild->ImplRemoveDel( &aDelData );
854 
855     if ( nSVEvent == EVENT_MOUSEMOVE )
856     {
857         // set new mouse pointer
858         if ( !bMouseLeave )
859             ImplSetMousePointer( pChild );
860     }
861     else if ( (nSVEvent == EVENT_MOUSEBUTTONDOWN) || (nSVEvent == EVENT_MOUSEBUTTONUP) )
862     {
863         if ( !bDrag )
864         {
865             // Command-Events
866             if ( /*(nRet == 0) &&*/ (nClicks == 1) && (nSVEvent == EVENT_MOUSEBUTTONDOWN) &&
867                  (nCode == MOUSE_MIDDLE) )
868             {
869                 sal_uInt16 nMiddleAction = pChild->GetSettings().GetMouseSettings().GetMiddleButtonAction();
870                 if ( nMiddleAction == MOUSE_MIDDLE_AUTOSCROLL )
871                     nRet = !ImplCallCommand( pChild, COMMAND_STARTAUTOSCROLL, NULL, sal_True, &aChildPos );
872                 else if ( nMiddleAction == MOUSE_MIDDLE_PASTESELECTION )
873                     nRet = !ImplCallCommand( pChild, COMMAND_PASTESELECTION, NULL, sal_True, &aChildPos );
874             }
875             else
876             {
877                 // ContextMenu
878                 const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
879                 if ( (nCode == rMSettings.GetContextMenuCode()) &&
880                      (nClicks == rMSettings.GetContextMenuClicks()) )
881                 {
882                     sal_Bool bContextMenu;
883                     if ( rMSettings.GetContextMenuDown() )
884                         bContextMenu = (nSVEvent == EVENT_MOUSEBUTTONDOWN);
885                     else
886                         bContextMenu = (nSVEvent == EVENT_MOUSEBUTTONUP);
887                     if ( bContextMenu )
888                     {
889                         if( pSVData->maAppData.mpActivePopupMenu )
890                         {
891                             /*  #i34277# there already is a context menu open
892                             *   that was probably just closed with EndPopupMode.
893                             *   We need to give the eventual corresponding
894                             *   PopupMenu::Execute a chance to end properly.
895                             *   Therefore delay context menu command and
896                             *   issue only after popping one frame of the
897                             *   Yield stack.
898                             */
899                             ContextMenuEvent* pEv = new ContextMenuEvent;
900                             pEv->pWindow = pChild;
901                             pEv->aChildPos = aChildPos;
902                             pChild->ImplAddDel( &pEv->aDelData );
903                             Application::PostUserEvent( Link( pEv, ContextMenuEventLink ) );
904                         }
905                         else
906                             nRet = ! ImplCallCommand( pChild, COMMAND_CONTEXTMENU, NULL, sal_True, &aChildPos );
907                     }
908                 }
909             }
910         }
911     }
912 
913     return nRet;
914 }
915 
916 // -----------------------------------------------------------------------
917 
918 static Window* ImplGetKeyInputWindow( Window* pWindow )
919 {
920     ImplSVData* pSVData = ImplGetSVData();
921 
922     // determine last input time
923     pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
924 
925     // #127104# workaround for destroyed windows
926     if( pWindow->ImplGetWindowImpl() == NULL )
927         return 0;
928 
929     // find window - is every time the window which has currently the
930     // focus or the last time the focus.
931     // the first floating window always has the focus
932     Window* pChild = pSVData->maWinData.mpFirstFloat;
933     if( !pChild || ( pChild->ImplGetWindowImpl()->mbFloatWin && !((FloatingWindow *)pChild)->GrabsFocus() ) )
934         pChild = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
935     else
936     {
937         // allow floaters to forward keyinput to some member
938         pChild = pChild->GetPreferredKeyInputWindow();
939     }
940 
941     // no child - than no input
942     if ( !pChild )
943         return 0;
944 
945     // We call also KeyInput if we haven't the focus, because on Unix
946     // system this is often the case when a Lookup Choise Window has
947     // the focus - because this windows send the KeyInput directly to
948     // the window without resetting the focus
949     DBG_ASSERTWARNING( pChild == pSVData->maWinData.mpFocusWin,
950                        "ImplHandleKey: Keyboard-Input is sent to a frame without focus" );
951 
952     // no keyinput to disabled windows
953     if ( !pChild->IsEnabled() || !pChild->IsInputEnabled() || pChild->IsInModalMode() )
954         return 0;
955 
956     return pChild;
957 }
958 
959 // -----------------------------------------------------------------------
960 
961 static long ImplHandleKey( Window* pWindow, sal_uInt16 nSVEvent,
962                            sal_uInt16 nKeyCode, sal_uInt16 nCharCode, sal_uInt16 nRepeat, sal_Bool bForward )
963 {
964     ImplSVData* pSVData = ImplGetSVData();
965     KeyCode     aKeyCode( nKeyCode, nKeyCode );
966     sal_uInt16      nEvCode = aKeyCode.GetCode();
967 
968     // allow application key listeners to remove the key event
969     // but make sure we're not forwarding external KeyEvents, (ie where bForward is sal_False)
970     // becasue those are coming back from the listener itself and MUST be processed
971     KeyEvent aKeyEvent( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
972     if( bForward )
973     {
974         sal_uInt16 nVCLEvent;
975         switch( nSVEvent )
976         {
977             case EVENT_KEYINPUT:
978                 nVCLEvent = VCLEVENT_WINDOW_KEYINPUT;
979                 break;
980             case EVENT_KEYUP:
981                 nVCLEvent = VCLEVENT_WINDOW_KEYUP;
982                 break;
983             default:
984                 nVCLEvent = 0;
985                 break;
986         }
987         if( nVCLEvent && pSVData->mpApp->HandleKey( nVCLEvent, pWindow, &aKeyEvent ) )
988             return 1;
989     }
990 
991     // #i1820# use locale specific decimal separator
992     if( nEvCode == KEY_DECIMAL )
993     {
994         if( Application::GetSettings().GetMiscSettings().GetEnableLocalizedDecimalSep() )
995         {
996             String aSep( pWindow->GetSettings().GetLocaleDataWrapper().getNumDecimalSep() );
997             nCharCode = (sal_uInt16) aSep.GetChar(0);
998         }
999     }
1000 
1001 	sal_Bool bCtrlF6 = (aKeyCode.GetCode() == KEY_F6) && aKeyCode.IsMod1();
1002 
1003     // determine last input time
1004     pSVData->maAppData.mnLastInputTime = Time::GetSystemTicks();
1005 
1006     // handle tracking window
1007     if ( nSVEvent == EVENT_KEYINPUT )
1008     {
1009 #ifdef DBG_UTIL
1010         // #105224# use Ctrl-Alt-Shift-D, Ctrl-Shift-D must be useable by app
1011         if ( aKeyCode.IsShift() && aKeyCode.IsMod1() && (aKeyCode.IsMod2() || aKeyCode.IsMod3()) && (aKeyCode.GetCode() == KEY_D) )
1012         {
1013             DBGGUI_START();
1014             return 1;
1015         }
1016 #endif
1017 
1018         if ( pSVData->maHelpData.mbExtHelpMode )
1019         {
1020             Help::EndExtHelp();
1021             if ( nEvCode == KEY_ESCAPE )
1022                 return 1;
1023         }
1024         if ( pSVData->maHelpData.mpHelpWin )
1025             ImplDestroyHelpWindow( false );
1026 
1027         // AutoScrollMode
1028         if ( pSVData->maWinData.mpAutoScrollWin )
1029         {
1030             pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1031             if ( nEvCode == KEY_ESCAPE )
1032                 return 1;
1033         }
1034 
1035         if ( pSVData->maWinData.mpTrackWin )
1036         {
1037             sal_uInt16 nOrigCode = aKeyCode.GetCode();
1038 
1039             if ( (nOrigCode == KEY_ESCAPE) && !(pSVData->maWinData.mnTrackFlags & STARTTRACK_NOKEYCANCEL) )
1040             {
1041                 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL | ENDTRACK_KEY );
1042                 if ( pSVData->maWinData.mpFirstFloat )
1043                 {
1044                     FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
1045                     if ( !(pLastLevelFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOKEYCLOSE) )
1046                     {
1047                         sal_uInt16 nEscCode = aKeyCode.GetCode();
1048 
1049                         if ( nEscCode == KEY_ESCAPE )
1050                             pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1051                     }
1052                 }
1053                 return 1;
1054             }
1055             else if ( nOrigCode == KEY_RETURN )
1056             {
1057                 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_KEY );
1058                 return 1;
1059             }
1060             else if ( !(pSVData->maWinData.mnTrackFlags & STARTTRACK_KEYINPUT) )
1061                 return 1;
1062         }
1063 
1064         // handle FloatingMode
1065         if ( pSVData->maWinData.mpFirstFloat )
1066         {
1067             FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
1068             if ( !(pLastLevelFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOKEYCLOSE) )
1069             {
1070                 sal_uInt16 nCode = aKeyCode.GetCode();
1071 
1072                 if ( (nCode == KEY_ESCAPE) || bCtrlF6)
1073                 {
1074                     pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1075                     if( !bCtrlF6 )
1076 						return 1;
1077                 }
1078             }
1079         }
1080 
1081         // test for accel
1082         if ( pSVData->maAppData.mpAccelMgr )
1083         {
1084             if ( pSVData->maAppData.mpAccelMgr->IsAccelKey( aKeyCode, nRepeat ) )
1085                 return 1;
1086         }
1087     }
1088 
1089     // find window
1090     Window* pChild = ImplGetKeyInputWindow( pWindow );
1091     if ( !pChild )
1092         return 0;
1093 
1094     // --- RTL --- mirror cursor keys
1095     if( (aKeyCode.GetCode() == KEY_LEFT || aKeyCode.GetCode() == KEY_RIGHT) &&
1096       pChild->ImplHasMirroredGraphics() && pChild->IsRTLEnabled() )
1097         aKeyCode = KeyCode( aKeyCode.GetCode() == KEY_LEFT ? KEY_RIGHT : KEY_LEFT, aKeyCode.GetModifier() );
1098 
1099     // call handler
1100     ImplDelData aDelData;
1101     pChild->ImplAddDel( &aDelData );
1102 
1103 	KeyEvent    aKeyEvt( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
1104     NotifyEvent aNotifyEvt( nSVEvent, pChild, &aKeyEvt );
1105     sal_Bool        bKeyPreNotify = (ImplCallPreNotify( aNotifyEvt ) != 0);
1106     long        nRet = 1;
1107 
1108     if ( !bKeyPreNotify && !aDelData.IsDelete() )
1109     {
1110         if ( nSVEvent == EVENT_KEYINPUT )
1111         {
1112             pChild->ImplGetWindowImpl()->mbKeyInput = sal_False;
1113             pChild->KeyInput( aKeyEvt );
1114         }
1115         else
1116         {
1117             pChild->ImplGetWindowImpl()->mbKeyUp = sal_False;
1118             pChild->KeyUp( aKeyEvt );
1119         }
1120         // #82968#
1121         if( !aDelData.IsDelete() )
1122             aNotifyEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNotifyEvt );
1123     }
1124 
1125     if ( aDelData.IsDelete() )
1126         return 1;
1127 
1128     pChild->ImplRemoveDel( &aDelData );
1129 
1130     if ( nSVEvent == EVENT_KEYINPUT )
1131     {
1132         if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyInput )
1133         {
1134             sal_uInt16 nCode = aKeyCode.GetCode();
1135 
1136             // #101999# is focus in or below toolbox
1137             sal_Bool bToolboxFocus=sal_False;
1138             if( (nCode == KEY_F1) && aKeyCode.IsShift() )
1139             {
1140                 Window *pWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1141                 while( pWin )
1142                 {
1143                     if( pWin->ImplGetWindowImpl()->mbToolBox )
1144                     {
1145                         bToolboxFocus = sal_True;
1146                         break;
1147                     }
1148                     else
1149                         pWin = pWin->GetParent();
1150                 }
1151             }
1152 
1153             // ContextMenu
1154             if ( (nCode == KEY_CONTEXTMENU) || ((nCode == KEY_F10) && aKeyCode.IsShift() && !aKeyCode.IsMod1() && !aKeyCode.IsMod2() ) )
1155                 nRet = !ImplCallCommand( pChild, COMMAND_CONTEXTMENU, NULL, sal_False );
1156             else if ( ( (nCode == KEY_F2) && aKeyCode.IsShift() ) || ( (nCode == KEY_F1) && aKeyCode.IsMod1() ) ||
1157                 // #101999# no active help when focus in toolbox, simulate BallonHelp instead
1158                 ( (nCode == KEY_F1) && aKeyCode.IsShift() && bToolboxFocus ) )
1159 			{
1160                 // TipHelp via Keyboard (Shift-F2 or Ctrl-F1)
1161 				// simulate mouseposition at center of window
1162 
1163 				Size aSize = pChild->GetOutputSize();
1164 				Point aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
1165 				aPos = pChild->OutputToScreenPixel( aPos );
1166 
1167                 HelpEvent aHelpEvent( aPos, HELPMODE_BALLOON );
1168 				aHelpEvent.SetKeyboardActivated( sal_True );
1169 				pSVData->maHelpData.mbSetKeyboardHelp = sal_True;
1170                 pChild->RequestHelp( aHelpEvent );
1171 				pSVData->maHelpData.mbSetKeyboardHelp = sal_False;
1172 			}
1173             else if ( (nCode == KEY_F1) || (nCode == KEY_HELP) )
1174             {
1175                 if ( !aKeyCode.GetModifier() )
1176                 {
1177                     if ( pSVData->maHelpData.mbContextHelp )
1178                     {
1179                         Point       aMousePos = pChild->OutputToScreenPixel( pChild->GetPointerPosPixel() );
1180                         HelpEvent   aHelpEvent( aMousePos, HELPMODE_CONTEXT );
1181                         pChild->RequestHelp( aHelpEvent );
1182                     }
1183                     else
1184                         nRet = 0;
1185                 }
1186                 else if ( aKeyCode.IsShift() )
1187                 {
1188                     if ( pSVData->maHelpData.mbExtHelp )
1189                         Help::StartExtHelp();
1190                     else
1191                         nRet = 0;
1192                 }
1193             }
1194             else
1195             {
1196                 if ( ImplCallHotKey( aKeyCode ) )
1197                     nRet = 1;
1198                 else
1199                     nRet = 0;
1200             }
1201         }
1202     }
1203     else
1204     {
1205         if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyUp )
1206             nRet = 0;
1207     }
1208 
1209     // #105591# send keyinput to parent if we are a floating window and the key was not pocessed yet
1210     if( !nRet && pWindow->ImplGetWindowImpl()->mbFloatWin && pWindow->GetParent() && (pWindow->ImplGetWindowImpl()->mpFrame != pWindow->GetParent()->ImplGetWindowImpl()->mpFrame) )
1211     {
1212         pChild = pWindow->GetParent();
1213 
1214         // call handler
1215         ImplDelData aChildDelData( pChild );
1216         KeyEvent    aKEvt( (xub_Unicode)nCharCode, aKeyCode, nRepeat );
1217         NotifyEvent aNEvt( nSVEvent, pChild, &aKEvt );
1218         sal_Bool        bPreNotify = (ImplCallPreNotify( aNEvt ) != 0);
1219         if ( aChildDelData.IsDelete() )
1220             return 1;
1221 
1222         if ( !bPreNotify )
1223         {
1224             if ( nSVEvent == EVENT_KEYINPUT )
1225             {
1226                 pChild->ImplGetWindowImpl()->mbKeyInput = sal_False;
1227                 pChild->KeyInput( aKEvt );
1228             }
1229             else
1230             {
1231                 pChild->ImplGetWindowImpl()->mbKeyUp = sal_False;
1232                 pChild->KeyUp( aKEvt );
1233             }
1234             // #82968#
1235             if( !aChildDelData.IsDelete() )
1236                 aNEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
1237             if ( aChildDelData.IsDelete() )
1238                 return 1;
1239         }
1240 
1241         if( bPreNotify || !pChild->ImplGetWindowImpl()->mbKeyInput )
1242             nRet = 1;
1243     }
1244 
1245     return nRet;
1246 }
1247 
1248 // -----------------------------------------------------------------------
1249 
1250 static long ImplHandleExtTextInput( Window* pWindow,
1251                                     const XubString& rText,
1252                                     const sal_uInt16* pTextAttr,
1253                                     sal_uLong nCursorPos, sal_uInt16 nCursorFlags )
1254 {
1255     ImplSVData* pSVData = ImplGetSVData();
1256     Window*     pChild = NULL;
1257 
1258     int nTries = 200;
1259     while( nTries-- )
1260     {
1261         pChild = pSVData->maWinData.mpExtTextInputWin;
1262         if ( !pChild )
1263         {
1264             pChild = ImplGetKeyInputWindow( pWindow );
1265             if ( !pChild )
1266                 return 0;
1267         }
1268         if( !pChild->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1269             break;
1270         Application::Yield();
1271     }
1272 
1273     // If it is the first ExtTextInput call, we inform the information
1274     // and allocate the data, which we must store in this mode
1275     ImplWinData* pWinData = pChild->ImplGetWinData();
1276     if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
1277     {
1278         pChild->ImplGetWindowImpl()->mbExtTextInput = sal_True;
1279         if ( !pWinData->mpExtOldText )
1280             pWinData->mpExtOldText = new UniString;
1281         else
1282             pWinData->mpExtOldText->Erase();
1283         if ( pWinData->mpExtOldAttrAry )
1284         {
1285             delete [] pWinData->mpExtOldAttrAry;
1286             pWinData->mpExtOldAttrAry = NULL;
1287         }
1288         pSVData->maWinData.mpExtTextInputWin = pChild;
1289         ImplCallCommand( pChild, COMMAND_STARTEXTTEXTINPUT );
1290     }
1291 
1292     // be aware of being recursively called in StartExtTextInput
1293     if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
1294         return 0;
1295 
1296     // Test for changes
1297     sal_Bool        bOnlyCursor = sal_False;
1298     xub_StrLen  nMinLen = Min( pWinData->mpExtOldText->Len(), rText.Len() );
1299     xub_StrLen  nDeltaStart = 0;
1300     while ( nDeltaStart < nMinLen )
1301     {
1302         if ( pWinData->mpExtOldText->GetChar( nDeltaStart ) != rText.GetChar( nDeltaStart ) )
1303             break;
1304         nDeltaStart++;
1305     }
1306     if ( pWinData->mpExtOldAttrAry || pTextAttr )
1307     {
1308         if ( !pWinData->mpExtOldAttrAry || !pTextAttr )
1309             nDeltaStart = 0;
1310         else
1311         {
1312             xub_StrLen i = 0;
1313             while ( i < nDeltaStart )
1314             {
1315                 if ( pWinData->mpExtOldAttrAry[i] != pTextAttr[i] )
1316                 {
1317                     nDeltaStart = i;
1318                     break;
1319                 }
1320                 i++;
1321             }
1322         }
1323     }
1324     if ( (nDeltaStart >= nMinLen) &&
1325          (pWinData->mpExtOldText->Len() == rText.Len()) )
1326         bOnlyCursor = sal_True;
1327 
1328     // Call Event and store the information
1329     CommandExtTextInputData aData( rText, pTextAttr,
1330                                    (xub_StrLen)nCursorPos, nCursorFlags,
1331                                    nDeltaStart, pWinData->mpExtOldText->Len(),
1332                                    bOnlyCursor );
1333     *pWinData->mpExtOldText = rText;
1334     if ( pWinData->mpExtOldAttrAry )
1335     {
1336         delete [] pWinData->mpExtOldAttrAry;
1337         pWinData->mpExtOldAttrAry = NULL;
1338     }
1339     if ( pTextAttr )
1340     {
1341         pWinData->mpExtOldAttrAry = new sal_uInt16[rText.Len()];
1342         memcpy( pWinData->mpExtOldAttrAry, pTextAttr, rText.Len()*sizeof( sal_uInt16 ) );
1343     }
1344     return !ImplCallCommand( pChild, COMMAND_EXTTEXTINPUT, &aData );
1345 }
1346 
1347 // -----------------------------------------------------------------------
1348 
1349 static long ImplHandleEndExtTextInput( Window* /* pWindow */ )
1350 {
1351     ImplSVData* pSVData = ImplGetSVData();
1352     Window*     pChild = pSVData->maWinData.mpExtTextInputWin;
1353     long        nRet = 0;
1354 
1355     if ( pChild )
1356     {
1357         pChild->ImplGetWindowImpl()->mbExtTextInput = sal_False;
1358         pSVData->maWinData.mpExtTextInputWin = NULL;
1359         ImplWinData* pWinData = pChild->ImplGetWinData();
1360         if ( pWinData->mpExtOldText )
1361         {
1362             delete pWinData->mpExtOldText;
1363             pWinData->mpExtOldText = NULL;
1364         }
1365         if ( pWinData->mpExtOldAttrAry )
1366         {
1367             delete [] pWinData->mpExtOldAttrAry;
1368             pWinData->mpExtOldAttrAry = NULL;
1369         }
1370         nRet = !ImplCallCommand( pChild, COMMAND_ENDEXTTEXTINPUT );
1371     }
1372 
1373     return nRet;
1374 }
1375 
1376 // -----------------------------------------------------------------------
1377 
1378 static void ImplHandleExtTextInputPos( Window* pWindow,
1379                                        Rectangle& rRect, long& rInputWidth,
1380                                        bool * pVertical )
1381 {
1382     ImplSVData* pSVData = ImplGetSVData();
1383     Window*     pChild = pSVData->maWinData.mpExtTextInputWin;
1384 
1385     if ( !pChild )
1386         pChild = ImplGetKeyInputWindow( pWindow );
1387     else
1388     {
1389         // Test, if the Window is related to the frame
1390         if ( !pWindow->ImplIsWindowOrChild( pChild ) )
1391             pChild = ImplGetKeyInputWindow( pWindow );
1392     }
1393 
1394     if ( pChild )
1395     {
1396         ImplCallCommand( pChild, COMMAND_CURSORPOS );
1397         const Rectangle* pRect = pChild->GetCursorRect();
1398         if ( pRect )
1399             rRect = pChild->ImplLogicToDevicePixel( *pRect );
1400         else
1401         {
1402             Cursor* pCursor = pChild->GetCursor();
1403             if ( pCursor )
1404             {
1405                 Point aPos = pChild->ImplLogicToDevicePixel( pCursor->GetPos() );
1406                 Size aSize = pChild->LogicToPixel( pCursor->GetSize() );
1407                 if ( !aSize.Width() )
1408                     aSize.Width() = pChild->GetSettings().GetStyleSettings().GetCursorSize();
1409                 rRect = Rectangle( aPos, aSize );
1410             }
1411             else
1412                 rRect = Rectangle( Point( pChild->GetOutOffXPixel(), pChild->GetOutOffYPixel() ), Size() );
1413         }
1414         rInputWidth = pChild->ImplLogicWidthToDevicePixel( pChild->GetCursorExtTextInputWidth() );
1415         if ( !rInputWidth )
1416             rInputWidth = rRect.GetWidth();
1417     }
1418     if (pVertical != 0)
1419         *pVertical
1420             = pChild != 0 && pChild->GetInputContext().GetFont().IsVertical();
1421 }
1422 
1423 // -----------------------------------------------------------------------
1424 
1425 static long ImplHandleInputContextChange( Window* pWindow, LanguageType eNewLang )
1426 {
1427     Window* pChild = ImplGetKeyInputWindow( pWindow );
1428     CommandInputContextData aData( eNewLang );
1429     return !ImplCallCommand( pChild, COMMAND_INPUTCONTEXTCHANGE, &aData );
1430 }
1431 
1432 // -----------------------------------------------------------------------
1433 
1434 static sal_Bool ImplCallWheelCommand( Window* pWindow, const Point& rPos,
1435                                   const CommandWheelData* pWheelData )
1436 {
1437     Point               aCmdMousePos = pWindow->ImplFrameToOutput( rPos );
1438     CommandEvent        aCEvt( aCmdMousePos, COMMAND_WHEEL, sal_True, pWheelData );
1439     NotifyEvent         aNCmdEvt( EVENT_COMMAND, pWindow, &aCEvt );
1440     ImplDelData         aDelData( pWindow );
1441     sal_Bool                bPreNotify = (ImplCallPreNotify( aNCmdEvt ) != 0);
1442     if ( aDelData.IsDelete() )
1443         return sal_False;
1444     if ( !bPreNotify )
1445     {
1446         pWindow->ImplGetWindowImpl()->mbCommand = sal_False;
1447         pWindow->Command( aCEvt );
1448         if ( aDelData.IsDelete() )
1449             return sal_False;
1450         if ( pWindow->ImplGetWindowImpl()->mbCommand )
1451             return sal_True;
1452     }
1453     return sal_False;
1454 }
1455 
1456 // -----------------------------------------------------------------------
1457 
1458 static long ImplHandleWheelEvent( Window* pWindow, const SalWheelMouseEvent& rEvt )
1459 {
1460     ImplDelData aDogTag( pWindow );
1461 
1462     ImplSVData* pSVData = ImplGetSVData();
1463     if ( pSVData->maWinData.mpAutoScrollWin )
1464         pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1465     if ( pSVData->maHelpData.mpHelpWin )
1466         ImplDestroyHelpWindow( true );
1467     if( aDogTag.IsDelete() )
1468         return 0;
1469 
1470     sal_uInt16 nMode;
1471     sal_uInt16 nCode = rEvt.mnCode;
1472     bool bHorz = rEvt.mbHorz;
1473     bool bPixel = rEvt.mbDeltaIsPixel;
1474     if ( nCode & KEY_MOD1 )
1475         nMode = COMMAND_WHEEL_ZOOM;
1476     else if ( nCode & KEY_MOD2 )
1477         nMode = COMMAND_WHEEL_DATAZOOM;
1478     else
1479     {
1480         nMode = COMMAND_WHEEL_SCROLL;
1481         // #i85450# interpret shift-wheel as horizontal wheel action
1482         if( (nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)) == KEY_SHIFT )
1483             bHorz = true;
1484     }
1485 
1486     CommandWheelData    aWheelData( rEvt.mnDelta, rEvt.mnNotchDelta, rEvt.mnScrollLines, nMode, nCode, bHorz, bPixel );
1487     Point               aMousePos( rEvt.mnX, rEvt.mnY );
1488     sal_Bool                bRet = sal_True;
1489 
1490     // first check any floating window ( eg. drop down listboxes)
1491     bool bIsFloat = false;
1492     Window *pMouseWindow = NULL;
1493     if ( pSVData->maWinData.mpFirstFloat && !pSVData->maWinData.mpCaptureWin &&
1494          !pSVData->maWinData.mpFirstFloat->ImplIsFloatPopupModeWindow( pWindow ) )
1495     {
1496         sal_uInt16 nHitTest = IMPL_FLOATWIN_HITTEST_OUTSIDE;
1497         pMouseWindow = pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( pWindow, aMousePos, nHitTest );
1498     }
1499     // then try the window directly beneath the mouse
1500     if( !pMouseWindow )
1501         pMouseWindow = pWindow->ImplFindWindow( aMousePos );
1502 	else
1503     {
1504         // transform coordinates to float window frame coordinates
1505 		pMouseWindow = pMouseWindow->ImplFindWindow(
1506                  pMouseWindow->OutputToScreenPixel(
1507                   pMouseWindow->AbsoluteScreenToOutputPixel(
1508 				   pWindow->OutputToAbsoluteScreenPixel(
1509                     pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
1510         bIsFloat = true;
1511     }
1512 
1513     if ( pMouseWindow &&
1514          pMouseWindow->IsEnabled() && pMouseWindow->IsInputEnabled() && ! pMouseWindow->IsInModalMode() )
1515     {
1516         // transform coordinates to float window frame coordinates
1517         Point aRelMousePos( pMouseWindow->OutputToScreenPixel(
1518                              pMouseWindow->AbsoluteScreenToOutputPixel(
1519                               pWindow->OutputToAbsoluteScreenPixel(
1520                                pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
1521         bRet = ImplCallWheelCommand( pMouseWindow, aRelMousePos, &aWheelData );
1522     }
1523 
1524     // if the commad was not handled try the focus window
1525     if ( bRet )
1526     {
1527         Window* pFocusWindow = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1528         if ( pFocusWindow && (pFocusWindow != pMouseWindow) &&
1529              (pFocusWindow == pSVData->maWinData.mpFocusWin) )
1530         {
1531             // no wheel-messages to disabled windows
1532             if ( pFocusWindow->IsEnabled() && pFocusWindow->IsInputEnabled() && ! pFocusWindow->IsInModalMode() )
1533             {
1534                 // transform coordinates to focus window frame coordinates
1535                 Point aRelMousePos( pFocusWindow->OutputToScreenPixel(
1536                                      pFocusWindow->AbsoluteScreenToOutputPixel(
1537 									  pWindow->OutputToAbsoluteScreenPixel(
1538                                        pWindow->ScreenToOutputPixel( aMousePos ) ) ) ) );
1539                 bRet = ImplCallWheelCommand( pFocusWindow, aRelMousePos, &aWheelData );
1540             }
1541         }
1542     }
1543 
1544     // close floaters
1545     if( ! bIsFloat && pSVData->maWinData.mpFirstFloat )
1546     {
1547         FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
1548         if( pLastLevelFloat )
1549         {
1550             sal_uLong nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
1551             if ( nPopupFlags & FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE )
1552             {
1553                 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1554             }
1555         }
1556     }
1557 
1558     return !bRet;
1559 }
1560 
1561 // -----------------------------------------------------------------------
1562 #define IMPL_PAINT_CHECKRTL         ((sal_uInt16)0x0020)
1563 
1564 static void ImplHandlePaint( Window* pWindow, const Rectangle& rBoundRect, bool bImmediateUpdate )
1565 {
1566     // give up background save when sytem paints arrive
1567     Window* pSaveBackWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFirstBackWin;
1568     while ( pSaveBackWin )
1569     {
1570         Window* pNext = pSaveBackWin->ImplGetWindowImpl()->mpOverlapData->mpNextBackWin;
1571         Rectangle aRect( Point( pSaveBackWin->GetOutOffXPixel(), pSaveBackWin->GetOutOffYPixel() ),
1572                          Size( pSaveBackWin->GetOutputWidthPixel(), pSaveBackWin->GetOutputHeightPixel() ) );
1573         if ( aRect.IsOver( rBoundRect ) )
1574             pSaveBackWin->ImplDeleteOverlapBackground();
1575         pSaveBackWin = pNext;
1576     }
1577 
1578     // system paint events must be checked for re-mirroring
1579     pWindow->ImplGetWindowImpl()->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
1580 
1581     // trigger paint for all windows that live in the new paint region
1582     Region aRegion( rBoundRect );
1583     pWindow->ImplInvalidateOverlapFrameRegion( aRegion );
1584     if( bImmediateUpdate )
1585     {
1586         // #i87663# trigger possible pending resize notifications
1587         // (GetSizePixel does that for us)
1588         pWindow->GetSizePixel();
1589         // force drawing inmmediately
1590         pWindow->Update();
1591     }
1592 }
1593 
1594 // -----------------------------------------------------------------------
1595 
1596 static void KillOwnPopups( Window* pWindow )
1597 {
1598     ImplSVData* pSVData = ImplGetSVData();
1599 	Window *pParent = pWindow->ImplGetWindowImpl()->mpFrameWindow;
1600     Window *pChild = pSVData->maWinData.mpFirstFloat;
1601     if ( pChild && pParent->ImplIsWindowOrChild( pChild, sal_True ) )
1602     {
1603         if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) )
1604             pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1605     }
1606 }
1607 
1608 // -----------------------------------------------------------------------
1609 
1610 void ImplHandleResize( Window* pWindow, long nNewWidth, long nNewHeight )
1611 {
1612     if( pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE) )
1613     {
1614         KillOwnPopups( pWindow );
1615         if( pWindow->ImplGetWindow() != ImplGetSVData()->maHelpData.mpHelpWin )
1616             ImplDestroyHelpWindow( true );
1617     }
1618 
1619     if (
1620          (nNewWidth > 0 && nNewHeight > 0) ||
1621          pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize
1622        )
1623     {
1624         if ( (nNewWidth != pWindow->GetOutputWidthPixel()) || (nNewHeight != pWindow->GetOutputHeightPixel()) )
1625         {
1626             pWindow->mnOutWidth  = nNewWidth;
1627             pWindow->mnOutHeight = nNewHeight;
1628             pWindow->ImplGetWindowImpl()->mbWaitSystemResize = sal_False;
1629             if ( pWindow->IsReallyVisible() )
1630                 pWindow->ImplSetClipFlag();
1631             if ( pWindow->IsVisible() || pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize ||
1632                 ( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow ) )   // propagate resize for system border windows
1633             {
1634                 bool bStartTimer = true;
1635                 // use resize buffering for user resizes
1636                 // ownerdraw decorated windows and floating windows can be resized immediately (i.e. synchronously)
1637                 if( pWindow->ImplGetWindowImpl()->mbFrame && (pWindow->GetStyle() & WB_SIZEABLE)
1638                     && !(pWindow->GetStyle() & WB_OWNERDRAWDECORATION)  // synchronous resize for ownerdraw decorated windows (toolbars)
1639                     && !pWindow->ImplGetWindowImpl()->mbFloatWin )             // synchronous resize for floating windows, #i43799#
1640                 {
1641                     if( pWindow->ImplGetWindowImpl()->mpClientWindow )
1642                     {
1643                         // #i42750# presentation wants to be informed about resize
1644                         // as early as possible
1645                         WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pWindow->ImplGetWindowImpl()->mpClientWindow);
1646                         if( ! pWorkWindow || pWorkWindow->IsPresentationMode() )
1647                             bStartTimer = false;
1648                     }
1649                     else
1650                     {
1651                         WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pWindow);
1652                         if( ! pWorkWindow || pWorkWindow->IsPresentationMode() )
1653                             bStartTimer = false;
1654                     }
1655                 }
1656                 else
1657                     bStartTimer = false;
1658 
1659                 if( bStartTimer )
1660                     pWindow->ImplGetWindowImpl()->mpFrameData->maResizeTimer.Start();
1661                 else
1662                     pWindow->ImplCallResize(); // otherwise menues cannot be positioned
1663             }
1664             else
1665                 pWindow->ImplGetWindowImpl()->mbCallResize = sal_True;
1666         }
1667     }
1668 
1669     pWindow->ImplGetWindowImpl()->mpFrameData->mbNeedSysWindow = (nNewWidth < IMPL_MIN_NEEDSYSWIN) ||
1670                                             (nNewHeight < IMPL_MIN_NEEDSYSWIN);
1671     sal_Bool bMinimized = (nNewWidth <= 0) || (nNewHeight <= 0);
1672     if( bMinimized != pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized )
1673         pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplNotifyIconifiedState( bMinimized );
1674     pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized = bMinimized;
1675 }
1676 
1677 // -----------------------------------------------------------------------
1678 
1679 static void ImplHandleMove( Window* pWindow )
1680 {
1681     if( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplIsFloatingWindow() && pWindow->IsReallyVisible() )
1682     {
1683         static_cast<FloatingWindow*>(pWindow)->EndPopupMode( FLOATWIN_POPUPMODEEND_TEAROFF );
1684         pWindow->ImplCallMove();
1685     }
1686 
1687     if( pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE) )
1688     {
1689         KillOwnPopups( pWindow );
1690         if( pWindow->ImplGetWindow() != ImplGetSVData()->maHelpData.mpHelpWin )
1691             ImplDestroyHelpWindow( true );
1692     }
1693 
1694     if ( pWindow->IsVisible() )
1695 		pWindow->ImplCallMove();
1696     else
1697         pWindow->ImplGetWindowImpl()->mbCallMove = sal_True; // make sure the framepos will be updated on the next Show()
1698 
1699     if ( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow )
1700 		pWindow->ImplGetWindowImpl()->mpClientWindow->ImplCallMove();	// notify client to update geometry
1701 
1702 }
1703 
1704 // -----------------------------------------------------------------------
1705 
1706 static void ImplHandleMoveResize( Window* pWindow, long nNewWidth, long nNewHeight )
1707 {
1708     ImplHandleMove( pWindow );
1709     ImplHandleResize( pWindow, nNewWidth, nNewHeight );
1710 }
1711 
1712 // -----------------------------------------------------------------------
1713 
1714 static void ImplActivateFloatingWindows( Window* pWindow, sal_Bool bActive )
1715 {
1716     // Zuerst alle ueberlappenden Fenster ueberpruefen
1717     Window* pTempWindow = pWindow->ImplGetWindowImpl()->mpFirstOverlap;
1718     while ( pTempWindow )
1719     {
1720         if ( !pTempWindow->GetActivateMode() )
1721         {
1722             if ( (pTempWindow->GetType() == WINDOW_BORDERWINDOW) &&
1723                  (pTempWindow->ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) )
1724                 ((ImplBorderWindow*)pTempWindow)->SetDisplayActive( bActive );
1725         }
1726 
1727         ImplActivateFloatingWindows( pTempWindow, bActive );
1728         pTempWindow = pTempWindow->ImplGetWindowImpl()->mpNext;
1729     }
1730 }
1731 
1732 
1733 // -----------------------------------------------------------------------
1734 
1735 IMPL_LINK( Window, ImplAsyncFocusHdl, void*, EMPTYARG )
1736 {
1737     ImplGetWindowImpl()->mpFrameData->mnFocusId = 0;
1738 
1739     // Wenn Status erhalten geblieben ist, weil wir den Focus in der
1740     // zwischenzeit schon wiederbekommen haben, brauchen wir auch
1741     // nichts machen
1742     sal_Bool bHasFocus = ImplGetWindowImpl()->mpFrameData->mbHasFocus || ImplGetWindowImpl()->mpFrameData->mbSysObjFocus;
1743 
1744     // Dann die zeitverzoegerten Funktionen ausfuehren
1745     if ( bHasFocus )
1746     {
1747         // Alle FloatingFenster deaktiv zeichnen
1748         if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
1749             ImplActivateFloatingWindows( this, bHasFocus );
1750 
1751         if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin )
1752         {
1753             sal_Bool bHandled = sal_False;
1754             if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInputEnabled() &&
1755                  ! ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInModalMode() )
1756             {
1757                 if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsEnabled() )
1758                 {
1759                     ImplGetWindowImpl()->mpFrameData->mpFocusWin->GrabFocus();
1760                     bHandled = sal_True;
1761                 }
1762                 else if( ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplHasDlgCtrl() )
1763                 {
1764                 // #109094# if the focus is restored to a disabled dialog control (was disabled meanwhile)
1765                 // try to move it to the next control
1766                     ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplDlgCtrlNextWindow();
1767                     bHandled = sal_True;
1768                 }
1769             }
1770             if ( !bHandled )
1771             {
1772                 ImplSVData* pSVData = ImplGetSVData();
1773                 Window*     pTopLevelWindow = ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplGetFirstOverlapWindow();
1774                 if ( ( ! pTopLevelWindow->IsInputEnabled() || pTopLevelWindow->IsInModalMode() )
1775                      && pSVData->maWinData.mpLastExecuteDlg )
1776                     pSVData->maWinData.mpLastExecuteDlg->ToTop( TOTOP_RESTOREWHENMIN | TOTOP_GRABFOCUSONLY);
1777                 else
1778                     pTopLevelWindow->GrabFocus();
1779             }
1780         }
1781         else
1782             GrabFocus();
1783     }
1784     else
1785     {
1786         Window* pFocusWin = ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1787         if ( pFocusWin )
1788         {
1789             ImplSVData* pSVData = ImplGetSVData();
1790 
1791             if ( pSVData->maWinData.mpFocusWin == pFocusWin )
1792             {
1793                 // FocusWindow umsetzen
1794                 Window* pOverlapWindow = pFocusWin->ImplGetFirstOverlapWindow();
1795                 pOverlapWindow->ImplGetWindowImpl()->mpLastFocusWindow = pFocusWin;
1796                 pSVData->maWinData.mpFocusWin = NULL;
1797 
1798                 if ( pFocusWin->ImplGetWindowImpl()->mpCursor )
1799                     pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide( true );
1800 
1801                 // Deaktivate rufen
1802                 Window* pOldFocusWindow = pFocusWin;
1803                 if ( pOldFocusWindow )
1804                 {
1805                     Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
1806                     Window* pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
1807 
1808                     pOldOverlapWindow->ImplGetWindowImpl()->mbActive = sal_False;
1809                     pOldOverlapWindow->Deactivate();
1810                     if ( pOldRealWindow != pOldOverlapWindow )
1811                     {
1812                         pOldRealWindow->ImplGetWindowImpl()->mbActive = sal_False;
1813                         pOldRealWindow->Deactivate();
1814                     }
1815                 }
1816 
1817                 // TrackingMode is ended in ImplHandleLoseFocus
1818 // To avoid problems with the Unix IME
1819 //                pFocusWin->EndExtTextInput( EXTTEXTINPUT_END_COMPLETE );
1820 
1821                 // XXX #102010# hack for accessibility: do not close the menu,
1822                 // even after focus lost
1823                 static const char* pEnv = getenv("SAL_FLOATWIN_NOAPPFOCUSCLOSE");
1824                 if( !(pEnv && *pEnv) )
1825                 {
1826                     NotifyEvent aNEvt( EVENT_LOSEFOCUS, pFocusWin );
1827                     if ( !ImplCallPreNotify( aNEvt ) )
1828                         pFocusWin->LoseFocus();
1829                     pFocusWin->ImplCallDeactivateListeners( NULL );
1830                     GetpApp()->FocusChanged();
1831                 }
1832                 // XXX
1833             }
1834         }
1835 
1836         // Alle FloatingFenster deaktiv zeichnen
1837         if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
1838             ImplActivateFloatingWindows( this, bHasFocus );
1839     }
1840 
1841     return 0;
1842 }
1843 
1844 // -----------------------------------------------------------------------
1845 
1846 static void ImplHandleGetFocus( Window* pWindow )
1847 {
1848     pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = sal_True;
1849 
1850     // Focus-Events zeitverzoegert ausfuehren, damit bei SystemChildFenstern
1851     // nicht alles flackert, wenn diese den Focus bekommen
1852     if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1853     {
1854         bool bCallDirect = ImplGetSVData()->mbIsTestTool;
1855         pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
1856         if( ! bCallDirect )
1857             Application::PostUserEvent( pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId, LINK( pWindow, Window, ImplAsyncFocusHdl ) );
1858 		Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1859 		if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
1860 			pFocusWin->ImplGetWindowImpl()->mpCursor->ImplShow();
1861         if( bCallDirect )
1862             pWindow->ImplAsyncFocusHdl( NULL );
1863     }
1864 }
1865 
1866 // -----------------------------------------------------------------------
1867 
1868 static void ImplHandleLoseFocus( Window* pWindow )
1869 {
1870     ImplSVData* pSVData = ImplGetSVData();
1871 
1872     // Wenn Frame den Focus verliert, brechen wir auch ein AutoScroll ab
1873     if ( pSVData->maWinData.mpAutoScrollWin )
1874         pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1875 
1876     // Wenn Frame den Focus verliert, brechen wir auch ein Tracking ab
1877     if ( pSVData->maWinData.mpTrackWin )
1878     {
1879         if ( pSVData->maWinData.mpTrackWin->ImplGetWindowImpl()->mpFrameWindow == pWindow )
1880             pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
1881     }
1882 
1883     // handle FloatingMode
1884     // hier beenden wir immer den PopupModus, auch dann, wenn NOFOCUSCLOSE
1885     // gesetzt ist, damit wir nicht beim Wechsel noch Fenster stehen lassen
1886     if ( pSVData->maWinData.mpFirstFloat )
1887     {
1888         if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) )
1889             pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1890     }
1891 
1892     pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = sal_False;
1893 
1894     // Focus-Events zeitverzoegert ausfuehren, damit bei SystemChildFenstern
1895     // nicht alles flackert, wenn diese den Focus bekommen
1896     bool bCallDirect = ImplGetSVData()->mbIsTestTool;
1897     if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1898     {
1899         pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
1900         if( ! bCallDirect )
1901             Application::PostUserEvent( pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId, LINK( pWindow, Window, ImplAsyncFocusHdl ) );
1902     }
1903 
1904 	Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1905 	if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
1906 		pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide( true );
1907     if( bCallDirect )
1908         pWindow->ImplAsyncFocusHdl( NULL );
1909 }
1910 
1911 // -----------------------------------------------------------------------
1912 struct DelayedCloseEvent
1913 {
1914     Window*         pWindow;
1915     ImplDelData     aDelData;
1916 };
1917 
1918 static long DelayedCloseEventLink( void* pCEvent, void* )
1919 {
1920     DelayedCloseEvent* pEv = (DelayedCloseEvent*)pCEvent;
1921 
1922     if( ! pEv->aDelData.IsDelete() )
1923     {
1924         pEv->pWindow->ImplRemoveDel( &pEv->aDelData );
1925         // dispatch to correct window type
1926         if( pEv->pWindow->IsSystemWindow() )
1927             ((SystemWindow*)pEv->pWindow)->Close();
1928         else if( pEv->pWindow->ImplIsDockingWindow() )
1929             ((DockingWindow*)pEv->pWindow)->Close();
1930     }
1931     delete pEv;
1932 
1933     return 0;
1934 }
1935 
1936 void ImplHandleClose( Window* pWindow )
1937 {
1938     ImplSVData* pSVData = ImplGetSVData();
1939 
1940     bool bWasPopup = false;
1941     if( pWindow->ImplIsFloatingWindow() &&
1942         static_cast<FloatingWindow*>(pWindow)->ImplIsInPrivatePopupMode() )
1943     {
1944         bWasPopup = true;
1945     }
1946 
1947     // on Close stop all floating modes and end popups
1948     if ( pSVData->maWinData.mpFirstFloat )
1949     {
1950         FloatingWindow* pLastLevelFloat;
1951         pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
1952         pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
1953     }
1954     if ( pSVData->maHelpData.mbExtHelpMode )
1955         Help::EndExtHelp();
1956     if ( pSVData->maHelpData.mpHelpWin )
1957         ImplDestroyHelpWindow( false );
1958     // AutoScrollMode
1959     if ( pSVData->maWinData.mpAutoScrollWin )
1960         pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1961 
1962     if ( pSVData->maWinData.mpTrackWin )
1963         pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL | ENDTRACK_KEY );
1964 
1965     if( ! bWasPopup )
1966     {
1967         Window *pWin = pWindow->ImplGetWindow();
1968         // check whether close is allowed
1969         if ( !pWin->IsEnabled() || !pWin->IsInputEnabled() || pWin->IsInModalMode() )
1970             Sound::Beep( SOUND_DISABLE, pWin );
1971         else
1972         {
1973             DelayedCloseEvent* pEv = new DelayedCloseEvent;
1974             pEv->pWindow = pWin;
1975             pWin->ImplAddDel( &pEv->aDelData );
1976             Application::PostUserEvent( Link( pEv, DelayedCloseEventLink ) );
1977         }
1978     }
1979 }
1980 
1981 // -----------------------------------------------------------------------
1982 
1983 static void ImplHandleUserEvent( ImplSVEvent* pSVEvent )
1984 {
1985     if ( pSVEvent )
1986     {
1987         if ( pSVEvent->mbCall && !pSVEvent->maDelData.IsDelete() )
1988         {
1989             if ( pSVEvent->mpWindow )
1990             {
1991                 pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) );
1992                 if ( pSVEvent->mpLink )
1993                     pSVEvent->mpLink->Call( pSVEvent->mpData );
1994                 else
1995                     pSVEvent->mpWindow->UserEvent( pSVEvent->mnEvent, pSVEvent->mpData );
1996             }
1997             else
1998             {
1999                 if ( pSVEvent->mpLink )
2000                     pSVEvent->mpLink->Call( pSVEvent->mpData );
2001                 else
2002                     GetpApp()->UserEvent( pSVEvent->mnEvent, pSVEvent->mpData );
2003             }
2004         }
2005 
2006         delete pSVEvent->mpLink;
2007         delete pSVEvent;
2008     }
2009 }
2010 
2011 // =======================================================================
2012 
2013 static sal_uInt16 ImplGetMouseMoveMode( SalMouseEvent* pEvent )
2014 {
2015     sal_uInt16 nMode = 0;
2016     if ( !pEvent->mnCode )
2017         nMode |= MOUSE_SIMPLEMOVE;
2018     if ( (pEvent->mnCode & MOUSE_LEFT) && !(pEvent->mnCode & KEY_MOD1) )
2019         nMode |= MOUSE_DRAGMOVE;
2020     if ( (pEvent->mnCode & MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) )
2021         nMode |= MOUSE_DRAGCOPY;
2022     return nMode;
2023 }
2024 
2025 // -----------------------------------------------------------------------
2026 
2027 static sal_uInt16 ImplGetMouseButtonMode( SalMouseEvent* pEvent )
2028 {
2029     sal_uInt16 nMode = 0;
2030     if ( pEvent->mnButton == MOUSE_LEFT )
2031         nMode |= MOUSE_SIMPLECLICK;
2032     if ( (pEvent->mnButton == MOUSE_LEFT) && !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT)) )
2033         nMode |= MOUSE_SELECT;
2034     if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) &&
2035          !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_SHIFT)) )
2036         nMode |= MOUSE_MULTISELECT;
2037     if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_SHIFT) &&
2038          !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_MOD1)) )
2039         nMode |= MOUSE_RANGESELECT;
2040     return nMode;
2041 }
2042 
2043 // -----------------------------------------------------------------------
2044 
2045 inline long ImplHandleSalMouseLeave( Window* pWindow, SalMouseEvent* pEvent )
2046 {
2047     return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, sal_True,
2048                                  pEvent->mnX, pEvent->mnY,
2049                                  pEvent->mnTime, pEvent->mnCode,
2050                                  ImplGetMouseMoveMode( pEvent ) );
2051 }
2052 
2053 // -----------------------------------------------------------------------
2054 
2055 inline long ImplHandleSalMouseMove( Window* pWindow, SalMouseEvent* pEvent )
2056 {
2057     return ImplHandleMouseEvent( pWindow, EVENT_MOUSEMOVE, sal_False,
2058                                  pEvent->mnX, pEvent->mnY,
2059                                  pEvent->mnTime, pEvent->mnCode,
2060                                  ImplGetMouseMoveMode( pEvent ) );
2061 }
2062 
2063 // -----------------------------------------------------------------------
2064 
2065 inline long ImplHandleSalMouseButtonDown( Window* pWindow, SalMouseEvent* pEvent )
2066 {
2067     return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONDOWN, sal_False,
2068                                  pEvent->mnX, pEvent->mnY,
2069                                  pEvent->mnTime,
2070 #ifdef MACOSX
2071 				 pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)),
2072 #else
2073                                  pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
2074 #endif
2075                                  ImplGetMouseButtonMode( pEvent ) );
2076 }
2077 
2078 // -----------------------------------------------------------------------
2079 
2080 inline long ImplHandleSalMouseButtonUp( Window* pWindow, SalMouseEvent* pEvent )
2081 {
2082     return ImplHandleMouseEvent( pWindow, EVENT_MOUSEBUTTONUP, sal_False,
2083                                  pEvent->mnX, pEvent->mnY,
2084                                  pEvent->mnTime,
2085 #ifdef MACOSX
2086 				 pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)),
2087 #else
2088                                  pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
2089 #endif
2090                                  ImplGetMouseButtonMode( pEvent ) );
2091 }
2092 
2093 // -----------------------------------------------------------------------
2094 
2095 static long ImplHandleSalMouseActivate( Window* /*pWindow*/, SalMouseActivateEvent* /*pEvent*/ )
2096 {
2097     return sal_False;
2098 }
2099 
2100 // -----------------------------------------------------------------------
2101 
2102 static long ImplHandleMenuEvent( Window* pWindow, SalMenuEvent* pEvent, sal_uInt16 nEvent )
2103 {
2104     // Find SystemWindow and its Menubar and let it dispatch the command
2105     long nRet = 0;
2106     Window *pWin = pWindow->ImplGetWindowImpl()->mpFirstChild;
2107     while ( pWin )
2108     {
2109         if ( pWin->ImplGetWindowImpl()->mbSysWin )
2110             break;
2111         pWin = pWin->ImplGetWindowImpl()->mpNext;
2112     }
2113     if( pWin )
2114     {
2115         MenuBar *pMenuBar = ((SystemWindow*) pWin)->GetMenuBar();
2116         if( pMenuBar )
2117         {
2118             switch( nEvent )
2119             {
2120                 case SALEVENT_MENUACTIVATE:
2121                     nRet = pMenuBar->HandleMenuActivateEvent( (Menu*) pEvent->mpMenu ) ? 1 : 0;
2122                     break;
2123                 case SALEVENT_MENUDEACTIVATE:
2124                     nRet = pMenuBar->HandleMenuDeActivateEvent( (Menu*) pEvent->mpMenu ) ? 1 : 0;
2125                     break;
2126                 case SALEVENT_MENUHIGHLIGHT:
2127                     nRet = pMenuBar->HandleMenuHighlightEvent( (Menu*) pEvent->mpMenu, pEvent->mnId ) ? 1 : 0;
2128                     break;
2129                 case SALEVENT_MENUBUTTONCOMMAND:
2130                     nRet = pMenuBar->HandleMenuButtonEvent( (Menu*) pEvent->mpMenu, pEvent->mnId ) ? 1 : 0;
2131                     break;
2132                 case SALEVENT_MENUCOMMAND:
2133                     nRet = pMenuBar->HandleMenuCommandEvent( (Menu*) pEvent->mpMenu, pEvent->mnId ) ? 1 : 0;
2134                     break;
2135                 default:
2136                     break;
2137             }
2138         }
2139     }
2140     return nRet;
2141 }
2142 
2143 // -----------------------------------------------------------------------
2144 
2145 static void ImplHandleSalKeyMod( Window* pWindow, SalKeyModEvent* pEvent )
2146 {
2147     ImplSVData* pSVData = ImplGetSVData();
2148     Window* pTrackWin = pSVData->maWinData.mpTrackWin;
2149     if ( pTrackWin )
2150         pWindow = pTrackWin;
2151 #ifdef MACOSX
2152     sal_uInt16 nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
2153 #else
2154     sal_uInt16 nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
2155 #endif
2156     sal_uInt16 nNewCode = pEvent->mnCode;
2157     if ( nOldCode != nNewCode )
2158     {
2159 #ifdef MACOSX
2160 	nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
2161 #else
2162         nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
2163 #endif
2164         pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplCallMouseMove( nNewCode, sal_True );
2165     }
2166 
2167     // #105224# send commandevent to allow special treatment of Ctrl-LeftShift/Ctrl-RightShift etc.
2168 
2169     // find window
2170     Window* pChild = ImplGetKeyInputWindow( pWindow );
2171     if ( !pChild )
2172         return;
2173 
2174     // send modkey events only if useful data is available
2175     if( pEvent->mnModKeyCode != 0 )
2176     {
2177         CommandModKeyData data( pEvent->mnModKeyCode );
2178         ImplCallCommand( pChild, COMMAND_MODKEYCHANGE, &data );
2179     }
2180 }
2181 
2182 // -----------------------------------------------------------------------
2183 
2184 static void ImplHandleInputLanguageChange( Window* pWindow )
2185 {
2186     // find window
2187     Window* pChild = ImplGetKeyInputWindow( pWindow );
2188     if ( !pChild )
2189         return;
2190 
2191     ImplCallCommand( pChild, COMMAND_INPUTLANGUAGECHANGE );
2192 }
2193 
2194 // -----------------------------------------------------------------------
2195 
2196 static void ImplHandleSalSettings( Window* pWindow, sal_uInt16 nEvent )
2197 {
2198     // Application Notification werden nur fuer das erste Window ausgeloest
2199     ImplSVData* pSVData = ImplGetSVData();
2200     if ( pWindow != pSVData->maWinData.mpFirstFrame )
2201         return;
2202 
2203     Application* pApp = GetpApp();
2204     if ( !pApp )
2205         return;
2206 
2207     if ( nEvent == SALEVENT_SETTINGSCHANGED )
2208     {
2209         AllSettings aSettings = pApp->GetSettings();
2210         pApp->MergeSystemSettings( aSettings );
2211         pApp->SystemSettingsChanging( aSettings, pWindow );
2212         pApp->SetSettings( aSettings );
2213     }
2214     else
2215     {
2216         sal_uInt16 nType;
2217         switch ( nEvent )
2218         {
2219             case SALEVENT_VOLUMECHANGED:
2220                 nType = 0;
2221                 break;
2222             case SALEVENT_PRINTERCHANGED:
2223                 ImplDeletePrnQueueList();
2224                 nType = DATACHANGED_PRINTER;
2225                 break;
2226             case SALEVENT_DISPLAYCHANGED:
2227                 nType = DATACHANGED_DISPLAY;
2228                 break;
2229             case SALEVENT_FONTCHANGED:
2230                 OutputDevice::ImplUpdateAllFontData( sal_True );
2231                 nType = DATACHANGED_FONTS;
2232                 break;
2233             case SALEVENT_DATETIMECHANGED:
2234                 nType = DATACHANGED_DATETIME;
2235                 break;
2236             case SALEVENT_KEYBOARDCHANGED:
2237                 nType = 0;
2238                 break;
2239             default:
2240                 nType = 0;
2241                 break;
2242         }
2243 
2244         if ( nType )
2245         {
2246             DataChangedEvent aDCEvt( nType );
2247             pApp->DataChanged( aDCEvt );
2248             pApp->NotifyAllWindows( aDCEvt );
2249         }
2250     }
2251 }
2252 
2253 // -----------------------------------------------------------------------
2254 
2255 static void ImplHandleSalExtTextInputPos( Window* pWindow, SalExtTextInputPosEvent* pEvt )
2256 {
2257     Rectangle aCursorRect;
2258     ImplHandleExtTextInputPos( pWindow, aCursorRect, pEvt->mnExtWidth, &pEvt->mbVertical );
2259     if ( aCursorRect.IsEmpty() )
2260     {
2261         pEvt->mnX       = -1;
2262         pEvt->mnY       = -1;
2263         pEvt->mnWidth   = -1;
2264         pEvt->mnHeight  = -1;
2265     }
2266     else
2267     {
2268         pEvt->mnX       = aCursorRect.Left();
2269         pEvt->mnY       = aCursorRect.Top();
2270         pEvt->mnWidth   = aCursorRect.GetWidth();
2271         pEvt->mnHeight  = aCursorRect.GetHeight();
2272     }
2273 }
2274 
2275 // -----------------------------------------------------------------------
2276 
2277 static long ImplHandleShowDialog( Window* pWindow, int nDialogId )
2278 {
2279     if( ! pWindow )
2280         return sal_False;
2281 
2282     if( pWindow->GetType() == WINDOW_BORDERWINDOW )
2283     {
2284         Window* pWrkWin = pWindow->GetWindow( WINDOW_CLIENT );
2285         if( pWrkWin )
2286             pWindow = pWrkWin;
2287     }
2288     CommandDialogData aCmdData( nDialogId );
2289     return ImplCallCommand( pWindow, COMMAND_SHOWDIALOG, &aCmdData );
2290 }
2291 
2292 // -----------------------------------------------------------------------
2293 
2294 static void ImplHandleSurroundingTextRequest( Window *pWindow,
2295 					      XubString& rText,
2296 					      Selection &rSelRange )
2297 {
2298     Window* pChild = ImplGetKeyInputWindow( pWindow );
2299 
2300     if ( !pChild )
2301     {
2302 	rText = XubString::EmptyString();
2303 	rSelRange.setMin( 0 );
2304 	rSelRange.setMax( 0 );
2305     }
2306     else
2307     {
2308 
2309 	rText = pChild->GetSurroundingText();
2310 	Selection aSel = pChild->GetSurroundingTextSelection();
2311 	rSelRange.setMin( aSel.Min() );
2312 	rSelRange.setMax( aSel.Max() );
2313     }
2314 }
2315 
2316 // -----------------------------------------------------------------------
2317 
2318 static void ImplHandleSalSurroundingTextRequest( Window *pWindow,
2319 						 SalSurroundingTextRequestEvent *pEvt )
2320 {
2321 	Selection aSelRange;
2322 	ImplHandleSurroundingTextRequest( pWindow, pEvt->maText, aSelRange );
2323 
2324 	aSelRange.Justify();
2325 
2326 	if( aSelRange.Min() < 0 )
2327 		pEvt->mnStart = 0;
2328 	else if( aSelRange.Min() > pEvt->maText.Len() )
2329 		pEvt->mnStart = pEvt->maText.Len();
2330 	else
2331 		pEvt->mnStart = aSelRange.Min();
2332 
2333 	if( aSelRange.Max() < 0 )
2334 		pEvt->mnStart = 0;
2335 	else if( aSelRange.Max() > pEvt->maText.Len() )
2336 		pEvt->mnEnd = pEvt->maText.Len();
2337 	else
2338 		pEvt->mnEnd = aSelRange.Max();
2339 }
2340 
2341 // -----------------------------------------------------------------------
2342 
2343 static void ImplHandleSurroundingTextSelectionChange( Window *pWindow,
2344 						      sal_uLong nStart,
2345 						      sal_uLong nEnd )
2346 {
2347     Window* pChild = ImplGetKeyInputWindow( pWindow );
2348     if( pChild )
2349     {
2350         CommandSelectionChangeData data( nStart, nEnd );
2351         ImplCallCommand( pChild, COMMAND_SELECTIONCHANGE, &data );
2352     }
2353 }
2354 
2355 // -----------------------------------------------------------------------
2356 
2357 static void ImplHandleStartReconversion( Window *pWindow )
2358 {
2359     Window* pChild = ImplGetKeyInputWindow( pWindow );
2360     if( pChild )
2361 	ImplCallCommand( pChild, COMMAND_PREPARERECONVERSION );
2362 }
2363 
2364 // -----------------------------------------------------------------------
2365 
2366 long ImplWindowFrameProc( Window* pWindow, SalFrame* /*pFrame*/,
2367                           sal_uInt16 nEvent, const void* pEvent )
2368 {
2369     DBG_TESTSOLARMUTEX();
2370 
2371     long nRet = 0;
2372 
2373     // #119709# for some unknown reason it is possible to receive events (in this case key events)
2374     // although the corresponding VCL window must have been destroyed already
2375     // at least ImplGetWindowImpl() was NULL in these cases, so check this here
2376     if( pWindow->ImplGetWindowImpl() == NULL )
2377         return 0;
2378 
2379     switch ( nEvent )
2380     {
2381         case SALEVENT_MOUSEMOVE:
2382             nRet = ImplHandleSalMouseMove( pWindow, (SalMouseEvent*)pEvent );
2383             break;
2384         case SALEVENT_EXTERNALMOUSEMOVE:
2385         {
2386             MouseEvent*     pMouseEvt = (MouseEvent*) pEvent;
2387             SalMouseEvent   aSalMouseEvent;
2388 
2389             aSalMouseEvent.mnTime = Time::GetSystemTicks();
2390             aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2391             aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2392             aSalMouseEvent.mnButton = 0;
2393             aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2394 
2395             nRet = ImplHandleSalMouseMove( pWindow, &aSalMouseEvent );
2396         }
2397         break;
2398         case SALEVENT_MOUSELEAVE:
2399             nRet = ImplHandleSalMouseLeave( pWindow, (SalMouseEvent*)pEvent );
2400             break;
2401         case SALEVENT_MOUSEBUTTONDOWN:
2402             nRet = ImplHandleSalMouseButtonDown( pWindow, (SalMouseEvent*)pEvent );
2403             break;
2404         case SALEVENT_EXTERNALMOUSEBUTTONDOWN:
2405         {
2406             MouseEvent*     pMouseEvt = (MouseEvent*) pEvent;
2407             SalMouseEvent   aSalMouseEvent;
2408 
2409             aSalMouseEvent.mnTime = Time::GetSystemTicks();
2410             aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2411             aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2412             aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
2413             aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2414 
2415             nRet = ImplHandleSalMouseButtonDown( pWindow, &aSalMouseEvent );
2416         }
2417         break;
2418         case SALEVENT_MOUSEBUTTONUP:
2419             nRet = ImplHandleSalMouseButtonUp( pWindow, (SalMouseEvent*)pEvent );
2420             break;
2421         case SALEVENT_EXTERNALMOUSEBUTTONUP:
2422         {
2423             MouseEvent*     pMouseEvt = (MouseEvent*) pEvent;
2424             SalMouseEvent   aSalMouseEvent;
2425 
2426             aSalMouseEvent.mnTime = Time::GetSystemTicks();
2427             aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2428             aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2429             aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
2430             aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2431 
2432             nRet = ImplHandleSalMouseButtonUp( pWindow, &aSalMouseEvent );
2433         }
2434         break;
2435         case SALEVENT_MOUSEACTIVATE:
2436             nRet = ImplHandleSalMouseActivate( pWindow, (SalMouseActivateEvent*)pEvent );
2437             break;
2438         case SALEVENT_KEYINPUT:
2439             {
2440             SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
2441             nRet = ImplHandleKey( pWindow, EVENT_KEYINPUT,
2442                 pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, sal_True );
2443             }
2444             break;
2445         case SALEVENT_EXTERNALKEYINPUT:
2446             {
2447             KeyEvent* pKeyEvt = (KeyEvent*) pEvent;
2448             nRet = ImplHandleKey( pWindow, EVENT_KEYINPUT,
2449                 pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), sal_False );
2450             }
2451             break;
2452         case SALEVENT_KEYUP:
2453             {
2454             SalKeyEvent* pKeyEvt = (SalKeyEvent*)pEvent;
2455             nRet = ImplHandleKey( pWindow, EVENT_KEYUP,
2456                 pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, sal_True );
2457             }
2458             break;
2459         case SALEVENT_EXTERNALKEYUP:
2460             {
2461             KeyEvent* pKeyEvt = (KeyEvent*) pEvent;
2462             nRet = ImplHandleKey( pWindow, EVENT_KEYUP,
2463                 pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), sal_False );
2464             }
2465             break;
2466         case SALEVENT_KEYMODCHANGE:
2467             ImplHandleSalKeyMod( pWindow, (SalKeyModEvent*)pEvent );
2468             break;
2469 
2470         case SALEVENT_INPUTLANGUAGECHANGE:
2471             ImplHandleInputLanguageChange( pWindow );
2472             break;
2473 
2474         case SALEVENT_MENUACTIVATE:
2475         case SALEVENT_MENUDEACTIVATE:
2476         case SALEVENT_MENUHIGHLIGHT:
2477         case SALEVENT_MENUCOMMAND:
2478         case SALEVENT_MENUBUTTONCOMMAND:
2479             nRet = ImplHandleMenuEvent( pWindow, (SalMenuEvent*)pEvent, nEvent );
2480             break;
2481 
2482         case SALEVENT_WHEELMOUSE:
2483             nRet = ImplHandleWheelEvent( pWindow, *(const SalWheelMouseEvent*)pEvent);
2484             break;
2485 
2486         case SALEVENT_PAINT:
2487             {
2488             SalPaintEvent* pPaintEvt = (SalPaintEvent*)pEvent;
2489 
2490             if( Application::GetSettings().GetLayoutRTL() )
2491             {
2492                 // --- RTL --- (mirror paint rect)
2493                 SalFrame* pSalFrame = pWindow->ImplGetWindowImpl()->mpFrame;
2494                 pPaintEvt->mnBoundX = pSalFrame->maGeometry.nWidth-pPaintEvt->mnBoundWidth-pPaintEvt->mnBoundX;
2495             }
2496 
2497             Rectangle aBoundRect( Point( pPaintEvt->mnBoundX, pPaintEvt->mnBoundY ),
2498                                   Size( pPaintEvt->mnBoundWidth, pPaintEvt->mnBoundHeight ) );
2499             ImplHandlePaint( pWindow, aBoundRect, pPaintEvt->mbImmediateUpdate );
2500             }
2501             break;
2502 
2503         case SALEVENT_MOVE:
2504             ImplHandleMove( pWindow );
2505             break;
2506 
2507         case SALEVENT_RESIZE:
2508             {
2509             long nNewWidth;
2510             long nNewHeight;
2511             pWindow->ImplGetWindowImpl()->mpFrame->GetClientSize( nNewWidth, nNewHeight );
2512             ImplHandleResize( pWindow, nNewWidth, nNewHeight );
2513             }
2514             break;
2515 
2516         case SALEVENT_MOVERESIZE:
2517             {
2518             SalFrameGeometry g = pWindow->ImplGetWindowImpl()->mpFrame->GetGeometry();
2519             ImplHandleMoveResize( pWindow, g.nWidth, g.nHeight );
2520             }
2521             break;
2522 
2523         case SALEVENT_CLOSEPOPUPS:
2524             {
2525             KillOwnPopups( pWindow );
2526             }
2527             break;
2528 
2529         case SALEVENT_GETFOCUS:
2530             ImplHandleGetFocus( pWindow );
2531             break;
2532         case SALEVENT_LOSEFOCUS:
2533             ImplHandleLoseFocus( pWindow );
2534             break;
2535 
2536         case SALEVENT_CLOSE:
2537             ImplHandleClose( pWindow );
2538             break;
2539 
2540         case SALEVENT_SHUTDOWN:
2541 			{
2542 				static bool bInQueryExit = false;
2543 				if( !bInQueryExit )
2544 				{
2545 					bInQueryExit = true;
2546 					if ( GetpApp()->QueryExit() )
2547 					{
2548 						// Message-Schleife beenden
2549 						Application::Quit();
2550 						return sal_False;
2551 					}
2552 					else
2553 					{
2554 						bInQueryExit = false;
2555 						return sal_True;
2556 					}
2557 				}
2558                 return sal_False;
2559 			}
2560 
2561         case SALEVENT_SETTINGSCHANGED:
2562         case SALEVENT_VOLUMECHANGED:
2563         case SALEVENT_PRINTERCHANGED:
2564         case SALEVENT_DISPLAYCHANGED:
2565         case SALEVENT_FONTCHANGED:
2566         case SALEVENT_DATETIMECHANGED:
2567         case SALEVENT_KEYBOARDCHANGED:
2568             ImplHandleSalSettings( pWindow, nEvent );
2569             break;
2570 
2571         case SALEVENT_USEREVENT:
2572             ImplHandleUserEvent( (ImplSVEvent*)pEvent );
2573             break;
2574 
2575         case SALEVENT_EXTTEXTINPUT:
2576             {
2577             SalExtTextInputEvent* pEvt = (SalExtTextInputEvent*)pEvent;
2578             nRet = ImplHandleExtTextInput( pWindow,
2579                                            pEvt->maText, pEvt->mpTextAttr,
2580                                            pEvt->mnCursorPos, pEvt->mnCursorFlags );
2581             }
2582             break;
2583         case SALEVENT_ENDEXTTEXTINPUT:
2584             nRet = ImplHandleEndExtTextInput( pWindow );
2585             break;
2586         case SALEVENT_EXTTEXTINPUTPOS:
2587             ImplHandleSalExtTextInputPos( pWindow, (SalExtTextInputPosEvent*)pEvent );
2588             break;
2589         case SALEVENT_INPUTCONTEXTCHANGE:
2590             nRet = ImplHandleInputContextChange( pWindow, ((SalInputContextChangeEvent*)pEvent)->meLanguage );
2591             break;
2592         case SALEVENT_SHOWDIALOG:
2593             {
2594                 int nDialogID = static_cast<int>(reinterpret_cast<sal_IntPtr>(pEvent));
2595                 nRet = ImplHandleShowDialog( pWindow, nDialogID );
2596             }
2597             break;
2598         case SALEVENT_SURROUNDINGTEXTREQUEST:
2599             ImplHandleSalSurroundingTextRequest( pWindow, (SalSurroundingTextRequestEvent*)pEvent );
2600             break;
2601         case SALEVENT_SURROUNDINGTEXTSELECTIONCHANGE:
2602         {
2603             SalSurroundingTextSelectionChangeEvent* pEvt
2604              = (SalSurroundingTextSelectionChangeEvent*)pEvent;
2605             ImplHandleSurroundingTextSelectionChange( pWindow,
2606 						      pEvt->mnStart,
2607 						      pEvt->mnEnd );
2608         }
2609         case SALEVENT_STARTRECONVERSION:
2610             ImplHandleStartReconversion( pWindow );
2611             break;
2612 #ifdef DBG_UTIL
2613         default:
2614             DBG_ERROR1( "ImplWindowFrameProc(): unknown event (%lu)", (sal_uLong)nEvent );
2615             break;
2616 #endif
2617     }
2618 
2619     return nRet;
2620 }
2621