cURL: follow redirects
[LibreOffice.git] / toolkit / source / awt / vclxtoolkit.cxx
blob116e77cb68ff02b2fabdb46a26aa4db102aecf06
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <stdio.h>
21 #ifdef _WIN32
22 #include <prewin.h>
23 #include <postwin.h>
24 #endif
25 #include <config_features.h>
26 #include <com/sun/star/awt/WindowAttribute.hpp>
27 #include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
28 #include <com/sun/star/awt/WindowClass.hpp>
29 #include <com/sun/star/awt/MessageBoxButtons.hpp>
30 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31 #include <com/sun/star/lang/SystemDependent.hpp>
32 #include <com/sun/star/awt/FocusEvent.hpp>
33 #include <com/sun/star/awt/KeyEvent.hpp>
34 #include <com/sun/star/awt/KeyModifier.hpp>
35 #include <com/sun/star/lang/EventObject.hpp>
36 #include <com/sun/star/uno/Reference.hxx>
37 #include <com/sun/star/uno/Sequence.hxx>
38 #include <com/sun/star/uno/XComponentContext.hpp>
39 #include <com/sun/star/uno/XInterface.hpp>
40 #include <com/sun/star/beans/NamedValue.hpp>
41 #include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp>
42 #include <com/sun/star/lang/XServiceInfo.hpp>
43 #include <com/sun/star/awt/XToolkitExperimental.hpp>
44 #include <com/sun/star/awt/XToolkitRobot.hpp>
45 #include <com/sun/star/awt/XMessageBoxFactory.hpp>
47 #include <cppuhelper/bootstrap.hxx>
48 #include <cppuhelper/compbase.hxx>
49 #include <cppuhelper/interfacecontainer.hxx>
50 #include <cppuhelper/supportsservice.hxx>
51 #include <cppuhelper/typeprovider.hxx>
52 #include <osl/conditn.hxx>
53 #include <osl/module.h>
54 #include <osl/thread.h>
55 #include <osl/mutex.hxx>
56 #include <rtl/uuid.h>
57 #include <rtl/process.h>
58 #include <tools/link.hxx>
59 #include <tools/fract.hxx>
60 #include <tools/wintypes.hxx>
62 #ifdef MACOSX
63 #include "premac.h"
64 #include <Cocoa/Cocoa.h>
65 #include "postmac.h"
66 #endif
68 #include <vcl/sysdata.hxx>
70 #include <toolkit/awt/vclxwindows.hxx>
71 #include <toolkit/awt/vclxsystemdependentwindow.hxx>
72 #include <toolkit/awt/vclxregion.hxx>
73 #include <toolkit/awt/vclxtabpagecontainer.hxx>
75 #include <toolkit/awt/animatedimagespeer.hxx>
76 #include <toolkit/awt/vclxtopwindow.hxx>
77 #include <toolkit/awt/vclxwindow.hxx>
78 #include <toolkit/helper/vclunohelper.hxx>
79 #include <toolkit/helper/servicenames.hxx>
81 #include <toolkit/helper/macros.hxx>
82 #include <toolkit/helper/convert.hxx>
83 #include <vcl/unohelp.hxx>
84 #include <vcl/button.hxx>
85 #include <vcl/combobox.hxx>
86 #include <vcl/ctrl.hxx>
87 #include <vcl/dialog.hxx>
88 #include <vcl/dockingarea.hxx>
89 #include <vcl/dockwin.hxx>
90 #include <vcl/edit.hxx>
91 #include <vcl/field.hxx>
92 #include <vcl/fixed.hxx>
93 #include <vcl/floatwin.hxx>
94 #include <vcl/group.hxx>
95 #include <vcl/scheduler.hxx>
96 #include <vcl/imgctrl.hxx>
97 #include <vcl/longcurr.hxx>
98 #include <vcl/lstbox.hxx>
99 #include <vcl/menubtn.hxx>
100 #include <vcl/morebtn.hxx>
101 #include <vcl/msgbox.hxx>
102 #include <vcl/scrbar.hxx>
103 #include <vcl/spin.hxx>
104 #include <vcl/split.hxx>
105 #include <vcl/splitwin.hxx>
106 #include <vcl/status.hxx>
107 #include <vcl/svapp.hxx>
108 #include <vcl/syschild.hxx>
109 #include <vcl/tabctrl.hxx>
110 #include <vcl/tabdlg.hxx>
111 #include <vcl/tabpage.hxx>
112 #include <vcl/toolbox.hxx>
113 #include <vcl/virdev.hxx>
114 #include <vcl/window.hxx>
115 #include <vcl/wrkwin.hxx>
116 #include <vcl/throbber.hxx>
117 #if HAVE_FEATURE_OPENGL
118 #include <vcl/opengl/OpenGLWrapper.hxx>
119 #endif
120 #include "toolkit/awt/vclxspinbutton.hxx"
121 #include <tools/debug.hxx>
122 #include <comphelper/processfactory.hxx>
123 #include <toolkit/awt/scrollabledialog.hxx>
125 #include "helper/unowrapper.hxx"
127 #define VCLWINDOW_FRAMEWINDOW 0x1000
128 #define VCLWINDOW_SYSTEMCHILDWINDOW 0x1001
130 #if defined(_WIN32)
131 #define SYSTEM_DEPENDENT_TYPE css::lang::SystemDependent::SYSTEM_WIN32
132 #elif defined(MACOSX)
133 #define SYSTEM_DEPENDENT_TYPE css::lang::SystemDependent::SYSTEM_MAC
134 #elif defined(UNX)
135 #define SYSTEM_DEPENDENT_TYPE css::lang::SystemDependent::SYSTEM_XWINDOW
136 #endif
138 namespace {
140 extern "C" typedef vcl::Window* (SAL_CALL *FN_SvtCreateWindow)(
141 VCLXWindow** ppNewComp,
142 const css::awt::WindowDescriptor* pDescriptor,
143 vcl::Window* pParent,
144 WinBits nWinBits );
146 class Pause : public Idle
148 public:
149 explicit Pause(sal_Int32 nPauseMilliseconds) :
150 Idle("pause"),
151 m_nPauseMilliseconds(nPauseMilliseconds)
153 SetPriority(SchedulerPriority::HIGHEST);
154 Start();
157 virtual ~Pause() override
161 virtual void Invoke() override
163 SolarMutexGuard aSolarGuard;
164 osl::Thread::wait(std::chrono::milliseconds(m_nPauseMilliseconds));
165 Stop();
166 delete this;
169 sal_Int32 m_nPauseMilliseconds;
172 class VCLXToolkitMutexHelper
174 protected:
175 ::osl::Mutex maMutex;
178 class VCLXToolkit : public VCLXToolkitMutexHelper,
179 public cppu::WeakComponentImplHelper<
180 css::awt::XToolkitExperimental,
181 css::awt::XToolkitRobot,
182 css::lang::XServiceInfo >
184 css::uno::Reference< css::datatransfer::clipboard::XClipboard > mxClipboard;
185 css::uno::Reference< css::datatransfer::clipboard::XClipboard > mxSelection;
187 oslModule hSvToolsLib;
188 FN_SvtCreateWindow fnSvtCreateWindow;
190 ::comphelper::OInterfaceContainerHelper2 m_aTopWindowListeners;
191 ::comphelper::OInterfaceContainerHelper2 m_aKeyHandlers;
192 ::comphelper::OInterfaceContainerHelper2 m_aFocusListeners;
193 ::Link<VclSimpleEvent&,void> m_aEventListenerLink;
194 ::Link<VclWindowEvent&,bool> m_aKeyListenerLink;
195 bool m_bEventListener;
196 bool m_bKeyListener;
198 DECL_LINK(eventListenerHandler, ::VclSimpleEvent&, void);
200 DECL_LINK(keyListenerHandler, ::VclWindowEvent&, bool);
202 void callTopWindowListeners(
203 ::VclSimpleEvent const * pEvent,
204 void (SAL_CALL css::awt::XTopWindowListener::* pFn)(
205 css::lang::EventObject const &));
207 bool callKeyHandlers(::VclSimpleEvent const * pEvent, bool bPressed);
209 void callFocusListeners(::VclSimpleEvent const * pEvent, bool bGained);
211 protected:
212 ::osl::Mutex& GetMutex() { return maMutex; }
214 virtual void SAL_CALL disposing() override;
216 static vcl::Window* ImplCreateWindow( VCLXWindow** ppNewComp, const css::awt::WindowDescriptor& rDescriptor, vcl::Window* pParent, WinBits nWinBits );
217 css::uno::Reference< css::awt::XWindowPeer > ImplCreateWindow( const css::awt::WindowDescriptor& Descriptor, WinBits nWinBits );
219 public:
221 VCLXToolkit();
222 virtual ~VCLXToolkit() override;
224 // css::awt::XToolkitExperimental
225 virtual void SAL_CALL processEventsToIdle()
226 throw (css::uno::RuntimeException, std::exception) override;
228 virtual sal_Int64 SAL_CALL getOpenGLBufferSwapCounter()
229 throw (css::uno::RuntimeException, std::exception) override;
231 virtual void SAL_CALL setDeterministicScheduling(sal_Bool bDeterministicMode)
232 throw (css::uno::RuntimeException, std::exception) override;
234 virtual void SAL_CALL pause(sal_Int32 nMilliseconds)
235 throw (css::uno::RuntimeException, std::exception) override;
237 // css::awt::XToolkit
238 css::uno::Reference< css::awt::XWindowPeer > SAL_CALL getDesktopWindow( ) throw(css::uno::RuntimeException, std::exception) override;
239 css::awt::Rectangle SAL_CALL getWorkArea( ) throw(css::uno::RuntimeException, std::exception) override;
240 css::uno::Reference< css::awt::XWindowPeer > SAL_CALL createWindow( const css::awt::WindowDescriptor& Descriptor ) throw(css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) override;
241 css::uno::Sequence< css::uno::Reference< css::awt::XWindowPeer > > SAL_CALL createWindows( const css::uno::Sequence< css::awt::WindowDescriptor >& Descriptors ) throw(css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) override;
242 css::uno::Reference< css::awt::XDevice > SAL_CALL createScreenCompatibleDevice( sal_Int32 Width, sal_Int32 Height ) throw
243 (css::uno::RuntimeException, std::exception) override;
244 css::uno::Reference< css::awt::XRegion > SAL_CALL createRegion( ) throw(css::uno::RuntimeException, std::exception) override;
246 // css::awt::XSystemChildFactory
247 css::uno::Reference< css::awt::XWindowPeer > SAL_CALL createSystemChild( const css::uno::Any& Parent, const css::uno::Sequence< sal_Int8 >& ProcessId, sal_Int16 SystemType ) throw(css::uno::RuntimeException, std::exception) override;
249 // css::awt::XMessageBoxFactory
250 virtual css::uno::Reference< css::awt::XMessageBox > SAL_CALL createMessageBox( const css::uno::Reference< css::awt::XWindowPeer >& aParent, css::awt::MessageBoxType eType, ::sal_Int32 aButtons, const OUString& aTitle, const OUString& aMessage ) throw (css::uno::RuntimeException, std::exception) override;
252 // css::awt::XDataTransfer
253 css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer > SAL_CALL getDragGestureRecognizer( const css::uno::Reference< css::awt::XWindow >& window ) throw(css::uno::RuntimeException, std::exception) override;
254 css::uno::Reference< css::datatransfer::dnd::XDragSource > SAL_CALL getDragSource( const css::uno::Reference< css::awt::XWindow >& window ) throw(css::uno::RuntimeException, std::exception) override;
255 css::uno::Reference< css::datatransfer::dnd::XDropTarget > SAL_CALL getDropTarget( const css::uno::Reference< css::awt::XWindow >& window ) throw(css::uno::RuntimeException, std::exception) override;
256 css::uno::Reference< css::datatransfer::clipboard::XClipboard > SAL_CALL getClipboard( const OUString& clipboardName ) throw(css::uno::RuntimeException, std::exception) override;
258 // css::lang::XServiceInfo
259 OUString SAL_CALL getImplementationName( ) throw(css::uno::RuntimeException, std::exception) override;
260 sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(css::uno::RuntimeException, std::exception) override;
261 css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(css::uno::RuntimeException, std::exception) override;
263 // css::awt::XExtendedToolkit:
265 virtual ::sal_Int32 SAL_CALL getTopWindowCount()
266 throw (css::uno::RuntimeException, std::exception) override;
268 virtual css::uno::Reference< css::awt::XTopWindow >
269 SAL_CALL getTopWindow(::sal_Int32 nIndex)
270 throw (css::uno::RuntimeException, std::exception) override;
272 virtual css::uno::Reference< css::awt::XTopWindow >
273 SAL_CALL getActiveTopWindow()
274 throw (css::uno::RuntimeException, std::exception) override;
276 virtual void SAL_CALL addTopWindowListener(
277 css::uno::Reference<
278 css::awt::XTopWindowListener > const & rListener)
279 throw (css::uno::RuntimeException, std::exception) override;
281 virtual void SAL_CALL removeTopWindowListener(
282 css::uno::Reference<
283 css::awt::XTopWindowListener > const & rListener)
284 throw (css::uno::RuntimeException, std::exception) override;
286 virtual void SAL_CALL addKeyHandler(
287 css::uno::Reference<
288 css::awt::XKeyHandler > const & rHandler)
289 throw (css::uno::RuntimeException, std::exception) override;
291 virtual void SAL_CALL removeKeyHandler(
292 css::uno::Reference<
293 css::awt::XKeyHandler > const & rHandler)
294 throw (css::uno::RuntimeException, std::exception) override;
296 virtual void SAL_CALL addFocusListener(
297 css::uno::Reference<
298 css::awt::XFocusListener > const & rListener)
299 throw (css::uno::RuntimeException, std::exception) override;
301 virtual void SAL_CALL removeFocusListener(
302 css::uno::Reference<
303 css::awt::XFocusListener > const & rListener)
304 throw (css::uno::RuntimeException, std::exception) override;
306 virtual void SAL_CALL fireFocusGained(
307 css::uno::Reference<
308 css::uno::XInterface > const & source)
309 throw (css::uno::RuntimeException, std::exception) override;
311 virtual void SAL_CALL fireFocusLost(
312 css::uno::Reference<
313 css::uno::XInterface > const & source)
314 throw (css::uno::RuntimeException, std::exception) override;
316 // css::awt::XReschedule:
317 virtual void SAL_CALL reschedule()
318 throw (css::uno::RuntimeException, std::exception) override;
320 // css:awt:XToolkitRobot
321 virtual void SAL_CALL keyPress( const css::awt::KeyEvent & aKeyEvent )
322 throw (css::uno::RuntimeException, std::exception) override;
324 virtual void SAL_CALL keyRelease( const css::awt::KeyEvent & aKeyEvent )
325 throw (css::uno::RuntimeException, std::exception) override;
327 virtual void SAL_CALL mousePress( const css::awt::MouseEvent & aMouseEvent )
328 throw (css::uno::RuntimeException, std::exception) override;
330 virtual void SAL_CALL mouseRelease( const css::awt::MouseEvent & aMouseEvent )
331 throw (css::uno::RuntimeException, std::exception) override;
333 virtual void SAL_CALL mouseMove( const css::awt::MouseEvent & aMouseEvent )
334 throw (css::uno::RuntimeException, std::exception) override;
338 WinBits ImplGetWinBits( sal_uInt32 nComponentAttribs, sal_uInt16 nCompType )
340 WinBits nWinBits = 0;
342 bool bMessBox = false;
343 if ( ( nCompType == WINDOW_INFOBOX ) ||
344 ( nCompType == WINDOW_MESSBOX ) ||
345 ( nCompType == WINDOW_QUERYBOX ) ||
346 ( nCompType == WINDOW_WARNINGBOX ) ||
347 ( nCompType == WINDOW_ERRORBOX ) )
349 bMessBox = true;
352 bool bDecoratedWindow = false;
353 if ( bMessBox
354 || ( nCompType == WINDOW_DIALOG )
355 || ( nCompType == WINDOW_MODELESSDIALOG )
356 || ( nCompType == WINDOW_MODALDIALOG )
357 || ( nCompType == WINDOW_SYSTEMDIALOG )
358 || ( nCompType == WINDOW_PATHDIALOG )
359 || ( nCompType == WINDOW_FILEDIALOG )
360 || ( nCompType == WINDOW_PRINTERSETUPDIALOG )
361 || ( nCompType == WINDOW_PRINTDIALOG )
362 || ( nCompType == WINDOW_COLORDIALOG )
363 || ( nCompType == WINDOW_FONTDIALOG )
364 || ( nCompType == WINDOW_DOCKINGWINDOW )
365 || ( nCompType == WINDOW_TABDIALOG )
366 || ( nCompType == WINDOW_BUTTONDIALOG )
367 || ( nCompType == WINDOW_SYSTEMCHILDWINDOW )
370 bDecoratedWindow = true;
373 if( nComponentAttribs & css::awt::WindowAttribute::BORDER )
374 nWinBits |= WB_BORDER;
375 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::NOBORDER )
376 nWinBits |= WB_NOBORDER;
377 if( nComponentAttribs & css::awt::WindowAttribute::SIZEABLE )
378 nWinBits |= WB_SIZEABLE;
379 if( nComponentAttribs & css::awt::WindowAttribute::MOVEABLE )
380 nWinBits |= WB_MOVEABLE;
381 if( nComponentAttribs & css::awt::WindowAttribute::CLOSEABLE )
382 nWinBits |= WB_CLOSEABLE;
383 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::HSCROLL )
384 nWinBits |= WB_HSCROLL;
385 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::VSCROLL )
386 nWinBits |= WB_VSCROLL;
387 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::LEFT )
388 nWinBits |= WB_LEFT;
389 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::CENTER )
390 nWinBits |= WB_CENTER;
391 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::RIGHT )
392 nWinBits |= WB_RIGHT;
393 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::SPIN )
394 nWinBits |= WB_SPIN;
395 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::SORT )
396 nWinBits |= WB_SORT;
397 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DROPDOWN )
398 nWinBits |= WB_DROPDOWN;
399 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEFBUTTON )
400 nWinBits |= WB_DEFBUTTON;
401 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::READONLY )
402 nWinBits |= WB_READONLY;
403 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::CLIPCHILDREN )
404 nWinBits |= WB_CLIPCHILDREN;
405 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::GROUP )
406 nWinBits |= WB_GROUP;
407 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::NOLABEL ) //added for issue79712
408 nWinBits |= WB_NOLABEL;
410 // These bits are not uniqe
411 if ( bMessBox )
413 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::OK )
414 nWinBits |= WB_OK;
415 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::OK_CANCEL )
416 nWinBits |= WB_OK_CANCEL;
417 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::YES_NO )
418 nWinBits |= WB_YES_NO;
419 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::YES_NO_CANCEL )
420 nWinBits |= WB_YES_NO_CANCEL;
421 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::RETRY_CANCEL )
422 nWinBits |= WB_RETRY_CANCEL;
423 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_OK )
424 nWinBits |= WB_DEF_OK;
425 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_CANCEL )
426 nWinBits |= WB_DEF_CANCEL;
427 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_RETRY )
428 nWinBits |= WB_DEF_RETRY;
429 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_YES )
430 nWinBits |= WB_DEF_YES;
431 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_NO )
432 nWinBits |= WB_DEF_NO;
434 if ( nCompType == WINDOW_MULTILINEEDIT || nCompType == WINDOW_DIALOG || nCompType == WINDOW_GROUPBOX )
436 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::AUTOHSCROLL )
437 nWinBits |= WB_AUTOHSCROLL;
438 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::AUTOVSCROLL )
439 nWinBits |= WB_AUTOVSCROLL;
443 if ( bDecoratedWindow )
445 if( nComponentAttribs & css::awt::WindowAttribute::NODECORATION )
447 // No decoration removes several window attributes and must
448 // set WB_NOBORDER!
449 nWinBits &= ~WB_BORDER;
450 nWinBits &= ~WB_SIZEABLE;
451 nWinBits &= ~WB_MOVEABLE;
452 nWinBits &= ~WB_CLOSEABLE;
453 nWinBits |= WB_NOBORDER;
457 return nWinBits;
460 struct ComponentInfo
462 const char* pName;
463 WindowType nWinType;
466 static ComponentInfo aComponentInfos [] =
468 { "buttondialog", WINDOW_BUTTONDIALOG },
469 { "cancelbutton", WINDOW_CANCELBUTTON },
470 { "checkbox", WINDOW_CHECKBOX },
471 { "combobox", WINDOW_COMBOBOX },
472 { "control", WINDOW_CONTROL },
473 { "currencybox", WINDOW_CURRENCYBOX },
474 { "currencyfield", WINDOW_CURRENCYFIELD },
475 { "datebox", WINDOW_DATEBOX },
476 { "datefield", WINDOW_DATEFIELD },
477 { "dialog", WINDOW_DIALOG },
478 { "dockingarea", WINDOW_DOCKINGAREA },
479 { "dockingwindow", WINDOW_DOCKINGWINDOW },
480 { "edit", WINDOW_EDIT },
481 { "errorbox", WINDOW_ERRORBOX },
482 { "fixedbitmap", WINDOW_FIXEDBITMAP },
483 { "fixedimage", WINDOW_FIXEDIMAGE },
484 { "fixedline", WINDOW_FIXEDLINE },
485 { "fixedtext", WINDOW_FIXEDTEXT },
486 { "floatingwindow", WINDOW_FLOATINGWINDOW },
487 { "framewindow", VCLWINDOW_FRAMEWINDOW },
488 { "groupbox", WINDOW_GROUPBOX },
489 { "frame", WINDOW_GROUPBOX },
490 { "helpbutton", WINDOW_HELPBUTTON },
491 { "imagebutton", WINDOW_IMAGEBUTTON },
492 { "infobox", WINDOW_INFOBOX },
493 { "listbox", WINDOW_LISTBOX },
494 { "longcurrencybox", WINDOW_LONGCURRENCYBOX },
495 { "longcurrencyfield", WINDOW_LONGCURRENCYFIELD },
496 { "menubutton", WINDOW_MENUBUTTON },
497 { "messbox", WINDOW_MESSBOX },
498 { "metricbox", WINDOW_METRICBOX },
499 { "metricfield", WINDOW_METRICFIELD },
500 { "modaldialog", WINDOW_MODALDIALOG },
501 { "modelessdialog", WINDOW_MODELESSDIALOG },
502 { "morebutton", WINDOW_MOREBUTTON },
503 { "multilineedit", WINDOW_MULTILINEEDIT },
504 { "multilistbox", WINDOW_MULTILISTBOX },
505 { "numericbox", WINDOW_NUMERICBOX },
506 { "numericfield", WINDOW_NUMERICFIELD },
507 { "okbutton", WINDOW_OKBUTTON },
508 { "patternbox", WINDOW_PATTERNBOX },
509 { "patternfield", WINDOW_PATTERNFIELD },
510 { "pushbutton", WINDOW_PUSHBUTTON },
511 { "querybox", WINDOW_QUERYBOX },
512 { "radiobutton", WINDOW_RADIOBUTTON },
513 { "scrollbar", WINDOW_SCROLLBAR },
514 { "scrollbarbox", WINDOW_SCROLLBARBOX },
515 { "animatedimages", WINDOW_CONTROL },
516 { "spinbutton", WINDOW_SPINBUTTON },
517 { "spinfield", WINDOW_SPINFIELD },
518 { "splitter", WINDOW_SPLITTER },
519 { "splitwindow", WINDOW_SPLITWINDOW },
520 { "statusbar", WINDOW_STATUSBAR },
521 { "systemchildwindow", VCLWINDOW_SYSTEMCHILDWINDOW },
522 { "tabcontrol", WINDOW_TABCONTROL },
523 { "tabdialog", WINDOW_TABDIALOG },
524 { "tabpage", WINDOW_TABPAGE },
525 { "timebox", WINDOW_TIMEBOX },
526 { "timefield", WINDOW_TIMEFIELD },
527 { "toolbox", WINDOW_TOOLBOX },
528 { "tristatebox", WINDOW_TRISTATEBOX },
529 { "warningbox", WINDOW_WARNINGBOX },
530 { "window", WINDOW_WINDOW },
531 { "workwindow", WINDOW_WORKWINDOW },
532 { "tabpagecontainer", WINDOW_CONTROL },
533 { "tabpagemodel", WINDOW_TABPAGE }
536 extern "C"
538 static int SAL_CALL ComponentInfoCompare( const void* pFirst, const void* pSecond)
540 return( strcmp( static_cast<ComponentInfo const *>(pFirst)->pName,
541 static_cast<ComponentInfo const *>(pSecond)->pName ) );
545 sal_uInt16 ImplGetComponentType( const OUString& rServiceName )
547 static bool bSorted = false;
548 if( !bSorted )
550 qsort( static_cast<void*>(aComponentInfos),
551 sizeof( aComponentInfos ) / sizeof( ComponentInfo ),
552 sizeof( ComponentInfo ),
553 ComponentInfoCompare );
554 bSorted = true;
558 ComponentInfo aSearch;
559 OString aServiceName(OUStringToOString(rServiceName, osl_getThreadTextEncoding()).toAsciiLowerCase());
560 if ( !aServiceName.isEmpty() )
561 aSearch.pName = aServiceName.getStr();
562 else
563 aSearch.pName = "window";
565 ComponentInfo* pInf = static_cast<ComponentInfo*>(bsearch( &aSearch,
566 static_cast<void*>(aComponentInfos),
567 sizeof( aComponentInfos ) / sizeof( ComponentInfo ),
568 sizeof( ComponentInfo ),
569 ComponentInfoCompare ));
571 return pInf ? pInf->nWinType : 0;
575 namespace
577 struct MessageBoxTypeInfo
579 css::awt::MessageBoxType eType;
580 const sal_Char *pName;
581 sal_Int32 nLen;
584 static const MessageBoxTypeInfo aMessageBoxTypeInfo[] =
586 { css::awt::MessageBoxType_MESSAGEBOX, RTL_CONSTASCII_STRINGPARAM("messbox") },
587 { css::awt::MessageBoxType_INFOBOX, RTL_CONSTASCII_STRINGPARAM("infobox") },
588 { css::awt::MessageBoxType_WARNINGBOX, RTL_CONSTASCII_STRINGPARAM("warningbox") },
589 { css::awt::MessageBoxType_ERRORBOX, RTL_CONSTASCII_STRINGPARAM("errorbox") },
590 { css::awt::MessageBoxType_QUERYBOX, RTL_CONSTASCII_STRINGPARAM("querybox") },
591 { css::awt::MessageBoxType_MAKE_FIXED_SIZE, nullptr, 0 }
594 bool lcl_convertMessageBoxType(
595 rtl::OUString &sType,
596 css::awt::MessageBoxType eType )
598 const MessageBoxTypeInfo *pMap = aMessageBoxTypeInfo;
599 css::awt::MessageBoxType eVal = css::awt::MessageBoxType_MAKE_FIXED_SIZE;
601 while ( pMap->pName )
603 if ( pMap->eType == eType )
605 eVal = eType;
606 sType = rtl::OUString( pMap->pName, pMap->nLen, RTL_TEXTENCODING_ASCII_US );
607 break;
609 pMap++;
612 return ( eVal != css::awt::MessageBoxType_MAKE_FIXED_SIZE );
616 static sal_Int32 nVCLToolkitInstanceCount = 0;
617 static bool bInitedByVCLToolkit = false;
619 osl::Mutex & getInitMutex()
621 static osl::Mutex * pM;
622 if( !pM )
624 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
625 if( !pM )
627 static osl::Mutex aMutex;
628 pM = &aMutex;
631 return *pM;
634 osl::Condition & getInitCondition()
636 static osl::Condition * pC = nullptr;
637 if( !pC )
639 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
640 if( !pC )
642 static osl::Condition aCondition;
643 pC = &aCondition;
646 return *pC;
649 extern "C"
651 static void SAL_CALL ToolkitWorkerFunction( void* pArgs )
653 osl_setThreadName("VCLXToolkit VCL main thread");
655 css::uno::Reference<css::lang::XMultiServiceFactory> xServiceManager;
658 xServiceManager = ::comphelper::getProcessServiceFactory();
660 catch (const css::uno::DeploymentException&)
663 if (!xServiceManager.is())
665 css::uno::Reference<css::uno::XComponentContext> xContext =
666 ::cppu::defaultBootstrap_InitialComponentContext();
668 xServiceManager.set( xContext->getServiceManager(), css::uno::UNO_QUERY_THROW );
669 // set global process service factory used by unotools config helpers
670 ::comphelper::setProcessServiceFactory( xServiceManager );
673 VCLXToolkit * pTk = static_cast<VCLXToolkit *>(pArgs);
674 bInitedByVCLToolkit = InitVCL();
675 if( bInitedByVCLToolkit )
677 UnoWrapper* pUnoWrapper = new UnoWrapper( pTk );
678 Application::SetUnoWrapper( pUnoWrapper );
680 getInitCondition().set();
681 if( bInitedByVCLToolkit )
684 SolarMutexGuard aGuard;
685 Application::Execute();
689 pTk->dispose();
691 catch( css::uno::Exception & )
694 DeInitVCL();
696 else
698 // having the thread join itself is pretty stupid.
699 // but we can't get the osl_Thread to destroy here so just leak it.
704 // constructor, which might initialize VCL
705 VCLXToolkit::VCLXToolkit():
706 cppu::WeakComponentImplHelper<
707 css::awt::XToolkitExperimental,
708 css::awt::XToolkitRobot,
709 css::lang::XServiceInfo>( GetMutex() ),
710 m_aTopWindowListeners(rBHelper.rMutex),
711 m_aKeyHandlers(rBHelper.rMutex),
712 m_aFocusListeners(rBHelper.rMutex),
713 m_aEventListenerLink(LINK(this, VCLXToolkit, eventListenerHandler)),
714 m_aKeyListenerLink(LINK(this, VCLXToolkit, keyListenerHandler)),
715 m_bEventListener(false),
716 m_bKeyListener(false)
718 hSvToolsLib = nullptr;
719 fnSvtCreateWindow = nullptr;
721 osl::Guard< osl::Mutex > aGuard( getInitMutex() );
722 nVCLToolkitInstanceCount++;
723 if( ( nVCLToolkitInstanceCount == 1 ) && ( !Application::IsInMain() ) )
725 // setup execute thread
726 CreateMainLoopThread( ToolkitWorkerFunction, this );
727 getInitCondition().wait();
731 VCLXToolkit::~VCLXToolkit()
736 void SAL_CALL VCLXToolkit::disposing()
738 #ifndef DISABLE_DYNLOADING
739 if ( hSvToolsLib )
741 osl_unloadModule( hSvToolsLib );
742 hSvToolsLib = nullptr;
743 fnSvtCreateWindow = nullptr;
745 #endif
748 osl::Guard< osl::Mutex > aGuard( getInitMutex() );
749 if( --nVCLToolkitInstanceCount == 0 )
751 if( bInitedByVCLToolkit )
753 Application::Quit();
754 JoinMainLoopThread();
755 bInitedByVCLToolkit = false;
760 if (m_bEventListener)
762 ::Application::RemoveEventListener(m_aEventListenerLink);
763 m_bEventListener = false;
765 if (m_bKeyListener)
767 ::Application::RemoveKeyListener(m_aKeyListenerLink);
768 m_bKeyListener = false;
770 css::lang::EventObject aEvent(
771 static_cast< ::cppu::OWeakObject * >(this));
772 m_aTopWindowListeners.disposeAndClear(aEvent);
773 m_aKeyHandlers.disposeAndClear(aEvent);
774 m_aFocusListeners.disposeAndClear(aEvent);
778 css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::getDesktopWindow( ) throw(css::uno::RuntimeException, std::exception)
780 css::uno::Reference< css::awt::XWindowPeer > xRef;
781 // 07/00: AppWindow doesn't exist anymore...
782 return xRef;
785 css::awt::Rectangle VCLXToolkit::getWorkArea( ) throw(css::uno::RuntimeException, std::exception)
787 sal_Int32 nDisplay = Application::GetDisplayBuiltInScreen();
788 Rectangle aWorkRect = Application::GetScreenPosSizePixel( nDisplay );
789 css::awt::Rectangle aNotherRect;
790 aNotherRect.X = aWorkRect.getX();
791 aNotherRect.Y = aWorkRect.getY();
792 aNotherRect.Width = aWorkRect.getWidth();
793 aNotherRect.Height = aWorkRect.getHeight();
794 return aNotherRect;
797 css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::createWindow( const css::awt::WindowDescriptor& rDescriptor ) throw(css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception)
799 return ImplCreateWindow( rDescriptor, WinBits(0) );
802 css::uno::Reference< css::awt::XDevice > VCLXToolkit::createScreenCompatibleDevice( sal_Int32 Width, sal_Int32 Height ) throw(css::uno::RuntimeException, std::exception)
804 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
806 css::uno::Reference< css::awt::XDevice > xRef;
807 VCLXVirtualDevice* pVDev = new VCLXVirtualDevice;
809 SolarMutexGuard aSolarGuard;
811 VclPtrInstance<VirtualDevice> pV;
812 pV->SetOutputSizePixel( Size( Width, Height ) );
813 pVDev->SetVirtualDevice( pV );
815 xRef = pVDev;
816 return xRef;
819 css::uno::Reference< css::awt::XRegion > VCLXToolkit::createRegion( ) throw(css::uno::RuntimeException, std::exception)
821 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
823 css::uno::Reference< css::awt::XRegion > xRef = new VCLXRegion;
824 return xRef;
827 vcl::Window* VCLXToolkit::ImplCreateWindow( VCLXWindow** ppNewComp,
828 const css::awt::WindowDescriptor& rDescriptor,
829 vcl::Window* pParent, WinBits nWinBits )
831 OUString aServiceName( rDescriptor.WindowServiceName );
832 aServiceName = aServiceName.toAsciiLowerCase();
834 VclPtr<vcl::Window> pNewWindow;
835 sal_uInt16 nType = ImplGetComponentType( aServiceName );
836 bool bFrameControl = false;
837 if ( aServiceName == "frame" )
838 bFrameControl = true;
839 if ( aServiceName == "tabcontrolnotabs" )
841 nWinBits |= WB_NOBORDER;
842 nType = ImplGetComponentType( "tabcontrol" );
844 if ( !pParent )
846 // Wenn die Component einen Parent braucht, dann NULL zurueckgeben,
847 // spaeter mal css::uno::Exception...
848 bool bException = true;
849 if ( ( nType == WINDOW_DIALOG )
850 || ( nType == WINDOW_MODALDIALOG )
851 || ( nType == WINDOW_MODELESSDIALOG )
852 || ( nType == WINDOW_MESSBOX )
853 || ( nType == WINDOW_INFOBOX )
854 || ( nType == WINDOW_WARNINGBOX )
855 || ( nType == WINDOW_ERRORBOX )
856 || ( nType == WINDOW_QUERYBOX )
858 bException = false;
859 else if ( ( nType == WINDOW_WINDOW ) ||
860 ( nType == WINDOW_WORKWINDOW ) ||
861 ( nType == VCLWINDOW_FRAMEWINDOW ) )
863 if ( rDescriptor.Type == css::awt::WindowClass_TOP )
864 bException = false;
867 if ( bException )
869 *ppNewComp = nullptr;
870 return nullptr;
874 if ( nType )
876 SolarMutexGuard aVclGuard;
877 switch ( (WindowType)nType )
879 case WINDOW_CANCELBUTTON:
880 pNewWindow = VclPtr<CancelButton>::Create( pParent, nWinBits );
881 *ppNewComp = new VCLXButton;
882 break;
883 case WINDOW_CHECKBOX:
884 pNewWindow = VclPtr<CheckBox>::Create( pParent, nWinBits );
885 *ppNewComp = new VCLXCheckBox;
886 break;
887 case WINDOW_COMBOBOX:
888 pNewWindow = VclPtr<ComboBox>::Create( pParent, nWinBits|WB_AUTOHSCROLL );
889 static_cast<ComboBox*>(pNewWindow.get())->EnableAutoSize( false );
890 *ppNewComp = new VCLXComboBox;
891 break;
892 case WINDOW_CURRENCYBOX:
893 pNewWindow = VclPtr<CurrencyBox>::Create( pParent, nWinBits );
894 break;
895 case WINDOW_CURRENCYFIELD:
896 pNewWindow = VclPtr<CurrencyField>::Create( pParent, nWinBits );
897 static_cast<CurrencyField*>(pNewWindow.get())->EnableEmptyFieldValue( true );
898 *ppNewComp = new VCLXNumericField;
899 static_cast<VCLXFormattedSpinField*>(*ppNewComp)->SetFormatter( static_cast<FormatterBase*>(static_cast<CurrencyField*>(pNewWindow.get())) );
900 break;
901 case WINDOW_DATEBOX:
902 pNewWindow = VclPtr<DateBox>::Create( pParent, nWinBits );
903 break;
904 case WINDOW_DATEFIELD:
905 pNewWindow = VclPtr<DateField>::Create( pParent, nWinBits );
906 static_cast<DateField*>(pNewWindow.get())->EnableEmptyFieldValue( true );
907 *ppNewComp = new VCLXDateField;
908 static_cast<VCLXFormattedSpinField*>(*ppNewComp)->SetFormatter( static_cast<FormatterBase*>(static_cast<DateField*>(pNewWindow.get())) );
909 break;
910 case WINDOW_DOCKINGAREA:
911 pNewWindow = VclPtr<DockingAreaWindow>::Create( pParent );
912 break;
913 case WINDOW_MULTILINEEDIT:
914 case WINDOW_EDIT:
915 pNewWindow = VclPtr<Edit>::Create( pParent, nWinBits );
916 *ppNewComp = new VCLXEdit;
917 break;
918 case WINDOW_ERRORBOX:
919 pNewWindow = VclPtr<ErrorBox>::Create( pParent, nWinBits, OUString() );
920 *ppNewComp = new VCLXMessageBox;
921 break;
922 case WINDOW_FIXEDBITMAP:
923 pNewWindow = VclPtr<FixedBitmap>::Create( pParent, nWinBits );
924 break;
925 case WINDOW_FIXEDIMAGE:
926 pNewWindow = VclPtr<ImageControl>::Create( pParent, nWinBits );
927 *ppNewComp = new VCLXImageControl;
928 break;
929 case WINDOW_FIXEDLINE:
930 pNewWindow = VclPtr<FixedLine>::Create( pParent, nWinBits );
931 break;
932 case WINDOW_FIXEDTEXT:
933 pNewWindow = VclPtr<FixedText>::Create( pParent, nWinBits );
934 *ppNewComp = new VCLXFixedText;
935 break;
936 case WINDOW_FLOATINGWINDOW:
937 pNewWindow = VclPtr<FloatingWindow>::Create( pParent, nWinBits );
938 break;
939 case WINDOW_GROUPBOX:
940 pNewWindow = VclPtr<GroupBox>::Create( pParent, nWinBits );
941 if ( bFrameControl )
943 GroupBox* pGroupBox = static_cast< GroupBox* >( pNewWindow.get() );
944 *ppNewComp = new VCLXFrame;
945 // Frame control needs to receive
946 // Mouse events
947 pGroupBox->SetMouseTransparent( false );
949 break;
950 case WINDOW_HELPBUTTON:
951 pNewWindow = VclPtr<HelpButton>::Create( pParent, nWinBits );
952 *ppNewComp = new VCLXButton;
953 break;
954 case WINDOW_IMAGEBUTTON:
955 pNewWindow = VclPtr<ImageButton>::Create( pParent, nWinBits );
956 *ppNewComp = new VCLXButton;
957 break;
958 case WINDOW_INFOBOX:
959 pNewWindow = VclPtr<InfoBox>::Create( pParent, OUString() );
960 *ppNewComp = new VCLXMessageBox;
961 break;
962 case WINDOW_LISTBOX:
963 pNewWindow = VclPtr<ListBox>::Create( pParent, nWinBits|WB_SIMPLEMODE|WB_AUTOHSCROLL );
964 static_cast<ListBox*>(pNewWindow.get())->EnableAutoSize( false );
965 *ppNewComp = new VCLXListBox;
966 break;
967 case WINDOW_LONGCURRENCYBOX:
968 pNewWindow = VclPtr<LongCurrencyBox>::Create( pParent, nWinBits );
969 break;
970 case WINDOW_LONGCURRENCYFIELD:
971 pNewWindow = VclPtr<LongCurrencyField>::Create( pParent, nWinBits );
972 *ppNewComp = new VCLXCurrencyField;
973 static_cast<VCLXFormattedSpinField*>(*ppNewComp)->SetFormatter( static_cast<FormatterBase*>(static_cast<LongCurrencyField*>(pNewWindow.get())) );
974 break;
975 case WINDOW_MENUBUTTON:
976 pNewWindow = VclPtr<MenuButton>::Create( pParent, nWinBits );
977 *ppNewComp = new VCLXButton;
978 break;
979 case WINDOW_MESSBOX:
980 pNewWindow = VclPtr<MessBox>::Create( pParent, nWinBits, OUString(), OUString() );
981 *ppNewComp = new VCLXMessageBox;
982 break;
983 case WINDOW_METRICBOX:
984 pNewWindow = VclPtr<MetricBox>::Create( pParent, nWinBits );
985 break;
986 case WINDOW_METRICFIELD:
987 pNewWindow = VclPtr<MetricField>::Create( pParent, nWinBits );
988 *ppNewComp = new VCLXMetricField;
989 static_cast<VCLXFormattedSpinField*>(*ppNewComp)->SetFormatter( static_cast<FormatterBase*>(static_cast<MetricField*>(pNewWindow.get())) );
990 break;
991 case WINDOW_DIALOG:
992 case WINDOW_MODALDIALOG:
993 case WINDOW_MODELESSDIALOG:
995 // Modal/Modeless nur durch Show/Execute
996 if ( (pParent == nullptr ) && ( rDescriptor.ParentIndex == -1 ) )
997 pNewWindow = VclPtr<toolkit::ScrollableWrapper<Dialog>>::Create( nullptr, nWinBits, Dialog::InitFlag::NoParent );
998 else
999 pNewWindow = VclPtr<toolkit::ScrollableWrapper<Dialog>>::Create( pParent, nWinBits );
1000 // #i70217# Don't always create a new component object. It's possible that VCL has called
1001 // GetComponentInterface( sal_True ) in the Dialog ctor itself (see Window::IsTopWindow() )
1002 // which creates a component object.
1003 css::uno::Reference< css::awt::XWindowPeer > xWinPeer = pNewWindow->GetComponentInterface( false );
1004 if ( xWinPeer.is() )
1005 *ppNewComp = dynamic_cast< VCLXDialog* >( xWinPeer.get() );
1006 else
1007 *ppNewComp = new VCLXDialog;
1009 break;
1010 case WINDOW_MOREBUTTON:
1011 pNewWindow = VclPtr<MoreButton>::Create( pParent, nWinBits );
1012 *ppNewComp = new VCLXButton;
1013 break;
1014 case WINDOW_MULTILISTBOX:
1015 pNewWindow = VclPtr<MultiListBox>::Create( pParent, nWinBits );
1016 *ppNewComp = new VCLXListBox;
1017 break;
1018 case WINDOW_NUMERICBOX:
1019 pNewWindow = VclPtr<NumericBox>::Create( pParent, nWinBits );
1020 break;
1021 case WINDOW_NUMERICFIELD:
1022 pNewWindow = VclPtr<NumericField>::Create( pParent, nWinBits );
1023 static_cast<NumericField*>(pNewWindow.get())->EnableEmptyFieldValue( true );
1024 *ppNewComp = new VCLXNumericField;
1025 static_cast<VCLXFormattedSpinField*>(*ppNewComp)->SetFormatter( static_cast<FormatterBase*>(static_cast<NumericField*>(pNewWindow.get())) );
1026 break;
1027 case WINDOW_OKBUTTON:
1028 pNewWindow = VclPtr<OKButton>::Create( pParent, nWinBits );
1029 *ppNewComp = new VCLXButton;
1030 break;
1031 case WINDOW_PATTERNBOX:
1032 pNewWindow = VclPtr<PatternBox>::Create( pParent, nWinBits );
1033 break;
1034 case WINDOW_PATTERNFIELD:
1035 pNewWindow = VclPtr<PatternField>::Create( pParent, nWinBits );
1036 *ppNewComp = new VCLXPatternField;
1037 static_cast<VCLXFormattedSpinField*>(*ppNewComp)->SetFormatter( static_cast<FormatterBase*>(static_cast<PatternField*>(pNewWindow.get())) );
1038 break;
1039 case WINDOW_PUSHBUTTON:
1040 pNewWindow = VclPtr<PushButton>::Create( pParent, nWinBits );
1041 *ppNewComp = new VCLXButton;
1042 break;
1043 case WINDOW_QUERYBOX:
1044 pNewWindow = VclPtr<QueryBox>::Create( pParent, nWinBits, OUString() );
1045 *ppNewComp = new VCLXMessageBox;
1046 break;
1047 case WINDOW_RADIOBUTTON:
1048 pNewWindow = VclPtr<RadioButton>::Create( pParent, nWinBits );
1049 *ppNewComp = new VCLXRadioButton;
1051 // by default, disable RadioCheck
1052 // Since the VCLXRadioButton really cares for its RadioCheck settings, this is important:
1053 // if we enable it, the VCLXRadioButton will use RadioButton::Check instead of RadioButton::SetState
1054 // This leads to a strange behaviour if the control is newly created: when settings the initial
1055 // state to "checked", the RadioButton::Check (called because RadioCheck=sal_True) will uncheck
1056 // _all_other_ radio buttons in the same group. However, at this moment the grouping of the controls
1057 // is not really valid: the controls are grouped after they have been created, but we're still in
1058 // the creation process, so the RadioButton::Check relies on invalid grouping information.
1059 // 07.08.2001 - #87254# - frank.schoenheit@sun.com
1060 static_cast<RadioButton*>(pNewWindow.get())->EnableRadioCheck( false );
1061 break;
1062 case WINDOW_SCROLLBAR:
1063 pNewWindow = VclPtr<ScrollBar>::Create( pParent, nWinBits );
1064 *ppNewComp = new VCLXScrollBar;
1065 break;
1066 case WINDOW_SCROLLBARBOX:
1067 pNewWindow = VclPtr<ScrollBarBox>::Create( pParent, nWinBits );
1068 break;
1069 case WINDOW_SPINBUTTON:
1070 pNewWindow = VclPtr<SpinButton>::Create( pParent, nWinBits );
1071 *ppNewComp = new ::toolkit::VCLXSpinButton;
1072 break;
1073 case WINDOW_SPINFIELD:
1074 pNewWindow = VclPtr<SpinField>::Create( pParent, nWinBits );
1075 *ppNewComp = new VCLXNumericField;
1076 break;
1077 case WINDOW_SPLITTER:
1078 pNewWindow = VclPtr<Splitter>::Create( pParent, nWinBits );
1079 break;
1080 case WINDOW_SPLITWINDOW:
1081 pNewWindow = VclPtr<SplitWindow>::Create( pParent, nWinBits );
1082 break;
1083 case WINDOW_STATUSBAR:
1084 pNewWindow = VclPtr<StatusBar>::Create( pParent, nWinBits );
1085 break;
1086 case VCLWINDOW_SYSTEMCHILDWINDOW:
1087 pNewWindow = VclPtr<SystemChildWindow>::Create( pParent, nWinBits );
1088 *ppNewComp = new VCLXSystemDependentWindow();
1089 break;
1090 case WINDOW_TABCONTROL:
1091 pNewWindow = VclPtr<TabControl>::Create( pParent, nWinBits );
1092 *ppNewComp = new VCLXMultiPage;
1093 break;
1094 case WINDOW_TABDIALOG:
1095 pNewWindow = VclPtr<TabDialog>::Create( pParent, nWinBits );
1096 break;
1097 case WINDOW_TABPAGE:
1099 pNewWindow = VclPtr<TabPage>::Create( pParent, nWinBits );
1100 *ppNewComp = new VCLXTabPage;
1102 break;
1103 case WINDOW_TIMEBOX:
1104 pNewWindow = VclPtr<TimeBox>::Create( pParent, nWinBits );
1105 break;
1106 case WINDOW_TIMEFIELD:
1107 pNewWindow = VclPtr<TimeField>::Create( pParent, nWinBits );
1108 static_cast<TimeField*>(pNewWindow.get())->EnableEmptyFieldValue( true );
1109 *ppNewComp = new VCLXTimeField;
1110 static_cast<VCLXFormattedSpinField*>(*ppNewComp)->SetFormatter( static_cast<FormatterBase*>(static_cast<TimeField*>(pNewWindow.get())) );
1111 break;
1112 case WINDOW_TOOLBOX:
1113 pNewWindow = VclPtr<ToolBox>::Create( pParent, nWinBits );
1114 *ppNewComp = new VCLXToolBox;
1115 break;
1116 case WINDOW_TRISTATEBOX:
1117 pNewWindow = VclPtr<TriStateBox>::Create( pParent, nWinBits );
1118 break;
1119 case WINDOW_WARNINGBOX:
1120 pNewWindow = VclPtr<WarningBox>::Create( pParent, nWinBits, OUString() );
1121 *ppNewComp = new VCLXMessageBox;
1122 break;
1123 case WINDOW_WORKWINDOW:
1124 case WINDOW_WINDOW:
1125 case VCLWINDOW_FRAMEWINDOW:
1126 case WINDOW_DOCKINGWINDOW:
1127 if ( rDescriptor.Type == css::awt::WindowClass_TOP )
1129 if (nType == WINDOW_DOCKINGWINDOW )
1130 pNewWindow = VclPtr<DockingWindow>::Create( pParent, nWinBits );
1131 else
1133 if ((pParent == nullptr) && rDescriptor.Parent.is())
1135 // try to get a system dependent window handle
1136 css::uno::Reference< css::awt::XSystemDependentWindowPeer > xSystemDepParent(rDescriptor.Parent, css::uno::UNO_QUERY);
1138 if (xSystemDepParent.is())
1140 sal_Int8 processID[16];
1142 rtl_getGlobalProcessId( reinterpret_cast<sal_uInt8*>(processID) );
1144 css::uno::Sequence<sal_Int8> processIdSeq(processID, 16);
1146 css::uno::Any anyHandle = xSystemDepParent->getWindowHandle(processIdSeq, SYSTEM_DEPENDENT_TYPE);
1148 // use sal_Int64 here to accommodate all int types
1149 // uno::Any shift operator whill upcast if necessary
1150 sal_Int64 nWindowHandle = 0;
1151 bool bXEmbed = false;
1153 bool bUseParentData = true;
1154 if( ! (anyHandle >>= nWindowHandle) )
1156 css::uno::Sequence< css::beans::NamedValue > aProps;
1157 if( anyHandle >>= aProps )
1159 const int nProps = aProps.getLength();
1160 const css::beans::NamedValue* pProps = aProps.getConstArray();
1161 for( int i = 0; i < nProps; i++ )
1163 if ( pProps[i].Name == "WINDOW" )
1164 pProps[i].Value >>= nWindowHandle;
1165 else if ( pProps[i].Name == "XEMBED" )
1166 pProps[i].Value >>= bXEmbed;
1169 else
1170 bUseParentData = false;
1173 if( bUseParentData )
1175 SystemParentData aParentData;
1176 aParentData.nSize = sizeof( aParentData );
1177 #if defined MACOSX
1178 aParentData.pView = reinterpret_cast<NSView*>(nWindowHandle);
1179 #elif defined ANDROID
1180 // Nothing
1181 #elif defined IOS
1182 // Nothing
1183 #elif defined UNX
1184 aParentData.aWindow = nWindowHandle;
1185 aParentData.bXEmbedSupport = bXEmbed;
1186 #elif defined WNT
1187 aParentData.hWnd = reinterpret_cast<HWND>(nWindowHandle);
1188 #endif
1189 pNewWindow = VclPtr<WorkWindow>::Create( &aParentData );
1194 if (!pNewWindow)
1195 pNewWindow = VclPtr<WorkWindow>::Create( pParent, nWinBits );
1198 *ppNewComp = new VCLXTopWindow( pNewWindow->GetType() == WINDOW_WORKWINDOW );
1200 else if ( rDescriptor.Type == css::awt::WindowClass_CONTAINER )
1202 if (nType == WINDOW_DOCKINGWINDOW )
1203 pNewWindow = VclPtr<DockingWindow>::Create( pParent, nWinBits );
1204 else
1205 pNewWindow = VclPtr<vcl::Window>::Create( pParent, nWinBits );
1206 *ppNewComp = new VCLXContainer;
1208 else
1210 if (nType == WINDOW_DOCKINGWINDOW )
1211 pNewWindow = VclPtr<DockingWindow>::Create( pParent, nWinBits );
1212 else
1213 pNewWindow = VclPtr<vcl::Window>::Create( pParent, nWinBits );
1214 *ppNewComp = new VCLXWindow;
1216 break;
1217 case WINDOW_CONTROL:
1218 if ( rDescriptor.WindowServiceName.equalsIgnoreAsciiCase(
1219 "tabpagecontainer" ) )
1221 pNewWindow = VclPtr<TabControl>::Create( pParent, nWinBits );
1222 *ppNewComp = new VCLXTabPageContainer;
1224 else if ( aServiceName == "animatedimages" )
1226 pNewWindow = VclPtr<Throbber>::Create( pParent, nWinBits );
1227 *ppNewComp = new ::toolkit::AnimatedImagesPeer;
1229 break;
1230 default:
1231 OSL_ENSURE( false, "VCLXToolkit::ImplCreateWindow: unknown window type!" );
1232 break;
1236 return pNewWindow;
1239 #ifndef DISABLE_DYNLOADING
1241 extern "C" { static void SAL_CALL thisModule() {} }
1243 #else
1245 extern "C" vcl::Window* SAL_CALL CreateWindow( VCLXWindow** ppNewComp, const css::awt::WindowDescriptor* pDescriptor, vcl::Window* pParent, WinBits nWinBits );
1247 #endif
1249 css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::ImplCreateWindow(
1250 const css::awt::WindowDescriptor& rDescriptor,
1251 WinBits nForceWinBits )
1253 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1255 SolarMutexGuard aSolarGuard;
1257 css::uno::Reference< css::awt::XWindowPeer > xRef;
1259 VclPtr<vcl::Window> pParent;
1260 if ( rDescriptor.Parent.is() )
1262 VCLXWindow* pParentComponent = VCLXWindow::GetImplementation( rDescriptor.Parent );
1264 // #103939# Don't throw assertion, may be it's a system dependent window, used in ImplCreateWindow.
1265 // DBG_ASSERT( pParentComponent, "ParentComponent not valid" );
1267 if ( pParentComponent )
1268 pParent = pParentComponent->GetWindow();
1270 WinBits nWinBits = ImplGetWinBits( rDescriptor.WindowAttributes,
1271 ImplGetComponentType( rDescriptor.WindowServiceName ) );
1272 nWinBits |= nForceWinBits;
1274 VCLXWindow* pNewComp = nullptr;
1276 vcl::Window* pNewWindow = nullptr;
1277 // Try to create the window with SvTools
1278 // (do this _before_ creating it on our own: The old mechanism (extended toolkit in SvTools) did it this way,
1279 // and we need to stay compatible)
1280 // try to load the lib
1281 if ( !fnSvtCreateWindow
1282 #ifndef DISABLE_DYNLOADING
1283 && !hSvToolsLib
1284 #endif
1287 #ifndef DISABLE_DYNLOADING
1288 OUString aLibName(SVT_DLL_NAME);
1289 hSvToolsLib = osl_loadModuleRelative(
1290 &thisModule, aLibName.pData, SAL_LOADMODULE_DEFAULT );
1291 if ( hSvToolsLib )
1293 OUString aFunctionName( "CreateWindow" );
1294 fnSvtCreateWindow = reinterpret_cast<FN_SvtCreateWindow>(osl_getFunctionSymbol( hSvToolsLib, aFunctionName.pData ));
1296 #else
1297 fnSvtCreateWindow = CreateWindow;
1298 #endif
1300 // ask the SvTool creation function
1301 if ( fnSvtCreateWindow )
1302 pNewWindow = fnSvtCreateWindow( &pNewComp, &rDescriptor, pParent, nWinBits );
1304 // if SvTools could not provide a window, create it ourself
1305 if ( !pNewWindow )
1306 pNewWindow = ImplCreateWindow( &pNewComp, rDescriptor, pParent, nWinBits );
1308 DBG_ASSERT( pNewWindow, "createWindow: Unknown Component!" );
1309 SAL_INFO_IF( !pNewComp, "toolkit", "createWindow: No special Interface!" );
1311 if ( pNewWindow )
1313 pNewWindow->SetCreatedWithToolkit( true );
1314 //pNewWindow->SetPosPixel( Point() ); // do not force (0,0) position, keep default pos instead
1316 if ( rDescriptor.WindowAttributes & css::awt::WindowAttribute::MINSIZE )
1318 pNewWindow->SetSizePixel( Size() );
1320 else if ( rDescriptor.WindowAttributes & css::awt::WindowAttribute::FULLSIZE )
1322 if ( pParent )
1323 pNewWindow->SetSizePixel( pParent->GetOutputSizePixel() );
1325 else if ( !VCLUnoHelper::IsZero( rDescriptor.Bounds ) )
1327 Rectangle aRect = VCLRectangle( rDescriptor.Bounds );
1328 pNewWindow->SetPosSizePixel( aRect.TopLeft(), aRect.GetSize() );
1331 if ( !pNewComp )
1333 // Default-Interface
1334 xRef = pNewWindow->GetComponentInterface();
1336 else
1338 pNewComp->SetCreatedWithToolkit( true );
1339 xRef = pNewComp;
1340 pNewWindow->SetComponentInterface( xRef );
1342 DBG_ASSERT( pNewWindow->GetComponentInterface( false ) == xRef,
1343 "VCLXToolkit::createWindow: did #133706# resurge?" );
1345 if ( rDescriptor.WindowAttributes & css::awt::WindowAttribute::SHOW )
1346 pNewWindow->Show();
1349 return xRef;
1352 css::uno::Sequence< css::uno::Reference< css::awt::XWindowPeer > > VCLXToolkit::createWindows( const css::uno::Sequence< css::awt::WindowDescriptor >& rDescriptors ) throw(css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception)
1354 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1356 sal_uInt32 nComponents = rDescriptors.getLength();
1357 css::uno::Sequence< css::uno::Reference< css::awt::XWindowPeer > > aSeq( nComponents );
1358 for ( sal_uInt32 n = 0; n < nComponents; n++ )
1360 css::awt::WindowDescriptor aDescr = rDescriptors.getConstArray()[n];
1362 if ( aDescr.ParentIndex == (-1) )
1363 aDescr.Parent = nullptr;
1364 else if ( ( aDescr.ParentIndex >= 0 ) && ( aDescr.ParentIndex < (short)n ) )
1365 aDescr.Parent = aSeq.getConstArray()[aDescr.ParentIndex];
1366 aSeq.getArray()[n] = createWindow( aDescr );
1368 return aSeq;
1371 // css::awt::XSystemChildFactory
1372 css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::createSystemChild( const css::uno::Any& Parent, const css::uno::Sequence< sal_Int8 >& /*ProcessId*/, sal_Int16 nSystemType ) throw(css::uno::RuntimeException, std::exception)
1374 VclPtr<vcl::Window> pChildWindow;
1375 if ( nSystemType == SYSTEM_DEPENDENT_TYPE )
1377 // use sal_Int64 here to accommodate all int types
1378 // uno::Any shift operator whill upcast if necessary
1379 sal_Int64 nWindowHandle = 0;
1380 bool bXEmbed = false;
1382 bool bUseParentData = true;
1383 if( ! (Parent >>= nWindowHandle) )
1385 css::uno::Sequence< css::beans::NamedValue > aProps;
1386 if( Parent >>= aProps )
1388 const int nProps = aProps.getLength();
1389 const css::beans::NamedValue* pProps = aProps.getConstArray();
1390 for( int i = 0; i < nProps; i++ )
1392 if ( pProps[i].Name == "WINDOW" )
1393 pProps[i].Value >>= nWindowHandle;
1394 else if ( pProps[i].Name == "XEMBED" )
1395 pProps[i].Value >>= bXEmbed;
1398 else
1399 bUseParentData = false;
1402 if( bUseParentData )
1404 SystemParentData aParentData;
1405 aParentData.nSize = sizeof( aParentData );
1406 #if defined MACOSX
1407 aParentData.pView = reinterpret_cast<NSView*>(nWindowHandle);
1408 #elif defined ANDROID
1409 // Nothing
1410 #elif defined IOS
1411 // Nothing
1412 #elif defined UNX
1413 aParentData.aWindow = nWindowHandle;
1414 aParentData.bXEmbedSupport = bXEmbed;
1415 #elif defined WNT
1416 aParentData.hWnd = reinterpret_cast<HWND>(nWindowHandle);
1417 #endif
1418 SolarMutexGuard aGuard;
1421 pChildWindow.reset( VclPtr<WorkWindow>::Create( &aParentData ) );
1423 catch ( const css::uno::RuntimeException & rEx )
1425 // system child window could not be created
1426 OSL_TRACE(
1427 "VCLXToolkit::createSystemChild: caught %s\n",
1428 OUStringToOString(
1429 rEx.Message, RTL_TEXTENCODING_UTF8).getStr());
1430 pChildWindow.clear();
1434 else if (nSystemType == css::lang::SystemDependent::SYSTEM_JAVA)
1436 SolarMutexGuard aGuard;
1437 pChildWindow.reset(VclPtr<WorkWindow>::Create(nullptr, Parent));
1440 css::uno::Reference< css::awt::XWindowPeer > xPeer;
1441 if ( pChildWindow )
1443 VCLXTopWindow* pPeer = new VCLXTopWindow(true);
1444 SolarMutexGuard aGuard;
1445 pPeer->SetWindow( pChildWindow );
1446 xPeer = pPeer;
1449 return xPeer;
1452 // css::awt::XMessageBoxFactory
1453 css::uno::Reference< css::awt::XMessageBox > SAL_CALL VCLXToolkit::createMessageBox(
1454 const css::uno::Reference< css::awt::XWindowPeer >& aParent,
1455 css::awt::MessageBoxType eType,
1456 ::sal_Int32 aButtons,
1457 const OUString& aTitle,
1458 const OUString& aMessage ) throw (css::uno::RuntimeException, std::exception)
1460 css::awt::WindowDescriptor aDescriptor;
1462 sal_Int32 nWindowAttributes = css::awt::WindowAttribute::BORDER|css::awt::WindowAttribute::MOVEABLE|css::awt::WindowAttribute::CLOSEABLE;
1464 // Map button definitions to window attributes
1465 if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_OK )
1466 nWindowAttributes |= css::awt::VclWindowPeerAttribute::OK;
1467 else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_OK_CANCEL )
1468 nWindowAttributes |= css::awt::VclWindowPeerAttribute::OK_CANCEL;
1469 else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_YES_NO )
1470 nWindowAttributes |= css::awt::VclWindowPeerAttribute::YES_NO;
1471 else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_YES_NO_CANCEL )
1472 nWindowAttributes |= css::awt::VclWindowPeerAttribute::YES_NO_CANCEL;
1473 else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_RETRY_CANCEL )
1474 nWindowAttributes |= css::awt::VclWindowPeerAttribute::RETRY_CANCEL;
1476 // Map default button definitions to window attributes
1477 if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_OK )
1478 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_OK;
1479 else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_CANCEL )
1480 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_CANCEL;
1481 else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_YES )
1482 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_YES;
1483 else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_NO )
1484 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_NO;
1485 else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_RETRY )
1486 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_RETRY;
1488 // No more bits for VclWindowPeerAttribute possible. Mapping must be
1489 // done explicitly using VCL methods
1490 WinBits nAddWinBits( 0 );
1491 if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_ABORT_IGNORE_RETRY )
1492 nAddWinBits |= WB_ABORT_RETRY_IGNORE;
1493 if ( sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_IGNORE )
1494 nAddWinBits |= WB_DEF_IGNORE;
1496 rtl::OUString aType;
1497 lcl_convertMessageBoxType( aType, eType );
1499 aDescriptor.Type = css::awt::WindowClass_MODALTOP;
1500 aDescriptor.WindowServiceName = aType;
1501 aDescriptor.ParentIndex = -1;
1502 aDescriptor.Parent = aParent;
1503 aDescriptor.WindowAttributes = nWindowAttributes;
1504 css::uno::Reference< css::awt::XMessageBox > xMsgBox(
1505 ImplCreateWindow( aDescriptor, nAddWinBits ), css::uno::UNO_QUERY );
1506 css::uno::Reference< css::awt::XWindow > xWindow( xMsgBox, css::uno::UNO_QUERY );
1507 if ( xMsgBox.is() && xWindow.is() )
1509 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
1510 if ( pWindow )
1512 SolarMutexGuard aGuard;
1513 xMsgBox->setCaptionText( aTitle );
1514 xMsgBox->setMessageText( aMessage );
1518 return xMsgBox;
1521 css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer > SAL_CALL VCLXToolkit::getDragGestureRecognizer( const css::uno::Reference< css::awt::XWindow >& window ) throw(css::uno::RuntimeException, std::exception)
1523 SolarMutexGuard g;
1525 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( window );
1527 if( pWindow )
1528 return pWindow->GetDragGestureRecognizer();
1530 return css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer >();
1533 css::uno::Reference< css::datatransfer::dnd::XDragSource > SAL_CALL VCLXToolkit::getDragSource( const css::uno::Reference< css::awt::XWindow >& window ) throw(css::uno::RuntimeException, std::exception)
1535 SolarMutexGuard g;
1537 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( window );
1539 if( pWindow )
1540 return pWindow->GetDragSource();
1542 return css::uno::Reference< css::datatransfer::dnd::XDragSource >();
1545 css::uno::Reference< css::datatransfer::dnd::XDropTarget > SAL_CALL VCLXToolkit::getDropTarget( const css::uno::Reference< css::awt::XWindow >& window ) throw(css::uno::RuntimeException, std::exception)
1547 SolarMutexGuard g;
1549 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( window );
1551 if( pWindow )
1552 return pWindow->GetDropTarget();
1554 return css::uno::Reference< css::datatransfer::dnd::XDropTarget >();
1557 css::uno::Reference< css::datatransfer::clipboard::XClipboard > SAL_CALL VCLXToolkit::getClipboard( const OUString& clipboardName ) throw(css::uno::RuntimeException, std::exception)
1559 if( clipboardName.isEmpty() )
1561 if( !mxClipboard.is() )
1563 // remember clipboard here
1564 mxClipboard = css::datatransfer::clipboard::SystemClipboard::create(
1565 comphelper::getProcessComponentContext());
1568 return mxClipboard;
1571 else if( clipboardName == "Selection" )
1573 return mxSelection;
1576 return css::uno::Reference< css::datatransfer::clipboard::XClipboard >();
1579 // XServiceInfo
1580 OUString VCLXToolkit::getImplementationName() throw(css::uno::RuntimeException, std::exception)
1582 return OUString("stardiv.Toolkit.VCLXToolkit");
1585 sal_Bool VCLXToolkit::supportsService( const OUString& rServiceName ) throw(css::uno::RuntimeException, std::exception)
1587 return cppu::supportsService(this, rServiceName);
1590 css::uno::Sequence< OUString > VCLXToolkit::getSupportedServiceNames() throw(css::uno::RuntimeException, std::exception)
1592 return css::uno::Sequence<OUString>{
1593 "com.sun.star.awt.Toolkit", "stardiv.vcl.VclToolkit"};
1596 // css::awt::XExtendedToolkit:
1598 // virtual
1599 ::sal_Int32 SAL_CALL VCLXToolkit::getTopWindowCount()
1600 throw (css::uno::RuntimeException, std::exception)
1602 return static_cast< ::sal_Int32 >(::Application::GetTopWindowCount());
1603 // XXX numeric overflow
1606 // virtual
1607 css::uno::Reference< css::awt::XTopWindow > SAL_CALL
1608 VCLXToolkit::getTopWindow(::sal_Int32 nIndex)
1609 throw (css::uno::RuntimeException, std::exception)
1611 vcl::Window * p = ::Application::GetTopWindow(static_cast< long >(nIndex));
1612 // XXX numeric overflow
1613 return css::uno::Reference< css::awt::XTopWindow >(
1614 p == nullptr ? nullptr : static_cast< css::awt::XWindow * >(p->GetWindowPeer()),
1615 css::uno::UNO_QUERY);
1618 // virtual
1619 css::uno::Reference< css::awt::XTopWindow > SAL_CALL
1620 VCLXToolkit::getActiveTopWindow() throw (css::uno::RuntimeException, std::exception)
1622 vcl::Window * p = ::Application::GetActiveTopWindow();
1623 return css::uno::Reference< css::awt::XTopWindow >(
1624 p == nullptr ? nullptr : static_cast< css::awt::XWindow * >(p->GetWindowPeer()),
1625 css::uno::UNO_QUERY);
1628 // virtual
1629 void SAL_CALL VCLXToolkit::addTopWindowListener(
1630 css::uno::Reference< css::awt::XTopWindowListener > const & rListener)
1631 throw (css::uno::RuntimeException, std::exception)
1633 OSL_ENSURE(rListener.is(), "Null rListener");
1634 ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
1635 if (rBHelper.bDisposed || rBHelper.bInDispose)
1637 aGuard.clear();
1638 rListener->disposing(
1639 css::lang::EventObject(
1640 static_cast< ::cppu::OWeakObject * >(this)));
1642 else if (m_aTopWindowListeners.addInterface(rListener) == 1
1643 && !m_bEventListener)
1645 m_bEventListener = true;
1646 ::Application::AddEventListener(m_aEventListenerLink);
1650 // virtual
1651 void SAL_CALL VCLXToolkit::removeTopWindowListener(
1652 css::uno::Reference< css::awt::XTopWindowListener > const & rListener)
1653 throw (css::uno::RuntimeException, std::exception)
1655 ::osl::MutexGuard aGuard(rBHelper.rMutex);
1656 if (!(rBHelper.bDisposed || rBHelper.bInDispose)
1657 && m_aTopWindowListeners.removeInterface(rListener) == 0
1658 && m_aFocusListeners.getLength() == 0 && m_bEventListener)
1660 ::Application::RemoveEventListener(m_aEventListenerLink);
1661 m_bEventListener = false;
1665 // virtual
1666 void SAL_CALL VCLXToolkit::addKeyHandler(
1667 css::uno::Reference< css::awt::XKeyHandler > const & rHandler)
1668 throw (css::uno::RuntimeException, std::exception)
1670 OSL_ENSURE(rHandler.is(), "Null rHandler");
1671 ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
1672 if (rBHelper.bDisposed || rBHelper.bInDispose)
1674 aGuard.clear();
1675 rHandler->disposing(
1676 css::lang::EventObject(
1677 static_cast< ::cppu::OWeakObject * >(this)));
1679 else if (m_aKeyHandlers.addInterface(rHandler) == 1 && !m_bKeyListener)
1681 m_bKeyListener = true;
1682 ::Application::AddKeyListener(m_aKeyListenerLink);
1686 // virtual
1687 void SAL_CALL VCLXToolkit::removeKeyHandler(
1688 css::uno::Reference< css::awt::XKeyHandler > const & rHandler)
1689 throw (css::uno::RuntimeException, std::exception)
1691 ::osl::MutexGuard aGuard(rBHelper.rMutex);
1692 if (!(rBHelper.bDisposed || rBHelper.bInDispose)
1693 && m_aKeyHandlers.removeInterface(rHandler) == 0 && m_bKeyListener)
1695 ::Application::RemoveKeyListener(m_aKeyListenerLink);
1696 m_bKeyListener = false;
1700 // virtual
1701 void SAL_CALL VCLXToolkit::addFocusListener(
1702 css::uno::Reference< css::awt::XFocusListener > const & rListener)
1703 throw (css::uno::RuntimeException, std::exception)
1705 OSL_ENSURE(rListener.is(), "Null rListener");
1706 ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
1707 if (rBHelper.bDisposed || rBHelper.bInDispose)
1709 aGuard.clear();
1710 rListener->disposing(
1711 css::lang::EventObject(
1712 static_cast< ::cppu::OWeakObject * >(this)));
1714 else if (m_aFocusListeners.addInterface(rListener) == 1
1715 && !m_bEventListener)
1717 m_bEventListener = true;
1718 ::Application::AddEventListener(m_aEventListenerLink);
1722 // virtual
1723 void SAL_CALL VCLXToolkit::removeFocusListener(
1724 css::uno::Reference< css::awt::XFocusListener > const & rListener)
1725 throw (css::uno::RuntimeException, std::exception)
1727 ::osl::MutexGuard aGuard(rBHelper.rMutex);
1728 if (!(rBHelper.bDisposed || rBHelper.bInDispose)
1729 && m_aFocusListeners.removeInterface(rListener) == 0
1730 && m_aTopWindowListeners.getLength() == 0 && m_bEventListener)
1732 ::Application::RemoveEventListener(m_aEventListenerLink);
1733 m_bEventListener = false;
1737 // virtual
1738 void SAL_CALL VCLXToolkit::fireFocusGained(
1739 css::uno::Reference<
1740 css::uno::XInterface > const &)
1741 throw (css::uno::RuntimeException, std::exception)
1745 // virtual
1746 void SAL_CALL VCLXToolkit::fireFocusLost(
1747 css::uno::Reference<
1748 css::uno::XInterface > const &)
1749 throw (css::uno::RuntimeException, std::exception)
1754 IMPL_LINK(VCLXToolkit, eventListenerHandler, ::VclSimpleEvent&, rEvent, void)
1756 switch (rEvent.GetId())
1758 case VCLEVENT_WINDOW_SHOW:
1759 callTopWindowListeners(
1760 &rEvent, &css::awt::XTopWindowListener::windowOpened);
1761 break;
1762 case VCLEVENT_WINDOW_HIDE:
1763 callTopWindowListeners(
1764 &rEvent, &css::awt::XTopWindowListener::windowClosed);
1765 break;
1766 case VCLEVENT_WINDOW_ACTIVATE:
1767 callTopWindowListeners(
1768 &rEvent, &css::awt::XTopWindowListener::windowActivated);
1769 break;
1770 case VCLEVENT_WINDOW_DEACTIVATE:
1771 callTopWindowListeners(
1772 &rEvent, &css::awt::XTopWindowListener::windowDeactivated);
1773 break;
1774 case VCLEVENT_WINDOW_CLOSE:
1775 callTopWindowListeners(
1776 &rEvent, &css::awt::XTopWindowListener::windowClosing);
1777 break;
1778 case VCLEVENT_WINDOW_GETFOCUS:
1779 callFocusListeners(&rEvent, true);
1780 break;
1781 case VCLEVENT_WINDOW_LOSEFOCUS:
1782 callFocusListeners(&rEvent, false);
1783 break;
1784 case VCLEVENT_WINDOW_MINIMIZE:
1785 callTopWindowListeners(
1786 &rEvent, &css::awt::XTopWindowListener::windowMinimized);
1787 break;
1788 case VCLEVENT_WINDOW_NORMALIZE:
1789 callTopWindowListeners(
1790 &rEvent, &css::awt::XTopWindowListener::windowNormalized);
1791 break;
1795 IMPL_LINK(VCLXToolkit, keyListenerHandler, ::VclWindowEvent&, rEvent, bool)
1797 switch (rEvent.GetId())
1799 case VCLEVENT_WINDOW_KEYINPUT:
1800 return callKeyHandlers(&rEvent, true);
1801 case VCLEVENT_WINDOW_KEYUP:
1802 return callKeyHandlers(&rEvent, false);
1804 return false;
1807 void VCLXToolkit::callTopWindowListeners(
1808 ::VclSimpleEvent const * pEvent,
1809 void (SAL_CALL css::awt::XTopWindowListener::* pFn)(
1810 css::lang::EventObject const &))
1812 vcl::Window * pWindow
1813 = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow();
1814 if (pWindow->IsTopWindow())
1816 std::vector< css::uno::Reference< css::uno::XInterface > >
1817 aListeners(m_aTopWindowListeners.getElements());
1818 if (!aListeners.empty())
1820 css::lang::EventObject aAwtEvent(
1821 static_cast< css::awt::XWindow * >(pWindow->GetWindowPeer()));
1822 for (css::uno::Reference<XInterface> & i : aListeners)
1824 css::uno::Reference< css::awt::XTopWindowListener >
1825 xListener(i, css::uno::UNO_QUERY);
1828 (xListener.get()->*pFn)(aAwtEvent);
1830 catch (const css::uno::RuntimeException & rEx)
1832 OSL_TRACE(
1833 "VCLXToolkit::callTopWindowListeners: caught %s\n",
1834 OUStringToOString(
1835 rEx.Message, RTL_TEXTENCODING_UTF8).getStr());
1842 bool VCLXToolkit::callKeyHandlers(::VclSimpleEvent const * pEvent,
1843 bool bPressed)
1845 std::vector< css::uno::Reference< css::uno::XInterface > >
1846 aHandlers(m_aKeyHandlers.getElements());
1848 if (!aHandlers.empty())
1850 vcl::Window * pWindow = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow();
1852 // See implementation in vclxwindow.cxx for mapping between VCL and UNO AWT event
1853 ::KeyEvent * pKeyEvent = static_cast< ::KeyEvent * >(
1854 static_cast< ::VclWindowEvent const * >(pEvent)->GetData());
1855 css::awt::KeyEvent aAwtEvent(
1856 static_cast< css::awt::XWindow * >(pWindow->GetWindowPeer()),
1857 (pKeyEvent->GetKeyCode().IsShift()
1858 ? css::awt::KeyModifier::SHIFT : 0)
1859 | (pKeyEvent->GetKeyCode().IsMod1()
1860 ? css::awt::KeyModifier::MOD1 : 0)
1861 | (pKeyEvent->GetKeyCode().IsMod2()
1862 ? css::awt::KeyModifier::MOD2 : 0)
1863 | (pKeyEvent->GetKeyCode().IsMod3()
1864 ? css::awt::KeyModifier::MOD3 : 0),
1865 pKeyEvent->GetKeyCode().GetCode(), pKeyEvent->GetCharCode(),
1866 sal::static_int_cast< sal_Int16 >(
1867 pKeyEvent->GetKeyCode().GetFunction()));
1868 for (css::uno::Reference<XInterface> & i : aHandlers)
1870 css::uno::Reference< css::awt::XKeyHandler > xHandler(
1871 i, css::uno::UNO_QUERY);
1874 if ((bPressed ? xHandler->keyPressed(aAwtEvent)
1875 : xHandler->keyReleased(aAwtEvent)))
1876 return true;
1878 catch (const css::uno::RuntimeException & rEx)
1880 OSL_TRACE(
1881 "VCLXToolkit::callKeyHandlers: caught %s\n",
1882 OUStringToOString(
1883 rEx.Message, RTL_TEXTENCODING_UTF8).getStr());
1887 return false;
1890 void VCLXToolkit::callFocusListeners(::VclSimpleEvent const * pEvent,
1891 bool bGained)
1893 vcl::Window * pWindow
1894 = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow();
1895 if (pWindow->IsTopWindow())
1897 std::vector< css::uno::Reference< css::uno::XInterface > >
1898 aListeners(m_aFocusListeners.getElements());
1899 if (!aListeners.empty())
1901 // Ignore the interior of compound controls when determining the
1902 // window that gets the focus next (see implementation in
1903 // vclxwindow.cxx for mapping between VCL and UNO AWT event):
1904 css::uno::Reference< css::uno::XInterface > xNext;
1905 vcl::Window * pFocus = ::Application::GetFocusWindow();
1906 for (vcl::Window * p = pFocus; p != nullptr; p = p->GetParent())
1907 if (!p->IsCompoundControl())
1909 pFocus = p;
1910 break;
1912 if (pFocus != nullptr)
1913 xNext = pFocus->GetComponentInterface();
1914 css::awt::FocusEvent aAwtEvent(
1915 static_cast< css::awt::XWindow * >(pWindow->GetWindowPeer()),
1916 static_cast<sal_Int16>(pWindow->GetGetFocusFlags()),
1917 xNext, false);
1918 for (css::uno::Reference<XInterface> & i : aListeners)
1920 css::uno::Reference< css::awt::XFocusListener > xListener(
1921 i, css::uno::UNO_QUERY);
1924 bGained ? xListener->focusGained(aAwtEvent)
1925 : xListener->focusLost(aAwtEvent);
1927 catch (const css::uno::RuntimeException & rEx)
1929 OSL_TRACE(
1930 "VCLXToolkit::callFocusListeners: caught %s\n",
1931 OUStringToOString(
1932 rEx.Message, RTL_TEXTENCODING_UTF8).getStr());
1939 // css::awt::XReschedule:
1941 void SAL_CALL VCLXToolkit::reschedule()
1942 throw (css::uno::RuntimeException, std::exception)
1944 SolarMutexGuard aSolarGuard;
1945 Application::Reschedule(true);
1948 // css::awt::XToolkitExperimental
1950 void SAL_CALL VCLXToolkit::processEventsToIdle()
1951 throw (css::uno::RuntimeException, std::exception)
1953 SolarMutexGuard aSolarGuard;
1954 Scheduler::ProcessEventsToIdle();
1957 sal_Int64 SAL_CALL VCLXToolkit::getOpenGLBufferSwapCounter()
1958 throw (css::uno::RuntimeException, std::exception)
1960 #if HAVE_FEATURE_OPENGL
1961 return OpenGLWrapper::getBufferSwapCounter();
1962 #else
1963 return 0;
1964 #endif
1967 void SAL_CALL VCLXToolkit::setDeterministicScheduling(sal_Bool bDeterministicMode)
1968 throw (css::uno::RuntimeException, std::exception)
1970 SolarMutexGuard aSolarGuard;
1971 Scheduler::SetDeterministicMode(bDeterministicMode);
1974 void SAL_CALL VCLXToolkit::pause(sal_Int32 nMilliseconds)
1975 throw (css::uno::RuntimeException, std::exception)
1977 new Pause(nMilliseconds);
1980 // css:awt:XToolkitRobot
1982 void SAL_CALL VCLXToolkit::keyPress( const css::awt::KeyEvent & aKeyEvent )
1983 throw (css::uno::RuntimeException, std::exception)
1985 css::uno::Reference<css::awt::XWindow> xWindow ( aKeyEvent.Source, css::uno::UNO_QUERY );
1986 if( !xWindow.is() )
1987 throw css::uno::RuntimeException( "invalid event source" );
1989 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
1990 if( !pWindow )
1991 throw css::uno::RuntimeException( "invalid event source" );
1993 ::KeyEvent aVCLKeyEvent = VCLUnoHelper::createVCLKeyEvent( aKeyEvent );
1994 ::Application::PostKeyEvent( VCLEVENT_WINDOW_KEYINPUT, pWindow, &aVCLKeyEvent );
1997 void SAL_CALL VCLXToolkit::keyRelease( const css::awt::KeyEvent & aKeyEvent )
1998 throw (css::uno::RuntimeException, std::exception)
2000 css::uno::Reference<css::awt::XWindow> xWindow ( aKeyEvent.Source, css::uno::UNO_QUERY );
2001 if( !xWindow.is() )
2002 throw css::uno::RuntimeException( "invalid event source" );
2004 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
2005 if( !pWindow )
2006 throw css::uno::RuntimeException( "invalid event source" );
2008 ::KeyEvent aVCLKeyEvent = VCLUnoHelper::createVCLKeyEvent( aKeyEvent );
2009 ::Application::PostKeyEvent( VCLEVENT_WINDOW_KEYUP, pWindow, &aVCLKeyEvent );
2013 void SAL_CALL VCLXToolkit::mousePress( const css::awt::MouseEvent & aMouseEvent )
2014 throw (css::uno::RuntimeException, std::exception)
2016 css::uno::Reference<css::awt::XWindow> xWindow ( aMouseEvent.Source, css::uno::UNO_QUERY );
2017 if( !xWindow.is() )
2018 throw css::uno::RuntimeException( "invalid event source" );
2020 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
2021 if( !pWindow )
2022 throw css::uno::RuntimeException( "invalid event source" );
2024 ::MouseEvent aVCLMouseEvent = VCLUnoHelper::createVCLMouseEvent( aMouseEvent );
2025 ::Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, pWindow, &aVCLMouseEvent );
2028 void SAL_CALL VCLXToolkit::mouseRelease( const css::awt::MouseEvent & aMouseEvent )
2029 throw (css::uno::RuntimeException, std::exception)
2031 css::uno::Reference<css::awt::XWindow> xWindow ( aMouseEvent.Source, css::uno::UNO_QUERY );
2032 if( !xWindow.is() )
2033 throw css::uno::RuntimeException( "invalid event source" );
2035 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
2036 if( !pWindow )
2037 throw css::uno::RuntimeException( "invalid event source" );
2039 ::MouseEvent aVCLMouseEvent = VCLUnoHelper::createVCLMouseEvent( aMouseEvent );
2040 ::Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEBUTTONUP, pWindow, &aVCLMouseEvent );
2043 void SAL_CALL VCLXToolkit::mouseMove( const css::awt::MouseEvent & aMouseEvent )
2044 throw (css::uno::RuntimeException, std::exception)
2046 css::uno::Reference<css::awt::XWindow> xWindow ( aMouseEvent.Source, css::uno::UNO_QUERY );
2047 if( !xWindow.is() )
2048 throw css::uno::RuntimeException( "invalid event source" );
2050 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
2051 if( !pWindow )
2052 throw css::uno::RuntimeException( "invalid event source" );
2054 ::MouseEvent aVCLMouseEvent = VCLUnoHelper::createVCLMouseEvent( aMouseEvent );
2055 ::Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEMOVE, pWindow, &aVCLMouseEvent );
2061 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
2062 stardiv_Toolkit_VCLXToolkit_get_implementation(
2063 css::uno::XComponentContext *,
2064 css::uno::Sequence<css::uno::Any> const &)
2066 return cppu::acquire(new VCLXToolkit());
2069 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */