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