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