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