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