1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <config_features.h>
22 #include <osl/file.hxx>
23 #include <osl/thread.hxx>
24 #include <osl/module.hxx>
26 #include <sal/log.hxx>
28 #include <tools/debug.hxx>
29 #include <tools/time.hxx>
30 #include <tools/stream.hxx>
32 #include <unotools/configmgr.hxx>
33 #include <unotools/syslocaleoptions.hxx>
35 #include <vcl/dialog.hxx>
36 #include <vcl/lok.hxx>
37 #include <vcl/floatwin.hxx>
38 #include <vcl/settings.hxx>
39 #include <vcl/keycod.hxx>
40 #include <vcl/event.hxx>
41 #include <vcl/vclevent.hxx>
42 #include <vcl/virdev.hxx>
43 #include <vcl/wrkwin.hxx>
44 #include <vcl/svapp.hxx>
45 #include <vcl/cvtgrf.hxx>
46 #include <vcl/toolkit/unowrap.hxx>
47 #include <vcl/timer.hxx>
48 #include <vcl/scheduler.hxx>
49 #if HAVE_FEATURE_OPENGL
50 #include <vcl/opengl/OpenGLWrapper.hxx>
53 #include <salinst.hxx>
54 #include <salframe.hxx>
57 #include <displayconnectiondispatch.hxx>
60 #include <strings.hrc>
61 #include <strings.hxx>
62 #if OSL_DEBUG_LEVEL > 0
63 #include <schedulerimpl.hxx>
66 #include <com/sun/star/uno/Reference.h>
67 #include <com/sun/star/awt/XToolkit.hpp>
68 #include <comphelper/lok.hxx>
69 #include <comphelper/solarmutex.hxx>
70 #include <osl/process.h>
76 using namespace ::com::sun::star
;
77 using namespace ::com::sun::star::uno
;
80 void InitSettings(ImplSVData
* pSVData
);
83 // keycodes handled internally by VCL
84 static vcl::KeyCode
const ReservedKeys
[]
86 vcl::KeyCode(KEY_F1
,0) ,
87 vcl::KeyCode(KEY_F1
,KEY_SHIFT
) ,
88 vcl::KeyCode(KEY_F1
,KEY_MOD1
) ,
89 vcl::KeyCode(KEY_F2
,KEY_SHIFT
) ,
90 vcl::KeyCode(KEY_F4
,KEY_MOD1
) ,
91 vcl::KeyCode(KEY_F4
,KEY_MOD2
) ,
92 vcl::KeyCode(KEY_F4
,KEY_MOD1
|KEY_MOD2
) ,
93 vcl::KeyCode(KEY_F6
,0) ,
94 vcl::KeyCode(KEY_F6
,KEY_MOD1
) ,
95 vcl::KeyCode(KEY_F6
,KEY_SHIFT
) ,
96 vcl::KeyCode(KEY_F6
,KEY_MOD1
|KEY_SHIFT
) ,
97 vcl::KeyCode(KEY_F10
,0)
100 vcl::KeyCode(KEY_1
,KEY_SHIFT
|KEY_MOD1
),
101 vcl::KeyCode(KEY_2
,KEY_SHIFT
|KEY_MOD1
),
102 vcl::KeyCode(KEY_3
,KEY_SHIFT
|KEY_MOD1
),
103 vcl::KeyCode(KEY_4
,KEY_SHIFT
|KEY_MOD1
),
104 vcl::KeyCode(KEY_5
,KEY_SHIFT
|KEY_MOD1
),
105 vcl::KeyCode(KEY_6
,KEY_SHIFT
|KEY_MOD1
),
106 vcl::KeyCode(KEY_7
,KEY_SHIFT
|KEY_MOD1
),
107 vcl::KeyCode(KEY_8
,KEY_SHIFT
|KEY_MOD1
),
108 vcl::KeyCode(KEY_9
,KEY_SHIFT
|KEY_MOD1
),
109 vcl::KeyCode(KEY_0
,KEY_SHIFT
|KEY_MOD1
),
110 vcl::KeyCode(KEY_ADD
,KEY_SHIFT
|KEY_MOD1
)
115 typedef UnoWrapperBase
* (*FN_TkCreateUnoWrapper
)();
118 struct ImplPostEventData
120 VclEventId
const mnEvent
;
121 VclPtr
<vcl::Window
> mpWin
;
122 ImplSVEvent
* mnEventId
;
124 MouseEvent maMouseEvent
;
125 GestureEvent maGestureEvent
;
127 ImplPostEventData(VclEventId nEvent
, vcl::Window
* pWin
, const KeyEvent
& rKeyEvent
)
131 , maKeyEvent(rKeyEvent
)
133 ImplPostEventData(VclEventId nEvent
, vcl::Window
* pWin
, const MouseEvent
& rMouseEvent
)
137 , maMouseEvent(rMouseEvent
)
139 ImplPostEventData(VclEventId nEvent
, vcl::Window
* pWin
, const GestureEvent
& rGestureEvent
)
143 , maGestureEvent(rGestureEvent
)
147 Application
* GetpApp()
149 ImplSVData
* pSVData
= ImplGetSVData();
152 return pSVData
->mpApp
;
155 Application::Application()
157 // useful for themes at least, perhaps extensions too
158 OUString
aVar("LIBO_VERSION"), aValue(LIBO_VERSION_DOTTED
);
159 osl_setEnvironment(aVar
.pData
, aValue
.pData
);
161 ImplGetSVData()->mpApp
= this;
164 Application::~Application()
167 ImplGetSVData()->mpApp
= nullptr;
170 int Application::Main()
172 SAL_WARN("vcl", "Application is a base class and should be overridden.");
176 bool Application::QueryExit()
178 WorkWindow
* pAppWin
= ImplGetSVData()->maWinData
.mpAppWin
;
180 // call the close handler of the application window
182 return pAppWin
->Close();
187 void Application::Init()
191 void Application::InitFinished()
195 void Application::DeInit()
199 sal_uInt16
Application::GetCommandLineParamCount()
201 return static_cast<sal_uInt16
>(osl_getCommandArgCount());
204 OUString
Application::GetCommandLineParam( sal_uInt16 nParam
)
207 osl_getCommandArg( nParam
, &aParam
.pData
);
211 OUString
Application::GetAppFileName()
213 ImplSVData
* pSVData
= ImplGetSVData();
214 SAL_WARN_IF( !pSVData
->maAppData
.mxAppFileName
, "vcl", "AppFileName should be set to something after SVMain!" );
215 if ( pSVData
->maAppData
.mxAppFileName
)
216 return *pSVData
->maAppData
.mxAppFileName
;
219 * provide a fallback for people without initialized vcl here (like setup
220 * in responsefile mode)
222 OUString aAppFileName
;
223 OUString aExeFileName
;
224 osl_getExecutableFile(&aExeFileName
.pData
);
226 // convert path to native file format
227 osl::FileBase::getSystemPathFromFileURL(aExeFileName
, aAppFileName
);
232 void Application::Exception( ExceptionCategory nCategory
)
236 // System has precedence (so do nothing)
237 case ExceptionCategory::System
:
238 case ExceptionCategory::UserInterface
:
242 case ExceptionCategory::ResourceNotLoaded
:
243 Abort("Resource not loaded");
246 Abort("Unknown Error");
256 void Application::Abort( const OUString
& rErrorText
)
258 //HACK: Dump core iff --norestore command line argument is given (assuming
259 // this process is run by developers who are interested in cores, vs. end
260 // users who are not):
261 bool dumpCore
= false;
262 sal_uInt16 n
= GetCommandLineParamCount();
263 for (sal_uInt16 i
= 0; i
!= n
; ++i
) {
264 if (GetCommandLineParam(i
) == "--norestore") {
269 #if OSL_DEBUG_LEVEL > 0
273 SalAbort( rErrorText
, dumpCore
);
276 sal_uLong
Application::GetReservedKeyCodeCount()
278 return SAL_N_ELEMENTS(ReservedKeys
);
281 const vcl::KeyCode
* Application::GetReservedKeyCode( sal_uLong i
)
283 if( i
>= GetReservedKeyCodeCount() )
286 return &ReservedKeys
[i
];
289 IMPL_STATIC_LINK_NOARG( ImplSVAppData
, ImplEndAllPopupsMsg
, void*, void )
291 ImplSVData
* pSVData
= ImplGetSVData();
292 while (pSVData
->maWinData
.mpFirstFloat
)
293 pSVData
->maWinData
.mpFirstFloat
->EndPopupMode(FloatWinPopupEndFlags::Cancel
);
296 IMPL_STATIC_LINK_NOARG( ImplSVAppData
, ImplEndAllDialogsMsg
, void*, void )
298 vcl::Window
* pAppWindow
= Application::GetFirstTopLevelWindow();
301 Dialog::EndAllDialogs(pAppWindow
);
302 pAppWindow
= Application::GetNextTopLevelWindow(pAppWindow
);
306 void Application::EndAllDialogs()
308 Application::PostUserEvent( LINK( nullptr, ImplSVAppData
, ImplEndAllDialogsMsg
) );
311 void Application::EndAllPopups()
313 Application::PostUserEvent( LINK( nullptr, ImplSVAppData
, ImplEndAllPopupsMsg
) );
319 VclPtr
<vcl::Window
> GetEventWindow()
321 VclPtr
<vcl::Window
> xWin(Application::GetFirstTopLevelWindow());
324 if (xWin
->IsVisible())
326 xWin
.reset(Application::GetNextTopLevelWindow(xWin
));
331 bool InjectKeyEvent(SvStream
& rStream
)
333 VclPtr
<vcl::Window
> xWin(GetEventWindow());
337 // skip the first available cycle and insert on the next one when we
338 // are trying the initial event, flagged by a triggered but undeleted
339 // mpEventTestingIdle
340 ImplSVData
* pSVData
= ImplGetSVData();
341 if (pSVData
->maAppData
.mpEventTestingIdle
)
343 delete pSVData
->maAppData
.mpEventTestingIdle
;
344 pSVData
->maAppData
.mpEventTestingIdle
= nullptr;
348 sal_uInt16 nCode
, nCharCode
;
349 rStream
.ReadUInt16(nCode
);
350 rStream
.ReadUInt16(nCharCode
);
354 KeyEvent
aVCLKeyEvt(nCharCode
, nCode
);
355 Application::PostKeyEvent(VclEventId::WindowKeyInput
, xWin
.get(), &aVCLKeyEvt
);
356 Application::PostKeyEvent(VclEventId::WindowKeyUp
, xWin
.get(), &aVCLKeyEvt
);
360 void CloseDialogsAndQuit()
362 Application::EndAllPopups();
363 Application::EndAllDialogs();
364 Application::PostUserEvent( LINK( nullptr, ImplSVAppData
, ImplPrepareExitMsg
) );
368 IMPL_LINK_NOARG(ImplSVAppData
, VclEventTestingHdl
, Timer
*, void)
370 if (Application::AnyInput())
372 mpEventTestingIdle
->Start();
376 Application::PostUserEvent( LINK( nullptr, ImplSVAppData
, ImplVclEventTestingHdl
) );
380 IMPL_STATIC_LINK_NOARG( ImplSVAppData
, ImplVclEventTestingHdl
, void*, void )
382 ImplSVData
* pSVData
= ImplGetSVData();
383 SAL_INFO("vcl.eventtesting", "EventTestLimit is " << pSVData
->maAppData
.mnEventTestLimit
);
384 if (pSVData
->maAppData
.mnEventTestLimit
== 0)
386 delete pSVData
->maAppData
.mpEventTestInput
;
387 SAL_INFO("vcl.eventtesting", "Event Limit reached, exiting" << pSVData
->maAppData
.mnEventTestLimit
);
388 CloseDialogsAndQuit();
392 if (InjectKeyEvent(*pSVData
->maAppData
.mpEventTestInput
))
393 --pSVData
->maAppData
.mnEventTestLimit
;
394 if (!pSVData
->maAppData
.mpEventTestInput
->good())
396 SAL_INFO("vcl.eventtesting", "Event Input exhausted, exit next cycle");
397 pSVData
->maAppData
.mnEventTestLimit
= 0;
399 Application::PostUserEvent( LINK( nullptr, ImplSVAppData
, ImplVclEventTestingHdl
) );
403 IMPL_STATIC_LINK_NOARG( ImplSVAppData
, ImplPrepareExitMsg
, void*, void )
405 //now close top level frames
406 (void)GetpApp()->QueryExit();
409 void Application::Execute()
411 ImplSVData
* pSVData
= ImplGetSVData();
412 pSVData
->maAppData
.mbInAppExecute
= true;
413 pSVData
->maAppData
.mbAppQuit
= false;
415 if (Application::IsEventTestingModeEnabled())
417 pSVData
->maAppData
.mnEventTestLimit
= 50;
418 pSVData
->maAppData
.mpEventTestingIdle
= new Idle("eventtesting");
419 pSVData
->maAppData
.mpEventTestingIdle
->SetInvokeHandler(LINK(&(pSVData
->maAppData
), ImplSVAppData
, VclEventTestingHdl
));
420 pSVData
->maAppData
.mpEventTestingIdle
->SetPriority(TaskPriority::HIGH_IDLE
);
421 pSVData
->maAppData
.mpEventTestInput
= new SvFileStream("eventtesting", StreamMode::READ
);
422 pSVData
->maAppData
.mpEventTestingIdle
->Start();
425 while ( !pSVData
->maAppData
.mbAppQuit
)
426 Application::Yield();
428 pSVData
->maAppData
.mbInAppExecute
= false;
431 static bool ImplYield(bool i_bWait
, bool i_bAllEvents
)
433 ImplSVData
* pSVData
= ImplGetSVData();
435 SAL_INFO("vcl.schedule", "Enter ImplYield: " << (i_bWait
? "wait" : "no wait") <<
436 ": " << (i_bAllEvents
? "all events" : "one event"));
438 // there's a data race here on WNT only because ImplYield may be
439 // called without SolarMutex; but the only remaining use of mnDispatchLevel
440 // is in OSX specific code
441 pSVData
->maAppData
.mnDispatchLevel
++;
443 // do not wait for events if application was already quit; in that
444 // case only dispatch events already available
445 bool bProcessedEvent
= pSVData
->mpDefInst
->DoYield(
446 i_bWait
&& !pSVData
->maAppData
.mbAppQuit
, i_bAllEvents
);
448 pSVData
->maAppData
.mnDispatchLevel
--;
450 DBG_TESTSOLARMUTEX(); // must be locked on return from Yield
452 SAL_INFO("vcl.schedule", "Leave ImplYield with return " << bProcessedEvent
);
453 return bProcessedEvent
;
456 bool Application::Reschedule( bool i_bAllEvents
)
458 return ImplYield(false, i_bAllEvents
);
461 void Scheduler::ProcessEventsToIdle()
464 while( Application::Reschedule( true ) )
466 if (0 == ++nSanity
% 1000)
468 SAL_WARN("vcl.schedule", "ProcessEventsToIdle: " << nSanity
);
471 #if OSL_DEBUG_LEVEL > 0
472 // If we yield from a non-main thread we just can guarantee that all idle
473 // events were processed at some point, but our check can't prevent further
474 // processing in the main thread, which may add new events, so skip it.
475 const ImplSVData
* pSVData
= ImplGetSVData();
476 if (!pSVData
->mpDefInst
->IsMainThread())
478 for (int nTaskPriority
= 0; nTaskPriority
< PRIO_COUNT
; ++nTaskPriority
)
480 const ImplSchedulerData
* pSchedulerData
= pSVData
->maSchedCtx
.mpFirstSchedulerData
[nTaskPriority
];
481 while (pSchedulerData
)
483 if (pSchedulerData
->mpTask
&& !pSchedulerData
->mbInScheduler
)
485 Idle
*pIdle
= dynamic_cast<Idle
*>(pSchedulerData
->mpTask
);
486 if (pIdle
&& pIdle
->IsActive())
488 SAL_WARN("vcl.schedule", "Unprocessed Idle: "
489 << pIdle
<< " " << pIdle
->GetDebugName());
492 pSchedulerData
= pSchedulerData
->mpNext
;
499 /// used by unit tests that test only via the LOK API
500 SAL_DLLPUBLIC_EXPORT
void unit_lok_process_events_to_idle()
502 const SolarMutexGuard aGuard
;
503 Scheduler::ProcessEventsToIdle();
507 void Application::Yield()
509 ImplYield(true, false);
512 IMPL_STATIC_LINK_NOARG( ImplSVAppData
, ImplQuitMsg
, void*, void )
514 ImplGetSVData()->maAppData
.mbAppQuit
= true;
517 void Application::Quit()
519 Application::PostUserEvent( LINK( nullptr, ImplSVAppData
, ImplQuitMsg
) );
522 comphelper::SolarMutex
& Application::GetSolarMutex()
524 ImplSVData
* pSVData
= ImplGetSVData();
525 return *(pSVData
->mpDefInst
->GetYieldMutex());
528 bool Application::IsMainThread()
530 return ImplGetSVData()->mnMainThreadId
== osl::Thread::getCurrentIdentifier();
533 sal_uInt32
Application::ReleaseSolarMutex()
535 ImplSVData
* pSVData
= ImplGetSVData();
536 return pSVData
->mpDefInst
->ReleaseYieldMutexAll();
539 void Application::AcquireSolarMutex( sal_uInt32 nCount
)
541 ImplSVData
* pSVData
= ImplGetSVData();
542 pSVData
->mpDefInst
->AcquireYieldMutex( nCount
);
545 bool Application::IsInMain()
547 ImplSVData
* pSVData
= ImplGetSVData();
548 return pSVData
&& pSVData
->maAppData
.mbInAppMain
;
551 bool Application::IsInExecute()
553 return ImplGetSVData()->maAppData
.mbInAppExecute
;
556 bool Application::IsInModalMode()
558 return (ImplGetSVData()->maAppData
.mnModalMode
!= 0);
561 sal_uInt16
Application::GetDispatchLevel()
563 return ImplGetSVData()->maAppData
.mnDispatchLevel
;
566 bool Application::AnyInput( VclInputFlags nType
)
568 return ImplGetSVData()->mpDefInst
->AnyInput( nType
);
571 sal_uInt64
Application::GetLastInputInterval()
573 return (tools::Time::GetSystemTicks()-ImplGetSVData()->maAppData
.mnLastInputTime
);
576 bool Application::IsUICaptured()
578 ImplSVData
* pSVData
= ImplGetSVData();
580 // If mouse was captured, or if in tracking- or in select-mode of a floatingwindow (e.g. menus
581 // or pulldown toolboxes) another window should be created
583 return pSVData
->maWinData
.mpCaptureWin
|| pSVData
->maWinData
.mpTrackWin
||
584 pSVData
->maWinData
.mpFirstFloat
|| nImplSysDialog
;
587 void Application::OverrideSystemSettings( AllSettings
& /*rSettings*/ )
591 void Application::MergeSystemSettings( AllSettings
& rSettings
)
593 vcl::Window
* pWindow
= ImplGetSVData()->maWinData
.mpFirstFrame
;
595 pWindow
= ImplGetDefaultWindow();
598 ImplSVData
* pSVData
= ImplGetSVData();
599 if ( !pSVData
->maAppData
.mbSettingsInit
)
601 // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
602 pWindow
->ImplUpdateGlobalSettings( *pSVData
->maAppData
.mpSettings
);
603 pSVData
->maAppData
.mbSettingsInit
= true;
605 // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
606 pWindow
->ImplUpdateGlobalSettings( rSettings
, false );
610 void Application::SetSettings( const AllSettings
& rSettings
)
612 const SolarMutexGuard aGuard
;
614 ImplSVData
* pSVData
= ImplGetSVData();
615 if ( !pSVData
->maAppData
.mpSettings
)
617 InitSettings(pSVData
);
618 *pSVData
->maAppData
.mpSettings
= rSettings
;
622 AllSettings aOldSettings
= *pSVData
->maAppData
.mpSettings
;
623 if (aOldSettings
.GetUILanguageTag().getLanguageType() != rSettings
.GetUILanguageTag().getLanguageType() &&
624 pSVData
->mbResLocaleSet
)
626 pSVData
->mbResLocaleSet
= false;
628 *pSVData
->maAppData
.mpSettings
= rSettings
;
629 AllSettingsFlags nChangeFlags
= aOldSettings
.GetChangeFlags( *pSVData
->maAppData
.mpSettings
);
630 if ( bool(nChangeFlags
) )
632 DataChangedEvent
aDCEvt( DataChangedEventType::SETTINGS
, &aOldSettings
, nChangeFlags
);
634 // notify data change handler
635 ImplCallEventListenersApplicationDataChanged( &aDCEvt
);
637 // Update all windows
638 vcl::Window
* pFirstFrame
= pSVData
->maWinData
.mpFirstFrame
;
639 // Reset data that needs to be re-calculated
644 nOldDPIX
= pFirstFrame
->GetDPIX();
645 nOldDPIY
= pFirstFrame
->GetDPIY();
646 vcl::Window::ImplInitAppFontData(pFirstFrame
);
648 vcl::Window
* pFrame
= pFirstFrame
;
651 // call UpdateSettings from ClientWindow in order to prevent updating data twice
652 vcl::Window
* pClientWin
= pFrame
;
653 while ( pClientWin
->ImplGetClientWindow() )
654 pClientWin
= pClientWin
->ImplGetClientWindow();
655 pClientWin
->UpdateSettings( rSettings
, true );
657 vcl::Window
* pTempWin
= pFrame
->mpWindowImpl
->mpFrameData
->mpFirstOverlap
;
660 // call UpdateSettings from ClientWindow in order to prevent updating data twice
661 pClientWin
= pTempWin
;
662 while ( pClientWin
->ImplGetClientWindow() )
663 pClientWin
= pClientWin
->ImplGetClientWindow();
664 pClientWin
->UpdateSettings( rSettings
, true );
665 pTempWin
= pTempWin
->mpWindowImpl
->mpNextOverlap
;
668 pFrame
= pFrame
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
671 // if DPI resolution for screen output was changed set the new resolution for all
672 // screen compatible VirDev's
673 pFirstFrame
= pSVData
->maWinData
.mpFirstFrame
;
676 if ( (pFirstFrame
->GetDPIX() != nOldDPIX
) ||
677 (pFirstFrame
->GetDPIY() != nOldDPIY
) )
679 VirtualDevice
* pVirDev
= pSVData
->maGDIData
.mpFirstVirDev
;
682 if ( pVirDev
->mbScreenComp
&&
683 (pVirDev
->GetDPIX() == nOldDPIX
) &&
684 (pVirDev
->GetDPIY() == nOldDPIY
) )
686 pVirDev
->SetDPIX( pFirstFrame
->GetDPIX() );
687 pVirDev
->SetDPIY( pFirstFrame
->GetDPIY() );
688 if ( pVirDev
->IsMapModeEnabled() )
690 MapMode aMapMode
= pVirDev
->GetMapMode();
691 pVirDev
->SetMapMode();
692 pVirDev
->SetMapMode( aMapMode
);
696 pVirDev
= pVirDev
->mpNext
;
704 const AllSettings
& Application::GetSettings()
706 ImplSVData
* pSVData
= ImplGetSVData();
707 if ( !pSVData
->maAppData
.mpSettings
)
709 InitSettings(pSVData
);
712 return *(pSVData
->maAppData
.mpSettings
);
717 void InitSettings(ImplSVData
* pSVData
)
719 assert(!pSVData
->maAppData
.mpSettings
&& "initialization should not happen twice!");
721 pSVData
->maAppData
.mpSettings
.reset(new AllSettings());
722 if (!utl::ConfigManager::IsFuzzing())
724 pSVData
->maAppData
.mpCfgListener
= new LocaleConfigurationListener
;
725 pSVData
->maAppData
.mpSettings
->GetSysLocale().GetOptions().AddListener( pSVData
->maAppData
.mpCfgListener
);
731 void Application::NotifyAllWindows( DataChangedEvent
& rDCEvt
)
733 ImplSVData
* pSVData
= ImplGetSVData();
734 vcl::Window
* pFrame
= pSVData
->maWinData
.mpFirstFrame
;
737 pFrame
->NotifyAllChildren( rDCEvt
);
739 vcl::Window
* pSysWin
= pFrame
->mpWindowImpl
->mpFrameData
->mpFirstOverlap
;
742 pSysWin
->NotifyAllChildren( rDCEvt
);
743 pSysWin
= pSysWin
->mpWindowImpl
->mpNextOverlap
;
746 pFrame
= pFrame
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
750 void Application::ImplCallEventListenersApplicationDataChanged( void* pData
)
752 ImplSVData
* pSVData
= ImplGetSVData();
753 VclWindowEvent
aEvent( nullptr, VclEventId::ApplicationDataChanged
, pData
);
755 pSVData
->maAppData
.maEventListeners
.Call( aEvent
);
758 void Application::ImplCallEventListeners( VclSimpleEvent
& rEvent
)
760 ImplSVData
* pSVData
= ImplGetSVData();
761 pSVData
->maAppData
.maEventListeners
.Call( rEvent
);
764 void Application::AddEventListener( const Link
<VclSimpleEvent
&,void>& rEventListener
)
766 ImplSVData
* pSVData
= ImplGetSVData();
767 pSVData
->maAppData
.maEventListeners
.addListener( rEventListener
);
770 void Application::RemoveEventListener( const Link
<VclSimpleEvent
&,void>& rEventListener
)
772 ImplSVData
* pSVData
= ImplGetSVData();
773 pSVData
->maAppData
.maEventListeners
.removeListener( rEventListener
);
776 void Application::AddKeyListener( const Link
<VclWindowEvent
&,bool>& rKeyListener
)
778 ImplSVData
* pSVData
= ImplGetSVData();
779 pSVData
->maAppData
.maKeyListeners
.push_back( rKeyListener
);
782 void Application::RemoveKeyListener( const Link
<VclWindowEvent
&,bool>& rKeyListener
)
784 ImplSVData
* pSVData
= ImplGetSVData();
785 auto & rVec
= pSVData
->maAppData
.maKeyListeners
;
786 rVec
.erase( std::remove(rVec
.begin(), rVec
.end(), rKeyListener
), rVec
.end() );
789 bool Application::HandleKey( VclEventId nEvent
, vcl::Window
*pWin
, KeyEvent
* pKeyEvent
)
791 // let listeners process the key event
792 VclWindowEvent
aEvent( pWin
, nEvent
, static_cast<void *>(pKeyEvent
) );
794 ImplSVData
* pSVData
= ImplGetSVData();
796 if ( pSVData
->maAppData
.maKeyListeners
.empty() )
799 bool bProcessed
= false;
800 // Copy the list, because this can be destroyed when calling a Link...
801 std::vector
<Link
<VclWindowEvent
&,bool>> aCopy( pSVData
->maAppData
.maKeyListeners
);
802 for ( const Link
<VclWindowEvent
&,bool>& rLink
: aCopy
)
804 if( rLink
.Call( aEvent
) )
813 ImplSVEvent
* Application::PostKeyEvent( VclEventId nEvent
, vcl::Window
*pWin
, KeyEvent
const * pKeyEvent
)
815 const SolarMutexGuard aGuard
;
816 ImplSVEvent
* nEventId
= nullptr;
818 if( pWin
&& pKeyEvent
)
820 std::unique_ptr
<ImplPostEventData
> pPostEventData(new ImplPostEventData( nEvent
, pWin
, *pKeyEvent
));
822 nEventId
= PostUserEvent(
823 LINK( nullptr, Application
, PostEventHandler
),
824 pPostEventData
.get() );
828 pPostEventData
->mnEventId
= nEventId
;
829 ImplGetSVData()->maAppData
.maPostedEventList
.emplace_back( pWin
, pPostEventData
.release() );
836 ImplSVEvent
* Application::PostGestureEvent(VclEventId nEvent
, vcl::Window
* pWin
, GestureEvent
const * pGestureEvent
)
838 const SolarMutexGuard aGuard
;
839 ImplSVEvent
* nEventId
= nullptr;
841 if (pWin
&& pGestureEvent
)
843 Point
aTransformedPosition(pGestureEvent
->mnX
, pGestureEvent
->mnY
);
845 aTransformedPosition
.AdjustX(pWin
->GetOutOffXPixel());
846 aTransformedPosition
.AdjustY(pWin
->GetOutOffYPixel());
848 const GestureEvent
aGestureEvent(
849 sal_Int32(aTransformedPosition
.X()),
850 sal_Int32(aTransformedPosition
.Y()),
851 pGestureEvent
->meEventType
,
852 pGestureEvent
->mnOffset
,
853 pGestureEvent
->meOrientation
856 std::unique_ptr
<ImplPostEventData
> pPostEventData(new ImplPostEventData(nEvent
, pWin
, aGestureEvent
));
858 nEventId
= PostUserEvent(
859 LINK( nullptr, Application
, PostEventHandler
),
860 pPostEventData
.get());
864 pPostEventData
->mnEventId
= nEventId
;
865 ImplGetSVData()->maAppData
.maPostedEventList
.emplace_back(pWin
, pPostEventData
.release());
872 ImplSVEvent
* Application::PostMouseEvent( VclEventId nEvent
, vcl::Window
*pWin
, MouseEvent
const * pMouseEvent
)
874 const SolarMutexGuard aGuard
;
875 ImplSVEvent
* nEventId
= nullptr;
877 if( pWin
&& pMouseEvent
)
879 Point
aTransformedPos( pMouseEvent
->GetPosPixel() );
881 // LOK uses (0, 0) as the origin of all windows; don't offset.
882 if (!comphelper::LibreOfficeKit::isActive())
884 aTransformedPos
.AdjustX(pWin
->GetOutOffXPixel());
885 aTransformedPos
.AdjustY(pWin
->GetOutOffYPixel());
888 const MouseEvent
aTransformedEvent( aTransformedPos
, pMouseEvent
->GetClicks(), pMouseEvent
->GetMode(),
889 pMouseEvent
->GetButtons(), pMouseEvent
->GetModifier() );
891 std::unique_ptr
<ImplPostEventData
> pPostEventData(new ImplPostEventData( nEvent
, pWin
, aTransformedEvent
));
893 nEventId
= PostUserEvent(
894 LINK( nullptr, Application
, PostEventHandler
),
895 pPostEventData
.get() );
899 pPostEventData
->mnEventId
= nEventId
;
900 ImplGetSVData()->maAppData
.maPostedEventList
.emplace_back( pWin
, pPostEventData
.release() );
908 IMPL_STATIC_LINK( Application
, PostEventHandler
, void*, pCallData
, void )
910 const SolarMutexGuard aGuard
;
911 ImplPostEventData
* pData
= static_cast< ImplPostEventData
* >( pCallData
);
912 const void* pEventData
;
914 ImplSVEvent
* const nEventId
= pData
->mnEventId
;
916 switch( pData
->mnEvent
)
918 case VclEventId::WindowMouseMove
:
919 nEvent
= SalEvent::ExternalMouseMove
;
920 pEventData
= &pData
->maMouseEvent
;
923 case VclEventId::WindowMouseButtonDown
:
924 nEvent
= SalEvent::ExternalMouseButtonDown
;
925 pEventData
= &pData
->maMouseEvent
;
928 case VclEventId::WindowMouseButtonUp
:
929 nEvent
= SalEvent::ExternalMouseButtonUp
;
930 pEventData
= &pData
->maMouseEvent
;
933 case VclEventId::WindowKeyInput
:
934 nEvent
= SalEvent::ExternalKeyInput
;
935 pEventData
= &pData
->maKeyEvent
;
938 case VclEventId::WindowKeyUp
:
939 nEvent
= SalEvent::ExternalKeyUp
;
940 pEventData
= &pData
->maKeyEvent
;
943 case VclEventId::WindowGestureEvent
:
944 nEvent
= SalEvent::ExternalGesture
;
945 pEventData
= &pData
->maGestureEvent
;
949 nEvent
= SalEvent::NONE
;
950 pEventData
= nullptr;
954 if( pData
->mpWin
&& pData
->mpWin
->mpWindowImpl
->mpFrameWindow
.get() && pEventData
)
955 ImplWindowFrameProc( pData
->mpWin
->mpWindowImpl
->mpFrameWindow
.get(), nEvent
, pEventData
);
957 // remove this event from list of posted events, watch for destruction of internal data
958 auto svdata
= ImplGetSVData();
959 ::std::vector
< ImplPostEventPair
>::iterator
aIter( svdata
->maAppData
.maPostedEventList
.begin() );
961 while( aIter
!= svdata
->maAppData
.maPostedEventList
.end() )
963 if( nEventId
== (*aIter
).second
->mnEventId
)
965 delete (*aIter
).second
;
966 aIter
= svdata
->maAppData
.maPostedEventList
.erase( aIter
);
973 void Application::RemoveMouseAndKeyEvents( vcl::Window
* pWin
)
975 const SolarMutexGuard aGuard
;
977 // remove all events for specific window, watch for destruction of internal data
978 auto svdata
= ImplGetSVData();
979 ::std::vector
< ImplPostEventPair
>::iterator
aIter( svdata
->maAppData
.maPostedEventList
.begin() );
981 while( aIter
!= svdata
->maAppData
.maPostedEventList
.end() )
983 if( pWin
== (*aIter
).first
)
985 if( (*aIter
).second
->mnEventId
)
986 RemoveUserEvent( (*aIter
).second
->mnEventId
);
988 delete (*aIter
).second
;
989 aIter
= svdata
->maAppData
.maPostedEventList
.erase( aIter
);
996 ImplSVEvent
* Application::PostUserEvent( const Link
<void*,void>& rLink
, void* pCaller
,
997 bool bReferenceLink
)
999 vcl::Window
* pDefWindow
= ImplGetDefaultWindow();
1000 if ( pDefWindow
== nullptr )
1003 std::unique_ptr
<ImplSVEvent
> pSVEvent(new ImplSVEvent
);
1004 pSVEvent
->mpData
= pCaller
;
1005 pSVEvent
->maLink
= rLink
;
1006 pSVEvent
->mpWindow
= nullptr;
1007 pSVEvent
->mbCall
= true;
1010 SolarMutexGuard aGuard
;
1011 // Double check that this is indeed a vcl::Window instance.
1012 assert(dynamic_cast<vcl::Window
*>(
1013 static_cast<OutputDevice
*>(rLink
.GetInstance())) ==
1014 static_cast<vcl::Window
*>(rLink
.GetInstance()));
1015 pSVEvent
->mpInstanceRef
= static_cast<vcl::Window
*>(rLink
.GetInstance());
1018 auto pTmpEvent
= pSVEvent
.get();
1019 if (!pDefWindow
->ImplGetFrame()->PostEvent( std::move(pSVEvent
) ))
1024 void Application::RemoveUserEvent( ImplSVEvent
* nUserEvent
)
1028 SAL_WARN_IF( nUserEvent
->mpWindow
, "vcl",
1029 "Application::RemoveUserEvent(): Event is send to a window" );
1030 SAL_WARN_IF( !nUserEvent
->mbCall
, "vcl",
1031 "Application::RemoveUserEvent(): Event is already removed" );
1033 nUserEvent
->mpWindow
.clear();
1034 nUserEvent
->mpInstanceRef
.clear();
1035 nUserEvent
->mbCall
= false;
1039 void Application::LockFontUpdates(bool bLock
)
1041 OutputDevice::LockFontUpdates(bLock
);
1044 WorkWindow
* Application::GetAppWindow()
1046 return ImplGetSVData()->maWinData
.mpAppWin
;
1049 vcl::Window
* Application::GetFocusWindow()
1051 return ImplGetSVData()->maWinData
.mpFocusWin
;
1054 OutputDevice
* Application::GetDefaultDevice()
1056 return ImplGetDefaultWindow();
1059 vcl::Window
* Application::GetFirstTopLevelWindow()
1061 ImplSVData
* pSVData
= ImplGetSVData();
1062 return pSVData
->maWinData
.mpFirstFrame
;
1065 vcl::Window
* Application::GetNextTopLevelWindow( vcl::Window
const * pWindow
)
1067 return pWindow
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
1070 long Application::GetTopWindowCount()
1073 ImplSVData
* pSVData
= ImplGetSVData();
1074 vcl::Window
*pWin
= pSVData
? pSVData
->maWinData
.mpFirstFrame
.get() : nullptr;
1077 if( pWin
->ImplGetWindow()->IsTopWindow() )
1079 pWin
= pWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
1084 vcl::Window
* Application::GetTopWindow( long nIndex
)
1087 ImplSVData
* pSVData
= ImplGetSVData();
1088 vcl::Window
*pWin
= pSVData
? pSVData
->maWinData
.mpFirstFrame
.get() : nullptr;
1091 if( pWin
->ImplGetWindow()->IsTopWindow() )
1093 if( nIdx
== nIndex
)
1094 return pWin
->ImplGetWindow();
1098 pWin
= pWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
1103 vcl::Window
* Application::GetActiveTopWindow()
1105 vcl::Window
*pWin
= ImplGetSVData()->maWinData
.mpFocusWin
;
1108 if( pWin
->IsTopWindow() )
1110 pWin
= pWin
->mpWindowImpl
->mpParent
;
1115 void Application::SetAppName( const OUString
& rUniqueName
)
1117 ImplSVData
* pSVData
= ImplGetSVData();
1118 pSVData
->maAppData
.mxAppName
= rUniqueName
;
1121 OUString
Application::GetAppName()
1123 ImplSVData
* pSVData
= ImplGetSVData();
1124 if ( pSVData
->maAppData
.mxAppName
)
1125 return *(pSVData
->maAppData
.mxAppName
);
1130 OUString
Application::GetHWOSConfInfo()
1132 ImplSVData
* pSVData
= ImplGetSVData();
1133 OUStringBuffer aDetails
;
1135 aDetails
.append( VclResId(SV_APP_CPUTHREADS
) );
1136 aDetails
.append( static_cast<sal_Int32
>(std::thread::hardware_concurrency()) );
1137 aDetails
.append( "; " );
1140 if ( pSVData
&& pSVData
->mpDefInst
)
1141 aVersion
= pSVData
->mpDefInst
->getOSVersion();
1145 aDetails
.append( VclResId(SV_APP_OSVERSION
) );
1146 aDetails
.append( aVersion
);
1147 aDetails
.append( "; " );
1149 aDetails
.append( VclResId(SV_APP_UIRENDER
) );
1150 #if HAVE_FEATURE_OPENGL
1151 if ( OpenGLWrapper::isVCLOpenGLEnabled() )
1152 aDetails
.append( VclResId(SV_APP_GL
) );
1155 aDetails
.append( VclResId(SV_APP_DEFAULT
) );
1156 aDetails
.append( "; " );
1158 #if (defined LINUX || defined _WIN32 || defined MACOSX)
1159 aDetails
.append( SV_APP_VCLBACKEND
);
1160 aDetails
.append( GetToolkitName() );
1161 aDetails
.append( "; " );
1164 return aDetails
.makeStringAndClear();
1167 void Application::SetDisplayName( const OUString
& rName
)
1169 ImplSVData
* pSVData
= ImplGetSVData();
1170 pSVData
->maAppData
.mxDisplayName
= rName
;
1173 OUString
Application::GetDisplayName()
1175 ImplSVData
* pSVData
= ImplGetSVData();
1176 if ( pSVData
->maAppData
.mxDisplayName
)
1177 return *(pSVData
->maAppData
.mxDisplayName
);
1178 else if ( pSVData
->maWinData
.mpAppWin
)
1179 return pSVData
->maWinData
.mpAppWin
->GetText();
1184 unsigned int Application::GetScreenCount()
1186 SalSystem
* pSys
= ImplGetSalSystem();
1187 return pSys
? pSys
->GetDisplayScreenCount() : 0;
1190 bool Application::IsUnifiedDisplay()
1192 SalSystem
* pSys
= ImplGetSalSystem();
1193 return pSys
== nullptr || pSys
->IsUnifiedDisplay();
1196 unsigned int Application::GetDisplayBuiltInScreen()
1198 SalSystem
* pSys
= ImplGetSalSystem();
1199 return pSys
? pSys
->GetDisplayBuiltInScreen() : 0;
1202 unsigned int Application::GetDisplayExternalScreen()
1204 // This is really unpleasant, in theory we could have multiple
1205 // external displays etc.
1207 switch (GetDisplayBuiltInScreen())
1216 // When the built-in display is neither 0 nor 1
1217 // then place the full-screen presentation on the
1218 // first available screen.
1225 tools::Rectangle
Application::GetScreenPosSizePixel( unsigned int nScreen
)
1227 SalSystem
* pSys
= ImplGetSalSystem();
1228 return pSys
? pSys
->GetDisplayScreenPosSizePixel( nScreen
) : tools::Rectangle();
1232 unsigned long calcDistSquare( const Point
& i_rPoint
, const tools::Rectangle
& i_rRect
)
1234 const Point
aRectCenter( (i_rRect
.Left() + i_rRect
.Right())/2,
1235 (i_rRect
.Top() + i_rRect
.Bottom())/ 2 );
1236 const long nDX
= aRectCenter
.X() - i_rPoint
.X();
1237 const long nDY
= aRectCenter
.Y() - i_rPoint
.Y();
1238 return nDX
*nDX
+ nDY
*nDY
;
1242 unsigned int Application::GetBestScreen( const tools::Rectangle
& i_rRect
)
1244 if( !IsUnifiedDisplay() )
1245 return GetDisplayBuiltInScreen();
1247 const unsigned int nScreens
= GetScreenCount();
1248 unsigned int nBestMatchScreen
= 0;
1249 unsigned long nOverlap
= 0;
1250 for( unsigned int i
= 0; i
< nScreens
; i
++ )
1252 const tools::Rectangle
aCurScreenRect( GetScreenPosSizePixel( i
) );
1253 // if a screen contains the rectangle completely it is obviously the best screen
1254 if( aCurScreenRect
.IsInside( i_rRect
) )
1256 // next the screen which contains most of the area of the rect is the best
1257 tools::Rectangle
aIntersection( aCurScreenRect
.GetIntersection( i_rRect
) );
1258 if( ! aIntersection
.IsEmpty() )
1260 const unsigned long nCurOverlap( aIntersection
.GetWidth() * aIntersection
.GetHeight() );
1261 if( nCurOverlap
> nOverlap
)
1263 nOverlap
= nCurOverlap
;
1264 nBestMatchScreen
= i
;
1269 return nBestMatchScreen
;
1271 // finally the screen which center is nearest to the rect is the best
1272 const Point
aCenter( (i_rRect
.Left() + i_rRect
.Right())/2,
1273 (i_rRect
.Top() + i_rRect
.Bottom())/2 );
1274 unsigned long nDist
= ULONG_MAX
;
1275 for( unsigned int i
= 0; i
< nScreens
; i
++ )
1277 const tools::Rectangle
aCurScreenRect( GetScreenPosSizePixel( i
) );
1278 const unsigned long nCurDist( calcDistSquare( aCenter
, aCurScreenRect
) );
1279 if( nCurDist
< nDist
)
1281 nBestMatchScreen
= i
;
1285 return nBestMatchScreen
;
1288 bool Application::InsertAccel( Accelerator
* pAccel
)
1290 ImplSVData
* pSVData
= ImplGetSVData();
1292 if ( !pSVData
->maAppData
.mpAccelMgr
)
1293 pSVData
->maAppData
.mpAccelMgr
= new ImplAccelManager();
1294 return pSVData
->maAppData
.mpAccelMgr
->InsertAccel( pAccel
);
1297 void Application::RemoveAccel( Accelerator
const * pAccel
)
1299 ImplSVData
* pSVData
= ImplGetSVData();
1301 if ( pSVData
->maAppData
.mpAccelMgr
)
1302 pSVData
->maAppData
.mpAccelMgr
->RemoveAccel( pAccel
);
1305 void Application::SetHelp( Help
* pHelp
)
1307 ImplGetSVData()->maAppData
.mpHelp
= pHelp
;
1310 void Application::UpdateMainThread()
1312 ImplSVData
* pSVData
= ImplGetSVData();
1313 if (pSVData
&& pSVData
->mpDefInst
)
1314 pSVData
->mpDefInst
->updateMainThread();
1317 Help
* Application::GetHelp()
1319 return ImplGetSVData()->maAppData
.mpHelp
;
1322 OUString
Application::GetToolkitName()
1324 ImplSVData
* pSVData
= ImplGetSVData();
1325 if ( pSVData
->maAppData
.mxToolkitName
)
1326 return *(pSVData
->maAppData
.mxToolkitName
);
1331 vcl::Window
* Application::GetDefDialogParent()
1333 ImplSVData
* pSVData
= ImplGetSVData();
1334 // find some useful dialog parent
1336 // always use the topmost parent of the candidate
1337 // window to avoid using dialogs or floaters
1338 // as DefDialogParent
1340 // current focus frame
1341 vcl::Window
*pWin
= pSVData
->maWinData
.mpFocusWin
;
1342 if (pWin
&& !pWin
->IsMenuFloatingWindow())
1344 while (pWin
->mpWindowImpl
&& pWin
->mpWindowImpl
->mpParent
)
1345 pWin
= pWin
->mpWindowImpl
->mpParent
;
1347 // check for corrupted window hierarchy, #122232#, may be we now crash somewhere else
1348 if (!pWin
->mpWindowImpl
)
1350 OSL_FAIL( "Window hierarchy corrupted!" );
1351 pSVData
->maWinData
.mpFocusWin
= nullptr; // avoid further access
1355 if ((pWin
->mpWindowImpl
->mnStyle
& WB_INTROWIN
) == 0)
1357 return pWin
->mpWindowImpl
->mpFrameWindow
->ImplGetWindow();
1361 // last active application frame
1362 pWin
= pSVData
->maWinData
.mpActiveApplicationFrame
;
1365 return pWin
->mpWindowImpl
->mpFrameWindow
->ImplGetWindow();
1368 // first visible top window (may be totally wrong...)
1369 pWin
= pSVData
->maWinData
.mpFirstFrame
;
1372 if( pWin
->ImplGetWindow()->IsTopWindow() &&
1373 pWin
->mpWindowImpl
->mbReallyVisible
&&
1374 (pWin
->mpWindowImpl
->mnStyle
& WB_INTROWIN
) == 0
1377 while( pWin
->mpWindowImpl
->mpParent
)
1378 pWin
= pWin
->mpWindowImpl
->mpParent
;
1379 return pWin
->mpWindowImpl
->mpFrameWindow
->ImplGetWindow();
1381 pWin
= pWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
1388 DialogCancelMode
Application::GetDialogCancelMode()
1390 return ImplGetSVData()->maAppData
.meDialogCancel
;
1393 void Application::SetDialogCancelMode( DialogCancelMode mode
)
1395 ImplGetSVData()->maAppData
.meDialogCancel
= mode
;
1398 bool Application::IsDialogCancelEnabled()
1400 return ImplGetSVData()->maAppData
.meDialogCancel
!= DialogCancelMode::Off
;
1403 void Application::SetSystemWindowMode( SystemWindowFlags nMode
)
1405 ImplGetSVData()->maAppData
.mnSysWinMode
= nMode
;
1408 SystemWindowFlags
Application::GetSystemWindowMode()
1410 return ImplGetSVData()->maAppData
.mnSysWinMode
;
1413 css::uno::Reference
< css::awt::XToolkit
> Application::GetVCLToolkit()
1415 css::uno::Reference
< css::awt::XToolkit
> xT
;
1416 UnoWrapperBase
* pWrapper
= UnoWrapperBase::GetUnoWrapper();
1418 xT
= pWrapper
->GetVCLToolkit();
1422 #ifdef DISABLE_DYNLOADING
1424 extern "C" { UnoWrapperBase
* CreateUnoWrapper(); }
1428 extern "C" { static void thisModule() {} }
1432 UnoWrapperBase
* UnoWrapperBase::GetUnoWrapper( bool bCreateIfNotExist
)
1434 ImplSVData
* pSVData
= ImplGetSVData();
1435 static bool bAlreadyTriedToCreate
= false;
1436 if ( !pSVData
->mpUnoWrapper
&& bCreateIfNotExist
&& !bAlreadyTriedToCreate
)
1438 #ifndef DISABLE_DYNLOADING
1440 aTkLib
.loadRelative(&thisModule
, TK_DLL_NAME
);
1443 FN_TkCreateUnoWrapper fnCreateWrapper
= reinterpret_cast<FN_TkCreateUnoWrapper
>(aTkLib
.getFunctionSymbol("CreateUnoWrapper"));
1444 if ( fnCreateWrapper
)
1446 pSVData
->mpUnoWrapper
= fnCreateWrapper();
1450 SAL_WARN_IF( !pSVData
->mpUnoWrapper
, "vcl", "UnoWrapper could not be created!" );
1452 pSVData
->mpUnoWrapper
= CreateUnoWrapper();
1454 bAlreadyTriedToCreate
= true;
1456 return pSVData
->mpUnoWrapper
;
1459 void UnoWrapperBase::SetUnoWrapper( UnoWrapperBase
* pWrapper
)
1461 ImplSVData
* pSVData
= ImplGetSVData();
1462 SAL_WARN_IF( pSVData
->mpUnoWrapper
, "vcl", "SetUnoWrapper: Wrapper already exists" );
1463 pSVData
->mpUnoWrapper
= pWrapper
;
1466 css::uno::Reference
< css::awt::XDisplayConnection
> Application::GetDisplayConnection()
1468 ImplSVData
* pSVData
= ImplGetSVData();
1470 if( !pSVData
->mxDisplayConnection
.is() )
1472 pSVData
->mxDisplayConnection
.set( new vcl::DisplayConnectionDispatch
);
1473 pSVData
->mxDisplayConnection
->start();
1476 return pSVData
->mxDisplayConnection
.get();
1479 void Application::SetFilterHdl( const Link
<ConvertData
&,bool>& rLink
)
1481 ImplGetSVData()->maGDIData
.mpGrfConverter
->SetFilterHdl( rLink
);
1484 const LocaleDataWrapper
& Application::GetAppLocaleDataWrapper()
1486 return GetSettings().GetLocaleDataWrapper();
1489 void Application::EnableHeadlessMode( bool dialogsAreFatal
)
1491 DialogCancelMode eNewMode
= dialogsAreFatal
? DialogCancelMode::Fatal
: DialogCancelMode::Silent
;
1492 DialogCancelMode eOldMode
= GetDialogCancelMode();
1493 assert(eOldMode
== DialogCancelMode::Off
|| GetDialogCancelMode() == eNewMode
);
1494 if (eOldMode
!= eNewMode
)
1495 SetDialogCancelMode( eNewMode
);
1498 bool Application::IsHeadlessModeEnabled()
1500 return IsDialogCancelEnabled() || comphelper::LibreOfficeKit::isActive();
1503 void Application::EnableBitmapRendering()
1505 ImplGetSVData()->maAppData
.mbRenderToBitmaps
= true;
1508 bool Application::IsBitmapRendering()
1510 return ImplGetSVData()->maAppData
.mbRenderToBitmaps
;
1513 void Application::EnableConsoleOnly()
1515 EnableHeadlessMode(true);
1516 EnableBitmapRendering();
1519 static bool bEventTestingMode
= false;
1521 bool Application::IsEventTestingModeEnabled()
1523 return bEventTestingMode
;
1526 void Application::EnableEventTestingMode()
1528 bEventTestingMode
= true;
1531 static bool bSafeMode
= false;
1533 bool Application::IsSafeModeEnabled()
1538 void Application::EnableSafeMode()
1543 void Application::ShowNativeErrorBox(const OUString
& sTitle
,
1544 const OUString
& sMessage
)
1546 int btn
= ImplGetSalSystem()->ShowNativeMessageBox(
1549 if (btn
!= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK
) {
1550 SAL_WARN( "vcl", "ShowNativeMessageBox returned " << btn
);
1554 const OUString
& Application::GetDesktopEnvironment()
1556 if (IsHeadlessModeEnabled())
1558 static const OUString
aNone("none");
1562 return SalGetDesktopEnvironment();
1565 void Application::AddToRecentDocumentList(const OUString
& rFileUrl
, const OUString
& rMimeType
, const OUString
& rDocumentService
)
1567 ImplSVData
* pSVData
= ImplGetSVData();
1568 pSVData
->mpDefInst
->AddToRecentDocumentList(rFileUrl
, rMimeType
, rDocumentService
);
1571 bool InitAccessBridge()
1573 // Disable MSAA bridge on UNIX
1577 bool bRet
= ImplInitAccessBridge();
1581 // disable accessibility if the user chooses to continue
1582 AllSettings aSettings
= Application::GetSettings();
1583 MiscSettings aMisc
= aSettings
.GetMiscSettings();
1584 aMisc
.SetEnableATToolSupport( false );
1585 aSettings
.SetMiscSettings( aMisc
);
1586 Application::SetSettings( aSettings
);
1592 // MT: AppEvent was in oldsv.cxx, but is still needed...
1593 void Application::AppEvent( const ApplicationEvent
& /*rAppEvent*/ )
1597 bool Application::hasNativeFileSelection()
1599 ImplSVData
* pSVData
= ImplGetSVData();
1600 return pSVData
->mpDefInst
->hasNativeFileSelection();
1603 Reference
< ui::dialogs::XFilePicker2
>
1604 Application::createFilePicker( const Reference
< uno::XComponentContext
>& xSM
)
1606 ImplSVData
* pSVData
= ImplGetSVData();
1607 return pSVData
->mpDefInst
->createFilePicker( xSM
);
1610 Reference
< ui::dialogs::XFolderPicker2
>
1611 Application::createFolderPicker( const Reference
< uno::XComponentContext
>& xSM
)
1613 ImplSVData
* pSVData
= ImplGetSVData();
1614 return pSVData
->mpDefInst
->createFolderPicker( xSM
);
1617 void Application::setDeInitHook(Link
<LinkParamNone
*,void> const & hook
) {
1618 ImplSVData
* pSVData
= ImplGetSVData();
1619 assert(!pSVData
->maDeInitHook
.IsSet());
1620 pSVData
->maDeInitHook
= hook
;
1621 // Fake this for VCLXToolkit ctor instantiated from
1622 // postprocess/CppunitTest_services.mk:
1623 pSVData
->maAppData
.mbInAppMain
= true;
1626 namespace vcl
{ namespace lok
{
1628 void registerPollCallbacks(
1629 LibreOfficeKitPollCallback pPollCallback
,
1630 LibreOfficeKitWakeCallback pWakeCallback
,
1633 ImplSVData
* pSVData
= ImplGetSVData();
1636 pSVData
->mpPollCallback
= pPollCallback
;
1637 pSVData
->mpWakeCallback
= pWakeCallback
;
1638 pSVData
->mpPollClosure
= pData
;
1642 void unregisterPollCallbacks()
1644 ImplSVData
* pSVData
= ImplGetSVData();
1647 // Just set mpPollClosure to null as that is what calling this means, that the callback data
1648 // points to an object that no longer exists. In particular, don't set
1649 // pSVData->mpPollCallback to nullptr as that is used to detect whether Unipoll is in use in
1651 pSVData
->mpPollClosure
= nullptr;
1657 ImplSVData
* pSVData
= ImplGetSVData();
1658 return pSVData
&& pSVData
->mpPollCallback
!= nullptr;
1661 } } // namespace lok, namespace vcl
1663 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */