xref: /AOO41X/main/vcl/source/window/window2.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <limits.h>
32 
33 #include <tools/debug.hxx>
34 #include <tools/poly.hxx>
35 
36 #include <vcl/bitmap.hxx>
37 #include <vcl/event.hxx>
38 #include <vcl/timer.hxx>
39 #include <vcl/metric.hxx>
40 #include <vcl/virdev.hxx>
41 #include <vcl/window.hxx>
42 #include <vcl/scrbar.hxx>
43 #include <vcl/dockwin.hxx>
44 
45 #include <window.h>
46 #include <outfont.hxx>
47 #include <outdev.h>
48 #include <svdata.hxx>
49 #include <impbmp.hxx>
50 #include <salbmp.hxx>
51 #include <salgdi.hxx>
52 #include <salframe.hxx>
53 #include <scrwnd.hxx>
54 
55 
56 // =======================================================================
57 
58 DBG_NAMEEX( Window )
59 
60 // =======================================================================
61 
62 #define IMPL_MAXSAVEBACKSIZE    (640*480)
63 #define IMPL_MAXALLSAVEBACKSIZE (800*600*2)
64 
65 // =======================================================================
66 
67 struct ImplFocusDelData : public ImplDelData
68 {
69     Window*         mpFocusWin;
70 };
71 
72 // =======================================================================
73 
74 sal_Bool Window::ImplIsWindowInFront( const Window* pTestWindow ) const
75 {
76     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
77     DBG_CHKOBJ( pTestWindow, Window, ImplDbgCheckWindow );
78 
79     // Testen, ob es Fenster untereinander liegen
80     pTestWindow = pTestWindow->ImplGetFirstOverlapWindow();
81     const Window* pTempWindow = pTestWindow;
82     const Window* pThisWindow = ImplGetFirstOverlapWindow();
83     if ( pTempWindow == pThisWindow )
84         return sal_False;
85     do
86     {
87         if ( pTempWindow == pThisWindow )
88             return sal_True;
89         if ( pTempWindow->mpWindowImpl->mbFrame )
90             break;
91         pTempWindow = pTempWindow->mpWindowImpl->mpOverlapWindow;
92     }
93     while ( pTempWindow );
94     pTempWindow = pThisWindow;
95     do
96     {
97         if ( pTempWindow == pTestWindow )
98             return sal_False;
99         if ( pTempWindow->mpWindowImpl->mbFrame )
100             break;
101         pTempWindow = pTempWindow->mpWindowImpl->mpOverlapWindow;
102     }
103     while ( pTempWindow );
104 
105     // Fenster auf gleiche Ebene bringen
106     if ( pThisWindow->mpWindowImpl->mpOverlapWindow != pTestWindow->mpWindowImpl->mpOverlapWindow )
107     {
108         sal_uInt16 nThisLevel = 0;
109         sal_uInt16 nTestLevel = 0;
110         pTempWindow = pThisWindow;
111         do
112         {
113             nThisLevel++;
114             pTempWindow = pTempWindow->mpWindowImpl->mpOverlapWindow;
115         }
116         while ( !pTempWindow->mpWindowImpl->mbFrame );
117         pTempWindow = pTestWindow;
118         do
119         {
120             nTestLevel++;
121             pTempWindow = pTempWindow->mpWindowImpl->mpOverlapWindow;
122         }
123         while ( !pTempWindow->mpWindowImpl->mbFrame );
124 
125         if ( nThisLevel < nTestLevel )
126         {
127             do
128             {
129                 if ( pTestWindow->mpWindowImpl->mpOverlapWindow == pThisWindow->mpWindowImpl->mpOverlapWindow )
130                     break;
131                 if ( pTestWindow->mpWindowImpl->mbFrame )
132                     break;
133                 pTestWindow = pTestWindow->mpWindowImpl->mpOverlapWindow;
134             }
135             while ( pTestWindow );
136         }
137         else
138         {
139             do
140             {
141                 if ( pThisWindow->mpWindowImpl->mpOverlapWindow == pTempWindow->mpWindowImpl->mpOverlapWindow )
142                     break;
143                 if ( pThisWindow->mpWindowImpl->mbFrame )
144                     break;
145                 pThisWindow = pThisWindow->mpWindowImpl->mpOverlapWindow;
146             }
147             while ( pThisWindow );
148         }
149     }
150 
151     // Wenn TestWindow vor ThisWindow kommt, liegt es vorne
152     pTempWindow = pTestWindow;
153     do
154     {
155         if ( pTempWindow == pThisWindow )
156             return sal_True;
157         pTempWindow = pTempWindow->mpWindowImpl->mpNext;
158     }
159     while ( pTempWindow );
160 
161     return sal_False;
162 }
163 
164 // =======================================================================
165 
166 void Window::ImplSaveOverlapBackground()
167 {
168     DBG_ASSERT( !mpWindowImpl->mpOverlapData->mpSaveBackDev, "Window::ImplSaveOverlapBackground() - Background already saved" );
169 
170     if ( !mpWindowImpl->mbFrame )
171     {
172         sal_uLong nSaveBackSize = mnOutWidth*mnOutHeight;
173         if ( nSaveBackSize <= IMPL_MAXSAVEBACKSIZE )
174         {
175             if ( nSaveBackSize+mpWindowImpl->mpFrameData->mnAllSaveBackSize <= IMPL_MAXALLSAVEBACKSIZE )
176             {
177                 Size aOutSize( mnOutWidth, mnOutHeight );
178                 mpWindowImpl->mpOverlapData->mpSaveBackDev = new VirtualDevice( *mpWindowImpl->mpFrameWindow );
179                 if ( mpWindowImpl->mpOverlapData->mpSaveBackDev->SetOutputSizePixel( aOutSize ) )
180                 {
181                     mpWindowImpl->mpFrameWindow->ImplUpdateAll();
182 
183                     if ( mpWindowImpl->mbInitWinClipRegion )
184                         ImplInitWinClipRegion();
185 
186                     mpWindowImpl->mpOverlapData->mnSaveBackSize = nSaveBackSize;
187                     mpWindowImpl->mpFrameData->mnAllSaveBackSize += nSaveBackSize;
188                     Point aDevPt;
189                     mpWindowImpl->mpFrameWindow->ImplGetFrameDev( Point( mnOutOffX, mnOutOffY ),
190                                                     aDevPt, aOutSize,
191                                                     *(mpWindowImpl->mpOverlapData->mpSaveBackDev) );
192                     mpWindowImpl->mpOverlapData->mpNextBackWin = mpWindowImpl->mpFrameData->mpFirstBackWin;
193                     mpWindowImpl->mpFrameData->mpFirstBackWin = this;
194                 }
195                 else
196                 {
197                     delete mpWindowImpl->mpOverlapData->mpSaveBackDev;
198                     mpWindowImpl->mpOverlapData->mpSaveBackDev = NULL;
199                 }
200             }
201         }
202     }
203 }
204 
205 // -----------------------------------------------------------------------
206 
207 sal_Bool Window::ImplRestoreOverlapBackground( Region& rInvRegion )
208 {
209     if ( mpWindowImpl->mpOverlapData->mpSaveBackDev )
210     {
211         if ( mpWindowImpl->mbInitWinClipRegion )
212             ImplInitWinClipRegion();
213 
214         if ( mpWindowImpl->mpOverlapData->mpSaveBackDev )
215         {
216             Point   aDevPt;
217             Point   aDestPt( mnOutOffX, mnOutOffY );
218             Size    aDevSize = mpWindowImpl->mpOverlapData->mpSaveBackDev->GetOutputSizePixel();
219             if ( mpWindowImpl->mpOverlapData->mpSaveBackRgn )
220             {
221                 mpWindowImpl->mpOverlapData->mpSaveBackRgn->Intersect( mpWindowImpl->maWinClipRegion );
222                 rInvRegion = mpWindowImpl->maWinClipRegion;
223                 rInvRegion.Exclude( *mpWindowImpl->mpOverlapData->mpSaveBackRgn );
224                 mpWindowImpl->mpFrameWindow->ImplDrawFrameDev( aDestPt, aDevPt, aDevSize,
225                                                  *(mpWindowImpl->mpOverlapData->mpSaveBackDev),
226                                                  *mpWindowImpl->mpOverlapData->mpSaveBackRgn );
227             }
228             else
229             {
230                 mpWindowImpl->mpFrameWindow->ImplDrawFrameDev( aDestPt, aDevPt, aDevSize,
231                                                  *(mpWindowImpl->mpOverlapData->mpSaveBackDev),
232                                                  mpWindowImpl->maWinClipRegion );
233             }
234             ImplDeleteOverlapBackground();
235         }
236 
237         return sal_True;
238     }
239 
240     return sal_False;
241 }
242 
243 // -----------------------------------------------------------------------
244 
245 void Window::ImplDeleteOverlapBackground()
246 {
247     if ( mpWindowImpl->mpOverlapData->mpSaveBackDev )
248     {
249         mpWindowImpl->mpFrameData->mnAllSaveBackSize -= mpWindowImpl->mpOverlapData->mnSaveBackSize;
250         delete mpWindowImpl->mpOverlapData->mpSaveBackDev;
251         mpWindowImpl->mpOverlapData->mpSaveBackDev = NULL;
252         if ( mpWindowImpl->mpOverlapData->mpSaveBackRgn )
253         {
254             delete mpWindowImpl->mpOverlapData->mpSaveBackRgn;
255             mpWindowImpl->mpOverlapData->mpSaveBackRgn = NULL;
256         }
257 
258         // Fenster aus der Liste entfernen
259         if ( mpWindowImpl->mpFrameData->mpFirstBackWin == this )
260             mpWindowImpl->mpFrameData->mpFirstBackWin = mpWindowImpl->mpOverlapData->mpNextBackWin;
261         else
262         {
263             Window* pTemp = mpWindowImpl->mpFrameData->mpFirstBackWin;
264             while ( pTemp->mpWindowImpl->mpOverlapData->mpNextBackWin != this )
265                 pTemp = pTemp->mpWindowImpl->mpOverlapData->mpNextBackWin;
266             pTemp->mpWindowImpl->mpOverlapData->mpNextBackWin = mpWindowImpl->mpOverlapData->mpNextBackWin;
267         }
268         mpWindowImpl->mpOverlapData->mpNextBackWin = NULL;
269     }
270 }
271 
272 // -----------------------------------------------------------------------
273 
274 void Window::ImplInvalidateAllOverlapBackgrounds()
275 {
276     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
277 
278     Window* pWindow = mpWindowImpl->mpFrameData->mpFirstBackWin;
279     while ( pWindow )
280     {
281         // Naechstes Fenster schon hier merken, da dieses Fenster in
282         // der if-Abfrage aus der Liste entfernt werden kann
283         Window* pNext = pWindow->mpWindowImpl->mpOverlapData->mpNextBackWin;
284 
285         if ( ImplIsWindowInFront( pWindow ) )
286         {
287             Rectangle aRect1( Point( mnOutOffX, mnOutOffY ),
288                               Size( mnOutWidth, mnOutHeight ) );
289             Rectangle aRect2( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
290                               Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
291             aRect1.Intersection( aRect2 );
292             if ( !aRect1.IsEmpty() )
293             {
294                 if ( !pWindow->mpWindowImpl->mpOverlapData->mpSaveBackRgn )
295                     pWindow->mpWindowImpl->mpOverlapData->mpSaveBackRgn = new Region( aRect2 );
296                 pWindow->mpWindowImpl->mpOverlapData->mpSaveBackRgn->Exclude( aRect1 );
297                 if ( pWindow->mpWindowImpl->mpOverlapData->mpSaveBackRgn->IsEmpty() )
298                     pWindow->ImplDeleteOverlapBackground();
299             }
300 
301         }
302 
303         pWindow = pNext;
304     }
305 }
306 
307 // =======================================================================
308 
309 Bitmap Window::SnapShot( sal_Bool bBorder ) const
310 {
311     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
312 
313     Bitmap aBmp;
314 
315     if ( IsReallyVisible() )
316     {
317         if ( bBorder && mpWindowImpl->mpBorderWindow )
318             aBmp = mpWindowImpl->mpBorderWindow->SnapShot();
319         else
320         {
321             ((Window*)this)->Update();
322 
323             if ( bBorder && mpWindowImpl->mbFrame )
324             {
325                 SalBitmap* pSalBmp = mpWindowImpl->mpFrame->SnapShot();
326 
327                 if ( pSalBmp )
328                 {
329                     ImpBitmap* pImpBmp = new ImpBitmap;
330                     pImpBmp->ImplSetSalBitmap( pSalBmp );
331                     aBmp.ImplSetImpBitmap( pImpBmp );
332                     return aBmp;
333                 }
334             }
335 
336             mpWindowImpl->mpFrameWindow->ImplGetFrameBitmap( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ), aBmp );
337         }
338     }
339 
340     return aBmp;
341 }
342 
343 // -----------------------------------------------------------------------
344 
345 Bitmap Window::SnapShot() const
346 {
347     // Should be merged in the next top level build !!!
348     return SnapShot( sal_True );
349 }
350 
351 // -----------------------------------------------------------------------
352 
353 void Window::ShowFocus( const Rectangle& rRect )
354 {
355     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
356 
357     if( mpWindowImpl->mbInShowFocus )
358         return;
359     mpWindowImpl->mbInShowFocus = sal_True;
360 
361     ImplWinData* pWinData = ImplGetWinData();
362 
363     // native themeing suggest not to use focus rects
364     if( ! ( mpWindowImpl->mbUseNativeFocus &&
365             IsNativeWidgetEnabled() ) )
366     {
367         if ( !mpWindowImpl->mbInPaint )
368         {
369             if ( mpWindowImpl->mbFocusVisible )
370             {
371                 if ( *(pWinData->mpFocusRect) == rRect )
372                 {
373                     mpWindowImpl->mbInShowFocus = sal_False;
374                     return;
375                 }
376 
377                 ImplInvertFocus( *(pWinData->mpFocusRect) );
378             }
379 
380             ImplInvertFocus( rRect );
381         }
382         if ( !pWinData->mpFocusRect )
383             pWinData->mpFocusRect = new Rectangle( rRect );
384         else
385             *(pWinData->mpFocusRect) = rRect;
386         mpWindowImpl->mbFocusVisible = sal_True;
387     }
388     else
389     {
390         if( ! mpWindowImpl->mbNativeFocusVisible )
391         {
392             mpWindowImpl->mbNativeFocusVisible = sal_True;
393             if ( !mpWindowImpl->mbInPaint )
394                 Invalidate();
395         }
396     }
397     mpWindowImpl->mbInShowFocus = sal_False;
398 }
399 
400 // -----------------------------------------------------------------------
401 
402 void Window::HideFocus()
403 {
404     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
405 
406     if( mpWindowImpl->mbInHideFocus )
407         return;
408     mpWindowImpl->mbInHideFocus = sal_True;
409 
410     // native themeing can suggest not to use focus rects
411     if( ! ( mpWindowImpl->mbUseNativeFocus &&
412             IsNativeWidgetEnabled() ) )
413     {
414         if ( !mpWindowImpl->mbFocusVisible )
415         {
416             mpWindowImpl->mbInHideFocus = sal_False;
417             return;
418         }
419 
420         if ( !mpWindowImpl->mbInPaint )
421             ImplInvertFocus( *(ImplGetWinData()->mpFocusRect) );
422         mpWindowImpl->mbFocusVisible = sal_False;
423     }
424     else
425     {
426         if( mpWindowImpl->mbNativeFocusVisible )
427         {
428             mpWindowImpl->mbNativeFocusVisible = sal_False;
429             if ( !mpWindowImpl->mbInPaint )
430                 Invalidate();
431         }
432     }
433     mpWindowImpl->mbInHideFocus = sal_False;
434 }
435 
436 // -----------------------------------------------------------------------
437 
438 void Window::Invert( const Rectangle& rRect, sal_uInt16 nFlags )
439 {
440     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
441 
442     if ( !IsDeviceOutputNecessary() )
443         return;
444 
445     Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
446 
447     if ( aRect.IsEmpty() )
448         return;
449     aRect.Justify();
450 
451     // we need a graphics
452     if ( !mpGraphics )
453     {
454         if ( !ImplGetGraphics() )
455             return;
456     }
457 
458     if ( mbInitClipRegion )
459         ImplInitClipRegion();
460 
461     if ( mbOutputClipped )
462         return;
463 
464     SalInvert nSalFlags = 0;
465     if ( nFlags & INVERT_HIGHLIGHT )
466         nSalFlags |= SAL_INVERT_HIGHLIGHT;
467     if ( nFlags & INVERT_50 )
468         nSalFlags |= SAL_INVERT_50;
469     mpGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), nSalFlags, this );
470 }
471 
472 // -----------------------------------------------------------------------
473 
474 void Window::Invert( const Polygon& rPoly, sal_uInt16 nFlags )
475 {
476     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
477 
478     if ( !IsDeviceOutputNecessary() )
479         return;
480 
481     sal_uInt16 nPoints = rPoly.GetSize();
482 
483     if ( nPoints < 2 )
484         return;
485 
486     Polygon aPoly( ImplLogicToDevicePixel( rPoly ) );
487 
488     // we need a graphics
489     if ( !mpGraphics )
490     {
491         if ( !ImplGetGraphics() )
492             return;
493     }
494 
495     if ( mbInitClipRegion )
496         ImplInitClipRegion();
497 
498     if ( mbOutputClipped )
499         return;
500 
501     SalInvert nSalFlags = 0;
502     if ( nFlags & INVERT_HIGHLIGHT )
503         nSalFlags |= SAL_INVERT_HIGHLIGHT;
504     if ( nFlags & INVERT_50 )
505         nSalFlags |= SAL_INVERT_50;
506     const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
507     mpGraphics->Invert( nPoints, pPtAry, nSalFlags, this );
508 }
509 
510 // -----------------------------------------------------------------------
511 
512 void Window::ShowTracking( const Rectangle& rRect, sal_uInt16 nFlags )
513 {
514     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
515 
516     ImplWinData* pWinData = ImplGetWinData();
517 
518     if ( !mpWindowImpl->mbInPaint || !(nFlags & SHOWTRACK_WINDOW) )
519     {
520         if ( mpWindowImpl->mbTrackVisible )
521         {
522             if ( (*(pWinData->mpTrackRect)  == rRect) &&
523                  (pWinData->mnTrackFlags    == nFlags) )
524                 return;
525 
526             InvertTracking( *(pWinData->mpTrackRect), pWinData->mnTrackFlags );
527         }
528 
529         InvertTracking( rRect, nFlags );
530     }
531 
532     if ( !pWinData->mpTrackRect )
533         pWinData->mpTrackRect = new Rectangle( rRect );
534     else
535         *(pWinData->mpTrackRect) = rRect;
536     pWinData->mnTrackFlags      = nFlags;
537     mpWindowImpl->mbTrackVisible              = sal_True;
538 }
539 
540 // -----------------------------------------------------------------------
541 
542 void Window::HideTracking()
543 {
544     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
545 
546     if ( mpWindowImpl->mbTrackVisible )
547     {
548         ImplWinData* pWinData = ImplGetWinData();
549         if ( !mpWindowImpl->mbInPaint || !(pWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
550             InvertTracking( *(pWinData->mpTrackRect), pWinData->mnTrackFlags );
551         mpWindowImpl->mbTrackVisible = sal_False;
552     }
553 }
554 
555 // -----------------------------------------------------------------------
556 
557 void Window::InvertTracking( const Rectangle& rRect, sal_uInt16 nFlags )
558 {
559     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
560 
561     Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
562 
563     if ( aRect.IsEmpty() )
564         return;
565     aRect.Justify();
566 
567     SalGraphics* pGraphics;
568 
569     if ( nFlags & SHOWTRACK_WINDOW )
570     {
571         if ( !IsDeviceOutputNecessary() )
572             return;
573 
574         // we need a graphics
575         if ( !mpGraphics )
576         {
577             if ( !ImplGetGraphics() )
578                 return;
579         }
580 
581         if ( mbInitClipRegion )
582             ImplInitClipRegion();
583 
584         if ( mbOutputClipped )
585             return;
586 
587         pGraphics = mpGraphics;
588     }
589     else
590     {
591         pGraphics = ImplGetFrameGraphics();
592 
593         if ( nFlags & SHOWTRACK_CLIP )
594         {
595             Point aPoint( mnOutOffX, mnOutOffY );
596             Region aRegion( Rectangle( aPoint,
597                                        Size( mnOutWidth, mnOutHeight ) ) );
598             ImplClipBoundaries( aRegion, sal_False, sal_False );
599             ImplSelectClipRegion( aRegion, pGraphics );
600         }
601     }
602 
603     sal_uInt16 nStyle = nFlags & SHOWTRACK_STYLE;
604     if ( nStyle == SHOWTRACK_OBJECT )
605         pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SAL_INVERT_TRACKFRAME, this );
606     else if ( nStyle == SHOWTRACK_SPLIT )
607         pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), SAL_INVERT_50, this );
608     else
609     {
610         long nBorder = 1;
611         if ( nStyle == SHOWTRACK_BIG )
612             nBorder = 5;
613         pGraphics->Invert( aRect.Left(), aRect.Top(), aRect.GetWidth(), nBorder, SAL_INVERT_50, this );
614         pGraphics->Invert( aRect.Left(), aRect.Bottom()-nBorder+1, aRect.GetWidth(), nBorder, SAL_INVERT_50, this );
615         pGraphics->Invert( aRect.Left(), aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SAL_INVERT_50, this );
616         pGraphics->Invert( aRect.Right()-nBorder+1, aRect.Top()+nBorder, nBorder, aRect.GetHeight()-(nBorder*2), SAL_INVERT_50, this );
617     }
618 }
619 
620 // -----------------------------------------------------------------------
621 
622 void Window::InvertTracking( const Polygon& rPoly, sal_uInt16 nFlags )
623 {
624     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
625 
626     sal_uInt16 nPoints = rPoly.GetSize();
627 
628     if ( nPoints < 2 )
629         return;
630 
631     Polygon aPoly( ImplLogicToDevicePixel( rPoly ) );
632 
633     SalGraphics* pGraphics;
634 
635     if ( nFlags & SHOWTRACK_WINDOW )
636     {
637         if ( !IsDeviceOutputNecessary() )
638             return;
639 
640         // we need a graphics
641         if ( !mpGraphics )
642         {
643             if ( !ImplGetGraphics() )
644                 return;
645         }
646 
647         if ( mbInitClipRegion )
648             ImplInitClipRegion();
649 
650         if ( mbOutputClipped )
651             return;
652 
653         pGraphics = mpGraphics;
654     }
655     else
656     {
657         pGraphics = ImplGetFrameGraphics();
658 
659         if ( nFlags & SHOWTRACK_CLIP )
660         {
661             Point aPoint( mnOutOffX, mnOutOffY );
662             Region aRegion( Rectangle( aPoint,
663                                        Size( mnOutWidth, mnOutHeight ) ) );
664             ImplClipBoundaries( aRegion, sal_False, sal_False );
665             ImplSelectClipRegion( aRegion, pGraphics );
666         }
667     }
668 
669     const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
670     pGraphics->Invert( nPoints, pPtAry, SAL_INVERT_TRACKFRAME, this );
671 }
672 
673 // -----------------------------------------------------------------------
674 
675 IMPL_LINK( Window, ImplTrackTimerHdl, Timer*, pTimer )
676 {
677     ImplSVData* pSVData = ImplGetSVData();
678 
679     // Bei Button-Repeat muessen wir den Timeout umsetzen
680     if ( pSVData->maWinData.mnTrackFlags & STARTTRACK_BUTTONREPEAT )
681         pTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonRepeat() );
682 
683     // Tracking-Event erzeugen
684     Point           aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
685     if( ImplIsAntiparallel() )
686     {
687         // - RTL - re-mirror frame pos at pChild
688         ImplReMirror( aMousePos );
689     }
690     MouseEvent      aMEvt( ImplFrameToOutput( aMousePos ),
691                            mpWindowImpl->mpFrameData->mnClickCount, 0,
692                            mpWindowImpl->mpFrameData->mnMouseCode, mpWindowImpl->mpFrameData->mnMouseCode );
693     TrackingEvent   aTEvt( aMEvt, TRACKING_REPEAT );
694     Tracking( aTEvt );
695 
696     return 0;
697 }
698 
699 // -----------------------------------------------------------------------
700 
701 void Window::StartTracking( sal_uInt16 nFlags )
702 {
703     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
704 
705     ImplSVData* pSVData = ImplGetSVData();
706 
707     if ( pSVData->maWinData.mpTrackWin != this )
708     {
709         if ( pSVData->maWinData.mpTrackWin )
710             pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL );
711     }
712 
713     if ( nFlags & (STARTTRACK_SCROLLREPEAT | STARTTRACK_BUTTONREPEAT) )
714     {
715         pSVData->maWinData.mpTrackTimer = new AutoTimer;
716 
717         if ( nFlags & STARTTRACK_SCROLLREPEAT )
718             pSVData->maWinData.mpTrackTimer->SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() );
719         else
720             pSVData->maWinData.mpTrackTimer->SetTimeout( GetSettings().GetMouseSettings().GetButtonStartRepeat() );
721         pSVData->maWinData.mpTrackTimer->SetTimeoutHdl( LINK( this, Window, ImplTrackTimerHdl ) );
722         pSVData->maWinData.mpTrackTimer->Start();
723     }
724 
725     pSVData->maWinData.mpTrackWin   = this;
726     pSVData->maWinData.mnTrackFlags = nFlags;
727     CaptureMouse();
728 }
729 
730 // -----------------------------------------------------------------------
731 
732 void Window::EndTracking( sal_uInt16 nFlags )
733 {
734     ImplSVData* pSVData = ImplGetSVData();
735 
736     if ( pSVData->maWinData.mpTrackWin == this )
737     {
738         // Hier wegen DbgChkThis geklammert, da Window im Handler zerstoert
739         // werden kann
740         {
741         DBG_CHKTHIS( Window, ImplDbgCheckWindow );
742 
743         if ( pSVData->maWinData.mpTrackTimer )
744         {
745             delete pSVData->maWinData.mpTrackTimer;
746             pSVData->maWinData.mpTrackTimer = NULL;
747         }
748 
749         pSVData->maWinData.mpTrackWin    = NULL;
750         pSVData->maWinData.mnTrackFlags  = 0;
751         ReleaseMouse();
752         }
753 
754         // EndTracking rufen, wenn es gerufen werden soll
755         if ( !(nFlags & ENDTRACK_DONTCALLHDL) )
756         {
757             Point           aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
758             if( ImplIsAntiparallel() )
759             {
760                 // - RTL - re-mirror frame pos at pChild
761                 ImplReMirror( aMousePos );
762             }
763 
764             MouseEvent      aMEvt( ImplFrameToOutput( aMousePos ),
765                                    mpWindowImpl->mpFrameData->mnClickCount, 0,
766                                    mpWindowImpl->mpFrameData->mnMouseCode, mpWindowImpl->mpFrameData->mnMouseCode );
767             TrackingEvent   aTEvt( aMEvt, nFlags | ENDTRACK_END );
768             Tracking( aTEvt );
769         }
770     }
771 }
772 
773 // -----------------------------------------------------------------------
774 
775 sal_Bool Window::IsTracking() const
776 {
777     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
778 
779     return (ImplGetSVData()->maWinData.mpTrackWin == this);
780 }
781 
782 // -----------------------------------------------------------------------
783 
784 void Window::StartAutoScroll( sal_uInt16 nFlags )
785 {
786     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
787 
788     ImplSVData* pSVData = ImplGetSVData();
789 
790     if ( pSVData->maWinData.mpAutoScrollWin != this )
791     {
792         if ( pSVData->maWinData.mpAutoScrollWin )
793             pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
794     }
795 
796     pSVData->maWinData.mpAutoScrollWin = this;
797     pSVData->maWinData.mnAutoScrollFlags = nFlags;
798     pSVData->maAppData.mpWheelWindow = new ImplWheelWindow( this );
799 }
800 
801 // -----------------------------------------------------------------------
802 
803 void Window::EndAutoScroll()
804 {
805     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
806 
807     ImplSVData* pSVData = ImplGetSVData();
808 
809     if ( pSVData->maWinData.mpAutoScrollWin == this )
810     {
811         pSVData->maWinData.mpAutoScrollWin = NULL;
812         pSVData->maWinData.mnAutoScrollFlags = 0;
813         pSVData->maAppData.mpWheelWindow->ImplStop();
814         pSVData->maAppData.mpWheelWindow->doLazyDelete();
815         pSVData->maAppData.mpWheelWindow = NULL;
816     }
817 }
818 
819 // -----------------------------------------------------------------------
820 
821 sal_Bool Window::IsAutoScroll() const
822 {
823     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
824 
825     return (ImplGetSVData()->maWinData.mpAutoScrollWin == this);
826 }
827 
828 // -----------------------------------------------------------------------
829 
830 void Window::SaveBackground( const Point& rPos, const Size& rSize,
831                              const Point& rDestOff, VirtualDevice& rSaveDevice )
832 {
833     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
834 
835     if ( mpWindowImpl->mpPaintRegion )
836     {
837         Region      aClip( *mpWindowImpl->mpPaintRegion );
838         const Point aPixPos( LogicToPixel( rPos ) );
839 
840         aClip.Move( -mnOutOffX, -mnOutOffY );
841         aClip.Intersect( Rectangle( aPixPos, LogicToPixel( rSize ) ) );
842 
843         if ( !aClip.IsEmpty() )
844         {
845             const Region    aOldClip( rSaveDevice.GetClipRegion() );
846             const Point     aPixOffset( rSaveDevice.LogicToPixel( rDestOff ) );
847             const sal_Bool      bMap = rSaveDevice.IsMapModeEnabled();
848 
849             // move clip region to have the same distance to DestOffset
850             aClip.Move( aPixOffset.X() - aPixPos.X(), aPixOffset.Y() - aPixPos.Y() );
851 
852             // set pixel clip region
853             rSaveDevice.EnableMapMode( sal_False );
854             rSaveDevice.SetClipRegion( aClip );
855             rSaveDevice.EnableMapMode( bMap );
856             rSaveDevice.DrawOutDev( rDestOff, rSize, rPos, rSize, *this );
857             rSaveDevice.SetClipRegion( aOldClip );
858         }
859     }
860     else
861         rSaveDevice.DrawOutDev( rDestOff, rSize, rPos, rSize, *this );
862 }
863 
864 // -----------------------------------------------------------------------
865 
866 sal_uIntPtr Window::SaveFocus()
867 {
868     ImplSVData* pSVData = ImplGetSVData();
869     if ( pSVData->maWinData.mpFocusWin )
870     {
871         ImplFocusDelData* pDelData = new ImplFocusDelData;
872         pSVData->maWinData.mpFocusWin->ImplAddDel( pDelData );
873         pDelData->mpFocusWin = pSVData->maWinData.mpFocusWin;
874         return (sal_uIntPtr)(void*)pDelData;
875     }
876     else
877         return 0;
878 }
879 
880 // -----------------------------------------------------------------------
881 
882 sal_Bool Window::EndSaveFocus( sal_uIntPtr nSaveId, sal_Bool bRestore )
883 {
884     if ( !nSaveId )
885         return sal_False;
886     else
887     {
888         sal_Bool                bOK = sal_True;
889         ImplFocusDelData*   pDelData = (ImplFocusDelData*)(void*)nSaveId;
890         if ( !pDelData->IsDelete() )
891         {
892             pDelData->mpFocusWin->ImplRemoveDel( pDelData );
893             if ( bRestore )
894                 pDelData->mpFocusWin->GrabFocus();
895         }
896         else
897             bOK = !bRestore;
898         delete pDelData;
899         return bOK;
900     }
901 }
902 
903 // -----------------------------------------------------------------------
904 
905 void Window::SetZoom( const Fraction& rZoom )
906 {
907     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
908 
909     if ( mpWindowImpl->maZoom != rZoom )
910     {
911         mpWindowImpl->maZoom = rZoom;
912         StateChanged( STATE_CHANGE_ZOOM );
913     }
914 }
915 
916 // -----------------------------------------------------------------------
917 
918 inline long WinFloatRound( double fVal )
919 {
920     return( fVal > 0.0 ? (long) ( fVal + 0.5 ) : -(long) ( -fVal + 0.5 ) );
921 }
922 
923 // -----------------------------------------------------------------------
924 
925 void Window::SetZoomedPointFont( const Font& rFont )
926 {
927     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
928 
929     const Fraction& rZoom = GetZoom();
930     if ( rZoom.GetNumerator() != rZoom.GetDenominator() )
931     {
932         Font aFont( rFont );
933         Size aSize = aFont.GetSize();
934         double n = (double)aSize.Width();
935         n *= (double)rZoom.GetNumerator();
936         n /= (double)rZoom.GetDenominator();
937         aSize.Width() = WinFloatRound( n );
938         n = (double)aSize.Height();
939         n *= (double)rZoom.GetNumerator();
940         n /= (double)rZoom.GetDenominator();
941         aSize.Height() = WinFloatRound( n );
942         aFont.SetSize( aSize );
943         SetPointFont( aFont );
944 
945         // Wenn Darstellung skaliert wird, nehmen wir gegebenenfalls
946         // einen anderen Font, wenn der aktuelle nicht skalierbar ist
947         FontMetric aMetric = GetFontMetric();
948         long       nFontDiff = Abs( GetFont().GetSize().Height()-aMetric.GetSize().Height() );
949         if ( (aMetric.GetType() == TYPE_RASTER) && (nFontDiff >= 2) )
950         {
951             sal_uInt16 nType;
952             if ( aMetric.GetPitch() == PITCH_FIXED )
953                 nType = DEFAULTFONT_FIXED;
954             else
955                 nType = DEFAULTFONT_UI_SANS;
956             Font aTempFont = GetDefaultFont( nType, GetSettings().GetLanguage(), 0 );
957             aFont.SetName( aTempFont.GetName() );
958             SetPointFont( aFont );
959         }
960     }
961     else
962         SetPointFont( rFont );
963 }
964 
965 // -----------------------------------------------------------------------
966 
967 long Window::CalcZoom( long nCalc ) const
968 {
969     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
970 
971     const Fraction& rZoom = GetZoom();
972     if ( rZoom.GetNumerator() != rZoom.GetDenominator() )
973     {
974         double n = (double)nCalc;
975         n *= (double)rZoom.GetNumerator();
976         n /= (double)rZoom.GetDenominator();
977         nCalc = WinFloatRound( n );
978     }
979     return nCalc;
980 }
981 
982 // -----------------------------------------------------------------------
983 
984 void Window::SetControlFont()
985 {
986     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
987 
988     if ( mpWindowImpl->mpControlFont )
989     {
990         delete mpWindowImpl->mpControlFont;
991         mpWindowImpl->mpControlFont = NULL;
992         StateChanged( STATE_CHANGE_CONTROLFONT );
993     }
994 }
995 
996 // -----------------------------------------------------------------------
997 
998 void Window::SetControlFont( const Font& rFont )
999 {
1000     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
1001 
1002     if ( rFont == Font() )
1003     {
1004         SetControlFont();
1005         return;
1006     }
1007 
1008     if ( mpWindowImpl->mpControlFont )
1009     {
1010         if ( *mpWindowImpl->mpControlFont == rFont )
1011             return;
1012         *mpWindowImpl->mpControlFont = rFont;
1013     }
1014     else
1015         mpWindowImpl->mpControlFont = new Font( rFont );
1016 
1017     StateChanged( STATE_CHANGE_CONTROLFONT );
1018 }
1019 
1020 // -----------------------------------------------------------------------
1021 
1022 Font Window::GetControlFont() const
1023 {
1024     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
1025 
1026     if ( mpWindowImpl->mpControlFont )
1027         return *mpWindowImpl->mpControlFont;
1028     else
1029     {
1030         Font aFont;
1031         return aFont;
1032     }
1033 }
1034 
1035 // -----------------------------------------------------------------------
1036 
1037 void Window::SetControlForeground()
1038 {
1039     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
1040 
1041     if ( mpWindowImpl->mbControlForeground )
1042     {
1043         mpWindowImpl->maControlForeground = Color( COL_TRANSPARENT );
1044         mpWindowImpl->mbControlForeground = sal_False;
1045         StateChanged( STATE_CHANGE_CONTROLFOREGROUND );
1046     }
1047 }
1048 
1049 // -----------------------------------------------------------------------
1050 
1051 void Window::SetControlForeground( const Color& rColor )
1052 {
1053     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
1054 
1055     if ( rColor.GetTransparency() )
1056     {
1057         if ( mpWindowImpl->mbControlForeground )
1058         {
1059             mpWindowImpl->maControlForeground = Color( COL_TRANSPARENT );
1060             mpWindowImpl->mbControlForeground = sal_False;
1061             StateChanged( STATE_CHANGE_CONTROLFOREGROUND );
1062         }
1063     }
1064     else
1065     {
1066         if ( mpWindowImpl->maControlForeground != rColor )
1067         {
1068             mpWindowImpl->maControlForeground = rColor;
1069             mpWindowImpl->mbControlForeground = sal_True;
1070             StateChanged( STATE_CHANGE_CONTROLFOREGROUND );
1071         }
1072     }
1073 }
1074 
1075 // -----------------------------------------------------------------------
1076 
1077 void Window::SetControlBackground()
1078 {
1079     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
1080 
1081     if ( mpWindowImpl->mbControlBackground )
1082     {
1083         mpWindowImpl->maControlBackground = Color( COL_TRANSPARENT );
1084         mpWindowImpl->mbControlBackground = sal_False;
1085         StateChanged( STATE_CHANGE_CONTROLBACKGROUND );
1086     }
1087 }
1088 
1089 // -----------------------------------------------------------------------
1090 
1091 void Window::SetControlBackground( const Color& rColor )
1092 {
1093     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
1094 
1095     if ( rColor.GetTransparency() )
1096     {
1097         if ( mpWindowImpl->mbControlBackground )
1098         {
1099             mpWindowImpl->maControlBackground = Color( COL_TRANSPARENT );
1100             mpWindowImpl->mbControlBackground = sal_False;
1101             StateChanged( STATE_CHANGE_CONTROLBACKGROUND );
1102         }
1103     }
1104     else
1105     {
1106         if ( mpWindowImpl->maControlBackground != rColor )
1107         {
1108             mpWindowImpl->maControlBackground = rColor;
1109             mpWindowImpl->mbControlBackground = sal_True;
1110             StateChanged( STATE_CHANGE_CONTROLBACKGROUND );
1111         }
1112     }
1113 }
1114 
1115 // -----------------------------------------------------------------------
1116 
1117 Size Window::CalcWindowSize( const Size& rOutSz ) const
1118 {
1119     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
1120 
1121     Size aSz = rOutSz;
1122     aSz.Width()  += mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder;
1123     aSz.Height() += mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder;
1124     return aSz;
1125 }
1126 
1127 // -----------------------------------------------------------------------
1128 
1129 Size Window::CalcOutputSize( const Size& rWinSz ) const
1130 {
1131     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
1132 
1133     Size aSz = rWinSz;
1134     aSz.Width()  -= mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder;
1135     aSz.Height() -= mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder;
1136     return aSz;
1137 }
1138 
1139 // -----------------------------------------------------------------------
1140 
1141 Font Window::GetDrawPixelFont( OutputDevice* pDev ) const
1142 {
1143     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
1144 
1145     Font    aFont = GetPointFont();
1146     Size    aFontSize = aFont.GetSize();
1147     MapMode aPtMapMode( MAP_POINT );
1148     aFontSize = pDev->LogicToPixel( aFontSize, aPtMapMode );
1149     aFont.SetSize( aFontSize );
1150     return aFont;
1151 }
1152 
1153 // -----------------------------------------------------------------------
1154 
1155 long Window::GetDrawPixel( OutputDevice* pDev, long nPixels ) const
1156 {
1157     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
1158 
1159     long nP = nPixels;
1160     if ( pDev->GetOutDevType() != OUTDEV_WINDOW )
1161     {
1162         MapMode aMap( MAP_100TH_MM );
1163         Size aSz( nP, 0 );
1164         aSz = PixelToLogic( aSz, aMap );
1165         aSz = pDev->LogicToPixel( aSz, aMap );
1166         nP = aSz.Width();
1167     }
1168     return nP;
1169 }
1170 
1171 // -----------------------------------------------------------------------
1172 
1173 sal_Bool Window::HandleScrollCommand( const CommandEvent& rCmd,
1174                                   ScrollBar* pHScrl, ScrollBar* pVScrl )
1175 {
1176     DBG_CHKTHIS( Window, ImplDbgCheckWindow );
1177 
1178     sal_Bool bRet = sal_False;
1179 
1180     if ( pHScrl || pVScrl )
1181     {
1182         switch( rCmd.GetCommand() )
1183         {
1184             case COMMAND_STARTAUTOSCROLL:
1185             {
1186                 sal_uInt16 nFlags = 0;
1187                 if ( pHScrl )
1188                 {
1189                     if ( (pHScrl->GetVisibleSize() < pHScrl->GetRangeMax()) &&
1190                          pHScrl->IsEnabled() && pHScrl->IsInputEnabled() && ! pHScrl->IsInModalMode() )
1191                         nFlags |= AUTOSCROLL_HORZ;
1192                 }
1193                 if ( pVScrl )
1194                 {
1195                     if ( (pVScrl->GetVisibleSize() < pVScrl->GetRangeMax()) &&
1196                          pVScrl->IsEnabled() && pVScrl->IsInputEnabled() && ! pVScrl->IsInModalMode() )
1197                         nFlags |= AUTOSCROLL_VERT;
1198                 }
1199 
1200                 if ( nFlags )
1201                 {
1202                     StartAutoScroll( nFlags );
1203                     bRet = sal_True;
1204                 }
1205             }
1206             break;
1207 
1208             case COMMAND_WHEEL:
1209             {
1210                 const CommandWheelData* pData = rCmd.GetWheelData();
1211 
1212                 if ( pData && (COMMAND_WHEEL_SCROLL == pData->GetMode()) )
1213                 {
1214                     sal_uLong nScrollLines = pData->GetScrollLines();
1215                     long nLines;
1216                     if ( nScrollLines == COMMAND_WHEEL_PAGESCROLL )
1217                     {
1218                         if ( pData->GetDelta() < 0 )
1219                             nLines = -LONG_MAX;
1220                         else
1221                             nLines = LONG_MAX;
1222                     }
1223                     else
1224                         nLines = pData->GetNotchDelta() * (long)nScrollLines;
1225                     if ( nLines )
1226                     {
1227                         ImplHandleScroll( NULL,
1228                                           0L,
1229                                           pData->IsHorz() ? pHScrl : pVScrl,
1230                                           nLines );
1231                         bRet = sal_True;
1232                     }
1233                 }
1234             }
1235             break;
1236 
1237             case COMMAND_AUTOSCROLL:
1238             {
1239                 const CommandScrollData* pData = rCmd.GetAutoScrollData();
1240                 if ( pData && (pData->GetDeltaX() || pData->GetDeltaY()) )
1241                 {
1242                     ImplHandleScroll( pHScrl, pData->GetDeltaX(),
1243                                       pVScrl, pData->GetDeltaY() );
1244                     bRet = sal_True;
1245                 }
1246             }
1247             break;
1248 
1249             default:
1250             break;
1251         }
1252     }
1253 
1254     return bRet;
1255 }
1256 
1257 // -----------------------------------------------------------------------
1258 
1259 void Window::ImplHandleScroll( ScrollBar* pHScrl, long nX,
1260                                ScrollBar* pVScrl, long nY )
1261 {
1262     if ( pHScrl && nX && pHScrl->IsEnabled() && pHScrl->IsInputEnabled() && ! pHScrl->IsInModalMode() )
1263     {
1264         long nNewPos = pHScrl->GetThumbPos();
1265 
1266         if ( nX == -LONG_MAX )
1267             nNewPos += pHScrl->GetPageSize();
1268         else if ( nX == LONG_MAX )
1269             nNewPos -= pHScrl->GetPageSize();
1270         else
1271         {
1272             const double fVal = (double)nNewPos - ((double)nX * pHScrl->GetLineSize());
1273 
1274             if ( fVal < LONG_MIN )
1275                 nNewPos = LONG_MIN;
1276             else if ( fVal > LONG_MAX )
1277                 nNewPos = LONG_MAX;
1278             else
1279                 nNewPos = (long)fVal;
1280         }
1281 
1282         pHScrl->DoScroll( nNewPos );
1283     }
1284 
1285     if ( pVScrl && nY && pVScrl->IsEnabled() && pVScrl->IsInputEnabled() && ! pVScrl->IsInModalMode() )
1286     {
1287         long nNewPos = pVScrl->GetThumbPos();
1288 
1289         if ( nY == -LONG_MAX )
1290             nNewPos += pVScrl->GetPageSize();
1291         else if ( nY == LONG_MAX )
1292             nNewPos -= pVScrl->GetPageSize();
1293         else
1294         {
1295             const double fVal = (double)nNewPos - ((double)nY * pVScrl->GetLineSize());
1296 
1297             if ( fVal < LONG_MIN )
1298                 nNewPos = LONG_MIN;
1299             else if ( fVal > LONG_MAX )
1300                 nNewPos = LONG_MAX;
1301             else
1302                 nNewPos = (long)fVal;
1303         }
1304 
1305         pVScrl->DoScroll( nNewPos );
1306     }
1307 }
1308 
1309 // support for docking
1310 // this is currently handled in ImplDockingWindowWrapper
1311 /*
1312 void Window::ImplSetFloatingMode( sal_Bool bFloatMode )
1313 {
1314     // if the window is docked, put it into a flaoting window
1315     // if it is floating put it back in the old frame
1316 
1317     ImplDockingWindowWrapper *pWrapper = pDockingMgr->GetDockingWindowWrapper( this );
1318     if( !pDockingData )
1319         return;
1320 
1321     if ( pWrapper->IsFloatingMode() != bFloatMode )
1322     {
1323         if ( pWrapper->PrepareToggleFloatingMode() )
1324         {
1325             sal_Bool bVisible = IsVisible();
1326 
1327             if ( bFloatMode )
1328             {
1329                 Show( sal_False, SHOW_NOFOCUSCHANGE );
1330 
1331                 pWrapper->maDockPos = GetPosPixel();
1332 
1333                 Window* pRealParent = mpWindowImpl->mpRealParent;
1334                 pWrapper->mpOldBorderWin = mpWindowImpl->mpBorderWindow;
1335 
1336                 ImplDockFloatWin* pWin =
1337                     new ImplDockFloatWin2(
1338                                          mpWindowImpl->mpParent,
1339                                          mnFloatBits & ( WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) ?  mnFloatBits | WB_SYSTEMWINDOW : mnFloatBits,
1340                                          pWrapper );
1341                 pWrapper->mpFloatWin = pWin;
1342                 mpWindowImpl->mpBorderWindow  = NULL;
1343                 mpWindowImpl->mnLeftBorder    = 0;
1344                 mpWindowImpl->mnTopBorder     = 0;
1345                 mpWindowImpl->mnRightBorder   = 0;
1346                 mpWindowImpl->mnBottomBorder  = 0;
1347                 // Falls Parent zerstoert wird, muessen wir auch vom
1348                 // BorderWindow den Parent umsetzen
1349                 if ( pWrapper->mpOldBorderWin )
1350                     pWrapper->mpOldBorderWin->SetParent( pWin );
1351                 SetParent( pWin );
1352                 pWin->SetPosPixel( Point() );
1353                 mpWindowImpl->mpBorderWindow = pWin;
1354                 pWin->mpWindowImpl->mpClientWindow = this;
1355                 mpWindowImpl->mpRealParent = pRealParent;
1356                 pWin->SetText( GetText() );
1357                 pWin->SetOutputSizePixel( GetSizePixel() );
1358                 pWin->SetPosPixel( pWrapper->maFloatPos );
1359                 // DockingDaten ans FloatingWindow weiterreichen
1360                 pWin->ShowTitleButton( TITLE_BUTTON_DOCKING, pWrapper->mbDockBtn );
1361                 pWin->ShowTitleButton( TITLE_BUTTON_HIDE, pWrapper->mbHideBtn );
1362                 pWin->SetPin( pWrapper->mbPined );
1363                 if ( pWrapper->mbRollUp )
1364                     pWin->RollUp();
1365                 else
1366                     pWin->RollDown();
1367                 pWin->SetRollUpOutputSizePixel( pWrapper->maRollUpOutSize );
1368                 pWin->SetMinOutputSizePixel( pWrapper->maMinOutSize );
1369 
1370                 pWrapper->ToggleFloatingMode();
1371 
1372                 if ( bVisible )
1373                     Show();
1374             }
1375             else
1376             {
1377                 Show( sal_False, SHOW_NOFOCUSCHANGE );
1378 
1379                 // FloatingDaten wird im FloatingWindow speichern
1380                 pWrapper->maFloatPos      = mpFloatWin->GetPosPixel();
1381                 pWrapper->mbDockBtn       = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_DOCKING );
1382                 pWrapper->mbHideBtn       = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_HIDE );
1383                 pWrapper->mbPined         = mpFloatWin->IsPined();
1384                 pWrapper->mbRollUp        = mpFloatWin->IsRollUp();
1385                 pWrapper->maRollUpOutSize = mpFloatWin->GetRollUpOutputSizePixel();
1386                 pWrapper->maMinOutSize    = mpFloatWin->GetMinOutputSizePixel();
1387 
1388                 Window* pRealParent = mpWindowImpl->mpRealParent;
1389                 mpWindowImpl->mpBorderWindow = NULL;
1390                 if ( pWrapper->mpOldBorderWin )
1391                 {
1392                     SetParent( pWrapper->mpOldBorderWin );
1393                     ((ImplBorderWindow*)pWrapper->mpOldBorderWin)->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
1394                     pWrapper->mpOldBorderWin->Resize();
1395                 }
1396                 mpWindowImpl->mpBorderWindow = pWrapper->mpOldBorderWin;
1397                 SetParent( pRealParent );
1398                 mpWindowImpl->mpRealParent = pRealParent;
1399                 delete static_cast<ImplDockFloatWin*>(mpFloatWin);
1400                 pWrapper->mpFloatWin = NULL;
1401                 SetPosPixel( maDockPos );
1402 
1403                 pWrapper->ToggleFloatingMode();
1404 
1405                 if ( bVisible )
1406                     Show();
1407             }
1408         }
1409     }
1410 }
1411 */
1412 
1413 DockingManager* Window::GetDockingManager()
1414 {
1415     return ImplGetDockingManager();
1416 }
1417 
1418 void Window::EnableDocking( sal_Bool bEnable )
1419 {
1420     // update list of dockable windows
1421     if( bEnable )
1422         ImplGetDockingManager()->AddWindow( this );
1423     else
1424         ImplGetDockingManager()->RemoveWindow( this );
1425 }
1426 
1427 
1428 // retrieves the list of owner draw decorated windows for this window hiearchy
1429 ::std::vector<Window *>& Window::ImplGetOwnerDrawList()
1430 {
1431     return ImplGetTopmostFrameWindow()->mpWindowImpl->mpFrameData->maOwnerDrawList;
1432 }
1433 
1434 Window* Window::ImplGetTopmostFrameWindow()
1435 {
1436     Window *pTopmostParent = this;
1437     while( pTopmostParent->ImplGetParent() )
1438         pTopmostParent = pTopmostParent->ImplGetParent();
1439     return pTopmostParent->mpWindowImpl->mpFrameWindow;
1440 }
1441 
1442 void Window::SetHelpId( const rtl::OString& rHelpId )
1443 {
1444     mpWindowImpl->maHelpId = rHelpId;
1445 }
1446 
1447 const rtl::OString& Window::GetHelpId() const
1448 {
1449     return mpWindowImpl->maHelpId;
1450 }
1451 
1452 void Window::SetUniqueId( const rtl::OString& rUniqueId )
1453 {
1454     mpWindowImpl->maUniqId = rUniqueId;
1455 }
1456 
1457 const rtl::OString& Window::GetUniqueId() const
1458 {
1459     return mpWindowImpl->maUniqId;
1460 }
1461 
1462 const rtl::OString& Window::GetUniqueOrHelpId() const
1463 {
1464     return mpWindowImpl->maUniqId.getLength() ? mpWindowImpl->maUniqId : mpWindowImpl->maHelpId;
1465 }
1466 
1467 // --------- old inline methods ---------------
1468 
1469 Window* Window::ImplGetWindow()
1470 {
1471     if ( mpWindowImpl->mpClientWindow )
1472         return mpWindowImpl->mpClientWindow;
1473     else
1474         return this;
1475 }
1476 
1477 ImplFrameData* Window::ImplGetFrameData()
1478 {
1479     return mpWindowImpl->mpFrameData;
1480 }
1481 
1482 SalFrame* Window::ImplGetFrame() const
1483 {
1484     return mpWindowImpl->mpFrame;
1485 }
1486 
1487 Window* Window::ImplGetParent() const
1488 {
1489     return mpWindowImpl->mpParent;
1490 }
1491 
1492 Window* Window::ImplGetClientWindow() const
1493 {
1494     return mpWindowImpl->mpClientWindow;
1495 }
1496 
1497 Window* Window::ImplGetBorderWindow() const
1498 {
1499     return mpWindowImpl->mpBorderWindow;
1500 }
1501 
1502 Window* Window::ImplGetFirstOverlapWindow()
1503 {
1504     if ( mpWindowImpl->mbOverlapWin )
1505         return this;
1506     else
1507         return mpWindowImpl->mpOverlapWindow;
1508 }
1509 
1510 const Window* Window::ImplGetFirstOverlapWindow() const
1511 {
1512     if ( mpWindowImpl->mbOverlapWin )
1513         return this;
1514     else
1515         return mpWindowImpl->mpOverlapWindow;
1516 }
1517 
1518 Window* Window::ImplGetFrameWindow() const
1519 {
1520     return mpWindowImpl->mpFrameWindow;
1521 }
1522 
1523 sal_Bool Window::ImplIsDockingWindow() const
1524 {
1525     return mpWindowImpl->mbDockWin;
1526 }
1527 
1528 sal_Bool Window::ImplIsFloatingWindow() const
1529 {
1530     return mpWindowImpl->mbFloatWin;
1531 }
1532 
1533 sal_Bool Window::ImplIsToolbox() const
1534 {
1535     return mpWindowImpl->mbToolBox;
1536 }
1537 
1538 sal_Bool Window::ImplIsSplitter() const
1539 {
1540     return mpWindowImpl->mbSplitter;
1541 }
1542 
1543 sal_Bool Window::ImplIsPushButton() const
1544 {
1545     return mpWindowImpl->mbPushButton;
1546 }
1547 
1548 sal_Bool Window::ImplIsOverlapWindow() const
1549 {
1550     return mpWindowImpl->mbOverlapWin;
1551 }
1552 
1553 void Window::ImplSetActive( sal_Bool bActive )
1554 {
1555     mpWindowImpl->mbActive = bActive;
1556 }
1557 
1558 sal_Bool Window::ImplIsMouseTransparent() const
1559 {
1560     return mpWindowImpl->mbMouseTransparent;
1561 }
1562 
1563 void Window::ImplSetMouseTransparent( sal_Bool bTransparent )
1564 {
1565     mpWindowImpl->mbMouseTransparent = bTransparent;
1566 }
1567 
1568 Point Window::ImplOutputToFrame( const Point& rPos )
1569 {
1570     return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
1571 }
1572 
1573 Point Window::ImplFrameToOutput( const Point& rPos )
1574 {
1575     return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
1576 }
1577 
1578 void Window::ImplOutputToFrame( Rectangle& rRect )
1579 {
1580     rRect.Left()+=mnOutOffX;
1581     rRect.Top()+=mnOutOffY;
1582     rRect.Right()+=mnOutOffX;
1583     rRect.Bottom()+=mnOutOffY;
1584 }
1585 
1586 void Window::ImplFrameToOutput( Rectangle& rRect )
1587 {
1588     rRect.Left()-=mnOutOffX;
1589     rRect.Top()-=mnOutOffY;
1590     rRect.Right()-=mnOutOffX;
1591     rRect.Bottom()-=mnOutOffY;
1592 }
1593 
1594 void Window::SetCompoundControl( sal_Bool bCompound )
1595 {
1596     mpWindowImpl->mbCompoundControl = bCompound;
1597 }
1598 
1599 void Window::IncrementLockCount()
1600 {
1601     mpWindowImpl->mnLockCount++;
1602 }
1603 
1604 void Window::DecrementLockCount()
1605 {
1606     mpWindowImpl->mnLockCount--;
1607 }
1608 
1609 WinBits Window::GetStyle() const
1610 {
1611     return mpWindowImpl->mnStyle;
1612 }
1613 
1614 WinBits Window::GetPrevStyle() const
1615 {
1616     return mpWindowImpl->mnPrevStyle;
1617 }
1618 
1619 WinBits Window::GetExtendedStyle() const
1620 {
1621     return mpWindowImpl->mnExtendedStyle;
1622 }
1623 
1624 WinBits Window::GetPrevExtendedStyle() const
1625 {
1626     return mpWindowImpl->mnExtendedStyle;
1627 }
1628 
1629 void Window::SetType( WindowType nType )
1630 {
1631     mpWindowImpl->mnType = nType;
1632 }
1633 
1634 WindowType Window::GetType() const
1635 {
1636     return mpWindowImpl->mnType;
1637 }
1638 sal_Bool Window::IsSystemWindow() const
1639 {
1640     return mpWindowImpl->mbSysWin;
1641 }
1642 
1643 sal_Bool Window::IsDialog() const
1644 {
1645     return mpWindowImpl->mbDialog;
1646 }
1647 
1648 sal_Bool Window::IsMenuFloatingWindow() const
1649 {
1650     return mpWindowImpl->mbMenuFloatingWindow;
1651 }
1652 
1653 sal_Bool Window::IsToolbarFloatingWindow() const
1654 {
1655     return mpWindowImpl->mbToolbarFloatingWindow;
1656 }
1657 
1658 void Window::EnableAllResize( sal_Bool bEnable )
1659 {
1660     mpWindowImpl->mbAllResize = bEnable;
1661 }
1662 
1663 sal_Bool Window::IsAllResizeEnabled() const
1664 {
1665     return mpWindowImpl->mbAllResize;
1666 }
1667 
1668 sal_Bool Window::IsClipSiblingsEnabled() const
1669 {
1670     return mpWindowImpl->mbClipSiblings;
1671 }
1672 
1673 void Window::EnableChildTransparentMode( sal_Bool bEnable )
1674 {
1675     mpWindowImpl->mbChildTransparent = bEnable;
1676 }
1677 
1678 sal_Bool Window::IsChildTransparentModeEnabled() const
1679 {
1680     return mpWindowImpl->mbChildTransparent;
1681 }
1682 
1683 sal_Bool Window::IsMouseTransparent() const
1684 {
1685     return mpWindowImpl->mbMouseTransparent;
1686 }
1687 
1688 sal_Bool Window::IsPaintTransparent() const
1689 {
1690     return mpWindowImpl->mbPaintTransparent;
1691 }
1692 
1693 void Window::SetDialogControlStart( sal_Bool bStart )
1694 {
1695     mpWindowImpl->mbDlgCtrlStart = bStart;
1696 }
1697 
1698 sal_Bool Window::IsDialogControlStart() const
1699 {
1700     return mpWindowImpl->mbDlgCtrlStart;
1701 }
1702 
1703 void Window::SetDialogControlFlags( sal_uInt16 nFlags )
1704 {
1705     mpWindowImpl->mnDlgCtrlFlags = nFlags;
1706 }
1707 
1708 sal_uInt16 Window::GetDialogControlFlags() const
1709 {
1710     return mpWindowImpl->mnDlgCtrlFlags;
1711 }
1712 
1713 const InputContext& Window::GetInputContext() const
1714 {
1715     return mpWindowImpl->maInputContext;
1716 }
1717 
1718 sal_Bool Window::IsExtTextInput() const
1719 {
1720     return mpWindowImpl->mbExtTextInput;
1721 }
1722 
1723 void Window::EnableChildNotify( sal_Bool bEnable )
1724 {
1725     mpWindowImpl->mbChildNotify = bEnable;
1726 }
1727 
1728 sal_Bool Window::IsChildNotify() const
1729 {
1730     return mpWindowImpl->mbChildNotify;
1731 }
1732 
1733 sal_Bool Window::IsControlFont() const
1734 {
1735     return (mpWindowImpl->mpControlFont != 0);
1736 }
1737 
1738 Color Window::GetControlForeground() const
1739 {
1740     return mpWindowImpl->maControlForeground;
1741 }
1742 
1743 sal_Bool Window::IsControlForeground() const
1744 {
1745     return mpWindowImpl->mbControlForeground;
1746 }
1747 
1748 Color Window::GetControlBackground() const
1749 {
1750     return mpWindowImpl->maControlBackground;
1751 }
1752 
1753 sal_Bool Window::IsControlBackground() const
1754 {
1755     return mpWindowImpl->mbControlBackground;
1756 }
1757 
1758 sal_Bool Window::IsInPaint() const
1759 {
1760     return mpWindowImpl->mbInPaint;
1761 }
1762 
1763 Window* Window::GetParent() const
1764 {
1765     return mpWindowImpl->mpRealParent;
1766 }
1767 
1768 sal_Bool Window::IsVisible() const
1769 {
1770     return mpWindowImpl->mbVisible;
1771 }
1772 
1773 sal_Bool Window::IsReallyVisible() const
1774 {
1775     return mpWindowImpl->mbReallyVisible;
1776 }
1777 
1778 sal_Bool Window::IsParentPathVisible() const
1779 {
1780     return mpWindowImpl->mbReallyVisible;
1781 }
1782 
1783 sal_Bool Window::IsReallyShown() const
1784 {
1785     return mpWindowImpl->mbReallyShown;
1786 }
1787 
1788 sal_Bool Window::IsInInitShow() const
1789 {
1790     return mpWindowImpl->mbInInitShow;
1791 }
1792 
1793 sal_Bool Window::IsEnabled() const
1794 {
1795     return !mpWindowImpl->mbDisabled;
1796 }
1797 
1798 sal_Bool Window::IsInputEnabled() const
1799 {
1800     return !mpWindowImpl->mbInputDisabled;
1801 }
1802 
1803 sal_Bool Window::IsAlwaysEnableInput() const
1804 {
1805     return mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled;
1806 }
1807 
1808 sal_Bool Window::IsAlwaysDisableInput() const
1809 {
1810     return mpWindowImpl->meAlwaysInputMode == AlwaysInputDisabled;
1811 }
1812 
1813 sal_uInt16 Window::GetActivateMode() const
1814 {
1815     return mpWindowImpl->mnActivateMode;
1816 
1817 }
1818 
1819 sal_Bool Window::IsAlwaysOnTopEnabled() const
1820 {
1821     return mpWindowImpl->mbAlwaysOnTop;
1822 }
1823 
1824 sal_Bool Window::IsDefaultPos() const
1825 {
1826     return mpWindowImpl->mbDefPos;
1827 }
1828 
1829 sal_Bool Window::IsDefaultSize() const
1830 {
1831     return mpWindowImpl->mbDefSize;
1832 }
1833 
1834 void Window::EnablePaint( sal_Bool bEnable )
1835 {
1836     mpWindowImpl->mbPaintDisabled = !bEnable;
1837 }
1838 
1839 sal_Bool Window::IsPaintEnabled() const
1840 {
1841     return !mpWindowImpl->mbPaintDisabled;
1842 }
1843 
1844 sal_Bool Window::IsUpdateMode() const
1845 {
1846     return !mpWindowImpl->mbNoUpdate;
1847 }
1848 
1849 void Window::SetParentUpdateMode( sal_Bool bUpdate )
1850 {
1851     mpWindowImpl->mbNoParentUpdate = !bUpdate;
1852 }
1853 
1854 sal_Bool Window::IsParentUpdateMode() const
1855 {
1856     return !mpWindowImpl->mbNoParentUpdate;
1857 }
1858 
1859 sal_Bool Window::IsActive() const
1860 {
1861     return mpWindowImpl->mbActive;
1862 }
1863 
1864 sal_uInt16 Window::GetGetFocusFlags() const
1865 {
1866     return mpWindowImpl->mnGetFocusFlags;
1867 }
1868 
1869 sal_Bool Window::IsCompoundControl() const
1870 {
1871     return mpWindowImpl->mbCompoundControl;
1872 }
1873 
1874 sal_Bool Window::HasCompoundControlFocus() const
1875 {
1876     return mpWindowImpl->mbCompoundControlHasFocus;
1877 }
1878 
1879 sal_Bool Window::IsChildPointerOverwrite() const
1880 {
1881     return mpWindowImpl->mbChildPtrOverwrite;
1882 }
1883 
1884 sal_Bool Window::IsPointerVisible() const
1885 {
1886     return !mpWindowImpl->mbNoPtrVisible;
1887 }
1888 
1889 sal_Bool Window::IsWait() const
1890 {
1891     return (mpWindowImpl->mnWaitCount != 0);
1892 }
1893 
1894 Cursor* Window::GetCursor() const
1895 {
1896     return mpWindowImpl->mpCursor;
1897 }
1898 
1899 const Fraction& Window::GetZoom() const
1900 {
1901     return mpWindowImpl->maZoom;
1902 }
1903 
1904 sal_Bool Window::IsZoom() const
1905 {
1906     return mpWindowImpl->maZoom.GetNumerator() != mpWindowImpl->maZoom.GetDenominator();
1907 }
1908 
1909 void Window::SetHelpText( const XubString& rHelpText )
1910 {
1911     mpWindowImpl->maHelpText = rHelpText;
1912     mpWindowImpl->mbHelpTextDynamic = sal_True;
1913 }
1914 
1915 void Window::SetQuickHelpText( const XubString& rHelpText )
1916 {
1917     mpWindowImpl->maQuickHelpText = rHelpText;
1918 }
1919 
1920 const XubString& Window::GetQuickHelpText() const
1921 {
1922     return mpWindowImpl->maQuickHelpText;
1923 }
1924 
1925 void Window::SetData( void* pNewData )
1926 {
1927     mpWindowImpl->mpUserData = pNewData;
1928 }
1929 
1930 void* Window::GetData() const
1931 {
1932     return mpWindowImpl->mpUserData;
1933 }
1934 
1935 sal_Bool Window::IsCreatedWithToolkit() const
1936 {
1937     return mpWindowImpl->mbCreatedWithToolkit;
1938 }
1939 
1940 void Window::SetCreatedWithToolkit( sal_Bool b )
1941 {
1942     mpWindowImpl->mbCreatedWithToolkit = b;
1943 
1944 }
1945 const Pointer& Window::GetPointer() const
1946 {
1947     return mpWindowImpl->maPointer;
1948 }
1949 
1950 VCLXWindow* Window::GetWindowPeer() const
1951 {
1952     return mpWindowImpl->mpVCLXWindow;
1953 }
1954 
1955 void Window::SetPosPixel( const Point& rNewPos )
1956 {
1957     SetPosSizePixel( rNewPos.X(), rNewPos.Y(), 0, 0, WINDOW_POSSIZE_POS );
1958 }
1959 
1960 void Window::SetSizePixel( const Size& rNewSize )
1961 {
1962     SetPosSizePixel( 0, 0, rNewSize.Width(), rNewSize.Height(),
1963                      WINDOW_POSSIZE_SIZE );
1964 }
1965 
1966 void Window::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
1967 {
1968     SetPosSizePixel( rNewPos.X(), rNewPos.Y(),
1969                      rNewSize.Width(), rNewSize.Height(),
1970                      WINDOW_POSSIZE_POSSIZE );
1971 }
1972 
1973 void Window::SetOutputSizePixel( const Size& rNewSize )
1974 {
1975     SetSizePixel( Size( rNewSize.Width()+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
1976                         rNewSize.Height()+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder ) );
1977 }
1978 
1979