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 "precompiled_sd.hxx" 29 30 #include "presenter/PresenterCanvasFactory.hxx" 31 #include "PresenterCanvas.hxx" 32 33 #include <com/sun/star/awt/Point.hpp> 34 #include <com/sun/star/awt/WindowAttribute.hpp> 35 #include <com/sun/star/awt/WindowClass.hpp> 36 #include <com/sun/star/awt/WindowDescriptor.hpp> 37 #include <com/sun/star/lang/XInitialization.hpp> 38 #include <com/sun/star/rendering/CompositeOperation.hpp> 39 #include <com/sun/star/drawing/CanvasFeature.hpp> 40 #include <com/sun/star/uno/XComponentContext.hpp> 41 #include <comphelper/processfactory.hxx> 42 #include <cppcanvas/vclfactory.hxx> 43 #include <cppuhelper/basemutex.hxx> 44 #include <cppuhelper/compbase3.hxx> 45 #include <cppuhelper/compbase2.hxx> 46 #include <rtl/ref.hxx> 47 #include <toolkit/helper/vclunohelper.hxx> 48 #include <vcl/svapp.hxx> 49 #include <vcl/window.hxx> 50 #include <vcl/wrkwin.hxx> 51 52 using namespace ::com::sun::star; 53 using namespace ::com::sun::star::uno; 54 using ::rtl::OUString; 55 56 namespace sd { namespace presenter { 57 58 //===== PresenterCanvasFactory::SharedWindowContainer ========================= 59 60 namespace { 61 class SharedWindowDescriptor 62 { 63 public: 64 Reference<awt::XWindow> mxSharedWindow; 65 Reference<rendering::XCanvas> mxSharedCanvas; 66 }; 67 } 68 69 class PresenterCanvasFactory::SharedWindowContainer 70 : public ::std::vector<SharedWindowDescriptor> 71 { 72 public: 73 iterator FindDescriptor (const Reference<awt::XWindow>& rxWindow) 74 { 75 for (iterator iDescriptor=begin(); iDescriptor!=end(); ++iDescriptor) 76 if (iDescriptor->mxSharedWindow == rxWindow) 77 return iDescriptor; 78 return end(); 79 } 80 }; 81 82 83 84 85 //===== PresenterCanvasFactory ================================================ 86 87 class PresenterCanvasFactory::Deleter 88 { 89 public: 90 void operator() (const PresenterCanvasFactory* pObject) { delete pObject; } 91 }; 92 93 94 ::boost::shared_ptr<PresenterCanvasFactory> PresenterCanvasFactory::mpInstance; 95 96 97 ::boost::shared_ptr<PresenterCanvasFactory> PresenterCanvasFactory::Instance (void) 98 { 99 ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); 100 if (mpInstance.get() == NULL) 101 { 102 mpInstance.reset(new PresenterCanvasFactory(), PresenterCanvasFactory::Deleter()); 103 } 104 105 return mpInstance; 106 } 107 108 109 110 111 void PresenterCanvasFactory::AddSharedWindow ( 112 const Reference<awt::XWindow>& rxWindow, 113 const Reference<rendering::XCanvas>& rxCanvas) 114 { 115 SharedWindowDescriptor aDescriptor; 116 117 if (mpSharedWindows->FindDescriptor(rxWindow) != mpSharedWindows->end()) 118 return; 119 120 aDescriptor.mxSharedWindow = rxWindow; 121 aDescriptor.mxSharedCanvas = rxCanvas; 122 123 // Store the new shared window only when both the window and the canvas 124 // are present. 125 if (aDescriptor.mxSharedCanvas.is() && aDescriptor.mxSharedCanvas.is()) 126 mpSharedWindows->push_back(aDescriptor); 127 } 128 129 130 131 132 void PresenterCanvasFactory::RemoveSharedWindow (const Reference<awt::XWindow>& rxWindow) 133 { 134 SharedWindowContainer::iterator iDescriptor = mpSharedWindows->FindDescriptor(rxWindow); 135 if (iDescriptor != mpSharedWindows->end()) 136 { 137 mpSharedWindows->erase(iDescriptor); 138 } 139 } 140 141 142 143 144 Reference<rendering::XCanvas> PresenterCanvasFactory::GetCanvas ( 145 const css::uno::Reference<css::awt::XWindow>& rxSharedWindow, 146 const css::uno::Reference<css::awt::XWindow>& rxWindow, 147 const sal_Int16 nRequestedCanvasFeatures, 148 const rtl::OUString& rsCanvasServiceName) 149 { 150 (void)nRequestedCanvasFeatures; 151 152 Reference<rendering::XCanvas> xCanvas; 153 154 if (rxSharedWindow.is() && rsCanvasServiceName.getLength()==0) 155 { 156 OSL_ASSERT(rxSharedWindow.is()); 157 xCanvas = CreateSharedCanvas(rxSharedWindow, rxWindow); 158 } 159 else 160 { 161 xCanvas = CreateCanvas(rxWindow, rsCanvasServiceName); 162 } 163 164 return xCanvas; 165 } 166 167 168 169 170 Reference<rendering::XCanvas> PresenterCanvasFactory::CreateSharedCanvas ( 171 const css::uno::Reference<css::awt::XWindow>& rxSharedWindow, 172 const css::uno::Reference<css::awt::XWindow>& rxWindow) const 173 { 174 // A shared window is given. Look it up and determine which canvas 175 // to return. 176 SharedWindowContainer::iterator iDescriptor ( 177 mpSharedWindows->FindDescriptor(rxSharedWindow)); 178 if (iDescriptor != mpSharedWindows->end()) 179 { 180 if (rxWindow == iDescriptor->mxSharedWindow || ! rxWindow.is()) 181 { 182 // A shared window itself is given. Return the previously 183 // created canvas. 184 return Reference<rendering::XCanvas>(iDescriptor->mxSharedCanvas, UNO_QUERY); 185 } 186 else 187 { 188 // A true child window is given. Create a canvas wrapper. 189 return new PresenterCanvas( 190 Reference<rendering::XCanvas>(iDescriptor->mxSharedCanvas, UNO_QUERY), 191 iDescriptor->mxSharedWindow, 192 rxWindow); 193 } 194 } 195 196 return NULL; 197 } 198 199 200 201 202 Reference<rendering::XCanvas> PresenterCanvasFactory::CreateCanvasForSprite ( 203 const css::uno::Reference<css::awt::XWindow>& rxSharedWindow, 204 const css::uno::Reference<css::awt::XWindow>& rxWindow) const 205 { 206 OSL_ASSERT(rxSharedWindow.is()); 207 (void)rxWindow.is(); 208 209 SharedWindowContainer::iterator iDescriptor ( 210 mpSharedWindows->FindDescriptor(rxSharedWindow)); 211 if (iDescriptor != mpSharedWindows->end()) 212 { 213 OSL_ASSERT(iDescriptor->mxSharedCanvas.is()); 214 Reference<rendering::XSpriteCanvas> xSpriteCanvas(iDescriptor->mxSharedCanvas, UNO_QUERY); 215 if (xSpriteCanvas.is()) 216 { 217 Reference<rendering::XCustomSprite> xSprite ( 218 xSpriteCanvas->createCustomSprite(geometry::RealSize2D(10,10))); 219 if (xSprite.is()) 220 { 221 return xSprite->getContentCanvas(); 222 } 223 } 224 } 225 return NULL; 226 } 227 228 229 230 231 Reference<rendering::XCanvas> PresenterCanvasFactory::CreateCanvas ( 232 const css::uno::Reference<css::awt::XWindow>& rxWindow, 233 const rtl::OUString& rsCanvasServiceName) const 234 { 235 // No shared window is given or an explicit canvas service name is 236 // specified. Create a new canvas. 237 ::Window* pWindow = VCLUnoHelper::GetWindow(rxWindow); 238 if (pWindow != NULL) 239 { 240 Sequence<Any> aArg (5); 241 242 // common: first any is VCL pointer to window (for VCL canvas) 243 aArg[0] = makeAny(reinterpret_cast<sal_Int64>(pWindow)); 244 aArg[1] = Any(); 245 aArg[2] = makeAny(::com::sun::star::awt::Rectangle()); 246 aArg[3] = makeAny(sal_False); 247 aArg[4] = makeAny(rxWindow); 248 249 Reference<lang::XMultiServiceFactory> xFactory (::comphelper::getProcessServiceFactory()); 250 return Reference<rendering::XCanvas>( 251 xFactory->createInstanceWithArguments( 252 rsCanvasServiceName.getLength()>0 253 ? rsCanvasServiceName 254 : OUString::createFromAscii("com.sun.star.rendering.VCLCanvas"), 255 aArg), 256 UNO_QUERY); 257 } 258 259 return NULL; 260 } 261 262 263 264 265 Reference<rendering::XCanvas> PresenterCanvasFactory::GetSharedCanvas ( 266 const Reference<awt::XWindow>& rxSharedWindow) 267 { 268 SharedWindowContainer::iterator iDescriptor = mpSharedWindows->FindDescriptor(rxSharedWindow); 269 if (iDescriptor != mpSharedWindows->end()) 270 return Reference<rendering::XCanvas>(iDescriptor->mxSharedCanvas, UNO_QUERY); 271 else 272 return NULL; 273 } 274 275 276 277 278 Reference<rendering::XCanvas> PresenterCanvasFactory::GetSharedCanvas ( 279 const Reference<rendering::XCanvas>& rxCanvas) 280 { 281 PresenterCanvas* pCanvas = dynamic_cast<PresenterCanvas*>(rxCanvas.get()); 282 if (pCanvas != NULL) 283 return pCanvas->GetSharedCanvas(); 284 else 285 return NULL; 286 } 287 288 289 290 291 PresenterCanvasFactory::PresenterCanvasFactory (void) 292 : mpSharedWindows(new SharedWindowContainer()) 293 { 294 } 295 296 297 298 299 PresenterCanvasFactory::~PresenterCanvasFactory (void) 300 { 301 mpSharedWindows.reset(); 302 } 303 304 305 306 307 } } // end of namespace ::sd::presenter 308