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