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