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 .
23 #include <config_features.h>
25 #include <sal/config.h>
31 #include <comphelper/solarmutex.hxx>
32 #include <osl/thread.hxx>
33 #include <tools/string.hxx>
34 #include <tools/link.hxx>
35 #include <tools/solar.h>
36 #include <vcl/dllapi.h>
37 #include <vcl/apptypes.hxx>
38 #include <vcl/settings.hxx>
39 #include <vcl/vclevent.hxx>
44 class DataChangedEvent
;
60 #include <com/sun/star/uno/Reference.h>
61 #include <com/sun/star/connection/XConnection.hpp>
67 class XComponentContext
;
77 class XDisplayConnection
;
81 // helper needed by SalLayout implementations as well as svx/source/dialog/svxbmpnumbalueset.cxx
82 VCL_DLLPUBLIC sal_UCS4
GetMirroredChar( sal_UCS4
);
83 VCL_DLLPUBLIC sal_UCS4
GetLocalizedChar( sal_UCS4
, LanguageType
);
85 #define SYSTEMWINDOW_MODE_NOAUTOMODE ((sal_uInt16)0x0001)
86 #define SYSTEMWINDOW_MODE_DIALOG ((sal_uInt16)0x0002)
88 typedef long (*VCLEventHookProc
)( NotifyEvent
& rEvt
, void* pData
);
90 // ATTENTION: ENUM duplicate in daemon.cxx under Unix!
93 enum Service
{ SERVICE_OLE
, SERVICE_APPEVENT
, SERVICE_IPC
};
96 class VCL_DLLPUBLIC ApplicationEvent
100 TYPE_ACCEPT
, TYPE_APPEAR
, TYPE_HELP
, TYPE_VERSION
, TYPE_OPEN
,
101 TYPE_OPENHELPURL
, TYPE_PRINT
, TYPE_PRIVATE_DOSHUTDOWN
, TYPE_QUICKSTART
,
102 TYPE_SHOWDIALOG
, TYPE_UNACCEPT
105 explicit ApplicationEvent(Type type
): aEvent(type
) {
107 type
== TYPE_APPEAR
|| type
== TYPE_VERSION
108 || type
== TYPE_PRIVATE_DOSHUTDOWN
|| type
== TYPE_QUICKSTART
);
111 ApplicationEvent(Type type
, OUString
const & data
): aEvent(type
) {
113 type
== TYPE_ACCEPT
|| type
== TYPE_HELP
|| type
== TYPE_OPENHELPURL
114 || type
== TYPE_SHOWDIALOG
|| type
== TYPE_UNACCEPT
);
115 aData
.push_back(data
);
118 ApplicationEvent(Type type
, std::vector
<OUString
> const & data
):
119 aEvent(type
), aData(data
)
120 { assert(type
== TYPE_OPEN
|| type
== TYPE_PRINT
); }
122 Type
GetEvent() const { return aEvent
; }
124 OUString
GetStringData() const {
126 aEvent
== TYPE_ACCEPT
|| aEvent
== TYPE_HELP
127 || aEvent
== TYPE_OPENHELPURL
|| aEvent
== TYPE_SHOWDIALOG
128 || aEvent
== TYPE_UNACCEPT
);
129 assert(aData
.size() == 1);
133 std::vector
<OUString
> const & GetStringsData() const {
134 assert(aEvent
== TYPE_OPEN
|| aEvent
== TYPE_PRINT
);
140 std::vector
<OUString
> aData
;
144 class VCL_DLLPUBLIC Application
147 enum DialogCancelMode
{
148 DIALOG_CANCEL_OFF
, ///< do not automatically cancel dialogs
149 DIALOG_CANCEL_SILENT
, ///< silently cancel any dialogs
151 ///< cancel any dialogs by throwing a DialogCancelledException
154 class VCL_DLLPUBLIC DialogCancelledException
:
155 virtual public std::runtime_error
158 explicit DialogCancelledException(char const * what_arg
):
159 runtime_error(what_arg
) {}
161 virtual ~DialogCancelledException() throw ();
165 virtual ~Application();
167 virtual int Main() = 0;
169 virtual sal_Bool
QueryExit();
171 virtual void UserEvent( sal_uLong nEvent
, void* pEventData
);
173 virtual void FocusChanged();
174 virtual void DataChanged( const DataChangedEvent
& rDCEvt
);
177 virtual void InitFinished();
178 virtual void DeInit();
180 static sal_uInt16
GetCommandLineParamCount();
181 static XubString
GetCommandLineParam( sal_uInt16 nParam
);
182 static const XubString
& GetAppFileName();
184 virtual sal_uInt16
Exception( sal_uInt16 nError
);
185 static void Abort( const XubString
& rErrorText
);
187 static void Execute();
189 static void Reschedule( bool bAllEvents
= false );
190 static void Yield( bool bAllEvents
= false );
191 static void EndYield();
192 static comphelper::SolarMutex
& GetSolarMutex();
193 static oslThreadIdentifier
GetMainThreadIdentifier();
194 static sal_uLong
ReleaseSolarMutex();
195 static void AcquireSolarMutex( sal_uLong nCount
);
196 static void EnableNoYieldMode( bool i_bNoYield
);
197 static void AddPostYieldListener( const Link
& i_rListener
);
198 static void RemovePostYieldListener( const Link
& i_rListener
);
200 static sal_Bool
IsInMain();
201 static sal_Bool
IsInExecute();
202 static sal_Bool
IsInModalMode();
204 static sal_uInt16
GetDispatchLevel();
205 static bool AnyInput( sal_uInt16 nType
= VCL_INPUT_ANY
);
206 static sal_uLong
GetLastInputInterval();
207 static sal_Bool
IsUICaptured();
209 virtual void SystemSettingsChanging( AllSettings
& rSettings
,
211 static void MergeSystemSettings( AllSettings
& rSettings
);
212 /** validate that the currently selected system UI font is suitable
213 to display the application's UI.
215 A localized test string will be checked if it can be displayed
216 in the currently selected system UI font. If no glyphs are
217 missing it can be assumed that the font is proper for display
218 of the application's UI.
221 <TRUE/> if the system font is suitable for our UI
222 <FALSE/> if the test string could not be displayed with the system font
224 static bool ValidateSystemFont();
226 static void SetSettings( const AllSettings
& rSettings
);
227 static const AllSettings
& GetSettings();
228 static void NotifyAllWindows( DataChangedEvent
& rDCEvt
);
230 static void AddEventListener( const Link
& rEventListener
);
231 static void RemoveEventListener( const Link
& rEventListener
);
232 static void AddKeyListener( const Link
& rKeyListener
);
233 static void RemoveKeyListener( const Link
& rKeyListener
);
234 static void ImplCallEventListeners( sal_uLong nEvent
, Window
* pWin
, void* pData
);
235 static void ImplCallEventListeners( VclSimpleEvent
* pEvent
);
236 static sal_Bool
HandleKey( sal_uLong nEvent
, Window
*pWin
, KeyEvent
* pKeyEvent
);
238 static sal_uLong
PostKeyEvent( sal_uLong nEvent
, Window
*pWin
, KeyEvent
* pKeyEvent
);
239 static sal_uLong
PostMouseEvent( sal_uLong nEvent
, Window
*pWin
, MouseEvent
* pMouseEvent
);
240 #if !HAVE_FEATURE_DESKTOP
241 static sal_uLong
PostZoomEvent( sal_uLong nEvent
, Window
*pWin
, ZoomEvent
* pZoomEvent
);
242 static sal_uLong
PostScrollEvent( sal_uLong nEvent
, Window
*pWin
, ScrollEvent
* pScrollEvent
);
244 static void RemoveMouseAndKeyEvents( Window
*pWin
);
246 static sal_uLong
PostUserEvent( const Link
& rLink
, void* pCaller
= NULL
);
247 static sal_Bool
PostUserEvent( sal_uLong
& rEventId
, const Link
& rLink
, void* pCaller
= NULL
);
248 static void RemoveUserEvent( sal_uLong nUserEvent
);
250 static sal_Bool
InsertIdleHdl( const Link
& rLink
, sal_uInt16 nPriority
);
251 static void RemoveIdleHdl( const Link
& rLink
);
253 virtual void AppEvent( const ApplicationEvent
& rAppEvent
);
255 #ifndef NO_GETAPPWINDOW
256 static WorkWindow
* GetAppWindow();
259 static Window
* GetFocusWindow();
260 static OutputDevice
* GetDefaultDevice();
262 static Window
* GetFirstTopLevelWindow();
263 static Window
* GetNextTopLevelWindow( Window
* pWindow
);
265 static long GetTopWindowCount();
266 static Window
* GetTopWindow( long nIndex
);
267 static Window
* GetActiveTopWindow();
269 static void SetAppName( const String
& rUniqueName
);
270 static String
GetAppName();
271 static bool LoadBrandBitmap (const char* pName
, BitmapEx
&rBitmap
);
273 // default name of the application for message dialogs and printing
274 static void SetDisplayName( const OUString
& rDisplayName
);
275 static OUString
GetDisplayName();
278 static unsigned int GetScreenCount();
279 static Rectangle
GetScreenPosSizePixel( unsigned int nScreen
);
281 // IsUnifiedDisplay returns:
282 // true: screens form up one large display area
283 // windows can be moved between single screens
284 // (e.g. Xserver with Xinerama, Windows)
285 // false: different screens are separate and windows cannot be moved
286 // between them (e.g. Xserver with multiple screens)
287 static bool IsUnifiedDisplay();
288 // if IsUnifiedDisplay() == true the return value will be
289 // nearest screen of the target rectangle
290 // in case of IsUnifiedDisplay() == false the return value
291 // will always be GetDisplayDefaultScreen()
292 SAL_DLLPRIVATE
static unsigned int GetBestScreen( const Rectangle
& );
293 static Rectangle
GetWorkAreaPosSizePixel( unsigned int nScreen
);
294 // This returns the LCD screen number for a laptop, or the primary
295 // external VGA display for a desktop machine - it is where a presenter
296 // console should be rendered if there are other (non-built-in) screens
298 static unsigned int GetDisplayBuiltInScreen();
299 // Practically, this means - Get the screen we should run a presentation on.
300 static unsigned int GetDisplayExternalScreen();
302 static const LocaleDataWrapper
& GetAppLocaleDataWrapper();
304 static sal_Bool
InsertAccel( Accelerator
* pAccel
);
305 static void RemoveAccel( Accelerator
* pAccel
);
307 static long CallEventHooks( NotifyEvent
& rEvt
);
309 static void SetHelp( Help
* pHelp
= NULL
);
310 static Help
* GetHelp();
312 static void EnableAutoHelpId( sal_Bool bEnabled
= sal_True
);
313 static sal_Bool
IsAutoHelpIdEnabled();
315 static void EnableAutoMnemonic( sal_Bool bEnabled
= sal_True
);
316 static sal_Bool
IsAutoMnemonicEnabled();
318 static sal_uLong
GetReservedKeyCodeCount();
319 static const KeyCode
* GetReservedKeyCode( sal_uLong i
);
321 static void SetDefDialogParent( Window
* pWindow
);
322 static Window
* GetDefDialogParent();
324 static DialogCancelMode
GetDialogCancelMode();
325 static void SetDialogCancelMode( DialogCancelMode mode
);
326 static sal_Bool
IsDialogCancelEnabled();
328 static void SetSystemWindowMode( sal_uInt16 nMode
);
329 static sal_uInt16
GetSystemWindowMode();
331 static void SetDialogScaleX( short nScale
);
333 static ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XDisplayConnection
> GetDisplayConnection();
335 // The global service manager has to be created before!
336 static ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XToolkit
> GetVCLToolkit();
337 static UnoWrapperBase
* GetUnoWrapper( sal_Bool bCreateIfNotExists
= sal_True
);
338 static void SetUnoWrapper( UnoWrapperBase
* pWrapper
);
340 static void SetFilterHdl( const Link
& rLink
);
341 static const Link
& GetFilterHdl();
343 static void EnableHeadlessMode( bool dialogsAreFatal
);
344 static sal_Bool
IsHeadlessModeEnabled();
345 /// check command line arguments for --headless
346 static bool IsHeadlessModeRequested();
347 /// used to disable Mac specific app init that requires an app bundle
348 static void EnableConsoleOnly();
349 /// used to see if Mac specific app init has been disabled
350 static bool IsConsoleOnly();
352 static void ShowNativeErrorBox(const String
& sTitle
,
353 const String
& sMessage
);
355 // IME Status Window Control:
357 /** Return true if any IME status window can be toggled on and off
360 Must only be called with the Solar mutex locked.
362 static bool CanToggleImeStatusWindow();
364 /** Toggle any IME status window on and off.
366 This only works if CanToggleImeStatusWinodw returns true (otherwise,
367 any calls of this method are ignored).
369 Must only be called with the Solar mutex locked.
371 static void ShowImeStatusWindow(bool bShow
);
373 /** Return true if any IME status window should be turned on by default
374 (this decision can be locale dependent, for example).
376 Can be called without the Solar mutex locked.
378 static bool GetShowImeStatusWindowDefault();
380 /** Returns a string representing the desktop environment
381 the process is currently running in.
383 static const OUString
& GetDesktopEnvironment();
385 /** Add a file to the system shells recent document list if there is any.
386 This function may have no effect under Unix because there is no
387 standard API among the different desktop managers.
390 The file url of the document.
393 The mime content type of the document specified by aFileUrl.
394 If an empty string will be provided "application/octet-stream"
397 static void AddToRecentDocumentList(const OUString
& rFileUrl
, const OUString
& rMimeType
, const OUString
& rDocumentService
);
399 /** Do we have a native / system file selector available ?
401 static bool hasNativeFileSelection();
403 /** Create a platform specific file picker, if one is available,
404 otherwise return an empty reference
406 static com::sun::star::uno::Reference
< com::sun::star::ui::dialogs::XFilePicker2
>
407 createFilePicker( const com::sun::star::uno::Reference
<
408 com::sun::star::uno::XComponentContext
>& rServiceManager
);
410 /** Create a platform specific folder picker, if one is available,
411 otherwise return an empty reference
413 static com::sun::star::uno::Reference
< com::sun::star::ui::dialogs::XFolderPicker2
>
414 createFolderPicker( const com::sun::star::uno::Reference
<
415 com::sun::star::uno::XComponentContext
>& rServiceManager
);
419 DECL_STATIC_LINK( Application
, PostEventHandler
, void* );
423 class VCL_DLLPUBLIC SolarMutexGuard
426 SolarMutexGuard( const SolarMutexGuard
& );
427 const SolarMutexGuard
& operator = ( const SolarMutexGuard
& );
428 comphelper::SolarMutex
& m_solarMutex
;
432 /** Acquires the object specified as parameter.
435 m_solarMutex(Application::GetSolarMutex())
437 m_solarMutex
.acquire();
440 /** Releases the mutex or interface. */
443 m_solarMutex
.release();
447 class VCL_DLLPUBLIC SolarMutexClearableGuard
449 SolarMutexClearableGuard( const SolarMutexClearableGuard
& );
450 const SolarMutexClearableGuard
& operator = ( const SolarMutexClearableGuard
& );
454 @param pMutex pointer to mutex which is to be acquired */
455 SolarMutexClearableGuard()
457 , m_solarMutex( Application::GetSolarMutex() )
459 m_solarMutex
.acquire();
462 /** Releases mutex. */
463 virtual ~SolarMutexClearableGuard()
467 m_solarMutex
.release();
471 /** Releases mutex. */
472 void SAL_CALL
clear()
476 m_solarMutex
.release();
481 comphelper::SolarMutex
& m_solarMutex
;
484 class VCL_DLLPUBLIC SolarMutexResettableGuard
486 SolarMutexResettableGuard( const SolarMutexResettableGuard
& );
487 const SolarMutexResettableGuard
& operator = ( const SolarMutexResettableGuard
& );
491 @param pMutex pointer to mutex which is to be acquired */
492 SolarMutexResettableGuard()
494 , m_solarMutex( Application::GetSolarMutex() )
496 m_solarMutex
.acquire();
499 /** Releases mutex. */
500 virtual ~SolarMutexResettableGuard()
504 m_solarMutex
.release();
508 /** Releases mutex. */
509 void SAL_CALL
clear()
513 m_solarMutex
.release();
517 /** Releases mutex. */
518 void SAL_CALL
reset()
522 m_solarMutex
.acquire();
527 comphelper::SolarMutex
& m_solarMutex
;
532 A helper class that calls Application::ReleaseSolarMutex() in its constructor
533 and restores the mutex in its destructor.
535 class SolarMutexReleaser
537 sal_uLong mnReleased
;
540 SolarMutexReleaser(): mnReleased(Application::ReleaseSolarMutex()) {}
542 ~SolarMutexReleaser()
544 Application::AcquireSolarMutex( mnReleased
);
548 VCL_DLLPUBLIC Application
* GetpApp();
550 VCL_DLLPUBLIC
bool InitVCL();
551 VCL_DLLPUBLIC
void DeInitVCL();
553 VCL_DLLPUBLIC
bool InitAccessBridge( bool bAllowCancel
, bool &rCancelled
);
555 // only allowed to call, if no thread is running. You must call JoinMainLoopThread to free all memory.
556 VCL_DLLPUBLIC
void CreateMainLoopThread( oslWorkerFunction pWorker
, void * pThreadData
);
557 VCL_DLLPUBLIC
void JoinMainLoopThread();
559 inline void Application::EndYield()
561 PostUserEvent( Link() );
566 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */