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 #include <ctype.h> // don't ask. msdev breaks otherwise... 29 #include <vcl/window.hxx> 30 #include <canvas/debug.hxx> 31 #include <canvas/verbosetrace.hxx> 32 #include <canvas/canvastools.hxx> 33 #include <tools/diagnose_ex.h> 34 35 #include <osl/mutex.hxx> 36 #include <cppuhelper/compbase1.hxx> 37 38 #include <com/sun/star/lang/NoSupportException.hpp> 39 #include <toolkit/helper/vclunohelper.hxx> 40 #include <basegfx/tools/canvastools.hxx> 41 #include "dx_linepolypolygon.hxx" 42 #include "dx_spritecanvas.hxx" 43 #include "dx_canvasbitmap.hxx" 44 #include "dx_spritedevicehelper.hxx" 45 46 47 #undef WB_LEFT 48 #undef WB_RIGHT 49 #include "dx_winstuff.hxx" 50 51 52 #include <vcl/sysdata.hxx> 53 54 using namespace ::com::sun::star; 55 56 namespace dxcanvas 57 { 58 SpriteDeviceHelper::SpriteDeviceHelper() : 59 DeviceHelper(), 60 mpSpriteCanvas( NULL ), 61 mpSurfaceProxyManager(), 62 mpRenderModule(), 63 mpBackBuffer() 64 { 65 } 66 67 void SpriteDeviceHelper::init( Window& rWindow, 68 SpriteCanvas& rSpriteCanvas, 69 const awt::Rectangle& rRect, 70 bool /*bFullscreen*/ ) 71 { 72 // #i60490# ensure backbuffer has sensible minimal size 73 const sal_Int32 w( ::std::max(sal_Int32(1),sal_Int32(rRect.Width))); 74 const sal_Int32 h( ::std::max(sal_Int32(1),sal_Int32(rRect.Height))); 75 76 rSpriteCanvas.setWindow( 77 uno::Reference<awt::XWindow2>( 78 VCLUnoHelper::GetInterface(&rWindow), 79 uno::UNO_QUERY_THROW) ); 80 81 const SystemEnvData *pData = rWindow.GetSystemData(); 82 const HWND hWnd = reinterpret_cast<HWND>(pData->hWnd); 83 if( !IsWindow( hWnd ) ) 84 throw lang::NoSupportException( 85 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 86 "Passed window has invalid system window, or canvas out-of-process!")), 87 NULL); 88 89 mpSpriteCanvas = &rSpriteCanvas; 90 91 try 92 { 93 // setup directx rendermodule 94 mpRenderModule = createRenderModule( rWindow ); 95 } 96 catch (...) { 97 98 throw lang::NoSupportException( 99 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 100 "Could not create DirectX device!") ), 101 static_cast< ::cppu::OWeakObject* >(&rSpriteCanvas) ); 102 } 103 104 // create the surfaceproxy manager 105 mpSurfaceProxyManager = ::canvas::createSurfaceProxyManager( mpRenderModule ); 106 107 // #i60490# ensure backbuffer has sensible minimal size 108 mpBackBuffer.reset(new DXSurfaceBitmap( 109 ::basegfx::B2ISize(w,h), 110 mpSurfaceProxyManager, 111 mpRenderModule, 112 false)); 113 114 // Assumes: SystemChildWindow() has CS_OWNDC 115 DeviceHelper::init(GetDC(mpRenderModule->getHWND()), 116 rSpriteCanvas); 117 } 118 119 void SpriteDeviceHelper::disposing() 120 { 121 // release all references 122 mpBackBuffer.reset(); 123 mpSurfaceProxyManager.reset(); 124 mpRenderModule.reset(); 125 mpSpriteCanvas = NULL; 126 127 DeviceHelper::disposing(); 128 } 129 130 uno::Reference< rendering::XBitmap > SpriteDeviceHelper::createCompatibleBitmap( 131 const uno::Reference< rendering::XGraphicDevice >& /*rDevice*/, 132 const geometry::IntegerSize2D& size ) 133 { 134 if( !getDevice() ) 135 return uno::Reference< rendering::XBitmap >(); // we're disposed 136 137 DXSurfaceBitmapSharedPtr pBitmap( 138 new DXSurfaceBitmap( 139 ::basegfx::unotools::b2ISizeFromIntegerSize2D(size), 140 mpSurfaceProxyManager, 141 mpRenderModule, 142 false)); 143 144 // create a 24bit RGB system memory surface 145 return uno::Reference< rendering::XBitmap >(new CanvasBitmap(pBitmap,getDevice())); 146 } 147 148 uno::Reference< rendering::XVolatileBitmap > SpriteDeviceHelper::createVolatileBitmap( 149 const uno::Reference< rendering::XGraphicDevice >& /*rDevice*/, 150 const geometry::IntegerSize2D& /*size*/ ) 151 { 152 return uno::Reference< rendering::XVolatileBitmap >(); 153 } 154 155 uno::Reference< rendering::XBitmap > SpriteDeviceHelper::createCompatibleAlphaBitmap( 156 const uno::Reference< rendering::XGraphicDevice >& /*rDevice*/, 157 const geometry::IntegerSize2D& size ) 158 { 159 if( !getDevice() ) 160 return uno::Reference< rendering::XBitmap >(); // we're disposed 161 162 DXSurfaceBitmapSharedPtr pBitmap( 163 new DXSurfaceBitmap( 164 ::basegfx::unotools::b2ISizeFromIntegerSize2D(size), 165 mpSurfaceProxyManager, 166 mpRenderModule, 167 true)); 168 169 // create a 32bit ARGB system memory surface 170 return uno::Reference< rendering::XBitmap >(new CanvasBitmap(pBitmap,getDevice())); 171 } 172 173 uno::Reference< rendering::XVolatileBitmap > SpriteDeviceHelper::createVolatileAlphaBitmap( 174 const uno::Reference< rendering::XGraphicDevice >& /*rDevice*/, 175 const geometry::IntegerSize2D& /*size*/ ) 176 { 177 return uno::Reference< rendering::XVolatileBitmap >(); 178 } 179 180 sal_Bool SpriteDeviceHelper::hasFullScreenMode() 181 { 182 // TODO(F3): offer fullscreen mode the XCanvas way 183 return false; 184 } 185 186 sal_Bool SpriteDeviceHelper::enterFullScreenMode( sal_Bool /*bEnter*/ ) 187 { 188 // TODO(F3): offer fullscreen mode the XCanvas way 189 return false; 190 } 191 192 ::sal_Int32 SpriteDeviceHelper::createBuffers( ::sal_Int32 /*nBuffers*/ ) 193 { 194 // TODO(F3): implement XBufferStrategy interface. For now, we 195 // _always_ will have exactly one backbuffer 196 return 1; 197 } 198 199 void SpriteDeviceHelper::destroyBuffers() 200 { 201 // TODO(F3): implement XBufferStrategy interface. For now, we 202 // _always_ will have exactly one backbuffer 203 } 204 205 ::sal_Bool SpriteDeviceHelper::showBuffer( bool, ::sal_Bool ) 206 { 207 OSL_ENSURE(false,"Not supposed to be called, handled by SpriteCanvas"); 208 return sal_False; 209 } 210 211 ::sal_Bool SpriteDeviceHelper::switchBuffer( bool, ::sal_Bool ) 212 { 213 OSL_ENSURE(false,"Not supposed to be called, handled by SpriteCanvas"); 214 return sal_False; 215 } 216 217 uno::Any SpriteDeviceHelper::isAccelerated() const 218 { 219 return ::com::sun::star::uno::makeAny(true); 220 } 221 222 void SpriteDeviceHelper::notifySizeUpdate( const awt::Rectangle& rBounds ) 223 { 224 // #i60490# ensure backbuffer has sensible minimal size 225 const sal_Int32 x(rBounds.X); 226 const sal_Int32 y(rBounds.Y); 227 const sal_Int32 w(::std::max(sal_Int32(1),sal_Int32(rBounds.Width))); 228 const sal_Int32 h(::std::max(sal_Int32(1),sal_Int32(rBounds.Height))); 229 230 if( mpRenderModule ) 231 mpRenderModule->resize(::basegfx::B2IRange(x,y,x+w,y+h)); 232 233 resizeBackBuffer(::basegfx::B2ISize(w,h)); 234 } 235 236 void SpriteDeviceHelper::resizeBackBuffer( const ::basegfx::B2ISize& rNewSize ) 237 { 238 // disposed? 239 if(!(mpBackBuffer)) 240 return; 241 242 mpBackBuffer->resize(rNewSize); 243 mpBackBuffer->clear(); 244 } 245 246 HWND SpriteDeviceHelper::getHwnd() const 247 { 248 if( mpRenderModule ) 249 return mpRenderModule->getHWND(); 250 else 251 return 0; 252 } 253 254 void SpriteDeviceHelper::dumpScreenContent() const 255 { 256 if( mpRenderModule ) 257 mpRenderModule->screenShot(); 258 } 259 } 260