Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / toolkit / source / awt / vclxtoolkit.cxx
blob2dfa25cf13cb46f62512e803f790e86f4265c86c
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 VCLXToolkitMutexHelper
148 protected:
149 ::osl::Mutex maMutex;
152 class VCLXToolkit : public VCLXToolkitMutexHelper,
153 public cppu::WeakComponentImplHelper<
154 css::awt::XToolkitExperimental,
155 css::awt::XToolkitRobot,
156 css::lang::XServiceInfo >
158 css::uno::Reference< css::datatransfer::clipboard::XClipboard > mxClipboard;
159 css::uno::Reference< css::datatransfer::clipboard::XClipboard > mxSelection;
161 oslModule hSvToolsLib;
162 FN_SvtCreateWindow fnSvtCreateWindow;
164 ::comphelper::OInterfaceContainerHelper2 m_aTopWindowListeners;
165 ::comphelper::OInterfaceContainerHelper2 m_aKeyHandlers;
166 ::comphelper::OInterfaceContainerHelper2 m_aFocusListeners;
167 ::Link<VclSimpleEvent&,void> m_aEventListenerLink;
168 ::Link<VclWindowEvent&,bool> m_aKeyListenerLink;
169 bool m_bEventListener;
170 bool m_bKeyListener;
172 DECL_LINK_TYPED(eventListenerHandler, ::VclSimpleEvent&, void);
174 DECL_LINK_TYPED(keyListenerHandler, ::VclWindowEvent&, bool);
176 void callTopWindowListeners(
177 ::VclSimpleEvent const * pEvent,
178 void (SAL_CALL css::awt::XTopWindowListener::* pFn)(
179 css::lang::EventObject const &));
181 bool callKeyHandlers(::VclSimpleEvent const * pEvent, bool bPressed);
183 void callFocusListeners(::VclSimpleEvent const * pEvent, bool bGained);
185 protected:
186 ::osl::Mutex& GetMutex() { return maMutex; }
188 virtual void SAL_CALL disposing() override;
190 static vcl::Window* ImplCreateWindow( VCLXWindow** ppNewComp, const css::awt::WindowDescriptor& rDescriptor, vcl::Window* pParent, WinBits nWinBits );
191 css::uno::Reference< css::awt::XWindowPeer > ImplCreateWindow( const css::awt::WindowDescriptor& Descriptor, WinBits nWinBits );
193 public:
195 VCLXToolkit();
196 virtual ~VCLXToolkit();
198 // css::awt::XToolkitExperimental
199 virtual void SAL_CALL processEventsToIdle()
200 throw (css::uno::RuntimeException, std::exception) override;
202 virtual sal_Int64 SAL_CALL getOpenGLBufferSwapCounter()
203 throw (css::uno::RuntimeException, std::exception) override;
205 virtual void SAL_CALL setDeterministicScheduling(sal_Bool bDeterministicMode)
206 throw (css::uno::RuntimeException, std::exception) override;
208 // css::awt::XToolkit
209 css::uno::Reference< css::awt::XWindowPeer > SAL_CALL getDesktopWindow( ) throw(css::uno::RuntimeException, std::exception) override;
210 css::awt::Rectangle SAL_CALL getWorkArea( ) throw(css::uno::RuntimeException, std::exception) override;
211 css::uno::Reference< css::awt::XWindowPeer > SAL_CALL createWindow( const css::awt::WindowDescriptor& Descriptor ) throw(css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) override;
212 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;
213 css::uno::Reference< css::awt::XDevice > SAL_CALL createScreenCompatibleDevice( sal_Int32 Width, sal_Int32 Height ) throw
214 (css::uno::RuntimeException, std::exception) override;
215 css::uno::Reference< css::awt::XRegion > SAL_CALL createRegion( ) throw(css::uno::RuntimeException, std::exception) override;
217 // css::awt::XSystemChildFactory
218 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;
220 // css::awt::XMessageBoxFactory
221 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;
223 // css::awt::XDataTransfer
224 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;
225 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;
226 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;
227 css::uno::Reference< css::datatransfer::clipboard::XClipboard > SAL_CALL getClipboard( const OUString& clipboardName ) throw(css::uno::RuntimeException, std::exception) override;
229 // css::lang::XServiceInfo
230 OUString SAL_CALL getImplementationName( ) throw(css::uno::RuntimeException, std::exception) override;
231 sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(css::uno::RuntimeException, std::exception) override;
232 css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(css::uno::RuntimeException, std::exception) override;
234 // css::awt::XExtendedToolkit:
236 virtual ::sal_Int32 SAL_CALL getTopWindowCount()
237 throw (css::uno::RuntimeException, std::exception) override;
239 virtual css::uno::Reference< css::awt::XTopWindow >
240 SAL_CALL getTopWindow(::sal_Int32 nIndex)
241 throw (css::uno::RuntimeException, std::exception) override;
243 virtual css::uno::Reference< css::awt::XTopWindow >
244 SAL_CALL getActiveTopWindow()
245 throw (css::uno::RuntimeException, std::exception) override;
247 virtual void SAL_CALL addTopWindowListener(
248 css::uno::Reference<
249 css::awt::XTopWindowListener > const & rListener)
250 throw (css::uno::RuntimeException, std::exception) override;
252 virtual void SAL_CALL removeTopWindowListener(
253 css::uno::Reference<
254 css::awt::XTopWindowListener > const & rListener)
255 throw (css::uno::RuntimeException, std::exception) override;
257 virtual void SAL_CALL addKeyHandler(
258 css::uno::Reference<
259 css::awt::XKeyHandler > const & rHandler)
260 throw (css::uno::RuntimeException, std::exception) override;
262 virtual void SAL_CALL removeKeyHandler(
263 css::uno::Reference<
264 css::awt::XKeyHandler > const & rHandler)
265 throw (css::uno::RuntimeException, std::exception) override;
267 virtual void SAL_CALL addFocusListener(
268 css::uno::Reference<
269 css::awt::XFocusListener > const & rListener)
270 throw (css::uno::RuntimeException, std::exception) override;
272 virtual void SAL_CALL removeFocusListener(
273 css::uno::Reference<
274 css::awt::XFocusListener > const & rListener)
275 throw (css::uno::RuntimeException, std::exception) override;
277 virtual void SAL_CALL fireFocusGained(
278 css::uno::Reference<
279 css::uno::XInterface > const & source)
280 throw (css::uno::RuntimeException, std::exception) override;
282 virtual void SAL_CALL fireFocusLost(
283 css::uno::Reference<
284 css::uno::XInterface > const & source)
285 throw (css::uno::RuntimeException, std::exception) override;
287 // css::awt::XReschedule:
288 virtual void SAL_CALL reschedule()
289 throw (css::uno::RuntimeException, std::exception) override;
291 // css:awt:XToolkitRobot
292 virtual void SAL_CALL keyPress( const css::awt::KeyEvent & aKeyEvent )
293 throw (css::uno::RuntimeException, std::exception) override;
295 virtual void SAL_CALL keyRelease( const css::awt::KeyEvent & aKeyEvent )
296 throw (css::uno::RuntimeException, std::exception) override;
298 virtual void SAL_CALL mousePress( const css::awt::MouseEvent & aMouseEvent )
299 throw (css::uno::RuntimeException, std::exception) override;
301 virtual void SAL_CALL mouseRelease( const css::awt::MouseEvent & aMouseEvent )
302 throw (css::uno::RuntimeException, std::exception) override;
304 virtual void SAL_CALL mouseMove( const css::awt::MouseEvent & aMouseEvent )
305 throw (css::uno::RuntimeException, std::exception) override;
309 WinBits ImplGetWinBits( sal_uInt32 nComponentAttribs, sal_uInt16 nCompType )
311 WinBits nWinBits = 0;
313 bool bMessBox = false;
314 if ( ( nCompType == WINDOW_INFOBOX ) ||
315 ( nCompType == WINDOW_MESSBOX ) ||
316 ( nCompType == WINDOW_QUERYBOX ) ||
317 ( nCompType == WINDOW_WARNINGBOX ) ||
318 ( nCompType == WINDOW_ERRORBOX ) )
320 bMessBox = true;
323 bool bDecoratedWindow = false;
324 if ( bMessBox
325 || ( nCompType == WINDOW_DIALOG )
326 || ( nCompType == WINDOW_MODELESSDIALOG )
327 || ( nCompType == WINDOW_MODALDIALOG )
328 || ( nCompType == WINDOW_SYSTEMDIALOG )
329 || ( nCompType == WINDOW_PATHDIALOG )
330 || ( nCompType == WINDOW_FILEDIALOG )
331 || ( nCompType == WINDOW_PRINTERSETUPDIALOG )
332 || ( nCompType == WINDOW_PRINTDIALOG )
333 || ( nCompType == WINDOW_COLORDIALOG )
334 || ( nCompType == WINDOW_FONTDIALOG )
335 || ( nCompType == WINDOW_DOCKINGWINDOW )
336 || ( nCompType == WINDOW_TABDIALOG )
337 || ( nCompType == WINDOW_BUTTONDIALOG )
338 || ( nCompType == WINDOW_SYSTEMCHILDWINDOW )
341 bDecoratedWindow = true;
344 if( nComponentAttribs & css::awt::WindowAttribute::BORDER )
345 nWinBits |= WB_BORDER;
346 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::NOBORDER )
347 nWinBits |= WB_NOBORDER;
348 if( nComponentAttribs & css::awt::WindowAttribute::SIZEABLE )
349 nWinBits |= WB_SIZEABLE;
350 if( nComponentAttribs & css::awt::WindowAttribute::MOVEABLE )
351 nWinBits |= WB_MOVEABLE;
352 if( nComponentAttribs & css::awt::WindowAttribute::CLOSEABLE )
353 nWinBits |= WB_CLOSEABLE;
354 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::HSCROLL )
355 nWinBits |= WB_HSCROLL;
356 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::VSCROLL )
357 nWinBits |= WB_VSCROLL;
358 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::LEFT )
359 nWinBits |= WB_LEFT;
360 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::CENTER )
361 nWinBits |= WB_CENTER;
362 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::RIGHT )
363 nWinBits |= WB_RIGHT;
364 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::SPIN )
365 nWinBits |= WB_SPIN;
366 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::SORT )
367 nWinBits |= WB_SORT;
368 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DROPDOWN )
369 nWinBits |= WB_DROPDOWN;
370 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEFBUTTON )
371 nWinBits |= WB_DEFBUTTON;
372 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::READONLY )
373 nWinBits |= WB_READONLY;
374 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::CLIPCHILDREN )
375 nWinBits |= WB_CLIPCHILDREN;
376 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::GROUP )
377 nWinBits |= WB_GROUP;
378 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::NOLABEL ) //added for issue79712
379 nWinBits |= WB_NOLABEL;
381 // These bits are not uniqe
382 if ( bMessBox )
384 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::OK )
385 nWinBits |= WB_OK;
386 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::OK_CANCEL )
387 nWinBits |= WB_OK_CANCEL;
388 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::YES_NO )
389 nWinBits |= WB_YES_NO;
390 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::YES_NO_CANCEL )
391 nWinBits |= WB_YES_NO_CANCEL;
392 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::RETRY_CANCEL )
393 nWinBits |= WB_RETRY_CANCEL;
394 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_OK )
395 nWinBits |= WB_DEF_OK;
396 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_CANCEL )
397 nWinBits |= WB_DEF_CANCEL;
398 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_RETRY )
399 nWinBits |= WB_DEF_RETRY;
400 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_YES )
401 nWinBits |= WB_DEF_YES;
402 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::DEF_NO )
403 nWinBits |= WB_DEF_NO;
405 if ( nCompType == WINDOW_MULTILINEEDIT || nCompType == WINDOW_DIALOG || nCompType == WINDOW_GROUPBOX )
407 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::AUTOHSCROLL )
408 nWinBits |= WB_AUTOHSCROLL;
409 if( nComponentAttribs & css::awt::VclWindowPeerAttribute::AUTOVSCROLL )
410 nWinBits |= WB_AUTOVSCROLL;
414 if ( bDecoratedWindow )
416 if( nComponentAttribs & css::awt::WindowAttribute::NODECORATION )
418 // No decoration removes several window attributes and must
419 // set WB_NOBORDER!
420 nWinBits &= ~WB_BORDER;
421 nWinBits &= ~WB_SIZEABLE;
422 nWinBits &= ~WB_MOVEABLE;
423 nWinBits &= ~WB_CLOSEABLE;
424 nWinBits |= WB_NOBORDER;
428 return nWinBits;
431 struct ComponentInfo
433 const char* pName;
434 WindowType nWinType;
437 static ComponentInfo aComponentInfos [] =
439 { "buttondialog", WINDOW_BUTTONDIALOG },
440 { "cancelbutton", WINDOW_CANCELBUTTON },
441 { "checkbox", WINDOW_CHECKBOX },
442 { "combobox", WINDOW_COMBOBOX },
443 { "control", WINDOW_CONTROL },
444 { "currencybox", WINDOW_CURRENCYBOX },
445 { "currencyfield", WINDOW_CURRENCYFIELD },
446 { "datebox", WINDOW_DATEBOX },
447 { "datefield", WINDOW_DATEFIELD },
448 { "dialog", WINDOW_DIALOG },
449 { "dockingarea", WINDOW_DOCKINGAREA },
450 { "dockingwindow", WINDOW_DOCKINGWINDOW },
451 { "edit", WINDOW_EDIT },
452 { "errorbox", WINDOW_ERRORBOX },
453 { "fixedbitmap", WINDOW_FIXEDBITMAP },
454 { "fixedimage", WINDOW_FIXEDIMAGE },
455 { "fixedline", WINDOW_FIXEDLINE },
456 { "fixedtext", WINDOW_FIXEDTEXT },
457 { "floatingwindow", WINDOW_FLOATINGWINDOW },
458 { "framewindow", VCLWINDOW_FRAMEWINDOW },
459 { "groupbox", WINDOW_GROUPBOX },
460 { "frame", WINDOW_GROUPBOX },
461 { "helpbutton", WINDOW_HELPBUTTON },
462 { "imagebutton", WINDOW_IMAGEBUTTON },
463 { "infobox", WINDOW_INFOBOX },
464 { "listbox", WINDOW_LISTBOX },
465 { "longcurrencybox", WINDOW_LONGCURRENCYBOX },
466 { "longcurrencyfield", WINDOW_LONGCURRENCYFIELD },
467 { "menubutton", WINDOW_MENUBUTTON },
468 { "messbox", WINDOW_MESSBOX },
469 { "metricbox", WINDOW_METRICBOX },
470 { "metricfield", WINDOW_METRICFIELD },
471 { "modaldialog", WINDOW_MODALDIALOG },
472 { "modelessdialog", WINDOW_MODELESSDIALOG },
473 { "morebutton", WINDOW_MOREBUTTON },
474 { "multilineedit", WINDOW_MULTILINEEDIT },
475 { "multilistbox", WINDOW_MULTILISTBOX },
476 { "numericbox", WINDOW_NUMERICBOX },
477 { "numericfield", WINDOW_NUMERICFIELD },
478 { "okbutton", WINDOW_OKBUTTON },
479 { "patternbox", WINDOW_PATTERNBOX },
480 { "patternfield", WINDOW_PATTERNFIELD },
481 { "pushbutton", WINDOW_PUSHBUTTON },
482 { "querybox", WINDOW_QUERYBOX },
483 { "radiobutton", WINDOW_RADIOBUTTON },
484 { "scrollbar", WINDOW_SCROLLBAR },
485 { "scrollbarbox", WINDOW_SCROLLBARBOX },
486 { "animatedimages", WINDOW_CONTROL },
487 { "spinbutton", WINDOW_SPINBUTTON },
488 { "spinfield", WINDOW_SPINFIELD },
489 { "splitter", WINDOW_SPLITTER },
490 { "splitwindow", WINDOW_SPLITWINDOW },
491 { "statusbar", WINDOW_STATUSBAR },
492 { "systemchildwindow", VCLWINDOW_SYSTEMCHILDWINDOW },
493 { "tabcontrol", WINDOW_TABCONTROL },
494 { "tabdialog", WINDOW_TABDIALOG },
495 { "tabpage", WINDOW_TABPAGE },
496 { "timebox", WINDOW_TIMEBOX },
497 { "timefield", WINDOW_TIMEFIELD },
498 { "toolbox", WINDOW_TOOLBOX },
499 { "tristatebox", WINDOW_TRISTATEBOX },
500 { "warningbox", WINDOW_WARNINGBOX },
501 { "window", WINDOW_WINDOW },
502 { "workwindow", WINDOW_WORKWINDOW },
503 { "tabpagecontainer", WINDOW_CONTROL },
504 { "tabpagemodel", WINDOW_TABPAGE }
507 extern "C"
509 static int SAL_CALL ComponentInfoCompare( const void* pFirst, const void* pSecond)
511 return( strcmp( static_cast<ComponentInfo const *>(pFirst)->pName,
512 static_cast<ComponentInfo const *>(pSecond)->pName ) );
516 sal_uInt16 ImplGetComponentType( const OUString& rServiceName )
518 static bool bSorted = false;
519 if( !bSorted )
521 qsort( static_cast<void*>(aComponentInfos),
522 sizeof( aComponentInfos ) / sizeof( ComponentInfo ),
523 sizeof( ComponentInfo ),
524 ComponentInfoCompare );
525 bSorted = true;
529 ComponentInfo aSearch;
530 OString aServiceName(OUStringToOString(rServiceName, osl_getThreadTextEncoding()).toAsciiLowerCase());
531 if ( !aServiceName.isEmpty() )
532 aSearch.pName = aServiceName.getStr();
533 else
534 aSearch.pName = "window";
536 ComponentInfo* pInf = static_cast<ComponentInfo*>(bsearch( &aSearch,
537 static_cast<void*>(aComponentInfos),
538 sizeof( aComponentInfos ) / sizeof( ComponentInfo ),
539 sizeof( ComponentInfo ),
540 ComponentInfoCompare ));
542 return pInf ? pInf->nWinType : 0;
546 namespace
548 struct MessageBoxTypeInfo
550 css::awt::MessageBoxType eType;
551 const sal_Char *pName;
552 sal_Int32 nLen;
555 static const MessageBoxTypeInfo aMessageBoxTypeInfo[] =
557 { css::awt::MessageBoxType_MESSAGEBOX, RTL_CONSTASCII_STRINGPARAM("messbox") },
558 { css::awt::MessageBoxType_INFOBOX, RTL_CONSTASCII_STRINGPARAM("infobox") },
559 { css::awt::MessageBoxType_WARNINGBOX, RTL_CONSTASCII_STRINGPARAM("warningbox") },
560 { css::awt::MessageBoxType_ERRORBOX, RTL_CONSTASCII_STRINGPARAM("errorbox") },
561 { css::awt::MessageBoxType_QUERYBOX, RTL_CONSTASCII_STRINGPARAM("querybox") },
562 { css::awt::MessageBoxType_MAKE_FIXED_SIZE, nullptr, 0 }
565 bool lcl_convertMessageBoxType(
566 rtl::OUString &sType,
567 css::awt::MessageBoxType eType )
569 const MessageBoxTypeInfo *pMap = aMessageBoxTypeInfo;
570 css::awt::MessageBoxType eVal = css::awt::MessageBoxType_MAKE_FIXED_SIZE;
572 while ( pMap->pName )
574 if ( pMap->eType == eType )
576 eVal = eType;
577 sType = rtl::OUString( pMap->pName, pMap->nLen, RTL_TEXTENCODING_ASCII_US );
578 break;
580 pMap++;
583 return ( eVal != css::awt::MessageBoxType_MAKE_FIXED_SIZE );
587 static sal_Int32 nVCLToolkitInstanceCount = 0;
588 static bool bInitedByVCLToolkit = false;
590 osl::Mutex & getInitMutex()
592 static osl::Mutex * pM;
593 if( !pM )
595 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
596 if( !pM )
598 static osl::Mutex aMutex;
599 pM = &aMutex;
602 return *pM;
605 osl::Condition & getInitCondition()
607 static osl::Condition * pC = nullptr;
608 if( !pC )
610 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
611 if( !pC )
613 static osl::Condition aCondition;
614 pC = &aCondition;
617 return *pC;
620 extern "C"
622 static void SAL_CALL ToolkitWorkerFunction( void* pArgs )
624 osl_setThreadName("VCLXToolkit VCL main thread");
626 css::uno::Reference<css::lang::XMultiServiceFactory> xServiceManager;
629 xServiceManager = ::comphelper::getProcessServiceFactory();
631 catch (const css::uno::DeploymentException&)
634 if (!xServiceManager.is())
636 css::uno::Reference<css::uno::XComponentContext> xContext =
637 ::cppu::defaultBootstrap_InitialComponentContext();
639 xServiceManager.set( xContext->getServiceManager(), css::uno::UNO_QUERY_THROW );
640 // set global process service factory used by unotools config helpers
641 ::comphelper::setProcessServiceFactory( xServiceManager );
644 VCLXToolkit * pTk = static_cast<VCLXToolkit *>(pArgs);
645 bInitedByVCLToolkit = InitVCL();
646 if( bInitedByVCLToolkit )
648 UnoWrapper* pUnoWrapper = new UnoWrapper( pTk );
649 Application::SetUnoWrapper( pUnoWrapper );
651 getInitCondition().set();
652 if( bInitedByVCLToolkit )
655 SolarMutexGuard aGuard;
656 Application::Execute();
660 pTk->dispose();
662 catch( css::uno::Exception & )
665 DeInitVCL();
667 else
669 // having the thread join itself is pretty stupid.
670 // but we can't get the osl_Thread to destroy here so just leak it.
675 // constructor, which might initialize VCL
676 VCLXToolkit::VCLXToolkit():
677 cppu::WeakComponentImplHelper<
678 css::awt::XToolkitExperimental,
679 css::awt::XToolkitRobot,
680 css::lang::XServiceInfo>( GetMutex() ),
681 m_aTopWindowListeners(rBHelper.rMutex),
682 m_aKeyHandlers(rBHelper.rMutex),
683 m_aFocusListeners(rBHelper.rMutex),
684 m_aEventListenerLink(LINK(this, VCLXToolkit, eventListenerHandler)),
685 m_aKeyListenerLink(LINK(this, VCLXToolkit, keyListenerHandler)),
686 m_bEventListener(false),
687 m_bKeyListener(false)
689 hSvToolsLib = nullptr;
690 fnSvtCreateWindow = nullptr;
692 osl::Guard< osl::Mutex > aGuard( getInitMutex() );
693 nVCLToolkitInstanceCount++;
694 if( ( nVCLToolkitInstanceCount == 1 ) && ( !Application::IsInMain() ) )
696 // setup execute thread
697 CreateMainLoopThread( ToolkitWorkerFunction, this );
698 getInitCondition().wait();
702 VCLXToolkit::~VCLXToolkit()
707 void SAL_CALL VCLXToolkit::disposing()
709 #ifndef DISABLE_DYNLOADING
710 if ( hSvToolsLib )
712 osl_unloadModule( hSvToolsLib );
713 hSvToolsLib = nullptr;
714 fnSvtCreateWindow = nullptr;
716 #endif
719 osl::Guard< osl::Mutex > aGuard( getInitMutex() );
720 if( --nVCLToolkitInstanceCount == 0 )
722 if( bInitedByVCLToolkit )
724 Application::Quit();
725 JoinMainLoopThread();
726 bInitedByVCLToolkit = false;
731 if (m_bEventListener)
733 ::Application::RemoveEventListener(m_aEventListenerLink);
734 m_bEventListener = false;
736 if (m_bKeyListener)
738 ::Application::RemoveKeyListener(m_aKeyListenerLink);
739 m_bKeyListener = false;
741 css::lang::EventObject aEvent(
742 static_cast< ::cppu::OWeakObject * >(this));
743 m_aTopWindowListeners.disposeAndClear(aEvent);
744 m_aKeyHandlers.disposeAndClear(aEvent);
745 m_aFocusListeners.disposeAndClear(aEvent);
749 css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::getDesktopWindow( ) throw(css::uno::RuntimeException, std::exception)
751 css::uno::Reference< css::awt::XWindowPeer > xRef;
752 // 07/00: AppWindow doesn't exist anymore...
753 return xRef;
756 css::awt::Rectangle VCLXToolkit::getWorkArea( ) throw(css::uno::RuntimeException, std::exception)
758 sal_Int32 nDisplay = Application::GetDisplayBuiltInScreen();
759 Rectangle aWorkRect = Application::GetScreenPosSizePixel( nDisplay );
760 css::awt::Rectangle aNotherRect;
761 aNotherRect.X = aWorkRect.getX();
762 aNotherRect.Y = aWorkRect.getY();
763 aNotherRect.Width = aWorkRect.getWidth();
764 aNotherRect.Height = aWorkRect.getHeight();
765 return aNotherRect;
768 css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::createWindow( const css::awt::WindowDescriptor& rDescriptor ) throw(css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception)
770 return ImplCreateWindow( rDescriptor, WinBits(0) );
773 css::uno::Reference< css::awt::XDevice > VCLXToolkit::createScreenCompatibleDevice( sal_Int32 Width, sal_Int32 Height ) throw(css::uno::RuntimeException, std::exception)
775 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
777 css::uno::Reference< css::awt::XDevice > xRef;
778 VCLXVirtualDevice* pVDev = new VCLXVirtualDevice;
780 SolarMutexGuard aSolarGuard;
782 VclPtrInstance<VirtualDevice> pV;
783 pV->SetOutputSizePixel( Size( Width, Height ) );
784 pVDev->SetVirtualDevice( pV );
786 xRef = pVDev;
787 return xRef;
790 css::uno::Reference< css::awt::XRegion > VCLXToolkit::createRegion( ) throw(css::uno::RuntimeException, std::exception)
792 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
794 css::uno::Reference< css::awt::XRegion > xRef = new VCLXRegion;
795 return xRef;
798 vcl::Window* VCLXToolkit::ImplCreateWindow( VCLXWindow** ppNewComp,
799 const css::awt::WindowDescriptor& rDescriptor,
800 vcl::Window* pParent, WinBits nWinBits )
802 OUString aServiceName( rDescriptor.WindowServiceName );
803 aServiceName = aServiceName.toAsciiLowerCase();
805 vcl::Window* pNewWindow = nullptr;
806 sal_uInt16 nType = ImplGetComponentType( aServiceName );
807 bool bFrameControl = false;
808 if ( aServiceName == "frame" )
809 bFrameControl = true;
810 if ( aServiceName == "tabcontrolnotabs" )
812 nWinBits |= WB_NOBORDER;
813 nType = ImplGetComponentType( "tabcontrol" );
815 if ( !pParent )
817 // Wenn die Component einen Parent braucht, dann NULL zurueckgeben,
818 // spaeter mal css::uno::Exception...
819 bool bException = true;
820 if ( ( nType == WINDOW_DIALOG )
821 || ( nType == WINDOW_MODALDIALOG )
822 || ( nType == WINDOW_MODELESSDIALOG )
823 || ( nType == WINDOW_MESSBOX )
824 || ( nType == WINDOW_INFOBOX )
825 || ( nType == WINDOW_WARNINGBOX )
826 || ( nType == WINDOW_ERRORBOX )
827 || ( nType == WINDOW_QUERYBOX )
829 bException = false;
830 else if ( ( nType == WINDOW_WINDOW ) ||
831 ( nType == WINDOW_WORKWINDOW ) ||
832 ( nType == VCLWINDOW_FRAMEWINDOW ) )
834 if ( rDescriptor.Type == css::awt::WindowClass_TOP )
835 bException = false;
838 if ( bException )
840 *ppNewComp = nullptr;
841 return nullptr;
845 if ( nType )
847 SolarMutexGuard aVclGuard;
848 switch ( (WindowType)nType )
850 case WINDOW_CANCELBUTTON:
851 pNewWindow = VclPtr<CancelButton>::Create( pParent, nWinBits );
852 *ppNewComp = new VCLXButton;
853 break;
854 case WINDOW_CHECKBOX:
855 pNewWindow = VclPtr<CheckBox>::Create( pParent, nWinBits );
856 *ppNewComp = new VCLXCheckBox;
857 break;
858 case WINDOW_COMBOBOX:
859 pNewWindow = VclPtr<ComboBox>::Create( pParent, nWinBits|WB_AUTOHSCROLL );
860 static_cast<ComboBox*>(pNewWindow)->EnableAutoSize( false );
861 *ppNewComp = new VCLXComboBox;
862 break;
863 case WINDOW_CURRENCYBOX:
864 pNewWindow = VclPtr<CurrencyBox>::Create( pParent, nWinBits );
865 break;
866 case WINDOW_CURRENCYFIELD:
867 pNewWindow = VclPtr<CurrencyField>::Create( pParent, nWinBits );
868 static_cast<CurrencyField*>(pNewWindow)->EnableEmptyFieldValue( true );
869 *ppNewComp = new VCLXNumericField;
870 static_cast<VCLXFormattedSpinField*>(*ppNewComp)->SetFormatter( static_cast<FormatterBase*>(static_cast<CurrencyField*>(pNewWindow)) );
871 break;
872 case WINDOW_DATEBOX:
873 pNewWindow = VclPtr<DateBox>::Create( pParent, nWinBits );
874 break;
875 case WINDOW_DATEFIELD:
876 pNewWindow = VclPtr<DateField>::Create( pParent, nWinBits );
877 static_cast<DateField*>(pNewWindow)->EnableEmptyFieldValue( true );
878 *ppNewComp = new VCLXDateField;
879 static_cast<VCLXFormattedSpinField*>(*ppNewComp)->SetFormatter( static_cast<FormatterBase*>(static_cast<DateField*>(pNewWindow)) );
880 break;
881 case WINDOW_DOCKINGAREA:
882 pNewWindow = VclPtr<DockingAreaWindow>::Create( pParent );
883 break;
884 case WINDOW_MULTILINEEDIT:
885 case WINDOW_EDIT:
886 pNewWindow = VclPtr<Edit>::Create( pParent, nWinBits );
887 *ppNewComp = new VCLXEdit;
888 break;
889 case WINDOW_ERRORBOX:
890 pNewWindow = VclPtr<ErrorBox>::Create( pParent, nWinBits, OUString() );
891 *ppNewComp = new VCLXMessageBox;
892 break;
893 case WINDOW_FIXEDBITMAP:
894 pNewWindow = VclPtr<FixedBitmap>::Create( pParent, nWinBits );
895 break;
896 case WINDOW_FIXEDIMAGE:
897 pNewWindow = VclPtr<ImageControl>::Create( pParent, nWinBits );
898 *ppNewComp = new VCLXImageControl;
899 break;
900 case WINDOW_FIXEDLINE:
901 pNewWindow = VclPtr<FixedLine>::Create( pParent, nWinBits );
902 break;
903 case WINDOW_FIXEDTEXT:
904 pNewWindow = VclPtr<FixedText>::Create( pParent, nWinBits );
905 *ppNewComp = new VCLXFixedText;
906 break;
907 case WINDOW_FLOATINGWINDOW:
908 pNewWindow = VclPtr<FloatingWindow>::Create( pParent, nWinBits );
909 break;
910 case WINDOW_GROUPBOX:
911 pNewWindow = VclPtr<GroupBox>::Create( pParent, nWinBits );
912 if ( bFrameControl )
914 GroupBox* pGroupBox = static_cast< GroupBox* >( pNewWindow );
915 *ppNewComp = new VCLXFrame;
916 // Frame control needs to receive
917 // Mouse events
918 pGroupBox->SetMouseTransparent( false );
920 break;
921 case WINDOW_HELPBUTTON:
922 pNewWindow = VclPtr<HelpButton>::Create( pParent, nWinBits );
923 *ppNewComp = new VCLXButton;
924 break;
925 case WINDOW_IMAGEBUTTON:
926 pNewWindow = VclPtr<ImageButton>::Create( pParent, nWinBits );
927 *ppNewComp = new VCLXButton;
928 break;
929 case WINDOW_INFOBOX:
930 pNewWindow = VclPtr<InfoBox>::Create( pParent, OUString() );
931 *ppNewComp = new VCLXMessageBox;
932 break;
933 case WINDOW_LISTBOX:
934 pNewWindow = VclPtr<ListBox>::Create( pParent, nWinBits|WB_SIMPLEMODE|WB_AUTOHSCROLL );
935 static_cast<ListBox*>(pNewWindow)->EnableAutoSize( false );
936 *ppNewComp = new VCLXListBox;
937 break;
938 case WINDOW_LONGCURRENCYBOX:
939 pNewWindow = VclPtr<LongCurrencyBox>::Create( pParent, nWinBits );
940 break;
941 case WINDOW_LONGCURRENCYFIELD:
942 pNewWindow = VclPtr<LongCurrencyField>::Create( pParent, nWinBits );
943 *ppNewComp = new VCLXCurrencyField;
944 static_cast<VCLXFormattedSpinField*>(*ppNewComp)->SetFormatter( static_cast<FormatterBase*>(static_cast<LongCurrencyField*>(pNewWindow)) );
945 break;
946 case WINDOW_MENUBUTTON:
947 pNewWindow = VclPtr<MenuButton>::Create( pParent, nWinBits );
948 *ppNewComp = new VCLXButton;
949 break;
950 case WINDOW_MESSBOX:
951 pNewWindow = VclPtr<MessBox>::Create( pParent, nWinBits, OUString(), OUString() );
952 *ppNewComp = new VCLXMessageBox;
953 break;
954 case WINDOW_METRICBOX:
955 pNewWindow = VclPtr<MetricBox>::Create( pParent, nWinBits );
956 break;
957 case WINDOW_METRICFIELD:
958 pNewWindow = VclPtr<MetricField>::Create( pParent, nWinBits );
959 *ppNewComp = new VCLXMetricField;
960 static_cast<VCLXFormattedSpinField*>(*ppNewComp)->SetFormatter( static_cast<FormatterBase*>(static_cast<MetricField*>(pNewWindow)) );
961 break;
962 case WINDOW_DIALOG:
963 case WINDOW_MODALDIALOG:
964 case WINDOW_MODELESSDIALOG:
966 // Modal/Modeless nur durch Show/Execute
967 if ( (pParent == nullptr ) && ( rDescriptor.ParentIndex == -1 ) )
968 pNewWindow = VclPtr<toolkit::ScrollableWrapper<Dialog>>::Create( nullptr, nWinBits, Dialog::InitFlag::NoParent );
969 else
970 pNewWindow = VclPtr<toolkit::ScrollableWrapper<Dialog>>::Create( pParent, nWinBits );
971 // #i70217# Don't always create a new component object. It's possible that VCL has called
972 // GetComponentInterface( sal_True ) in the Dialog ctor itself (see Window::IsTopWindow() )
973 // which creates a component object.
974 css::uno::Reference< css::awt::XWindowPeer > xWinPeer = pNewWindow->GetComponentInterface( false );
975 if ( xWinPeer.is() )
976 *ppNewComp = dynamic_cast< VCLXDialog* >( xWinPeer.get() );
977 else
978 *ppNewComp = new VCLXDialog;
980 break;
981 case WINDOW_MOREBUTTON:
982 pNewWindow = VclPtr<MoreButton>::Create( pParent, nWinBits );
983 *ppNewComp = new VCLXButton;
984 break;
985 case WINDOW_MULTILISTBOX:
986 pNewWindow = VclPtr<MultiListBox>::Create( pParent, nWinBits );
987 *ppNewComp = new VCLXListBox;
988 break;
989 case WINDOW_NUMERICBOX:
990 pNewWindow = VclPtr<NumericBox>::Create( pParent, nWinBits );
991 break;
992 case WINDOW_NUMERICFIELD:
993 pNewWindow = VclPtr<NumericField>::Create( pParent, nWinBits );
994 static_cast<NumericField*>(pNewWindow)->EnableEmptyFieldValue( true );
995 *ppNewComp = new VCLXNumericField;
996 static_cast<VCLXFormattedSpinField*>(*ppNewComp)->SetFormatter( static_cast<FormatterBase*>(static_cast<NumericField*>(pNewWindow)) );
997 break;
998 case WINDOW_OKBUTTON:
999 pNewWindow = VclPtr<OKButton>::Create( pParent, nWinBits );
1000 *ppNewComp = new VCLXButton;
1001 break;
1002 case WINDOW_PATTERNBOX:
1003 pNewWindow = VclPtr<PatternBox>::Create( pParent, nWinBits );
1004 break;
1005 case WINDOW_PATTERNFIELD:
1006 pNewWindow = VclPtr<PatternField>::Create( pParent, nWinBits );
1007 *ppNewComp = new VCLXPatternField;
1008 static_cast<VCLXFormattedSpinField*>(*ppNewComp)->SetFormatter( static_cast<FormatterBase*>(static_cast<PatternField*>(pNewWindow)) );
1009 break;
1010 case WINDOW_PUSHBUTTON:
1011 pNewWindow = VclPtr<PushButton>::Create( pParent, nWinBits );
1012 *ppNewComp = new VCLXButton;
1013 break;
1014 case WINDOW_QUERYBOX:
1015 pNewWindow = VclPtr<QueryBox>::Create( pParent, nWinBits, OUString() );
1016 *ppNewComp = new VCLXMessageBox;
1017 break;
1018 case WINDOW_RADIOBUTTON:
1019 pNewWindow = VclPtr<RadioButton>::Create( pParent, nWinBits );
1020 *ppNewComp = new VCLXRadioButton;
1022 // by default, disable RadioCheck
1023 // Since the VCLXRadioButton really cares for its RadioCheck settings, this is important:
1024 // if we enable it, the VCLXRadioButton will use RadioButton::Check instead of RadioButton::SetState
1025 // This leads to a strange behaviour if the control is newly created: when settings the initial
1026 // state to "checked", the RadioButton::Check (called because RadioCheck=sal_True) will uncheck
1027 // _all_other_ radio buttons in the same group. However, at this moment the grouping of the controls
1028 // is not really valid: the controls are grouped after they have been created, but we're still in
1029 // the creation process, so the RadioButton::Check relies on invalid grouping information.
1030 // 07.08.2001 - #87254# - frank.schoenheit@sun.com
1031 static_cast<RadioButton*>(pNewWindow)->EnableRadioCheck( false );
1032 break;
1033 case WINDOW_SCROLLBAR:
1034 pNewWindow = VclPtr<ScrollBar>::Create( pParent, nWinBits );
1035 *ppNewComp = new VCLXScrollBar;
1036 break;
1037 case WINDOW_SCROLLBARBOX:
1038 pNewWindow = VclPtr<ScrollBarBox>::Create( pParent, nWinBits );
1039 break;
1040 case WINDOW_SPINBUTTON:
1041 pNewWindow = VclPtr<SpinButton>::Create( pParent, nWinBits );
1042 *ppNewComp = new ::toolkit::VCLXSpinButton;
1043 break;
1044 case WINDOW_SPINFIELD:
1045 pNewWindow = VclPtr<SpinField>::Create( pParent, nWinBits );
1046 *ppNewComp = new VCLXNumericField;
1047 break;
1048 case WINDOW_SPLITTER:
1049 pNewWindow = VclPtr<Splitter>::Create( pParent, nWinBits );
1050 break;
1051 case WINDOW_SPLITWINDOW:
1052 pNewWindow = VclPtr<SplitWindow>::Create( pParent, nWinBits );
1053 break;
1054 case WINDOW_STATUSBAR:
1055 pNewWindow = VclPtr<StatusBar>::Create( pParent, nWinBits );
1056 break;
1057 case VCLWINDOW_SYSTEMCHILDWINDOW:
1058 pNewWindow = VclPtr<SystemChildWindow>::Create( pParent, nWinBits );
1059 *ppNewComp = new VCLXSystemDependentWindow();
1060 break;
1061 case WINDOW_TABCONTROL:
1062 pNewWindow = VclPtr<TabControl>::Create( pParent, nWinBits );
1063 *ppNewComp = new VCLXMultiPage;
1064 break;
1065 case WINDOW_TABDIALOG:
1066 pNewWindow = VclPtr<TabDialog>::Create( pParent, nWinBits );
1067 break;
1068 case WINDOW_TABPAGE:
1070 pNewWindow = VclPtr<TabPage>::Create( pParent, nWinBits );
1071 *ppNewComp = new VCLXTabPage;
1073 break;
1074 case WINDOW_TIMEBOX:
1075 pNewWindow = VclPtr<TimeBox>::Create( pParent, nWinBits );
1076 break;
1077 case WINDOW_TIMEFIELD:
1078 pNewWindow = VclPtr<TimeField>::Create( pParent, nWinBits );
1079 static_cast<TimeField*>(pNewWindow)->EnableEmptyFieldValue( true );
1080 *ppNewComp = new VCLXTimeField;
1081 static_cast<VCLXFormattedSpinField*>(*ppNewComp)->SetFormatter( static_cast<FormatterBase*>(static_cast<TimeField*>(pNewWindow)) );
1082 break;
1083 case WINDOW_TOOLBOX:
1084 pNewWindow = VclPtr<ToolBox>::Create( pParent, nWinBits );
1085 *ppNewComp = new VCLXToolBox;
1086 break;
1087 case WINDOW_TRISTATEBOX:
1088 pNewWindow = VclPtr<TriStateBox>::Create( pParent, nWinBits );
1089 break;
1090 case WINDOW_WARNINGBOX:
1091 pNewWindow = VclPtr<WarningBox>::Create( pParent, nWinBits, OUString() );
1092 *ppNewComp = new VCLXMessageBox;
1093 break;
1094 case WINDOW_WORKWINDOW:
1095 case WINDOW_WINDOW:
1096 case VCLWINDOW_FRAMEWINDOW:
1097 case WINDOW_DOCKINGWINDOW:
1098 if ( rDescriptor.Type == css::awt::WindowClass_TOP )
1100 if (nType == WINDOW_DOCKINGWINDOW )
1101 pNewWindow = VclPtr<DockingWindow>::Create( pParent, nWinBits );
1102 else
1104 if ((pParent == nullptr) && rDescriptor.Parent.is())
1106 // try to get a system dependent window handle
1107 css::uno::Reference< css::awt::XSystemDependentWindowPeer > xSystemDepParent(rDescriptor.Parent, css::uno::UNO_QUERY);
1109 if (xSystemDepParent.is())
1111 sal_Int8 processID[16];
1113 rtl_getGlobalProcessId( reinterpret_cast<sal_uInt8*>(processID) );
1115 css::uno::Sequence<sal_Int8> processIdSeq(processID, 16);
1117 css::uno::Any anyHandle = xSystemDepParent->getWindowHandle(processIdSeq, SYSTEM_DEPENDENT_TYPE);
1119 // use sal_Int64 here to accommodate all int types
1120 // uno::Any shift operator whill upcast if necessary
1121 sal_Int64 nWindowHandle = 0;
1122 bool bXEmbed = false;
1124 bool bUseParentData = true;
1125 if( ! (anyHandle >>= nWindowHandle) )
1127 css::uno::Sequence< css::beans::NamedValue > aProps;
1128 if( anyHandle >>= aProps )
1130 const int nProps = aProps.getLength();
1131 const css::beans::NamedValue* pProps = aProps.getConstArray();
1132 for( int i = 0; i < nProps; i++ )
1134 if ( pProps[i].Name == "WINDOW" )
1135 pProps[i].Value >>= nWindowHandle;
1136 else if ( pProps[i].Name == "XEMBED" )
1137 pProps[i].Value >>= bXEmbed;
1140 else
1141 bUseParentData = false;
1144 if( bUseParentData )
1146 SystemParentData aParentData;
1147 aParentData.nSize = sizeof( aParentData );
1148 #if defined MACOSX
1149 aParentData.pView = reinterpret_cast<NSView*>(nWindowHandle);
1150 #elif defined ANDROID
1151 // Nothing
1152 #elif defined IOS
1153 // Nothing
1154 #elif defined UNX
1155 aParentData.aWindow = nWindowHandle;
1156 aParentData.bXEmbedSupport = bXEmbed;
1157 #elif defined WNT
1158 aParentData.hWnd = reinterpret_cast<HWND>(nWindowHandle);
1159 #endif
1160 pNewWindow = VclPtr<WorkWindow>::Create( &aParentData );
1165 if (!pNewWindow)
1166 pNewWindow = VclPtr<WorkWindow>::Create( pParent, nWinBits );
1169 *ppNewComp = new VCLXTopWindow( pNewWindow->GetType() == WINDOW_WORKWINDOW );
1171 else if ( rDescriptor.Type == css::awt::WindowClass_CONTAINER )
1173 if (nType == WINDOW_DOCKINGWINDOW )
1174 pNewWindow = VclPtr<DockingWindow>::Create( pParent, nWinBits );
1175 else
1176 pNewWindow = VclPtr<vcl::Window>::Create( pParent, nWinBits );
1177 *ppNewComp = new VCLXContainer;
1179 else
1181 if (nType == WINDOW_DOCKINGWINDOW )
1182 pNewWindow = VclPtr<DockingWindow>::Create( pParent, nWinBits );
1183 else
1184 pNewWindow = VclPtr<vcl::Window>::Create( pParent, nWinBits );
1185 *ppNewComp = new VCLXWindow;
1187 break;
1188 case WINDOW_CONTROL:
1189 if ( rDescriptor.WindowServiceName.equalsIgnoreAsciiCase(
1190 "tabpagecontainer" ) )
1192 pNewWindow = VclPtr<TabControl>::Create( pParent, nWinBits );
1193 *ppNewComp = new VCLXTabPageContainer;
1195 else if ( aServiceName == "animatedimages" )
1197 pNewWindow = VclPtr<Throbber>::Create( pParent, nWinBits );
1198 *ppNewComp = new ::toolkit::AnimatedImagesPeer;
1200 break;
1201 default:
1202 OSL_ENSURE( false, "VCLXToolkit::ImplCreateWindow: unknown window type!" );
1203 break;
1207 return pNewWindow;
1210 #ifndef DISABLE_DYNLOADING
1212 extern "C" { static void SAL_CALL thisModule() {} }
1214 #else
1216 extern "C" vcl::Window* SAL_CALL CreateWindow( VCLXWindow** ppNewComp, const css::awt::WindowDescriptor* pDescriptor, vcl::Window* pParent, WinBits nWinBits );
1218 #endif
1220 css::uno::Reference< css::awt::XWindowPeer > VCLXToolkit::ImplCreateWindow(
1221 const css::awt::WindowDescriptor& rDescriptor,
1222 WinBits nForceWinBits )
1224 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1226 SolarMutexGuard aSolarGuard;
1228 css::uno::Reference< css::awt::XWindowPeer > xRef;
1230 vcl::Window* pParent = nullptr;
1231 if ( rDescriptor.Parent.is() )
1233 VCLXWindow* pParentComponent = VCLXWindow::GetImplementation( rDescriptor.Parent );
1235 // #103939# Don't throw assertion, may be it's a system dependent window, used in ImplCreateWindow.
1236 // DBG_ASSERT( pParentComponent, "ParentComponent not valid" );
1238 if ( pParentComponent )
1239 pParent = pParentComponent->GetWindow();
1241 WinBits nWinBits = ImplGetWinBits( rDescriptor.WindowAttributes,
1242 ImplGetComponentType( rDescriptor.WindowServiceName ) );
1243 nWinBits |= nForceWinBits;
1245 VCLXWindow* pNewComp = nullptr;
1247 vcl::Window* pNewWindow = nullptr;
1248 // Try to create the window with SvTools
1249 // (do this _before_ creating it on our own: The old mechanism (extended toolkit in SvTools) did it this way,
1250 // and we need to stay compatible)
1251 // try to load the lib
1252 if ( !fnSvtCreateWindow
1253 #ifndef DISABLE_DYNLOADING
1254 && !hSvToolsLib
1255 #endif
1258 #ifndef DISABLE_DYNLOADING
1259 OUString aLibName(SVT_DLL_NAME);
1260 hSvToolsLib = osl_loadModuleRelative(
1261 &thisModule, aLibName.pData, SAL_LOADMODULE_DEFAULT );
1262 if ( hSvToolsLib )
1264 OUString aFunctionName( "CreateWindow" );
1265 fnSvtCreateWindow = reinterpret_cast<FN_SvtCreateWindow>(osl_getFunctionSymbol( hSvToolsLib, aFunctionName.pData ));
1267 #else
1268 fnSvtCreateWindow = CreateWindow;
1269 #endif
1271 // ask the SvTool creation function
1272 if ( fnSvtCreateWindow )
1273 pNewWindow = fnSvtCreateWindow( &pNewComp, &rDescriptor, pParent, nWinBits );
1275 // if SvTools could not provide a window, create it ourself
1276 if ( !pNewWindow )
1277 pNewWindow = ImplCreateWindow( &pNewComp, rDescriptor, pParent, nWinBits );
1279 DBG_ASSERT( pNewWindow, "createWindow: Unknown Component!" );
1280 SAL_INFO_IF( !pNewComp, "toolkit", "createWindow: No special Interface!" );
1282 if ( pNewWindow )
1284 pNewWindow->SetCreatedWithToolkit( true );
1285 //pNewWindow->SetPosPixel( Point() ); // do not force (0,0) position, keep default pos instead
1287 if ( rDescriptor.WindowAttributes & css::awt::WindowAttribute::MINSIZE )
1289 pNewWindow->SetSizePixel( Size() );
1291 else if ( rDescriptor.WindowAttributes & css::awt::WindowAttribute::FULLSIZE )
1293 if ( pParent )
1294 pNewWindow->SetSizePixel( pParent->GetOutputSizePixel() );
1296 else if ( !VCLUnoHelper::IsZero( rDescriptor.Bounds ) )
1298 Rectangle aRect = VCLRectangle( rDescriptor.Bounds );
1299 pNewWindow->SetPosSizePixel( aRect.TopLeft(), aRect.GetSize() );
1302 if ( !pNewComp )
1304 // Default-Interface
1305 xRef = pNewWindow->GetComponentInterface();
1307 else
1309 pNewComp->SetCreatedWithToolkit( true );
1310 xRef = pNewComp;
1311 pNewWindow->SetComponentInterface( xRef );
1313 DBG_ASSERT( pNewWindow->GetComponentInterface( false ) == xRef,
1314 "VCLXToolkit::createWindow: did #133706# resurge?" );
1316 if ( rDescriptor.WindowAttributes & css::awt::WindowAttribute::SHOW )
1317 pNewWindow->Show();
1320 return xRef;
1323 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)
1325 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1327 sal_uInt32 nComponents = rDescriptors.getLength();
1328 css::uno::Sequence< css::uno::Reference< css::awt::XWindowPeer > > aSeq( nComponents );
1329 for ( sal_uInt32 n = 0; n < nComponents; n++ )
1331 css::awt::WindowDescriptor aDescr = rDescriptors.getConstArray()[n];
1333 if ( aDescr.ParentIndex == (-1) )
1334 aDescr.Parent = nullptr;
1335 else if ( ( aDescr.ParentIndex >= 0 ) && ( aDescr.ParentIndex < (short)n ) )
1336 aDescr.Parent = aSeq.getConstArray()[aDescr.ParentIndex];
1337 aSeq.getArray()[n] = createWindow( aDescr );
1339 return aSeq;
1342 // css::awt::XSystemChildFactory
1343 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)
1345 VclPtr<vcl::Window> pChildWindow;
1346 if ( nSystemType == SYSTEM_DEPENDENT_TYPE )
1348 // use sal_Int64 here to accommodate all int types
1349 // uno::Any shift operator whill upcast if necessary
1350 sal_Int64 nWindowHandle = 0;
1351 bool bXEmbed = false;
1353 bool bUseParentData = true;
1354 if( ! (Parent >>= nWindowHandle) )
1356 css::uno::Sequence< css::beans::NamedValue > aProps;
1357 if( Parent >>= aProps )
1359 const int nProps = aProps.getLength();
1360 const css::beans::NamedValue* pProps = aProps.getConstArray();
1361 for( int i = 0; i < nProps; i++ )
1363 if ( pProps[i].Name == "WINDOW" )
1364 pProps[i].Value >>= nWindowHandle;
1365 else if ( pProps[i].Name == "XEMBED" )
1366 pProps[i].Value >>= bXEmbed;
1369 else
1370 bUseParentData = false;
1373 if( bUseParentData )
1375 SystemParentData aParentData;
1376 aParentData.nSize = sizeof( aParentData );
1377 #if defined MACOSX
1378 aParentData.pView = reinterpret_cast<NSView*>(nWindowHandle);
1379 #elif defined ANDROID
1380 // Nothing
1381 #elif defined IOS
1382 // Nothing
1383 #elif defined UNX
1384 aParentData.aWindow = nWindowHandle;
1385 aParentData.bXEmbedSupport = bXEmbed;
1386 #elif defined WNT
1387 aParentData.hWnd = reinterpret_cast<HWND>(nWindowHandle);
1388 #endif
1389 SolarMutexGuard aGuard;
1392 pChildWindow.reset( VclPtr<WorkWindow>::Create( &aParentData ) );
1394 catch ( const css::uno::RuntimeException & rEx )
1396 // system child window could not be created
1397 OSL_TRACE(
1398 "VCLXToolkit::createSystemChild: caught %s\n",
1399 OUStringToOString(
1400 rEx.Message, RTL_TEXTENCODING_UTF8).getStr());
1401 pChildWindow.clear();
1405 else if (nSystemType == css::lang::SystemDependent::SYSTEM_JAVA)
1407 SolarMutexGuard aGuard;
1408 pChildWindow.reset(VclPtr<WorkWindow>::Create(nullptr, Parent));
1411 css::uno::Reference< css::awt::XWindowPeer > xPeer;
1412 if ( pChildWindow )
1414 VCLXTopWindow* pPeer = new VCLXTopWindow(true);
1415 SolarMutexGuard aGuard;
1416 pPeer->SetWindow( pChildWindow );
1417 xPeer = pPeer;
1420 return xPeer;
1423 // css::awt::XMessageBoxFactory
1424 css::uno::Reference< css::awt::XMessageBox > SAL_CALL VCLXToolkit::createMessageBox(
1425 const css::uno::Reference< css::awt::XWindowPeer >& aParent,
1426 css::awt::MessageBoxType eType,
1427 ::sal_Int32 aButtons,
1428 const OUString& aTitle,
1429 const OUString& aMessage ) throw (css::uno::RuntimeException, std::exception)
1431 css::awt::WindowDescriptor aDescriptor;
1433 sal_Int32 nWindowAttributes = css::awt::WindowAttribute::BORDER|css::awt::WindowAttribute::MOVEABLE|css::awt::WindowAttribute::CLOSEABLE;
1435 // Map button definitions to window attributes
1436 if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_OK )
1437 nWindowAttributes |= css::awt::VclWindowPeerAttribute::OK;
1438 else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_OK_CANCEL )
1439 nWindowAttributes |= css::awt::VclWindowPeerAttribute::OK_CANCEL;
1440 else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_YES_NO )
1441 nWindowAttributes |= css::awt::VclWindowPeerAttribute::YES_NO;
1442 else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_YES_NO_CANCEL )
1443 nWindowAttributes |= css::awt::VclWindowPeerAttribute::YES_NO_CANCEL;
1444 else if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_RETRY_CANCEL )
1445 nWindowAttributes |= css::awt::VclWindowPeerAttribute::RETRY_CANCEL;
1447 // Map default button definitions to window attributes
1448 if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_OK )
1449 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_OK;
1450 else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_CANCEL )
1451 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_CANCEL;
1452 else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_YES )
1453 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_YES;
1454 else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_NO )
1455 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_NO;
1456 else if (sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_RETRY )
1457 nWindowAttributes |= css::awt::VclWindowPeerAttribute::DEF_RETRY;
1459 // No more bits for VclWindowPeerAttribute possible. Mapping must be
1460 // done explicitly using VCL methods
1461 WinBits nAddWinBits( 0 );
1462 if (( aButtons & 0x0000ffffL ) == css::awt::MessageBoxButtons::BUTTONS_ABORT_IGNORE_RETRY )
1463 nAddWinBits |= WB_ABORT_RETRY_IGNORE;
1464 if ( sal_Int32( aButtons & 0xffff0000L ) == css::awt::MessageBoxButtons::DEFAULT_BUTTON_IGNORE )
1465 nAddWinBits |= WB_DEF_IGNORE;
1467 rtl::OUString aType;
1468 lcl_convertMessageBoxType( aType, eType );
1470 aDescriptor.Type = css::awt::WindowClass_MODALTOP;
1471 aDescriptor.WindowServiceName = aType;
1472 aDescriptor.ParentIndex = -1;
1473 aDescriptor.Parent = aParent;
1474 aDescriptor.WindowAttributes = nWindowAttributes;
1475 css::uno::Reference< css::awt::XMessageBox > xMsgBox(
1476 ImplCreateWindow( aDescriptor, nAddWinBits ), css::uno::UNO_QUERY );
1477 css::uno::Reference< css::awt::XWindow > xWindow( xMsgBox, css::uno::UNO_QUERY );
1478 if ( xMsgBox.is() && xWindow.is() )
1480 vcl::Window * pWindow = VCLUnoHelper::GetWindow( xWindow );
1481 if ( pWindow )
1483 SolarMutexGuard aGuard;
1484 xMsgBox->setCaptionText( aTitle );
1485 xMsgBox->setMessageText( aMessage );
1489 return xMsgBox;
1492 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)
1494 SolarMutexGuard g;
1496 vcl::Window * pWindow = VCLUnoHelper::GetWindow( window );
1498 if( pWindow )
1499 return pWindow->GetDragGestureRecognizer();
1501 return css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer >();
1504 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)
1506 SolarMutexGuard g;
1508 vcl::Window * pWindow = VCLUnoHelper::GetWindow( window );
1510 if( pWindow )
1511 return pWindow->GetDragSource();
1513 return css::uno::Reference< css::datatransfer::dnd::XDragSource >();
1516 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)
1518 SolarMutexGuard g;
1520 vcl::Window * pWindow = VCLUnoHelper::GetWindow( window );
1522 if( pWindow )
1523 return pWindow->GetDropTarget();
1525 return css::uno::Reference< css::datatransfer::dnd::XDropTarget >();
1528 css::uno::Reference< css::datatransfer::clipboard::XClipboard > SAL_CALL VCLXToolkit::getClipboard( const OUString& clipboardName ) throw(css::uno::RuntimeException, std::exception)
1530 if( clipboardName.isEmpty() )
1532 if( !mxClipboard.is() )
1534 // remember clipboard here
1535 mxClipboard = css::datatransfer::clipboard::SystemClipboard::create(
1536 comphelper::getProcessComponentContext());
1539 return mxClipboard;
1542 else if( clipboardName == "Selection" )
1544 return mxSelection;
1547 return css::uno::Reference< css::datatransfer::clipboard::XClipboard >();
1550 // XServiceInfo
1551 OUString VCLXToolkit::getImplementationName() throw(css::uno::RuntimeException, std::exception)
1553 return OUString("stardiv.Toolkit.VCLXToolkit");
1556 sal_Bool VCLXToolkit::supportsService( const OUString& rServiceName ) throw(css::uno::RuntimeException, std::exception)
1558 return cppu::supportsService(this, rServiceName);
1561 css::uno::Sequence< OUString > VCLXToolkit::getSupportedServiceNames() throw(css::uno::RuntimeException, std::exception)
1563 return css::uno::Sequence<OUString>{
1564 "com.sun.star.awt.Toolkit", "stardiv.vcl.VclToolkit"};
1567 // css::awt::XExtendedToolkit:
1569 // virtual
1570 ::sal_Int32 SAL_CALL VCLXToolkit::getTopWindowCount()
1571 throw (css::uno::RuntimeException, std::exception)
1573 return static_cast< ::sal_Int32 >(::Application::GetTopWindowCount());
1574 // XXX numeric overflow
1577 // virtual
1578 css::uno::Reference< css::awt::XTopWindow > SAL_CALL
1579 VCLXToolkit::getTopWindow(::sal_Int32 nIndex)
1580 throw (css::uno::RuntimeException, std::exception)
1582 vcl::Window * p = ::Application::GetTopWindow(static_cast< long >(nIndex));
1583 // XXX numeric overflow
1584 return css::uno::Reference< css::awt::XTopWindow >(
1585 p == nullptr ? nullptr : static_cast< css::awt::XWindow * >(p->GetWindowPeer()),
1586 css::uno::UNO_QUERY);
1589 // virtual
1590 css::uno::Reference< css::awt::XTopWindow > SAL_CALL
1591 VCLXToolkit::getActiveTopWindow() throw (css::uno::RuntimeException, std::exception)
1593 vcl::Window * p = ::Application::GetActiveTopWindow();
1594 return css::uno::Reference< css::awt::XTopWindow >(
1595 p == nullptr ? nullptr : static_cast< css::awt::XWindow * >(p->GetWindowPeer()),
1596 css::uno::UNO_QUERY);
1599 // virtual
1600 void SAL_CALL VCLXToolkit::addTopWindowListener(
1601 css::uno::Reference< css::awt::XTopWindowListener > const & rListener)
1602 throw (css::uno::RuntimeException, std::exception)
1604 OSL_ENSURE(rListener.is(), "Null rListener");
1605 ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
1606 if (rBHelper.bDisposed || rBHelper.bInDispose)
1608 aGuard.clear();
1609 rListener->disposing(
1610 css::lang::EventObject(
1611 static_cast< ::cppu::OWeakObject * >(this)));
1613 else if (m_aTopWindowListeners.addInterface(rListener) == 1
1614 && !m_bEventListener)
1616 m_bEventListener = true;
1617 ::Application::AddEventListener(m_aEventListenerLink);
1621 // virtual
1622 void SAL_CALL VCLXToolkit::removeTopWindowListener(
1623 css::uno::Reference< css::awt::XTopWindowListener > const & rListener)
1624 throw (css::uno::RuntimeException, std::exception)
1626 ::osl::MutexGuard aGuard(rBHelper.rMutex);
1627 if (!(rBHelper.bDisposed || rBHelper.bInDispose)
1628 && m_aTopWindowListeners.removeInterface(rListener) == 0
1629 && m_aFocusListeners.getLength() == 0 && m_bEventListener)
1631 ::Application::RemoveEventListener(m_aEventListenerLink);
1632 m_bEventListener = false;
1636 // virtual
1637 void SAL_CALL VCLXToolkit::addKeyHandler(
1638 css::uno::Reference< css::awt::XKeyHandler > const & rHandler)
1639 throw (css::uno::RuntimeException, std::exception)
1641 OSL_ENSURE(rHandler.is(), "Null rHandler");
1642 ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
1643 if (rBHelper.bDisposed || rBHelper.bInDispose)
1645 aGuard.clear();
1646 rHandler->disposing(
1647 css::lang::EventObject(
1648 static_cast< ::cppu::OWeakObject * >(this)));
1650 else if (m_aKeyHandlers.addInterface(rHandler) == 1 && !m_bKeyListener)
1652 m_bKeyListener = true;
1653 ::Application::AddKeyListener(m_aKeyListenerLink);
1657 // virtual
1658 void SAL_CALL VCLXToolkit::removeKeyHandler(
1659 css::uno::Reference< css::awt::XKeyHandler > const & rHandler)
1660 throw (css::uno::RuntimeException, std::exception)
1662 ::osl::MutexGuard aGuard(rBHelper.rMutex);
1663 if (!(rBHelper.bDisposed || rBHelper.bInDispose)
1664 && m_aKeyHandlers.removeInterface(rHandler) == 0 && m_bKeyListener)
1666 ::Application::RemoveKeyListener(m_aKeyListenerLink);
1667 m_bKeyListener = false;
1671 // virtual
1672 void SAL_CALL VCLXToolkit::addFocusListener(
1673 css::uno::Reference< css::awt::XFocusListener > const & rListener)
1674 throw (css::uno::RuntimeException, std::exception)
1676 OSL_ENSURE(rListener.is(), "Null rListener");
1677 ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
1678 if (rBHelper.bDisposed || rBHelper.bInDispose)
1680 aGuard.clear();
1681 rListener->disposing(
1682 css::lang::EventObject(
1683 static_cast< ::cppu::OWeakObject * >(this)));
1685 else if (m_aFocusListeners.addInterface(rListener) == 1
1686 && !m_bEventListener)
1688 m_bEventListener = true;
1689 ::Application::AddEventListener(m_aEventListenerLink);
1693 // virtual
1694 void SAL_CALL VCLXToolkit::removeFocusListener(
1695 css::uno::Reference< css::awt::XFocusListener > const & rListener)
1696 throw (css::uno::RuntimeException, std::exception)
1698 ::osl::MutexGuard aGuard(rBHelper.rMutex);
1699 if (!(rBHelper.bDisposed || rBHelper.bInDispose)
1700 && m_aFocusListeners.removeInterface(rListener) == 0
1701 && m_aTopWindowListeners.getLength() == 0 && m_bEventListener)
1703 ::Application::RemoveEventListener(m_aEventListenerLink);
1704 m_bEventListener = false;
1708 // virtual
1709 void SAL_CALL VCLXToolkit::fireFocusGained(
1710 css::uno::Reference<
1711 css::uno::XInterface > const &)
1712 throw (css::uno::RuntimeException, std::exception)
1716 // virtual
1717 void SAL_CALL VCLXToolkit::fireFocusLost(
1718 css::uno::Reference<
1719 css::uno::XInterface > const &)
1720 throw (css::uno::RuntimeException, std::exception)
1725 IMPL_LINK_TYPED(VCLXToolkit, eventListenerHandler, ::VclSimpleEvent&, rEvent, void)
1727 switch (rEvent.GetId())
1729 case VCLEVENT_WINDOW_SHOW:
1730 callTopWindowListeners(
1731 &rEvent, &css::awt::XTopWindowListener::windowOpened);
1732 break;
1733 case VCLEVENT_WINDOW_HIDE:
1734 callTopWindowListeners(
1735 &rEvent, &css::awt::XTopWindowListener::windowClosed);
1736 break;
1737 case VCLEVENT_WINDOW_ACTIVATE:
1738 callTopWindowListeners(
1739 &rEvent, &css::awt::XTopWindowListener::windowActivated);
1740 break;
1741 case VCLEVENT_WINDOW_DEACTIVATE:
1742 callTopWindowListeners(
1743 &rEvent, &css::awt::XTopWindowListener::windowDeactivated);
1744 break;
1745 case VCLEVENT_WINDOW_CLOSE:
1746 callTopWindowListeners(
1747 &rEvent, &css::awt::XTopWindowListener::windowClosing);
1748 break;
1749 case VCLEVENT_WINDOW_GETFOCUS:
1750 callFocusListeners(&rEvent, true);
1751 break;
1752 case VCLEVENT_WINDOW_LOSEFOCUS:
1753 callFocusListeners(&rEvent, false);
1754 break;
1755 case VCLEVENT_WINDOW_MINIMIZE:
1756 callTopWindowListeners(
1757 &rEvent, &css::awt::XTopWindowListener::windowMinimized);
1758 break;
1759 case VCLEVENT_WINDOW_NORMALIZE:
1760 callTopWindowListeners(
1761 &rEvent, &css::awt::XTopWindowListener::windowNormalized);
1762 break;
1766 IMPL_LINK_TYPED(VCLXToolkit, keyListenerHandler, ::VclWindowEvent&, rEvent, bool)
1768 switch (rEvent.GetId())
1770 case VCLEVENT_WINDOW_KEYINPUT:
1771 return callKeyHandlers(&rEvent, true);
1772 case VCLEVENT_WINDOW_KEYUP:
1773 return callKeyHandlers(&rEvent, false);
1775 return false;
1778 void VCLXToolkit::callTopWindowListeners(
1779 ::VclSimpleEvent const * pEvent,
1780 void (SAL_CALL css::awt::XTopWindowListener::* pFn)(
1781 css::lang::EventObject const &))
1783 vcl::Window * pWindow
1784 = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow();
1785 if (pWindow->IsTopWindow())
1787 std::vector< css::uno::Reference< css::uno::XInterface > >
1788 aListeners(m_aTopWindowListeners.getElements());
1789 if (!aListeners.empty())
1791 css::lang::EventObject aAwtEvent(
1792 static_cast< css::awt::XWindow * >(pWindow->GetWindowPeer()));
1793 for (css::uno::Reference<XInterface> & i : aListeners)
1795 css::uno::Reference< css::awt::XTopWindowListener >
1796 xListener(i, css::uno::UNO_QUERY);
1799 (xListener.get()->*pFn)(aAwtEvent);
1801 catch (const css::uno::RuntimeException & rEx)
1803 OSL_TRACE(
1804 "VCLXToolkit::callTopWindowListeners: caught %s\n",
1805 OUStringToOString(
1806 rEx.Message, RTL_TEXTENCODING_UTF8).getStr());
1813 bool VCLXToolkit::callKeyHandlers(::VclSimpleEvent const * pEvent,
1814 bool bPressed)
1816 std::vector< css::uno::Reference< css::uno::XInterface > >
1817 aHandlers(m_aKeyHandlers.getElements());
1819 if (!aHandlers.empty())
1821 vcl::Window * pWindow = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow();
1823 // See implementation in vclxwindow.cxx for mapping between VCL and UNO AWT event
1824 ::KeyEvent * pKeyEvent = static_cast< ::KeyEvent * >(
1825 static_cast< ::VclWindowEvent const * >(pEvent)->GetData());
1826 css::awt::KeyEvent aAwtEvent(
1827 static_cast< css::awt::XWindow * >(pWindow->GetWindowPeer()),
1828 (pKeyEvent->GetKeyCode().IsShift()
1829 ? css::awt::KeyModifier::SHIFT : 0)
1830 | (pKeyEvent->GetKeyCode().IsMod1()
1831 ? css::awt::KeyModifier::MOD1 : 0)
1832 | (pKeyEvent->GetKeyCode().IsMod2()
1833 ? css::awt::KeyModifier::MOD2 : 0)
1834 | (pKeyEvent->GetKeyCode().IsMod3()
1835 ? css::awt::KeyModifier::MOD3 : 0),
1836 pKeyEvent->GetKeyCode().GetCode(), pKeyEvent->GetCharCode(),
1837 sal::static_int_cast< sal_Int16 >(
1838 pKeyEvent->GetKeyCode().GetFunction()));
1839 for (css::uno::Reference<XInterface> & i : aHandlers)
1841 css::uno::Reference< css::awt::XKeyHandler > xHandler(
1842 i, css::uno::UNO_QUERY);
1845 if ((bPressed ? xHandler->keyPressed(aAwtEvent)
1846 : xHandler->keyReleased(aAwtEvent)))
1847 return true;
1849 catch (const css::uno::RuntimeException & rEx)
1851 OSL_TRACE(
1852 "VCLXToolkit::callKeyHandlers: caught %s\n",
1853 OUStringToOString(
1854 rEx.Message, RTL_TEXTENCODING_UTF8).getStr());
1858 return false;
1861 void VCLXToolkit::callFocusListeners(::VclSimpleEvent const * pEvent,
1862 bool bGained)
1864 vcl::Window * pWindow
1865 = static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow();
1866 if (pWindow->IsTopWindow())
1868 std::vector< css::uno::Reference< css::uno::XInterface > >
1869 aListeners(m_aFocusListeners.getElements());
1870 if (!aListeners.empty())
1872 // Ignore the interior of compound controls when determining the
1873 // window that gets the focus next (see implementation in
1874 // vclxwindow.cxx for mapping between VCL and UNO AWT event):
1875 css::uno::Reference< css::uno::XInterface > xNext;
1876 vcl::Window * pFocus = ::Application::GetFocusWindow();
1877 for (vcl::Window * p = pFocus; p != nullptr; p = p->GetParent())
1878 if (!p->IsCompoundControl())
1880 pFocus = p;
1881 break;
1883 if (pFocus != nullptr)
1884 xNext = pFocus->GetComponentInterface();
1885 css::awt::FocusEvent aAwtEvent(
1886 static_cast< css::awt::XWindow * >(pWindow->GetWindowPeer()),
1887 static_cast<sal_Int16>(pWindow->GetGetFocusFlags()),
1888 xNext, false);
1889 for (css::uno::Reference<XInterface> & i : aListeners)
1891 css::uno::Reference< css::awt::XFocusListener > xListener(
1892 i, css::uno::UNO_QUERY);
1895 bGained ? xListener->focusGained(aAwtEvent)
1896 : xListener->focusLost(aAwtEvent);
1898 catch (const css::uno::RuntimeException & rEx)
1900 OSL_TRACE(
1901 "VCLXToolkit::callFocusListeners: caught %s\n",
1902 OUStringToOString(
1903 rEx.Message, RTL_TEXTENCODING_UTF8).getStr());
1910 // css::awt::XReschedule:
1912 void SAL_CALL VCLXToolkit::reschedule()
1913 throw (css::uno::RuntimeException, std::exception)
1915 SolarMutexGuard aSolarGuard;
1916 Application::Reschedule(true);
1919 // css::awt::XToolkitExperimental
1921 void SAL_CALL VCLXToolkit::processEventsToIdle()
1922 throw (css::uno::RuntimeException, std::exception)
1924 SolarMutexGuard aSolarGuard;
1925 Scheduler::ProcessEventsToIdle();
1928 sal_Int64 SAL_CALL VCLXToolkit::getOpenGLBufferSwapCounter()
1929 throw (css::uno::RuntimeException, std::exception)
1931 #if HAVE_FEATURE_OPENGL
1932 return OpenGLWrapper::getBufferSwapCounter();
1933 #else
1934 return 0;
1935 #endif
1938 void SAL_CALL VCLXToolkit::setDeterministicScheduling(sal_Bool bDeterministicMode)
1939 throw (css::uno::RuntimeException, std::exception)
1941 SolarMutexGuard aSolarGuard;
1942 Scheduler::SetDeterministicMode(bDeterministicMode);
1945 // css:awt:XToolkitRobot
1947 void SAL_CALL VCLXToolkit::keyPress( const css::awt::KeyEvent & aKeyEvent )
1948 throw (css::uno::RuntimeException, std::exception)
1950 css::uno::Reference<css::awt::XWindow> xWindow ( aKeyEvent.Source, css::uno::UNO_QUERY );
1951 if( !xWindow.is() )
1952 throw css::uno::RuntimeException( "invalid event source" );
1954 vcl::Window * pWindow = VCLUnoHelper::GetWindow( xWindow );
1955 if( !pWindow )
1956 throw css::uno::RuntimeException( "invalid event source" );
1958 ::KeyEvent aVCLKeyEvent = VCLUnoHelper::createVCLKeyEvent( aKeyEvent );
1959 ::Application::PostKeyEvent( VCLEVENT_WINDOW_KEYINPUT, pWindow, &aVCLKeyEvent );
1962 void SAL_CALL VCLXToolkit::keyRelease( const css::awt::KeyEvent & aKeyEvent )
1963 throw (css::uno::RuntimeException, std::exception)
1965 css::uno::Reference<css::awt::XWindow> xWindow ( aKeyEvent.Source, css::uno::UNO_QUERY );
1966 if( !xWindow.is() )
1967 throw css::uno::RuntimeException( "invalid event source" );
1969 vcl::Window * pWindow = VCLUnoHelper::GetWindow( xWindow );
1970 if( !pWindow )
1971 throw css::uno::RuntimeException( "invalid event source" );
1973 ::KeyEvent aVCLKeyEvent = VCLUnoHelper::createVCLKeyEvent( aKeyEvent );
1974 ::Application::PostKeyEvent( VCLEVENT_WINDOW_KEYUP, pWindow, &aVCLKeyEvent );
1978 void SAL_CALL VCLXToolkit::mousePress( const css::awt::MouseEvent & aMouseEvent )
1979 throw (css::uno::RuntimeException, std::exception)
1981 css::uno::Reference<css::awt::XWindow> xWindow ( aMouseEvent.Source, css::uno::UNO_QUERY );
1982 if( !xWindow.is() )
1983 throw css::uno::RuntimeException( "invalid event source" );
1985 vcl::Window * pWindow = VCLUnoHelper::GetWindow( xWindow );
1986 if( !pWindow )
1987 throw css::uno::RuntimeException( "invalid event source" );
1989 ::MouseEvent aVCLMouseEvent = VCLUnoHelper::createVCLMouseEvent( aMouseEvent );
1990 ::Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, pWindow, &aVCLMouseEvent );
1993 void SAL_CALL VCLXToolkit::mouseRelease( const css::awt::MouseEvent & aMouseEvent )
1994 throw (css::uno::RuntimeException, std::exception)
1996 css::uno::Reference<css::awt::XWindow> xWindow ( aMouseEvent.Source, css::uno::UNO_QUERY );
1997 if( !xWindow.is() )
1998 throw css::uno::RuntimeException( "invalid event source" );
2000 vcl::Window * pWindow = VCLUnoHelper::GetWindow( xWindow );
2001 if( !pWindow )
2002 throw css::uno::RuntimeException( "invalid event source" );
2004 ::MouseEvent aVCLMouseEvent = VCLUnoHelper::createVCLMouseEvent( aMouseEvent );
2005 ::Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEBUTTONUP, pWindow, &aVCLMouseEvent );
2008 void SAL_CALL VCLXToolkit::mouseMove( const css::awt::MouseEvent & aMouseEvent )
2009 throw (css::uno::RuntimeException, std::exception)
2011 css::uno::Reference<css::awt::XWindow> xWindow ( aMouseEvent.Source, css::uno::UNO_QUERY );
2012 if( !xWindow.is() )
2013 throw css::uno::RuntimeException( "invalid event source" );
2015 vcl::Window * pWindow = VCLUnoHelper::GetWindow( xWindow );
2016 if( !pWindow )
2017 throw css::uno::RuntimeException( "invalid event source" );
2019 ::MouseEvent aVCLMouseEvent = VCLUnoHelper::createVCLMouseEvent( aMouseEvent );
2020 ::Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEMOVE, pWindow, &aVCLMouseEvent );
2026 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
2027 stardiv_Toolkit_VCLXToolkit_get_implementation(
2028 css::uno::XComponentContext *,
2029 css::uno::Sequence<css::uno::Any> const &)
2031 return cppu::acquire(new VCLXToolkit());
2034 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */