xref: /trunk/main/canvas/inc/canvas/base/bufferedgraphicdevicebase.hxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 #ifndef INCLUDED_CANVAS_BUFFEREDGRAPHICDEVICEBASE_HXX
25 #define INCLUDED_CANVAS_BUFFEREDGRAPHICDEVICEBASE_HXX
26 
27 #ifndef _COM_SUN_STAR_AWT_XWINDOW2_HPP_
28 #include <com/sun/star/awt/XWindow2.hpp>
29 #endif
30 #ifndef _COM_SUN_STAR_AWT_XTOPWINDOW_HPP_
31 #include <com/sun/star/awt/XTopWindow.hpp>
32 #endif
33 #ifndef _COM_SUN_STAR_AWT_XWINDOWLISTENER_HPP_
34 #include <com/sun/star/awt/XWindowListener.hpp>
35 #endif
36 
37 #ifndef INCLUDED_CANVAS_CANVASTOOLS_HXX
38 #include <canvas/canvastools.hxx>
39 #endif
40 #ifndef INCLUDED_CANVAS_GRAPHICDEVICEBASE_HXX
41 #include <canvas/base/graphicdevicebase.hxx>
42 #endif
43 
44 
45 /* Definition of BufferedGraphicDeviceBase class */
46 
47 namespace canvas
48 {
49     /** Helper template base class for XGraphicDevice implementations
50         on windows.
51 
52         Use this base class if your target device is a
53         window. Additionally to GraphicDeviceBase, this template
54         provides an implementation of the awt::XWindowListener
55         interface, to receive notifications about state changes of the
56         associated window.
57 
58         @tpl Base
59         Base class to use, most probably one of the
60         WeakComponentImplHelperN templates with the appropriate
61         interfaces. At least XGraphicDevice should be among them (why else
62         would you use this template, then?). Base class must have an
63         Base( const Mutex& ) constructor (like the
64         WeakComponentImplHelperN templates have). As the very least,
65         the base class must be derived from uno::XInterface, as some
66         error reporting mechanisms rely on that.
67 
68         @tpl DeviceHelper
69         Device helper implementation for the backend in question. This
70         object will be held as a member of this template class, and
71         basically gets forwarded all XGraphicDevice API calls that
72         could not be handled generically.
73 
74         @tpl Mutex
75         Lock strategy to use. Defaults to using the
76         OBaseMutex-provided lock.  Every time one of the methods is
77         entered, an object of type Mutex is created with m_aMutex as
78         the sole parameter, and destroyed again when the method scope
79         is left.
80 
81         @tpl UnambiguousBase
82         Optional unambiguous base class for XInterface of Base. It's
83         sometimes necessary to specify this parameter, e.g. if Base
84         derives from multiple UNO interface (were each provides its
85         own version of XInterface, making the conversion ambiguous)
86      */
87     template< class Base,
88               class DeviceHelper,
89               class Mutex=::osl::MutexGuard,
90               class UnambiguousBase=::com::sun::star::uno::XInterface > class BufferedGraphicDeviceBase :
91         public GraphicDeviceBase< Base, DeviceHelper, Mutex, UnambiguousBase >
92     {
93     public:
94         typedef GraphicDeviceBase< Base, DeviceHelper, Mutex, UnambiguousBase > BaseType;
95         typedef BufferedGraphicDeviceBase OurType;
96         typedef Mutex MutexType;
97 
BufferedGraphicDeviceBase()98         BufferedGraphicDeviceBase() :
99             mxWindow(),
100             maBounds(),
101             mbIsVisible( false ),
102             mbIsTopLevel( false )
103         {
104             BaseType::maPropHelper.addProperties( PropertySetHelper::MakeMap
105                                                   ("Window",
106                                                    boost::bind(&OurType::getXWindow,
107                                                                this)));
108         }
109 
110         // XGraphicDevice
getBufferController()111         virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBufferController > SAL_CALL getBufferController(  )
112         {
113             return this;
114         }
115 
116         // XBufferController
createBuffers(::sal_Int32 nBuffers)117         virtual ::sal_Int32 SAL_CALL createBuffers( ::sal_Int32 nBuffers )
118         {
119             tools::verifyRange( nBuffers, (sal_Int32)1 );
120 
121             MutexType aGuard( BaseType::m_aMutex );
122 
123             return BaseType::maDeviceHelper.createBuffers( nBuffers );
124         }
125 
destroyBuffers()126         virtual void SAL_CALL destroyBuffers(  )
127         {
128             MutexType aGuard( BaseType::m_aMutex );
129 
130             BaseType::maDeviceHelper.destroyBuffers();
131         }
132 
showBuffer(::sal_Bool bUpdateAll)133         virtual ::sal_Bool SAL_CALL showBuffer( ::sal_Bool bUpdateAll )
134         {
135             MutexType aGuard( BaseType::m_aMutex );
136 
137             return BaseType::maDeviceHelper.showBuffer( mbIsVisible, bUpdateAll );
138         }
139 
switchBuffer(::sal_Bool bUpdateAll)140         virtual ::sal_Bool SAL_CALL switchBuffer( ::sal_Bool bUpdateAll )
141         {
142             MutexType aGuard( BaseType::m_aMutex );
143 
144             return BaseType::maDeviceHelper.switchBuffer( mbIsVisible, bUpdateAll );
145         }
146 
147 
148         /** Set corresponding canvas window
149 
150             Use this method to set the window this canvas displays
151             on. Comes in handy when the canvas needs to adapt size or
152             output position to the changing window.
153 
154             Whenever the bounds of the window change, <code>void
155             notifySizeUpdate( const awt::Rectangle& rBounds )</code>
156             is called, with rBounds the window bound rect relative to
157             the frame window.
158          */
setWindow(const::com::sun::star::uno::Reference<::com::sun::star::awt::XWindow2> & rWindow)159         void setWindow( const ::com::sun::star::uno::Reference<
160                               ::com::sun::star::awt::XWindow2 >& rWindow )
161         {
162             if( mxWindow.is() )
163                 mxWindow->removeWindowListener( this );
164 
165             mxWindow = rWindow;
166 
167             if( mxWindow.is() )
168             {
169                 mbIsVisible = mxWindow->isVisible();
170                 mbIsTopLevel =
171                     ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindow >(
172                         mxWindow,
173                         ::com::sun::star::uno::UNO_QUERY ).is();
174 
175                 maBounds = transformBounds( mxWindow->getPosSize() );
176                 mxWindow->addWindowListener( this );
177             }
178         }
179 
getWindow() const180         ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow2 > getWindow() const
181         {
182             return mxWindow;
183         }
184 
getXWindow() const185         ::com::sun::star::uno::Any getXWindow() const
186         {
187             return ::com::sun::star::uno::makeAny(mxWindow);
188         }
189 
190 #if defined __SUNPRO_CC
191         using Base::disposing;
192 #endif
disposing()193         virtual void SAL_CALL disposing()
194         {
195             typename BaseType::MutexType aGuard( BaseType::m_aMutex );
196 
197             if( mxWindow.is() )
198             {
199                 mxWindow->removeWindowListener(this);
200                 mxWindow.clear();
201             }
202 
203             // pass on to base class
204             BaseType::disposing();
205         }
206 
transformBounds(const::com::sun::star::awt::Rectangle & rBounds)207         ::com::sun::star::awt::Rectangle transformBounds( const ::com::sun::star::awt::Rectangle& rBounds )
208         {
209             // notifySizeUpdate's bounds are relative to the toplevel
210             // window
211             if( !mbIsTopLevel )
212                 return tools::getAbsoluteWindowRect(
213                     rBounds,
214                     mxWindow );
215             else
216                 return ::com::sun::star::awt::Rectangle( 0,0,rBounds.Width,rBounds.Height );
217         }
218 
boundsChanged(const::com::sun::star::awt::WindowEvent & e)219         void boundsChanged( const ::com::sun::star::awt::WindowEvent& e )
220         {
221             typename BaseType::MutexType aGuard( BaseType::m_aMutex );
222 
223             const ::com::sun::star::awt::Rectangle& rNewBounds(
224                 transformBounds(
225                     ::com::sun::star::awt::Rectangle( e.X,
226                                                       e.Y,
227                                                       e.Width,
228                                                       e.Height )));
229 
230             if( rNewBounds.X != maBounds.X ||
231                 rNewBounds.Y != maBounds.Y ||
232                 rNewBounds.Width != maBounds.Width ||
233                 rNewBounds.Height != maBounds.Height )
234             {
235                 maBounds = rNewBounds;
236                 BaseType::maDeviceHelper.notifySizeUpdate( maBounds );
237             }
238         }
239 
240         // XWindowListener
disposing(const::com::sun::star::lang::EventObject & Source)241         virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
242         {
243             typename BaseType::MutexType aGuard( BaseType::m_aMutex );
244 
245             if( Source.Source == mxWindow )
246                 mxWindow.clear();
247         }
248 
windowResized(const::com::sun::star::awt::WindowEvent & e)249         virtual void SAL_CALL windowResized( const ::com::sun::star::awt::WindowEvent& e )
250         {
251             boundsChanged( e );
252         }
253 
windowMoved(const::com::sun::star::awt::WindowEvent & e)254         virtual void SAL_CALL windowMoved( const ::com::sun::star::awt::WindowEvent& e )
255         {
256             boundsChanged( e );
257         }
258 
windowShown(const::com::sun::star::lang::EventObject &)259         virtual void SAL_CALL windowShown( const ::com::sun::star::lang::EventObject& )
260         {
261             typename BaseType::MutexType aGuard( BaseType::m_aMutex );
262 
263             mbIsVisible = true;
264         }
265 
windowHidden(const::com::sun::star::lang::EventObject &)266         virtual void SAL_CALL windowHidden( const ::com::sun::star::lang::EventObject& )
267         {
268             typename BaseType::MutexType aGuard( BaseType::m_aMutex );
269 
270             mbIsVisible = false;
271         }
272 
273     protected:
274         ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow2 >  mxWindow;
275 
276         /// Current bounds of the owning Window
277         ::com::sun::star::awt::Rectangle                                     maBounds;
278 
279         /// True, if the window this canvas is contained in, is visible
280         bool                                                                 mbIsVisible;
281 
282     private:
283         /// True, if the window this canvas is contained in, is a toplevel window
284         bool                                                                 mbIsTopLevel;
285     };
286 }
287 
288 #endif /* INCLUDED_CANVAS_BUFFEREDGRAPHICDEVICEBASE_HXX */
289