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.  Everytime 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(  ) throw (::com::sun::star::uno::RuntimeException)
112         {
113             return this;
114         }
115 
116         // XBufferController
createBuffers(::sal_Int32 nBuffers)117         virtual ::sal_Int32 SAL_CALL createBuffers( ::sal_Int32 nBuffers ) throw (::com::sun::star::lang::IllegalArgumentException,
118                                                                                   ::com::sun::star::uno::RuntimeException)
119         {
120             tools::verifyRange( nBuffers, (sal_Int32)1 );
121 
122             MutexType aGuard( BaseType::m_aMutex );
123 
124             return BaseType::maDeviceHelper.createBuffers( nBuffers );
125         }
126 
destroyBuffers()127         virtual void SAL_CALL destroyBuffers(  ) throw (::com::sun::star::uno::RuntimeException)
128         {
129             MutexType aGuard( BaseType::m_aMutex );
130 
131             BaseType::maDeviceHelper.destroyBuffers();
132         }
133 
showBuffer(::sal_Bool bUpdateAll)134         virtual ::sal_Bool SAL_CALL showBuffer( ::sal_Bool bUpdateAll ) throw (::com::sun::star::uno::RuntimeException)
135         {
136             MutexType aGuard( BaseType::m_aMutex );
137 
138             return BaseType::maDeviceHelper.showBuffer( mbIsVisible, bUpdateAll );
139         }
140 
switchBuffer(::sal_Bool bUpdateAll)141         virtual ::sal_Bool SAL_CALL switchBuffer( ::sal_Bool bUpdateAll ) throw (::com::sun::star::uno::RuntimeException)
142         {
143             MutexType aGuard( BaseType::m_aMutex );
144 
145             return BaseType::maDeviceHelper.switchBuffer( mbIsVisible, bUpdateAll );
146         }
147 
148 
149         /** Set corresponding canvas window
150 
151             Use this method to set the window this canvas displays
152             on. Comes in handy when the canvas needs to adapt size or
153             output position to the changing window.
154 
155             Whenever the bounds of the window change, <code>void
156             notifySizeUpdate( const awt::Rectangle& rBounds )</code>
157             is called, with rBounds the window bound rect relative to
158             the frame window.
159          */
setWindow(const::com::sun::star::uno::Reference<::com::sun::star::awt::XWindow2> & rWindow)160         void setWindow( const ::com::sun::star::uno::Reference<
161                               ::com::sun::star::awt::XWindow2 >& rWindow )
162         {
163             if( mxWindow.is() )
164                 mxWindow->removeWindowListener( this );
165 
166             mxWindow = rWindow;
167 
168             if( mxWindow.is() )
169             {
170                 mbIsVisible = mxWindow->isVisible();
171                 mbIsTopLevel =
172                     ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindow >(
173                         mxWindow,
174                         ::com::sun::star::uno::UNO_QUERY ).is();
175 
176                 maBounds = transformBounds( mxWindow->getPosSize() );
177                 mxWindow->addWindowListener( this );
178             }
179         }
180 
getWindow() const181         ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow2 > getWindow() const
182         {
183             return mxWindow;
184         }
185 
getXWindow() const186         ::com::sun::star::uno::Any getXWindow() const
187         {
188             return ::com::sun::star::uno::makeAny(mxWindow);
189         }
190 
191 #if defined __SUNPRO_CC
192         using Base::disposing;
193 #endif
disposing()194         virtual void SAL_CALL disposing()
195         {
196             typename BaseType::MutexType aGuard( BaseType::m_aMutex );
197 
198             if( mxWindow.is() )
199             {
200                 mxWindow->removeWindowListener(this);
201                 mxWindow.clear();
202             }
203 
204             // pass on to base class
205             BaseType::disposing();
206         }
207 
transformBounds(const::com::sun::star::awt::Rectangle & rBounds)208         ::com::sun::star::awt::Rectangle transformBounds( const ::com::sun::star::awt::Rectangle& rBounds )
209         {
210             // notifySizeUpdate's bounds are relative to the toplevel
211             // window
212             if( !mbIsTopLevel )
213                 return tools::getAbsoluteWindowRect(
214                     rBounds,
215                     mxWindow );
216             else
217                 return ::com::sun::star::awt::Rectangle( 0,0,rBounds.Width,rBounds.Height );
218         }
219 
boundsChanged(const::com::sun::star::awt::WindowEvent & e)220         void boundsChanged( const ::com::sun::star::awt::WindowEvent& e )
221         {
222             typename BaseType::MutexType aGuard( BaseType::m_aMutex );
223 
224             const ::com::sun::star::awt::Rectangle& rNewBounds(
225                 transformBounds(
226                     ::com::sun::star::awt::Rectangle( e.X,
227                                                       e.Y,
228                                                       e.Width,
229                                                       e.Height )));
230 
231             if( rNewBounds.X != maBounds.X ||
232                 rNewBounds.Y != maBounds.Y ||
233                 rNewBounds.Width != maBounds.Width ||
234                 rNewBounds.Height != maBounds.Height )
235             {
236                 maBounds = rNewBounds;
237                 BaseType::maDeviceHelper.notifySizeUpdate( maBounds );
238             }
239         }
240 
241         // XWindowListener
disposing(const::com::sun::star::lang::EventObject & Source)242         virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException)
243         {
244             typename BaseType::MutexType aGuard( BaseType::m_aMutex );
245 
246             if( Source.Source == mxWindow )
247                 mxWindow.clear();
248         }
249 
windowResized(const::com::sun::star::awt::WindowEvent & e)250         virtual void SAL_CALL windowResized( const ::com::sun::star::awt::WindowEvent& e ) throw (::com::sun::star::uno::RuntimeException)
251         {
252             boundsChanged( e );
253         }
254 
windowMoved(const::com::sun::star::awt::WindowEvent & e)255         virtual void SAL_CALL windowMoved( const ::com::sun::star::awt::WindowEvent& e ) throw (::com::sun::star::uno::RuntimeException)
256         {
257             boundsChanged( e );
258         }
259 
windowShown(const::com::sun::star::lang::EventObject &)260         virtual void SAL_CALL windowShown( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
261         {
262             typename BaseType::MutexType aGuard( BaseType::m_aMutex );
263 
264             mbIsVisible = true;
265         }
266 
windowHidden(const::com::sun::star::lang::EventObject &)267         virtual void SAL_CALL windowHidden( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
268         {
269             typename BaseType::MutexType aGuard( BaseType::m_aMutex );
270 
271             mbIsVisible = false;
272         }
273 
274     protected:
275         ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow2 >  mxWindow;
276 
277         /// Current bounds of the owning Window
278 	    ::com::sun::star::awt::Rectangle                                     maBounds;
279 
280         /// True, if the window this canvas is contained in, is visible
281         bool                                                                 mbIsVisible;
282 
283     private:
284         /// True, if the window this canvas is contained in, is a toplevel window
285         bool                                                                 mbIsTopLevel;
286     };
287 }
288 
289 #endif /* INCLUDED_CANVAS_BUFFEREDGRAPHICDEVICEBASE_HXX */
290