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:
FindDescriptor(const Reference<awt::XWindow> & rxWindow)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:
operator ()(const PresenterCanvasFactory * pObject)86     void operator() (const PresenterCanvasFactory* pObject) { delete pObject; }
87 };
88 
89 
90 ::boost::shared_ptr<PresenterCanvasFactory> PresenterCanvasFactory::mpInstance;
91 
92 
Instance(void)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 
AddSharedWindow(const Reference<awt::XWindow> & rxWindow,const Reference<rendering::XCanvas> & rxCanvas)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 
RemoveSharedWindow(const Reference<awt::XWindow> & rxWindow)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 
GetCanvas(const css::uno::Reference<css::awt::XWindow> & rxSharedWindow,const css::uno::Reference<css::awt::XWindow> & rxWindow,const sal_Int16 nRequestedCanvasFeatures,const rtl::OUString & rsCanvasServiceName)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 
CreateSharedCanvas(const css::uno::Reference<css::awt::XWindow> & rxSharedWindow,const css::uno::Reference<css::awt::XWindow> & rxWindow) const166 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 
CreateCanvasForSprite(const css::uno::Reference<css::awt::XWindow> & rxSharedWindow,const css::uno::Reference<css::awt::XWindow> & rxWindow) const198 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 
CreateCanvas(const css::uno::Reference<css::awt::XWindow> & rxWindow,const rtl::OUString & rsCanvasServiceName) const227 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 
GetSharedCanvas(const Reference<awt::XWindow> & rxSharedWindow)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 
GetSharedCanvas(const Reference<rendering::XCanvas> & rxCanvas)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 
PresenterCanvasFactory(void)287 PresenterCanvasFactory::PresenterCanvasFactory (void)
288     : mpSharedWindows(new SharedWindowContainer())
289 {
290 }
291 
292 
293 
294 
~PresenterCanvasFactory(void)295 PresenterCanvasFactory::~PresenterCanvasFactory (void)
296 {
297     mpSharedWindows.reset();
298 }
299 
300 
301 
302 
303 } } // end of namespace ::sd::presenter
304