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 <comphelper/processfactory.hxx>
24 #include <osl/module.h>
25 #include <osl/file.hxx>
26 #include <osl/thread.h>
28 #include <rtl/tencinfo.h>
29 #include <rtl/instance.hxx>
31 #include <tools/debug.hxx>
32 #include <tools/time.hxx>
34 #include <i18nlangtag/mslangid.hxx>
36 #include <unotools/configmgr.hxx>
37 #include <unotools/syslocaleoptions.hxx>
39 #include <vcl/dialog.hxx>
40 #include <vcl/floatwin.hxx>
41 #include <vcl/settings.hxx>
42 #include <vcl/keycod.hxx>
43 #include <vcl/event.hxx>
44 #include <vcl/vclevent.hxx>
45 #include <vcl/virdev.hxx>
46 #include <vcl/wrkwin.hxx>
47 #include <vcl/svapp.hxx>
48 #include <vcl/cvtgrf.hxx>
49 #include <vcl/unowrap.hxx>
50 #include <vcl/timer.hxx>
51 #include <vcl/scheduler.hxx>
52 #include <vcl/unohelp.hxx>
53 #include <vcl/lazydelete.hxx>
54 #if HAVE_FEATURE_OPENGL
55 #include <vcl/opengl/OpenGLWrapper.hxx>
58 #include "salinst.hxx"
59 #include "salframe.hxx"
62 #include "salimestatus.hxx"
63 #include "displayconnectiondispatch.hxx"
68 #include <com/sun/star/uno/Reference.h>
69 #include <com/sun/star/awt/XToolkit.hpp>
70 #include <com/sun/star/frame/Desktop.hpp>
71 #include <com/sun/star/uno/XNamingService.hpp>
72 #include <com/sun/star/util/XModifiable.hpp>
73 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
74 #include <comphelper/solarmutex.hxx>
75 #include <osl/process.h>
81 using namespace ::com::sun::star
;
82 using namespace ::com::sun::star::uno
;
85 void InitSettings(ImplSVData
* pSVData
);
88 // keycodes handled internally by VCL
92 explicit ImplReservedKey( vcl::KeyCode aKeyCode
)
97 vcl::KeyCode mKeyCode
;
100 typedef std::pair
<ImplReservedKey
*, size_t> ReservedKeys
;
103 struct ImplReservedKeysImpl
105 ReservedKeys
* operator()()
107 static ImplReservedKey ImplReservedKeys
[] =
109 ImplReservedKey(vcl::KeyCode(KEY_F1
,0) ),
110 ImplReservedKey(vcl::KeyCode(KEY_F1
,KEY_SHIFT
) ),
111 ImplReservedKey(vcl::KeyCode(KEY_F1
,KEY_MOD1
) ),
112 ImplReservedKey(vcl::KeyCode(KEY_F2
,KEY_SHIFT
) ),
113 ImplReservedKey(vcl::KeyCode(KEY_F4
,KEY_MOD1
) ),
114 ImplReservedKey(vcl::KeyCode(KEY_F4
,KEY_MOD2
) ),
115 ImplReservedKey(vcl::KeyCode(KEY_F4
,KEY_MOD1
|KEY_MOD2
) ),
116 ImplReservedKey(vcl::KeyCode(KEY_F6
,0) ),
117 ImplReservedKey(vcl::KeyCode(KEY_F6
,KEY_MOD1
) ),
118 ImplReservedKey(vcl::KeyCode(KEY_F6
,KEY_SHIFT
) ),
119 ImplReservedKey(vcl::KeyCode(KEY_F6
,KEY_MOD1
|KEY_SHIFT
) ),
120 ImplReservedKey(vcl::KeyCode(KEY_F10
,0) )
123 ImplReservedKey(vcl::KeyCode(KEY_1
,KEY_SHIFT
|KEY_MOD1
)),
124 ImplReservedKey(vcl::KeyCode(KEY_2
,KEY_SHIFT
|KEY_MOD1
)),
125 ImplReservedKey(vcl::KeyCode(KEY_3
,KEY_SHIFT
|KEY_MOD1
)),
126 ImplReservedKey(vcl::KeyCode(KEY_4
,KEY_SHIFT
|KEY_MOD1
)),
127 ImplReservedKey(vcl::KeyCode(KEY_5
,KEY_SHIFT
|KEY_MOD1
)),
128 ImplReservedKey(vcl::KeyCode(KEY_6
,KEY_SHIFT
|KEY_MOD1
)),
129 ImplReservedKey(vcl::KeyCode(KEY_7
,KEY_SHIFT
|KEY_MOD1
)),
130 ImplReservedKey(vcl::KeyCode(KEY_8
,KEY_SHIFT
|KEY_MOD1
)),
131 ImplReservedKey(vcl::KeyCode(KEY_9
,KEY_SHIFT
|KEY_MOD1
)),
132 ImplReservedKey(vcl::KeyCode(KEY_0
,KEY_SHIFT
|KEY_MOD1
)),
133 ImplReservedKey(vcl::KeyCode(KEY_ADD
,KEY_SHIFT
|KEY_MOD1
))
136 static ReservedKeys aKeys
138 &ImplReservedKeys
[0],
139 sizeof(ImplReservedKeys
) / sizeof(ImplReservedKey
)
145 struct ImplReservedKeys
146 : public rtl::StaticAggregate
<ReservedKeys
, ImplReservedKeysImpl
> {};
150 typedef UnoWrapperBase
* (SAL_CALL
*FN_TkCreateUnoWrapper
)();
156 vcl::KeyCode maKeyCode
;
161 ImplEventHook
* mpNext
;
163 VCLEventHookProc mpProc
;
166 struct ImplPostEventData
169 VclPtr
<vcl::Window
> mpWin
;
170 ImplSVEvent
* mnEventId
;
172 MouseEvent maMouseEvent
;
174 ImplPostEventData( VclEventId nEvent
, vcl::Window
* pWin
, const KeyEvent
& rKeyEvent
) :
175 mnEvent( nEvent
), mpWin( pWin
), mnEventId( nullptr ), maKeyEvent( rKeyEvent
) {}
176 ImplPostEventData( VclEventId nEvent
, vcl::Window
* pWin
, const MouseEvent
& rMouseEvent
) :
177 mnEvent( nEvent
), mpWin( pWin
), mnEventId( nullptr ), maMouseEvent( rMouseEvent
) {}
180 Application
* GetpApp()
182 ImplSVData
* pSVData
= ImplGetSVData();
185 return pSVData
->mpApp
;
188 Application::Application()
190 // useful for themes at least, perhaps extensions too
191 OUString
aVar("LIBO_VERSION"), aValue(LIBO_VERSION_DOTTED
);
192 osl_setEnvironment(aVar
.pData
, aValue
.pData
);
194 ImplGetSVData()->mpApp
= this;
198 Application::~Application()
202 ImplGetSVData()->mpApp
= nullptr;
205 int Application::Main()
207 SAL_WARN("vcl", "Application is a base class and should be overridden.");
211 bool Application::QueryExit()
213 WorkWindow
* pAppWin
= ImplGetSVData()->maWinData
.mpAppWin
;
215 // call the close handler of the application window
217 return pAppWin
->Close();
222 void Application::Init()
226 void Application::InitFinished()
230 void Application::DeInit()
234 sal_uInt16
Application::GetCommandLineParamCount()
236 return (sal_uInt16
)osl_getCommandArgCount();
239 OUString
Application::GetCommandLineParam( sal_uInt16 nParam
)
242 osl_getCommandArg( nParam
, &aParam
.pData
);
246 OUString
Application::GetAppFileName()
248 ImplSVData
* pSVData
= ImplGetSVData();
249 SAL_WARN_IF( !pSVData
->maAppData
.mpAppFileName
, "vcl", "AppFileName should be set to something after SVMain!" );
250 if ( pSVData
->maAppData
.mpAppFileName
)
251 return *pSVData
->maAppData
.mpAppFileName
;
254 * provide a fallback for people without initialized vcl here (like setup
255 * in responsefile mode)
257 OUString aAppFileName
;
258 OUString aExeFileName
;
259 osl_getExecutableFile(&aExeFileName
.pData
);
261 // convert path to native file format
262 osl::FileBase::getSystemPathFromFileURL(aExeFileName
, aAppFileName
);
267 void Application::Exception( ExceptionCategory nCategory
)
271 // System has precedence (so do nothing)
272 case ExceptionCategory::System
:
273 case ExceptionCategory::UserInterface
:
277 case ExceptionCategory::ResourceNotLoaded
:
278 Abort("Resource not loaded");
281 Abort("Unknown Error");
291 void Application::Abort( const OUString
& rErrorText
)
293 //HACK: Dump core iff --norestore command line argument is given (assuming
294 // this process is run by developers who are interested in cores, vs. end
295 // users who are not):
296 bool dumpCore
= false;
297 sal_uInt16 n
= GetCommandLineParamCount();
298 for (sal_uInt16 i
= 0; i
!= n
; ++i
) {
299 if (GetCommandLineParam(i
) == "--norestore") {
305 SalAbort( rErrorText
, dumpCore
);
308 sal_uLong
Application::GetReservedKeyCodeCount()
310 return ImplReservedKeys::get()->second
;
313 const vcl::KeyCode
* Application::GetReservedKeyCode( sal_uLong i
)
315 if( i
>= GetReservedKeyCodeCount() )
318 return &ImplReservedKeys::get()->first
[i
].mKeyCode
;
321 IMPL_STATIC_LINK_NOARG( ImplSVAppData
, ImplEndAllPopupsMsg
, void*, void )
323 ImplSVData
* pSVData
= ImplGetSVData();
324 while (pSVData
->maWinData
.mpFirstFloat
)
325 pSVData
->maWinData
.mpFirstFloat
->EndPopupMode(FloatWinPopupEndFlags::Cancel
);
328 IMPL_STATIC_LINK_NOARG( ImplSVAppData
, ImplEndAllDialogsMsg
, void*, void )
330 vcl::Window
* pAppWindow
= Application::GetFirstTopLevelWindow();
333 Dialog::EndAllDialogs(pAppWindow
);
334 pAppWindow
= Application::GetNextTopLevelWindow(pAppWindow
);
338 void Application::EndAllDialogs()
340 Application::PostUserEvent( LINK( nullptr, ImplSVAppData
, ImplEndAllDialogsMsg
) );
343 void Application::EndAllPopups()
345 Application::PostUserEvent( LINK( nullptr, ImplSVAppData
, ImplEndAllPopupsMsg
) );
351 VclPtr
<vcl::Window
> GetEventWindow()
353 VclPtr
<vcl::Window
> xWin(Application::GetFirstTopLevelWindow());
356 if (xWin
->IsVisible())
358 xWin
.reset(Application::GetNextTopLevelWindow(xWin
));
363 bool InjectKeyEvent(SvStream
& rStream
)
365 VclPtr
<vcl::Window
> xWin(GetEventWindow());
369 // skip the first available cycle and insert on the next one when we
370 // are trying the initial event, flagged by a triggered but undeleted
371 // mpEventTestingIdle
372 ImplSVData
* pSVData
= ImplGetSVData();
373 if (pSVData
->maAppData
.mpEventTestingIdle
)
375 delete pSVData
->maAppData
.mpEventTestingIdle
;
376 pSVData
->maAppData
.mpEventTestingIdle
= nullptr;
380 sal_uInt16 nCode
, nCharCode
;
381 rStream
.ReadUInt16(nCode
);
382 rStream
.ReadUInt16(nCharCode
);
386 KeyEvent
aVCLKeyEvt(nCharCode
, nCode
);
387 Application::PostKeyEvent(VclEventId::WindowKeyInput
, xWin
.get(), &aVCLKeyEvt
);
388 Application::PostKeyEvent(VclEventId::WindowKeyUp
, xWin
.get(), &aVCLKeyEvt
);
392 void CloseDialogsAndQuit()
394 Application::EndAllPopups();
395 Application::EndAllDialogs();
396 Application::PostUserEvent( LINK( nullptr, ImplSVAppData
, ImplPrepareExitMsg
) );
400 IMPL_LINK_NOARG(ImplSVAppData
, VclEventTestingHdl
, Timer
*, void)
402 if (Application::AnyInput())
404 mpEventTestingIdle
->Start();
408 Application::PostUserEvent( LINK( nullptr, ImplSVAppData
, ImplVclEventTestingHdl
) );
412 IMPL_STATIC_LINK_NOARG( ImplSVAppData
, ImplVclEventTestingHdl
, void*, void )
414 ImplSVData
* pSVData
= ImplGetSVData();
415 SAL_INFO("vcl.eventtesting", "EventTestLimit is " << pSVData
->maAppData
.mnEventTestLimit
);
416 if (pSVData
->maAppData
.mnEventTestLimit
== 0)
418 delete pSVData
->maAppData
.mpEventTestInput
;
419 SAL_INFO("vcl.eventtesting", "Event Limit reached, exiting" << pSVData
->maAppData
.mnEventTestLimit
);
420 CloseDialogsAndQuit();
424 if (InjectKeyEvent(*pSVData
->maAppData
.mpEventTestInput
))
425 --pSVData
->maAppData
.mnEventTestLimit
;
426 if (!pSVData
->maAppData
.mpEventTestInput
->good())
428 SAL_INFO("vcl.eventtesting", "Event Input exhausted, exit next cycle");
429 pSVData
->maAppData
.mnEventTestLimit
= 0;
431 Application::PostUserEvent( LINK( nullptr, ImplSVAppData
, ImplVclEventTestingHdl
) );
435 IMPL_STATIC_LINK_NOARG( ImplSVAppData
, ImplPrepareExitMsg
, void*, void )
437 //now close top level frames
438 (void)GetpApp()->QueryExit();
441 void Application::Execute()
443 ImplSVData
* pSVData
= ImplGetSVData();
444 pSVData
->maAppData
.mbInAppExecute
= true;
445 pSVData
->maAppData
.mbAppQuit
= false;
447 if (Application::IsEventTestingModeEnabled())
449 pSVData
->maAppData
.mnEventTestLimit
= 50;
450 pSVData
->maAppData
.mpEventTestingIdle
= new Idle("eventtesting");
451 pSVData
->maAppData
.mpEventTestingIdle
->SetInvokeHandler(LINK(&(pSVData
->maAppData
), ImplSVAppData
, VclEventTestingHdl
));
452 pSVData
->maAppData
.mpEventTestingIdle
->SetPriority(TaskPriority::MEDIUM
);
453 pSVData
->maAppData
.mpEventTestInput
= new SvFileStream("eventtesting", StreamMode::READ
);
454 pSVData
->maAppData
.mpEventTestingIdle
->Start();
457 while ( !pSVData
->maAppData
.mbAppQuit
)
458 Application::Yield();
460 pSVData
->maAppData
.mbInAppExecute
= false;
463 inline bool ImplYield(bool i_bWait
, bool i_bAllEvents
, sal_uLong
const nReleased
)
465 ImplSVData
* pSVData
= ImplGetSVData();
467 SAL_INFO("vcl.schedule", "Enter ImplYield: " << (i_bWait
? "wait" : "no wait") <<
468 ": " << (i_bAllEvents
? "all events" : "one event") << ": " << nReleased
);
470 bool bHasActiveIdles
= false;
471 sal_uInt64 nMinTimeout
= 0;
472 if (nReleased
== 0) // else thread doesn't have SolarMutex so avoid race
473 nMinTimeout
= Scheduler::CalculateMinimumTimeout(bHasActiveIdles
);
475 // FIXME: should use returned value as param to DoYield
478 // If we have idles, don't wait for the timeout; check for events
479 // and come back as quick as possible.
483 // TODO: there's a data race here on WNT only because ImplYield may be
484 // called without SolarMutex; if we can get rid of LazyDelete (with VclPtr)
485 // then the only remaining use of mnDispatchLevel is in OSX specific code
486 // so that would effectively eliminate the race on WNT
487 pSVData
->maAppData
.mnDispatchLevel
++;
489 // do not wait for events if application was already quit; in that
490 // case only dispatch events already available
491 // do not wait for events either if the app decided that it is too busy for timers
492 // (feature added for the slideshow)
493 SalYieldResult eResult
=
494 pSVData
->mpDefInst
->DoYield(
495 i_bWait
&& !pSVData
->maAppData
.mbAppQuit
,
496 i_bAllEvents
, nReleased
);
498 SAL_INFO("vcl.schedule", "DoYield with " << (bHasActiveIdles
? "active idles" : "no idles") <<
499 " returns: " << (eResult
== SalYieldResult::EVENT
? "processed event" : "timeout"));
501 pSVData
->maAppData
.mnDispatchLevel
--;
503 DBG_TESTSOLARMUTEX(); // must be locked on return from Yield
505 if (nReleased
== 0) // tdf#99383 don't run stuff from ReAcquireSolarMutex
508 Scheduler::ProcessTaskScheduling(eResult
!= SalYieldResult::EVENT
);
511 // flush lazy deleted objects
512 if( pSVData
->maAppData
.mnDispatchLevel
== 0 )
513 vcl::LazyDelete::flush();
515 SAL_INFO("vcl.schedule", "Leave ImplYield");
517 return bHasActiveIdles
|| eResult
== SalYieldResult::EVENT
;
520 void Application::Reschedule( bool i_bAllEvents
)
522 ImplYield(false, i_bAllEvents
, 0);
525 void Scheduler::ProcessEventsToSignal(bool& bSignal
)
527 while(!bSignal
&& (Scheduler::ProcessTaskScheduling( true ) ||
528 ImplYield(false, false, 0)))
533 void Scheduler::ProcessEventsToIdle()
536 while(Scheduler::ProcessTaskScheduling( true ) ||
537 ImplYield(false, false, 0))
541 SAL_WARN("vcl.schedule", "Unexpected volume of events to process");
548 /// used by unit tests that test only via the LOK API
549 SAL_DLLPUBLIC_EXPORT
void unit_lok_process_events_to_idle()
551 const SolarMutexGuard aGuard
;
552 Scheduler::ProcessEventsToIdle();
556 void Application::Yield()
558 ImplYield(true, false, 0);
561 void Application::ReAcquireSolarMutex(sal_uLong
const nReleased
)
563 // 0 would mean that events/timers will be handled without locking
565 SAL_WARN_IF(nReleased
== 0, "vcl", "SolarMutexReleaser without SolarMutex");
567 if (nReleased
== 0 || ImplGetSVData()->mbDeInit
) //do not Yield in DeInitVCL
568 AcquireSolarMutex(nReleased
);
570 ImplYield(false, false, nReleased
);
572 // a) Yield is not needed on non-WNT platforms
573 // b) some Yield implementations for X11 (e.g. kde4) make it non-obvious
574 // how to use nReleased
575 // c) would require a review of what all Yield implementations do
576 // currently _before_ releasing SolarMutex that would run without lock
577 AcquireSolarMutex(nReleased
);
581 IMPL_STATIC_LINK_NOARG( ImplSVAppData
, ImplQuitMsg
, void*, void )
583 ImplGetSVData()->maAppData
.mbAppQuit
= true;
586 void Application::Quit()
588 Application::PostUserEvent( LINK( nullptr, ImplSVAppData
, ImplQuitMsg
) );
591 comphelper::SolarMutex
& Application::GetSolarMutex()
593 ImplSVData
* pSVData
= ImplGetSVData();
594 return *(pSVData
->mpDefInst
->GetYieldMutex());
597 oslThreadIdentifier
Application::GetMainThreadIdentifier()
599 return ImplGetSVData()->mnMainThreadId
;
602 sal_uLong
Application::ReleaseSolarMutex()
604 ImplSVData
* pSVData
= ImplGetSVData();
605 return pSVData
->mpDefInst
->ReleaseYieldMutex();
608 void Application::AcquireSolarMutex( sal_uLong nCount
)
610 ImplSVData
* pSVData
= ImplGetSVData();
611 pSVData
->mpDefInst
->AcquireYieldMutex( nCount
);
614 bool Application::IsInMain()
616 ImplSVData
* pSVData
= ImplGetSVData();
617 return pSVData
&& pSVData
->maAppData
.mbInAppMain
;
620 bool Application::IsInExecute()
622 return ImplGetSVData()->maAppData
.mbInAppExecute
;
625 bool Application::IsInModalMode()
627 return (ImplGetSVData()->maAppData
.mnModalMode
!= 0);
630 sal_uInt16
Application::GetDispatchLevel()
632 return ImplGetSVData()->maAppData
.mnDispatchLevel
;
635 bool Application::AnyInput( VclInputFlags nType
)
637 return ImplGetSVData()->mpDefInst
->AnyInput( nType
);
640 sal_uInt64
Application::GetLastInputInterval()
642 return (tools::Time::GetSystemTicks()-ImplGetSVData()->maAppData
.mnLastInputTime
);
645 bool Application::IsUICaptured()
647 ImplSVData
* pSVData
= ImplGetSVData();
649 // If mouse was captured, or if in tracking- or in select-mode of a floatingwindow (e.g. menus
650 // or pulldown toolboxes) another window should be created
652 return pSVData
->maWinData
.mpCaptureWin
|| pSVData
->maWinData
.mpTrackWin
||
653 pSVData
->maWinData
.mpFirstFloat
|| nImplSysDialog
;
656 void Application::OverrideSystemSettings( AllSettings
& /*rSettings*/ )
660 void Application::MergeSystemSettings( AllSettings
& rSettings
)
662 vcl::Window
* pWindow
= ImplGetSVData()->maWinData
.mpFirstFrame
;
664 pWindow
= ImplGetDefaultWindow();
667 ImplSVData
* pSVData
= ImplGetSVData();
668 if ( !pSVData
->maAppData
.mbSettingsInit
)
670 // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
671 pWindow
->ImplUpdateGlobalSettings( *pSVData
->maAppData
.mpSettings
);
672 pSVData
->maAppData
.mbSettingsInit
= true;
674 // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings
675 pWindow
->ImplUpdateGlobalSettings( rSettings
, false );
679 void Application::SetSettings( const AllSettings
& rSettings
)
681 const SolarMutexGuard aGuard
;
683 ImplSVData
* pSVData
= ImplGetSVData();
684 if ( !pSVData
->maAppData
.mpSettings
)
686 InitSettings(pSVData
);
687 *pSVData
->maAppData
.mpSettings
= rSettings
;
688 ResMgr::SetDefaultLocale( rSettings
.GetUILanguageTag() );
692 AllSettings aOldSettings
= *pSVData
->maAppData
.mpSettings
;
693 if( aOldSettings
.GetUILanguageTag().getLanguageType() != rSettings
.GetUILanguageTag().getLanguageType() &&
696 delete pSVData
->mpResMgr
;
697 pSVData
->mpResMgr
= nullptr;
699 ResMgr::SetDefaultLocale( rSettings
.GetUILanguageTag() );
700 *pSVData
->maAppData
.mpSettings
= rSettings
;
701 AllSettingsFlags nChangeFlags
= aOldSettings
.GetChangeFlags( *pSVData
->maAppData
.mpSettings
);
702 if ( bool(nChangeFlags
) )
704 DataChangedEvent
aDCEvt( DataChangedEventType::SETTINGS
, &aOldSettings
, nChangeFlags
);
706 // notify data change handler
707 ImplCallEventListeners( VclEventId::ApplicationDataChanged
, nullptr, &aDCEvt
);
709 // Update all windows
710 vcl::Window
* pFirstFrame
= pSVData
->maWinData
.mpFirstFrame
;
711 // Reset data that needs to be re-calculated
716 nOldDPIX
= pFirstFrame
->GetDPIX();
717 nOldDPIY
= pFirstFrame
->GetDPIY();
718 vcl::Window::ImplInitAppFontData(pFirstFrame
);
720 vcl::Window
* pFrame
= pFirstFrame
;
723 // call UpdateSettings from ClientWindow in order to prevent updating data twice
724 vcl::Window
* pClientWin
= pFrame
;
725 while ( pClientWin
->ImplGetClientWindow() )
726 pClientWin
= pClientWin
->ImplGetClientWindow();
727 pClientWin
->UpdateSettings( rSettings
, true );
729 vcl::Window
* pTempWin
= pFrame
->mpWindowImpl
->mpFrameData
->mpFirstOverlap
;
732 // call UpdateSettings from ClientWindow in order to prevent updating data twice
733 pClientWin
= pTempWin
;
734 while ( pClientWin
->ImplGetClientWindow() )
735 pClientWin
= pClientWin
->ImplGetClientWindow();
736 pClientWin
->UpdateSettings( rSettings
, true );
737 pTempWin
= pTempWin
->mpWindowImpl
->mpNextOverlap
;
740 pFrame
= pFrame
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
743 // if DPI resolution for screen output was changed set the new resolution for all
744 // screen compatible VirDev's
745 pFirstFrame
= pSVData
->maWinData
.mpFirstFrame
;
748 if ( (pFirstFrame
->GetDPIX() != nOldDPIX
) ||
749 (pFirstFrame
->GetDPIY() != nOldDPIY
) )
751 VirtualDevice
* pVirDev
= pSVData
->maGDIData
.mpFirstVirDev
;
754 if ( pVirDev
->mbScreenComp
&&
755 (pVirDev
->GetDPIX() == nOldDPIX
) &&
756 (pVirDev
->GetDPIY() == nOldDPIY
) )
758 pVirDev
->SetDPIX( pFirstFrame
->GetDPIX() );
759 pVirDev
->SetDPIY( pFirstFrame
->GetDPIY() );
760 if ( pVirDev
->IsMapModeEnabled() )
762 MapMode aMapMode
= pVirDev
->GetMapMode();
763 pVirDev
->SetMapMode();
764 pVirDev
->SetMapMode( aMapMode
);
768 pVirDev
= pVirDev
->mpNext
;
776 const AllSettings
& Application::GetSettings()
778 ImplSVData
* pSVData
= ImplGetSVData();
779 if ( !pSVData
->maAppData
.mpSettings
)
781 InitSettings(pSVData
);
784 return *(pSVData
->maAppData
.mpSettings
);
789 void InitSettings(ImplSVData
* pSVData
)
791 assert(!pSVData
->maAppData
.mpSettings
&& "initialization should not happen twice!");
793 pSVData
->maAppData
.mpSettings
= new AllSettings();
794 if (!utl::ConfigManager::IsAvoidConfig())
796 pSVData
->maAppData
.mpCfgListener
= new LocaleConfigurationListener
;
797 pSVData
->maAppData
.mpSettings
->GetSysLocale().GetOptions().AddListener( pSVData
->maAppData
.mpCfgListener
);
803 void Application::NotifyAllWindows( DataChangedEvent
& rDCEvt
)
805 ImplSVData
* pSVData
= ImplGetSVData();
806 vcl::Window
* pFrame
= pSVData
->maWinData
.mpFirstFrame
;
809 pFrame
->NotifyAllChildren( rDCEvt
);
811 vcl::Window
* pSysWin
= pFrame
->mpWindowImpl
->mpFrameData
->mpFirstOverlap
;
814 pSysWin
->NotifyAllChildren( rDCEvt
);
815 pSysWin
= pSysWin
->mpWindowImpl
->mpNextOverlap
;
818 pFrame
= pFrame
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
822 void Application::ImplCallEventListeners( VclEventId nEvent
, vcl::Window
*pWin
, void* pData
)
824 ImplSVData
* pSVData
= ImplGetSVData();
825 VclWindowEvent
aEvent( pWin
, nEvent
, pData
);
827 if ( pSVData
->maAppData
.mpEventListeners
)
828 pSVData
->maAppData
.mpEventListeners
->Call( aEvent
);
831 void Application::ImplCallEventListeners( VclSimpleEvent
& rEvent
)
833 ImplSVData
* pSVData
= ImplGetSVData();
835 if ( pSVData
->maAppData
.mpEventListeners
)
836 pSVData
->maAppData
.mpEventListeners
->Call( rEvent
);
839 void Application::AddEventListener( const Link
<VclSimpleEvent
&,void>& rEventListener
)
841 ImplSVData
* pSVData
= ImplGetSVData();
842 if( !pSVData
->maAppData
.mpEventListeners
)
843 pSVData
->maAppData
.mpEventListeners
= new VclEventListeners
;
844 pSVData
->maAppData
.mpEventListeners
->addListener( rEventListener
);
847 void Application::RemoveEventListener( const Link
<VclSimpleEvent
&,void>& rEventListener
)
849 ImplSVData
* pSVData
= ImplGetSVData();
850 if( pSVData
->maAppData
.mpEventListeners
)
851 pSVData
->maAppData
.mpEventListeners
->removeListener( rEventListener
);
854 void Application::AddKeyListener( const Link
<VclWindowEvent
&,bool>& rKeyListener
)
856 ImplSVData
* pSVData
= ImplGetSVData();
857 if( !pSVData
->maAppData
.mpKeyListeners
)
858 pSVData
->maAppData
.mpKeyListeners
= new SVAppKeyListeners
;
859 pSVData
->maAppData
.mpKeyListeners
->push_back( rKeyListener
);
862 void Application::RemoveKeyListener( const Link
<VclWindowEvent
&,bool>& rKeyListener
)
864 ImplSVData
* pSVData
= ImplGetSVData();
865 if( pSVData
->maAppData
.mpKeyListeners
)
867 auto pVec
= pSVData
->maAppData
.mpKeyListeners
;
868 pVec
->erase( std::remove(pVec
->begin(), pVec
->end(), rKeyListener
), pVec
->end() );
872 bool Application::HandleKey( VclEventId nEvent
, vcl::Window
*pWin
, KeyEvent
* pKeyEvent
)
874 // let listeners process the key event
875 VclWindowEvent
aEvent( pWin
, nEvent
, static_cast<void *>(pKeyEvent
) );
877 ImplSVData
* pSVData
= ImplGetSVData();
879 if ( !pSVData
->maAppData
.mpKeyListeners
)
882 if ( pSVData
->maAppData
.mpKeyListeners
->empty() )
885 bool bProcessed
= false;
886 // Copy the list, because this can be destroyed when calling a Link...
887 std::vector
<Link
<VclWindowEvent
&,bool>> aCopy( *pSVData
->maAppData
.mpKeyListeners
);
888 for ( Link
<VclWindowEvent
&,bool>& rLink
: aCopy
)
890 if( rLink
.Call( aEvent
) )
899 ImplSVEvent
* Application::PostKeyEvent( VclEventId nEvent
, vcl::Window
*pWin
, KeyEvent
* pKeyEvent
)
901 const SolarMutexGuard aGuard
;
902 ImplSVEvent
* nEventId
= nullptr;
904 if( pWin
&& pKeyEvent
)
906 ImplPostEventData
* pPostEventData
= new ImplPostEventData( nEvent
, pWin
, *pKeyEvent
);
908 nEventId
= PostUserEvent(
909 LINK( nullptr, Application
, PostEventHandler
),
914 pPostEventData
->mnEventId
= nEventId
;
915 ImplGetSVData()->maAppData
.maPostedEventList
.push_back( ImplPostEventPair( pWin
, pPostEventData
) );
918 delete pPostEventData
;
924 ImplSVEvent
* Application::PostMouseEvent( VclEventId nEvent
, vcl::Window
*pWin
, MouseEvent
* pMouseEvent
)
926 const SolarMutexGuard aGuard
;
927 ImplSVEvent
* nEventId
= nullptr;
929 if( pWin
&& pMouseEvent
)
931 Point
aTransformedPos( pMouseEvent
->GetPosPixel() );
933 aTransformedPos
.X() += pWin
->GetOutOffXPixel();
934 aTransformedPos
.Y() += pWin
->GetOutOffYPixel();
936 const MouseEvent
aTransformedEvent( aTransformedPos
, pMouseEvent
->GetClicks(), pMouseEvent
->GetMode(),
937 pMouseEvent
->GetButtons(), pMouseEvent
->GetModifier() );
939 ImplPostEventData
* pPostEventData
= new ImplPostEventData( nEvent
, pWin
, aTransformedEvent
);
941 nEventId
= PostUserEvent(
942 LINK( nullptr, Application
, PostEventHandler
),
947 pPostEventData
->mnEventId
= nEventId
;
948 ImplGetSVData()->maAppData
.maPostedEventList
.push_back( ImplPostEventPair( pWin
, pPostEventData
) );
951 delete pPostEventData
;
958 IMPL_STATIC_LINK( Application
, PostEventHandler
, void*, pCallData
, void )
960 const SolarMutexGuard aGuard
;
961 ImplPostEventData
* pData
= static_cast< ImplPostEventData
* >( pCallData
);
962 const void* pEventData
;
964 ImplSVEvent
* const nEventId
= pData
->mnEventId
;
966 switch( pData
->mnEvent
)
968 case VclEventId::WindowMouseMove
:
969 nEvent
= SalEvent::ExternalMouseMove
;
970 pEventData
= &pData
->maMouseEvent
;
973 case VclEventId::WindowMouseButtonDown
:
974 nEvent
= SalEvent::ExternalMouseButtonDown
;
975 pEventData
= &pData
->maMouseEvent
;
978 case VclEventId::WindowMouseButtonUp
:
979 nEvent
= SalEvent::ExternalMouseButtonUp
;
980 pEventData
= &pData
->maMouseEvent
;
983 case VclEventId::WindowKeyInput
:
984 nEvent
= SalEvent::ExternalKeyInput
;
985 pEventData
= &pData
->maKeyEvent
;
988 case VclEventId::WindowKeyUp
:
989 nEvent
= SalEvent::ExternalKeyUp
;
990 pEventData
= &pData
->maKeyEvent
;
994 nEvent
= SalEvent::NONE
;
995 pEventData
= nullptr;
999 if( pData
->mpWin
&& pData
->mpWin
.get()->mpWindowImpl
->mpFrameWindow
.get() && pEventData
)
1000 ImplWindowFrameProc( pData
->mpWin
.get()->mpWindowImpl
->mpFrameWindow
.get(), nEvent
, pEventData
);
1002 // remove this event from list of posted events, watch for destruction of internal data
1003 auto svdata
= ImplGetSVData();
1004 ::std::list
< ImplPostEventPair
>::iterator
aIter( svdata
->maAppData
.maPostedEventList
.begin() );
1006 while( aIter
!= svdata
->maAppData
.maPostedEventList
.end() )
1008 if( nEventId
== (*aIter
).second
->mnEventId
)
1010 delete (*aIter
).second
;
1011 aIter
= svdata
->maAppData
.maPostedEventList
.erase( aIter
);
1018 void Application::RemoveMouseAndKeyEvents( vcl::Window
* pWin
)
1020 const SolarMutexGuard aGuard
;
1022 // remove all events for specific window, watch for destruction of internal data
1023 auto svdata
= ImplGetSVData();
1024 ::std::list
< ImplPostEventPair
>::iterator
aIter( svdata
->maAppData
.maPostedEventList
.begin() );
1026 while( aIter
!= svdata
->maAppData
.maPostedEventList
.end() )
1028 if( pWin
== (*aIter
).first
)
1030 if( (*aIter
).second
->mnEventId
)
1031 RemoveUserEvent( (*aIter
).second
->mnEventId
);
1033 delete (*aIter
).second
;
1034 aIter
= svdata
->maAppData
.maPostedEventList
.erase( aIter
);
1041 ImplSVEvent
* Application::PostUserEvent( const Link
<void*,void>& rLink
, void* pCaller
,
1042 bool bReferenceLink
)
1044 ImplSVEvent
* pSVEvent
= new ImplSVEvent
;
1045 pSVEvent
->mpData
= pCaller
;
1046 pSVEvent
->maLink
= rLink
;
1047 pSVEvent
->mpWindow
= nullptr;
1048 pSVEvent
->mbCall
= true;
1051 SolarMutexGuard aGuard
;
1052 // Double check that this is indeed a vcl::Window instance.
1053 assert(dynamic_cast<vcl::Window
*>(
1054 static_cast<vcl::Window
*>(rLink
.GetInstance())) ==
1055 static_cast<vcl::Window
*>(rLink
.GetInstance()));
1056 pSVEvent
->mpInstanceRef
= static_cast<vcl::Window
*>(rLink
.GetInstance());
1059 vcl::Window
* pDefWindow
= ImplGetDefaultWindow();
1060 if ( pDefWindow
== nullptr || !pDefWindow
->ImplGetFrame()->PostEvent( pSVEvent
) )
1068 void Application::RemoveUserEvent( ImplSVEvent
* nUserEvent
)
1072 SAL_WARN_IF( nUserEvent
->mpWindow
, "vcl",
1073 "Application::RemoveUserEvent(): Event is send to a window" );
1074 SAL_WARN_IF( !nUserEvent
->mbCall
, "vcl",
1075 "Application::RemoveUserEvent(): Event is already removed" );
1077 nUserEvent
->mpWindow
.clear();
1078 nUserEvent
->mpInstanceRef
.clear();
1079 nUserEvent
->mbCall
= false;
1083 WorkWindow
* Application::GetAppWindow()
1085 return ImplGetSVData()->maWinData
.mpAppWin
;
1088 vcl::Window
* Application::GetFocusWindow()
1090 return ImplGetSVData()->maWinData
.mpFocusWin
;
1093 OutputDevice
* Application::GetDefaultDevice()
1095 return ImplGetDefaultWindow();
1098 vcl::Window
* Application::GetFirstTopLevelWindow()
1100 ImplSVData
* pSVData
= ImplGetSVData();
1101 return pSVData
->maWinData
.mpFirstFrame
;
1104 vcl::Window
* Application::GetNextTopLevelWindow( vcl::Window
* pWindow
)
1106 return pWindow
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
1109 long Application::GetTopWindowCount()
1112 ImplSVData
* pSVData
= ImplGetSVData();
1113 vcl::Window
*pWin
= pSVData
? pSVData
->maWinData
.mpFirstFrame
.get() : nullptr;
1116 if( pWin
->ImplGetWindow()->IsTopWindow() )
1118 pWin
= pWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
1123 vcl::Window
* Application::GetTopWindow( long nIndex
)
1126 ImplSVData
* pSVData
= ImplGetSVData();
1127 vcl::Window
*pWin
= pSVData
? pSVData
->maWinData
.mpFirstFrame
.get() : nullptr;
1130 if( pWin
->ImplGetWindow()->IsTopWindow() )
1132 if( nIdx
== nIndex
)
1133 return pWin
->ImplGetWindow();
1137 pWin
= pWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
1142 vcl::Window
* Application::GetActiveTopWindow()
1144 vcl::Window
*pWin
= ImplGetSVData()->maWinData
.mpFocusWin
;
1147 if( pWin
->IsTopWindow() )
1149 pWin
= pWin
->mpWindowImpl
->mpParent
;
1154 void Application::SetAppName( const OUString
& rUniqueName
)
1156 ImplSVData
* pSVData
= ImplGetSVData();
1158 // create if does not exist
1159 if ( !pSVData
->maAppData
.mpAppName
)
1160 pSVData
->maAppData
.mpAppName
= new OUString( rUniqueName
);
1162 *(pSVData
->maAppData
.mpAppName
) = rUniqueName
;
1165 OUString
Application::GetAppName()
1167 ImplSVData
* pSVData
= ImplGetSVData();
1168 if ( pSVData
->maAppData
.mpAppName
)
1169 return *(pSVData
->maAppData
.mpAppName
);
1174 OUString
Application::GetHWOSConfInfo()
1176 ImplSVData
* pSVData
= ImplGetSVData();
1177 OUStringBuffer aDetails
;
1179 aDetails
.append( VclResId(SV_APP_CPUTHREADS
) );
1180 aDetails
.append( (sal_Int32
)
1181 std::thread::hardware_concurrency() );
1182 aDetails
.append( "; " );
1185 if ( pSVData
&& pSVData
->mpDefInst
)
1186 aVersion
= pSVData
->mpDefInst
->getOSVersion();
1190 aDetails
.append( VclResId(SV_APP_OSVERSION
) );
1191 aDetails
.append( aVersion
);
1192 aDetails
.append( "; " );
1194 aDetails
.append( VclResId(SV_APP_UIRENDER
) );
1195 #if HAVE_FEATURE_OPENGL
1196 if ( OpenGLWrapper::isVCLOpenGLEnabled() )
1197 aDetails
.append( VclResId(SV_APP_GL
) );
1200 aDetails
.append( VclResId(SV_APP_DEFAULT
) );
1201 aDetails
.append( "; " );
1204 // Only linux has different backends, so don't show blank for others.
1205 aDetails
.append( VclResId(SV_APP_VCLBACKEND
) );
1206 aDetails
.append( GetToolkitName() );
1207 aDetails
.append( "; " );
1210 return aDetails
.makeStringAndClear();
1213 void Application::SetDisplayName( const OUString
& rName
)
1215 ImplSVData
* pSVData
= ImplGetSVData();
1217 // create if does not exist
1218 if ( !pSVData
->maAppData
.mpDisplayName
)
1219 pSVData
->maAppData
.mpDisplayName
= new OUString( rName
);
1221 *(pSVData
->maAppData
.mpDisplayName
) = rName
;
1224 OUString
Application::GetDisplayName()
1226 ImplSVData
* pSVData
= ImplGetSVData();
1227 if ( pSVData
->maAppData
.mpDisplayName
)
1228 return *(pSVData
->maAppData
.mpDisplayName
);
1229 else if ( pSVData
->maWinData
.mpAppWin
)
1230 return pSVData
->maWinData
.mpAppWin
->GetText();
1235 unsigned int Application::GetScreenCount()
1237 SalSystem
* pSys
= ImplGetSalSystem();
1238 return pSys
? pSys
->GetDisplayScreenCount() : 0;
1241 bool Application::IsUnifiedDisplay()
1243 SalSystem
* pSys
= ImplGetSalSystem();
1244 return pSys
== nullptr || pSys
->IsUnifiedDisplay();
1247 unsigned int Application::GetDisplayBuiltInScreen()
1249 SalSystem
* pSys
= ImplGetSalSystem();
1250 return pSys
? pSys
->GetDisplayBuiltInScreen() : 0;
1253 unsigned int Application::GetDisplayExternalScreen()
1255 // This is really unpleasant, in theory we could have multiple
1256 // external displays etc.
1258 switch (GetDisplayBuiltInScreen())
1267 // When the built-in display is neither 0 nor 1
1268 // then place the full-screen presentation on the
1269 // first available screen.
1276 tools::Rectangle
Application::GetScreenPosSizePixel( unsigned int nScreen
)
1278 SalSystem
* pSys
= ImplGetSalSystem();
1279 return pSys
? pSys
->GetDisplayScreenPosSizePixel( nScreen
) : tools::Rectangle();
1283 unsigned long calcDistSquare( const Point
& i_rPoint
, const tools::Rectangle
& i_rRect
)
1285 const Point
aRectCenter( (i_rRect
.Left() + i_rRect
.Right())/2,
1286 (i_rRect
.Top() + i_rRect
.Bottom())/ 2 );
1287 const long nDX
= aRectCenter
.X() - i_rPoint
.X();
1288 const long nDY
= aRectCenter
.Y() - i_rPoint
.Y();
1289 return nDX
*nDX
+ nDY
*nDY
;
1293 unsigned int Application::GetBestScreen( const tools::Rectangle
& i_rRect
)
1295 if( !IsUnifiedDisplay() )
1296 return GetDisplayBuiltInScreen();
1298 const unsigned int nScreens
= GetScreenCount();
1299 unsigned int nBestMatchScreen
= 0;
1300 unsigned long nOverlap
= 0;
1301 for( unsigned int i
= 0; i
< nScreens
; i
++ )
1303 const tools::Rectangle
aCurScreenRect( GetScreenPosSizePixel( i
) );
1304 // if a screen contains the rectangle completely it is obviously the best screen
1305 if( aCurScreenRect
.IsInside( i_rRect
) )
1307 // next the screen which contains most of the area of the rect is the best
1308 tools::Rectangle
aIntersection( aCurScreenRect
.GetIntersection( i_rRect
) );
1309 if( ! aIntersection
.IsEmpty() )
1311 const unsigned long nCurOverlap( aIntersection
.GetWidth() * aIntersection
.GetHeight() );
1312 if( nCurOverlap
> nOverlap
)
1314 nOverlap
= nCurOverlap
;
1315 nBestMatchScreen
= i
;
1320 return nBestMatchScreen
;
1322 // finally the screen which center is nearest to the rect is the best
1323 const Point
aCenter( (i_rRect
.Left() + i_rRect
.Right())/2,
1324 (i_rRect
.Top() + i_rRect
.Bottom())/2 );
1325 unsigned long nDist
= ULONG_MAX
;
1326 for( unsigned int i
= 0; i
< nScreens
; i
++ )
1328 const tools::Rectangle
aCurScreenRect( GetScreenPosSizePixel( i
) );
1329 const unsigned long nCurDist( calcDistSquare( aCenter
, aCurScreenRect
) );
1330 if( nCurDist
< nDist
)
1332 nBestMatchScreen
= i
;
1336 return nBestMatchScreen
;
1339 bool Application::InsertAccel( Accelerator
* pAccel
)
1341 ImplSVData
* pSVData
= ImplGetSVData();
1343 if ( !pSVData
->maAppData
.mpAccelMgr
)
1344 pSVData
->maAppData
.mpAccelMgr
= new ImplAccelManager();
1345 return pSVData
->maAppData
.mpAccelMgr
->InsertAccel( pAccel
);
1348 void Application::RemoveAccel( Accelerator
* pAccel
)
1350 ImplSVData
* pSVData
= ImplGetSVData();
1352 if ( pSVData
->maAppData
.mpAccelMgr
)
1353 pSVData
->maAppData
.mpAccelMgr
->RemoveAccel( pAccel
);
1356 void Application::SetHelp( Help
* pHelp
)
1358 ImplGetSVData()->maAppData
.mpHelp
= pHelp
;
1361 Help
* Application::GetHelp()
1363 return ImplGetSVData()->maAppData
.mpHelp
;
1366 OUString
Application::GetToolkitName()
1368 ImplSVData
* pSVData
= ImplGetSVData();
1369 if ( pSVData
->maAppData
.mpToolkitName
)
1370 return *(pSVData
->maAppData
.mpToolkitName
);
1375 vcl::Window
* Application::GetDefDialogParent()
1377 ImplSVData
* pSVData
= ImplGetSVData();
1378 // find some useful dialog parent
1380 // always use the topmost parent of the candidate
1381 // window to avoid using dialogs or floaters
1382 // as DefDialogParent
1384 // current focus frame
1385 vcl::Window
*pWin
= pSVData
->maWinData
.mpFocusWin
;
1386 if (pWin
&& !pWin
->IsMenuFloatingWindow())
1388 while (pWin
->mpWindowImpl
&& pWin
->mpWindowImpl
->mpParent
)
1389 pWin
= pWin
->mpWindowImpl
->mpParent
;
1391 // check for corrupted window hierarchy, #122232#, may be we now crash somewhere else
1392 if (!pWin
->mpWindowImpl
)
1394 OSL_FAIL( "Window hierarchy corrupted!" );
1395 pSVData
->maWinData
.mpFocusWin
= nullptr; // avoid further access
1399 if ((pWin
->mpWindowImpl
->mnStyle
& WB_INTROWIN
) == 0)
1401 return pWin
->mpWindowImpl
->mpFrameWindow
->ImplGetWindow();
1405 // last active application frame
1406 pWin
= pSVData
->maWinData
.mpActiveApplicationFrame
;
1409 return pWin
->mpWindowImpl
->mpFrameWindow
->ImplGetWindow();
1412 // first visible top window (may be totally wrong....)
1413 pWin
= pSVData
->maWinData
.mpFirstFrame
;
1416 if( pWin
->ImplGetWindow()->IsTopWindow() &&
1417 pWin
->mpWindowImpl
->mbReallyVisible
&&
1418 (pWin
->mpWindowImpl
->mnStyle
& WB_INTROWIN
) == 0
1421 while( pWin
->mpWindowImpl
->mpParent
)
1422 pWin
= pWin
->mpWindowImpl
->mpParent
;
1423 return pWin
->mpWindowImpl
->mpFrameWindow
->ImplGetWindow();
1425 pWin
= pWin
->mpWindowImpl
->mpFrameData
->mpNextFrame
;
1432 Application::DialogCancelMode
Application::GetDialogCancelMode()
1434 return ImplGetSVData()->maAppData
.meDialogCancel
;
1437 void Application::SetDialogCancelMode( DialogCancelMode mode
)
1439 ImplGetSVData()->maAppData
.meDialogCancel
= mode
;
1442 bool Application::IsDialogCancelEnabled()
1444 return ImplGetSVData()->maAppData
.meDialogCancel
!= DialogCancelMode::Off
;
1447 void Application::SetSystemWindowMode( SystemWindowFlags nMode
)
1449 ImplGetSVData()->maAppData
.mnSysWinMode
= nMode
;
1452 SystemWindowFlags
Application::GetSystemWindowMode()
1454 return ImplGetSVData()->maAppData
.mnSysWinMode
;
1457 css::uno::Reference
< css::awt::XToolkit
> Application::GetVCLToolkit()
1459 css::uno::Reference
< css::awt::XToolkit
> xT
;
1460 UnoWrapperBase
* pWrapper
= Application::GetUnoWrapper();
1462 xT
= pWrapper
->GetVCLToolkit();
1466 #ifdef DISABLE_DYNLOADING
1468 extern "C" { UnoWrapperBase
* CreateUnoWrapper(); }
1472 extern "C" { static void SAL_CALL
thisModule() {} }
1476 UnoWrapperBase
* Application::GetUnoWrapper( bool bCreateIfNotExist
)
1478 ImplSVData
* pSVData
= ImplGetSVData();
1479 static bool bAlreadyTriedToCreate
= false;
1480 if ( !pSVData
->mpUnoWrapper
&& bCreateIfNotExist
&& !bAlreadyTriedToCreate
)
1482 #ifndef DISABLE_DYNLOADING
1484 OUString
aLibName(TK_DLL_NAME
);
1485 aTkLib
.loadRelative(&thisModule
, aLibName
);
1488 FN_TkCreateUnoWrapper fnCreateWrapper
= reinterpret_cast<FN_TkCreateUnoWrapper
>(aTkLib
.getFunctionSymbol("CreateUnoWrapper"));
1489 if ( fnCreateWrapper
)
1491 pSVData
->mpUnoWrapper
= fnCreateWrapper();
1495 SAL_WARN_IF( !pSVData
->mpUnoWrapper
, "vcl", "UnoWrapper could not be created!" );
1497 pSVData
->mpUnoWrapper
= CreateUnoWrapper();
1499 bAlreadyTriedToCreate
= true;
1501 return pSVData
->mpUnoWrapper
;
1504 void Application::SetUnoWrapper( UnoWrapperBase
* pWrapper
)
1506 ImplSVData
* pSVData
= ImplGetSVData();
1507 SAL_WARN_IF( pSVData
->mpUnoWrapper
, "vcl", "SetUnoWrapper: Wrapper already exists" );
1508 pSVData
->mpUnoWrapper
= pWrapper
;
1511 css::uno::Reference
< css::awt::XDisplayConnection
> Application::GetDisplayConnection()
1513 ImplSVData
* pSVData
= ImplGetSVData();
1515 if( !pSVData
->mxDisplayConnection
.is() )
1517 pSVData
->mxDisplayConnection
.set( new vcl::DisplayConnectionDispatch
);
1518 pSVData
->mxDisplayConnection
->start();
1521 return pSVData
->mxDisplayConnection
.get();
1524 void Application::SetFilterHdl( const Link
<ConvertData
&,bool>& rLink
)
1526 ImplGetSVData()->maGDIData
.mpGrfConverter
->SetFilterHdl( rLink
);
1529 bool ImplCallHotKey( const vcl::KeyCode
& rKeyCode
)
1531 ImplSVData
* pSVData
= ImplGetSVData();
1532 ImplHotKey
* pHotKeyData
= pSVData
->maAppData
.mpFirstHotKey
;
1533 while ( pHotKeyData
)
1535 if ( pHotKeyData
->maKeyCode
== rKeyCode
)
1540 pHotKeyData
= pHotKeyData
->mpNext
;
1546 void ImplFreeHotKeyData()
1548 ImplSVData
* pSVData
= ImplGetSVData();
1549 ImplHotKey
* pTempHotKeyData
;
1550 ImplHotKey
* pHotKeyData
= pSVData
->maAppData
.mpFirstHotKey
;
1551 while ( pHotKeyData
)
1553 pTempHotKeyData
= pHotKeyData
->mpNext
;
1555 pHotKeyData
= pTempHotKeyData
;
1558 pSVData
->maAppData
.mpFirstHotKey
= nullptr;
1561 void ImplFreeEventHookData()
1563 ImplSVData
* pSVData
= ImplGetSVData();
1564 ImplEventHook
* pTempEventHookData
;
1565 ImplEventHook
* pEventHookData
= pSVData
->maAppData
.mpFirstEventHook
;
1566 while ( pEventHookData
)
1568 pTempEventHookData
= pEventHookData
->mpNext
;
1569 delete pEventHookData
;
1570 pEventHookData
= pTempEventHookData
;
1573 pSVData
->maAppData
.mpFirstEventHook
= nullptr;
1576 long Application::CallEventHooks( NotifyEvent
& rEvt
)
1578 ImplSVData
* pSVData
= ImplGetSVData();
1580 ImplEventHook
* pTempEventHookData
;
1581 ImplEventHook
* pEventHookData
= pSVData
->maAppData
.mpFirstEventHook
;
1582 while ( pEventHookData
)
1584 pTempEventHookData
= pEventHookData
->mpNext
;
1585 nRet
= pEventHookData
->mpProc( rEvt
, pEventHookData
->mpUserData
);
1588 pEventHookData
= pTempEventHookData
;
1594 const LocaleDataWrapper
& Application::GetAppLocaleDataWrapper()
1596 return GetSettings().GetLocaleDataWrapper();
1599 void Application::EnableHeadlessMode( bool dialogsAreFatal
)
1601 SetDialogCancelMode(
1602 dialogsAreFatal
? DialogCancelMode::Fatal
: DialogCancelMode::Silent
);
1605 bool Application::IsHeadlessModeEnabled()
1607 return IsDialogCancelEnabled();
1610 static bool bConsoleOnly
= false;
1612 bool Application::IsConsoleOnly()
1614 return bConsoleOnly
;
1617 void Application::EnableConsoleOnly()
1619 EnableHeadlessMode(true);
1620 bConsoleOnly
= true;
1623 static bool bEventTestingMode
= false;
1625 bool Application::IsEventTestingModeEnabled()
1627 return bEventTestingMode
;
1630 void Application::EnableEventTestingMode()
1632 bEventTestingMode
= true;
1635 static bool bSafeMode
= false;
1637 bool Application::IsSafeModeEnabled()
1642 void Application::EnableSafeMode()
1647 void Application::ShowNativeErrorBox(const OUString
& sTitle
,
1648 const OUString
& sMessage
)
1650 int btn
= ImplGetSalSystem()->ShowNativeMessageBox(
1653 if (btn
!= SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK
) {
1654 SAL_WARN( "vcl", "ShowNativeMessageBox returned " << btn
);
1658 bool Application::CanToggleImeStatusWindow()
1660 ImplSVData
* pSVData
= ImplGetSVData();
1661 if( ! pSVData
->mpImeStatus
)
1662 pSVData
->mpImeStatus
= pSVData
->mpDefInst
->CreateI18NImeStatus();
1663 return pSVData
->mpImeStatus
->canToggle();
1666 void Application::ShowImeStatusWindow(bool bShow
)
1668 ImplGetSVData()->maAppData
.meShowImeStatusWindow
= bShow
1669 ? ImplSVAppData::ImeStatusWindowMode_SHOW
1670 : ImplSVAppData::ImeStatusWindowMode_HIDE
;
1672 ImplSVData
* pSVData
= ImplGetSVData();
1673 if( ! pSVData
->mpImeStatus
)
1674 pSVData
->mpImeStatus
= pSVData
->mpDefInst
->CreateI18NImeStatus();
1675 pSVData
->mpImeStatus
->toggle();
1678 bool Application::GetShowImeStatusWindowDefault()
1680 rtl_TextEncodingInfo aInfo
;
1681 aInfo
.StructSize
= sizeof aInfo
;
1682 return rtl_getTextEncodingInfo(osl_getThreadTextEncoding(), &aInfo
)
1683 && aInfo
.MaximumCharSize
> 1;
1686 const OUString
& Application::GetDesktopEnvironment()
1688 if (IsHeadlessModeEnabled())
1690 static OUString
aNone("none");
1694 return SalGetDesktopEnvironment();
1697 void Application::AddToRecentDocumentList(const OUString
& rFileUrl
, const OUString
& rMimeType
, const OUString
& rDocumentService
)
1699 ImplSVData
* pSVData
= ImplGetSVData();
1700 pSVData
->mpDefInst
->AddToRecentDocumentList(rFileUrl
, rMimeType
, rDocumentService
);
1703 bool InitAccessBridge()
1705 // Disable MSAA bridge on UNIX
1709 bool bRet
= ImplInitAccessBridge();
1713 // disable accessibility if the user chooses to continue
1714 AllSettings aSettings
= Application::GetSettings();
1715 MiscSettings aMisc
= aSettings
.GetMiscSettings();
1716 aMisc
.SetEnableATToolSupport( false );
1717 aSettings
.SetMiscSettings( aMisc
);
1718 Application::SetSettings( aSettings
);
1724 // MT: AppEvent was in oldsv.cxx, but is still needed...
1725 void Application::AppEvent( const ApplicationEvent
& /*rAppEvent*/ )
1729 bool Application::hasNativeFileSelection()
1731 ImplSVData
* pSVData
= ImplGetSVData();
1732 return pSVData
->mpDefInst
->hasNativeFileSelection();
1735 Reference
< ui::dialogs::XFilePicker2
>
1736 Application::createFilePicker( const Reference
< uno::XComponentContext
>& xSM
)
1738 ImplSVData
* pSVData
= ImplGetSVData();
1739 return pSVData
->mpDefInst
->createFilePicker( xSM
);
1742 Reference
< ui::dialogs::XFolderPicker2
>
1743 Application::createFolderPicker( const Reference
< uno::XComponentContext
>& xSM
)
1745 ImplSVData
* pSVData
= ImplGetSVData();
1746 return pSVData
->mpDefInst
->createFolderPicker( xSM
);
1749 void Application::setDeInitHook(Link
<LinkParamNone
*,void> const & hook
) {
1750 ImplSVData
* pSVData
= ImplGetSVData();
1751 assert(!pSVData
->maDeInitHook
.IsSet());
1752 pSVData
->maDeInitHook
= hook
;
1753 // Fake this for VCLXToolkit ctor instantiated from
1754 // postprocess/CppunitTest_services.mk:
1755 pSVData
->maAppData
.mbInAppMain
= true;
1758 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */