1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #pragma once
21
22 #include <sal/config.h>
23
24 #include <o3tl/lru_map.hxx>
25 #include <o3tl/hash_combine.hxx>
26 #include <o3tl/sorted_vector.hxx>
27 #include <osl/conditn.hxx>
28 #include <tools/fldunit.hxx>
29 #include <unotools/options.hxx>
30 #include <vcl/bitmapex.hxx>
31 #include <vcl/cvtgrf.hxx>
32 #include <vcl/dropcache.hxx>
33 #include <vcl/image.hxx>
34 #include <vcl/settings.hxx>
35 #include <vcl/svapp.hxx>
36 #include <vcl/print.hxx>
37 #include <vcl/uitest/logger.hxx>
38 #include <vcl/virdev.hxx>
39 #include <vcl/wrkwin.hxx>
40 #include <vcl/window.hxx>
41 #include <vcl/task.hxx>
42 #include <LibreOfficeKit/LibreOfficeKitTypes.h>
43 #include <unotools/resmgr.hxx>
44
45 #include <com/sun/star/lang/XComponent.hpp>
46 #include <com/sun/star/i18n/XCharacterClassification.hpp>
47 #include "vcleventlisteners.hxx"
48 #include "print.h"
49 #include "salwtype.hxx"
50 #include "windowdev.hxx"
51 #include "displayconnectiondispatch.hxx"
52
53 #include <atomic>
54 #include <mutex>
55 #include <optional>
56 #include <vector>
57 #include <unordered_map>
58 #include "schedulerimpl.hxx"
59 #include <basegfx/DrawCommands.hxx>
60
61 struct ImplPostEventData;
62 struct ImplTimerData;
63 struct ImplIdleData;
64 struct ImplConfigData;
65 namespace rtl
66 {
67 class OStringBuffer;
68 }
69 namespace vcl::font
70 {
71 class DirectFontSubstitution;
72 class PhysicalFontCollection;
73 }
74 struct BlendFrameCache;
75 struct ImplHotKey;
76 struct ImplEventHook;
77 class Point;
78 class ImplAccelManager;
79 class ImplFontCache;
80 class HelpTextWindow;
81 class ImplTBDragMgr;
82 class ImplIdleMgr;
83 class FloatingWindow;
84 class AllSettings;
85 class NotifyEvent;
86 class Timer;
87 class AutoTimer;
88 class Idle;
89 class Help;
90 class PopupMenu;
91 class Application;
92 class OutputDevice;
93 class SvFileStream;
94 class SystemWindow;
95 class WorkWindow;
96 class Dialog;
97 class VirtualDevice;
98 class Printer;
99 class SalFrame;
100 class SalInstance;
101 class SalSystem;
102 class ImplPrnQueueList;
103 class UnoWrapperBase;
104 class GraphicConverter;
105 class ImplWheelWindow;
106 class SalTimer;
107 class DockingManager;
108 class VclEventListeners2;
109 class SalData;
110 class OpenGLContext;
111 class UITestLogger;
112
113 #define SV_ICON_ID_OFFICE 1
114 #define SV_ICON_ID_TEXT 2
115 #define SV_ICON_ID_TEXT_TEMPLATE 3
116 #define SV_ICON_ID_SPREADSHEET 4
117 #define SV_ICON_ID_SPREADSHEET_TEMPLATE 5
118 #define SV_ICON_ID_DRAWING 6
119 #define SV_ICON_ID_PRESENTATION 8
120 #define SV_ICON_ID_MASTER_DOCUMENT 10
121 #define SV_ICON_ID_TEMPLATE 11
122 #define SV_ICON_ID_DATABASE 12
123 #define SV_ICON_ID_FORMULA 13
124
125 const FloatWinPopupFlags LISTBOX_FLOATWINPOPUPFLAGS = FloatWinPopupFlags::Down |
126 FloatWinPopupFlags::NoHorzPlacement | FloatWinPopupFlags::AllMouseButtonClose;
127
128 namespace com::sun::star::datatransfer::clipboard { class XClipboard; }
129
130 namespace vcl
131 {
132 class DisplayConnectionDispatch;
133 class Window;
134 }
135
136 namespace basegfx
137 {
138 class SystemDependentDataManager;
139 }
140
141 class LocaleConfigurationListener final : public utl::ConfigurationListener
142 {
143 public:
144 virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, ConfigurationHints ) override;
145 };
146
147 typedef std::pair<VclPtr<vcl::Window>, ImplPostEventData *> ImplPostEventPair;
148
149 struct ImplSVAppData
150 {
151 ImplSVAppData();
152 ~ImplSVAppData();
153
154 std::optional<AllSettings> mxSettings; // Application settings
155 LocaleConfigurationListener* mpCfgListener = nullptr;
156 VclEventListeners maEventListeners; // listeners for vcl events (eg, extended toolkit)
157 std::vector<Link<VclWindowEvent&,bool> >
158 maKeyListeners; // listeners for key events only (eg, extended toolkit)
159 std::vector<ImplPostEventPair> maPostedEventList;
160 ImplAccelManager* mpAccelMgr = nullptr; // Accelerator Manager
161 std::optional<OUString> mxAppName; // Application name
162 std::optional<OUString> mxAppFileName; // Abs. Application FileName
163 std::optional<OUString> mxDisplayName; // Application Display Name
164 std::optional<OUString> mxToolkitName; // Toolkit Name
165 Help* mpHelp = nullptr; // Application help
166 VclPtr<PopupMenu> mpActivePopupMenu; // Actives Popup-Menu (in Execute)
167 VclPtr<ImplWheelWindow> mpWheelWindow; // WheelWindow
168 sal_uInt64 mnLastInputTime = 0; // GetLastInputTime()
169 sal_uInt16 mnDispatchLevel = 0; // DispatchLevel
170 sal_uInt16 mnModalMode = 0; // ModalMode Count
171 SystemWindowFlags mnSysWinMode = SystemWindowFlags(0); // Mode, when SystemWindows should be created
172 bool mbInAppMain = false; // is Application::Main() on stack
173 bool mbInAppExecute = false; // is Application::Execute() on stack
174 std::atomic<bool> mbAppQuit = false; // is Application::Quit() called, volatile because we read/write from different threads
175 bool mbSettingsInit = false; // true: Settings are initialized
176 DialogCancelMode meDialogCancel = DialogCancelMode::Off; // true: All Dialog::Execute() calls will be terminated immediately with return false
177 bool mbRenderToBitmaps = false; // set via svp / headless plugin
178 bool m_bUseSystemLoop = false;
179
180 DECL_STATIC_LINK(ImplSVAppData, ImplQuitMsg, void*, void);
181 };
182
183 /// Cache multiple scalings for the same bitmap
184 struct ScaleCacheKey {
185 SalBitmap *mpBitmap;
186 Size maDestSize;
ScaleCacheKeyScaleCacheKey187 ScaleCacheKey(SalBitmap *pBitmap, const Size &aDestSize)
188 {
189 mpBitmap = pBitmap;
190 maDestSize = aDestSize;
191 }
ScaleCacheKeyScaleCacheKey192 ScaleCacheKey(const ScaleCacheKey &key)
193 {
194 mpBitmap = key.mpBitmap;
195 maDestSize = key.maDestSize;
196 }
operator ==ScaleCacheKey197 bool operator==(ScaleCacheKey const& rOther) const
198 {
199 return mpBitmap == rOther.mpBitmap && maDestSize == rOther.maDestSize;
200 }
201 };
202
203 namespace std
204 {
205 template <> struct hash<ScaleCacheKey>
206 {
operator ()std::hash207 std::size_t operator()(ScaleCacheKey const& k) const noexcept
208 {
209 std::size_t seed = 0;
210 o3tl::hash_combine(seed, k.mpBitmap);
211 o3tl::hash_combine(seed, k.maDestSize.getWidth());
212 o3tl::hash_combine(seed, k.maDestSize.getHeight());
213 return seed;
214 }
215 };
216
217 } // end std namespace
218
219 typedef o3tl::lru_map<ScaleCacheKey, Bitmap> lru_scale_cache;
220
221 struct ImplSVGDIData
222 {
223 ~ImplSVGDIData();
224
225 VclPtr<vcl::WindowOutputDevice> mpFirstWinGraphics; // First OutputDevice with a Frame Graphics
226 VclPtr<vcl::WindowOutputDevice> mpLastWinGraphics; // Last OutputDevice with a Frame Graphics
227 VclPtr<OutputDevice> mpFirstVirGraphics; // First OutputDevice with a VirtualDevice Graphics
228 VclPtr<OutputDevice> mpLastVirGraphics; // Last OutputDevice with a VirtualDevice Graphics
229 VclPtr<Printer> mpFirstPrnGraphics; // First OutputDevice with an InfoPrinter Graphics
230 VclPtr<Printer> mpLastPrnGraphics; // Last OutputDevice with an InfoPrinter Graphics
231 VclPtr<VirtualDevice> mpFirstVirDev; // First VirtualDevice
232 OpenGLContext* mpLastContext = nullptr; // Last OpenGLContext
233 VclPtr<Printer> mpFirstPrinter; // First Printer
234 std::unique_ptr<ImplPrnQueueList> mpPrinterQueueList; // List of all printer queue
235 std::shared_ptr<vcl::font::PhysicalFontCollection> mxScreenFontList; // Screen-Font-List
236 std::shared_ptr<ImplFontCache> mxScreenFontCache; // Screen-Font-Cache
237 lru_scale_cache maScaleCache = lru_scale_cache(10); // Cache for scaled images
238 vcl::font::DirectFontSubstitution* mpDirectFontSubst = nullptr; // Font-Substitutions defined in Tools->Options->Fonts
239 std::unique_ptr<GraphicConverter> mxGrfConverter; // Converter for graphics
240 tools::Long mnAppFontX = 0; // AppFont X-Numenator for 40/tel Width
241 tools::Long mnAppFontY = 0; // AppFont Y-Numenator for 80/tel Height
242 bool mbFontSubChanged = false; // true: FontSubstitution was changed between Begin/End
243
244 o3tl::lru_map<OUString, Bitmap> maThemeImageCache = o3tl::lru_map<OUString, Bitmap>(10);
245 o3tl::lru_map<OUString, gfx::DrawRoot> maThemeDrawCommandsCache = o3tl::lru_map<OUString, gfx::DrawRoot>(50);
246 };
247
248 struct ImplSVFrameData
249 {
250 ~ImplSVFrameData();
251 VclPtr<vcl::Window> mpFirstFrame; // First FrameWindow
252 VclPtr<vcl::Window> mpActiveApplicationFrame; // the last active application frame, can be used as DefModalDialogParent if no focuswin set
253 VclPtr<WorkWindow> mpAppWin; // Application-Window
254
255 std::unique_ptr<UITestLogger> m_pUITestLogger;
256 };
257
258 struct ImplSVWinData
259 {
260 ~ImplSVWinData();
261 VclPtr<vcl::Window> mpFocusWin; // window, that has the focus
262 VclPtr<vcl::Window> mpCaptureWin; // window, that has the mouse capture
263 VclPtr<vcl::Window> mpLastDeacWin; // Window, that need a deactivate (FloatingWindow-Handling)
264 VclPtr<FloatingWindow> mpFirstFloat; // First FloatingWindow in PopupMode
265 std::vector<VclPtr<Dialog>> mpExecuteDialogs; ///< Stack of dialogs that are Execute()'d - the last one is the top most one.
266 VclPtr<vcl::Window> mpExtTextInputWin; // Window, which is in ExtTextInput
267 VclPtr<vcl::Window> mpTrackWin; // window, that is in tracking mode
268 std::unique_ptr<AutoTimer> mpTrackTimer; // tracking timer
269 std::vector<Image> maMsgBoxImgList; // ImageList for MessageBox
270 VclPtr<vcl::Window> mpAutoScrollWin; // window, that is in AutoScrollMode mode
271 VclPtr<vcl::Window> mpLastWheelWindow; // window, that last received a mouse wheel event
272 SalWheelMouseEvent maLastWheelEvent; // the last received mouse wheel event
273
274 StartTrackingFlags mnTrackFlags = StartTrackingFlags::NONE; // tracking flags
275 StartAutoScrollFlags mnAutoScrollFlags = StartAutoScrollFlags::NONE; // auto scroll flags
276 bool mbNoDeactivate = false; // true: do not execute Deactivate
277 bool mbNoSaveFocus = false; // true: menus must not save/restore focus
278 bool mbIsLiveResize = false; // true: skip waiting for events and low priority timers
279 bool mbIsWaitingForNativeEvent = false; // true: code is executing via a native callback while waiting for the next native event
280 };
281
282 typedef std::vector< std::pair< OUString, FieldUnit > > FieldUnitStringList;
283
284 struct ImplSVCtrlData
285 {
286 std::vector<Image> maCheckImgList; // ImageList for CheckBoxes
287 std::vector<Image> maRadioImgList; // ImageList for RadioButtons
288 std::optional<Image> moDisclosurePlus;
289 std::optional<Image> moDisclosureMinus;
290 ImplTBDragMgr* mpTBDragMgr = nullptr; // DragMgr for ToolBox
291 sal_uInt16 mnCheckStyle = 0; // CheckBox-Style for ImageList-Update
292 sal_uInt16 mnRadioStyle = 0; // Radio-Style for ImageList-Update
293 Color mnLastCheckFColor; // Last FaceColor for CheckImage
294 Color mnLastCheckWColor; // Last WindowColor for CheckImage
295 Color mnLastCheckLColor; // Last LightColor for CheckImage
296 Color mnLastRadioFColor; // Last FaceColor for RadioImage
297 Color mnLastRadioWColor; // Last WindowColor for RadioImage
298 Color mnLastRadioLColor; // Last LightColor for RadioImage
299 FieldUnitStringList maFieldUnitStrings; // list with field units
300 FieldUnitStringList maCleanUnitStrings; // same list but with some "fluff" like spaces removed
301 };
302
303 struct ImplSVHelpData
304 {
305 ~ImplSVHelpData();
306 bool mbContextHelp = false; // is ContextHelp enabled
307 bool mbExtHelp = false; // is ExtendedHelp enabled
308 bool mbExtHelpMode = false; // is in ExtendedHelp Mode
309 bool mbOldBalloonMode = false; // BalloonMode, before ExtHelpMode started
310 bool mbBalloonHelp = false; // is BalloonHelp enabled
311 bool mbQuickHelp = false; // is QuickHelp enabled
312 bool mbSetKeyboardHelp = false; // tiphelp was activated by keyboard
313 bool mbKeyboardHelp = false; // tiphelp was activated by keyboard
314 bool mbRequestingHelp = false; // In Window::RequestHelp
315 VclPtr<HelpTextWindow> mpHelpWin; // HelpWindow
316 sal_uInt64 mnLastHelpHideTime = 0; // ticks of last show
317 };
318
319 // "NWF" means "Native Widget Framework" and was the term used for the
320 // idea that StarView/OOo "widgets" should *look* (and feel) like the
321 // "native widgets" on each platform, even if not at all implemented
322 // using them. See http://people.redhat.com/dcbw/ooo-nwf.html .
323
324 struct ImplSVNWFData
325 {
326 int mnStatusBarLowerRightOffset = 0; // amount in pixel to avoid in the lower righthand corner
327 int mnMenuFormatBorderX = 0; // horizontal inner popup menu border
328 int mnMenuFormatBorderY = 0; // vertical inner popup menu border
329 ::Color maMenuBarHighlightTextColor = COL_TRANSPARENT; // override highlight text color
330 // in menubar if not transparent
331 bool mbMenuBarDockingAreaCommonBG = false; // e.g. WinXP default theme
332 bool mbDockingAreaSeparateTB = false; // individual toolbar backgrounds
333 // instead of one for docking area
334 bool mbDockingAreaAvoidTBFrames = false; ///< don't draw frames around the individual toolbars if mbDockingAreaSeparateTB is false
335 bool mbFlatMenu = false; // no popup 3D border
336 bool mbNoFocusRects = false; // on Aqua/Gtk3 use native focus rendering, except for flat buttons
337 bool mbNoFocusRectsForFlatButtons = false; // on Gtk3 native focusing is also preferred for flat buttons
338 bool mbNoFrameJunctionForPopups = false; // on Gtk4 popups are done via popovers and a toolbar menu won't align to its toolitem, so
339 // omit the effort the creation a visual junction
340 bool mbCenteredTabs = false; // on Aqua, tabs are centered
341 bool mbNoActiveTabTextRaise = false; // on Aqua the text for the selected tab
342 // should not "jump up" a pixel
343 bool mbProgressNeedsErase = false; // set true for platforms that should draw the
344 // window background before drawing the native
345 // progress bar
346 bool mbCanDrawWidgetAnySize = false; // set to true currently on gtk
347
348 /// entire drop down listbox resembles a button, no textarea/button parts (as currently on Windows)
349 bool mbDDListBoxNoTextArea = false;
350 bool mbAutoAccel = false; // whether accelerators are only shown when Alt is held down
351 bool mbRolloverMenubar = false; // theming engine supports rollover in menubar
352 // gnome#768128 I cannot see a route under wayland at present to support
353 // floating toolbars that can be redocked because there's no way to track
354 // that the toolbar is over a dockable area.
355 bool mbCanDetermineWindowPosition = true;
356
357 int mnListBoxEntryMargin = 0;
358 };
359
360 struct ImplSchedulerContext
361 {
362 ImplSchedulerData* mpFirstSchedulerData[PRIO_COUNT] = { nullptr, }; ///< list of all active tasks per priority
363 ImplSchedulerData* mpLastSchedulerData[PRIO_COUNT] = { nullptr, }; ///< last item of each mpFirstSchedulerData list
364 ImplSchedulerData* mpSchedulerStack = nullptr; ///< stack of invoked tasks
365 ImplSchedulerData* mpSchedulerStackTop = nullptr; ///< top most stack entry to detect needed rescheduling during pop
366 SalTimer* mpSalTimer = nullptr; ///< interface to sal event loop / system timer
367 sal_uInt64 mnTimerStart = 0; ///< start time of the timer
368 sal_uInt64 mnTimerPeriod = SAL_MAX_UINT64; ///< current timer period
369 std::mutex maMutex; ///< the "scheduler mutex" (see
370 ///< vcl/README.scheduler)
371 bool mbActive = true; ///< is the scheduler active?
372 oslInterlockedCount mnIdlesLockCount = 0; ///< temporary ignore idles
373 };
374
375 struct ImplSVData
376 {
377 ImplSVData();
378 ~ImplSVData();
379 SalData* mpSalData = nullptr;
380 SalInstance* mpDefInst = nullptr; // Default SalInstance
381 Application* mpApp = nullptr; // pApp
382 VclPtr<WorkWindow> mpDefaultWin; // Default-Window
383 bool mbDeInit = false; // Is VCL deinitializing
384 std::unique_ptr<SalSystem> mpSalSystem; // SalSystem interface
385 bool mbResLocaleSet = false; // SV-Resource-Manager
386 std::locale maResLocale; // Resource locale
387 ImplSchedulerContext maSchedCtx; // Data for class Scheduler
388 ImplSVAppData maAppData; // Data for class Application
389 ImplSVGDIData maGDIData; // Data for Output classes
390 ImplSVFrameData maFrameData; // Data for Frame classes
391 ImplSVWinData* mpWinData = nullptr; // Data for per-view Windows classes
392 ImplSVCtrlData maCtrlData; // Data for Control classes
393 ImplSVHelpData* mpHelpData; // Data for Help classes
394 ImplSVNWFData maNWFData;
395 UnoWrapperBase* mpUnoWrapper = nullptr;
396 VclPtr<vcl::Window> mpIntroWindow; // the splash screen
397 std::unique_ptr<DockingManager> mpDockingManager;
398 std::unique_ptr<BlendFrameCache> mpBlendFrameCache;
399
400 oslThreadIdentifier mnMainThreadId = 0;
401 rtl::Reference< vcl::DisplayConnectionDispatch > mxDisplayConnection;
402
403 css::uno::Reference< css::lang::XComponent > mxAccessBridge;
404 std::unordered_map< int, OUString > maPaperNames;
405 o3tl::sorted_vector<CacheOwner*> maCacheOwners;
406
407 css::uno::Reference<css::i18n::XCharacterClassification> m_xCharClass;
408
409 #if defined _WIN32
410 css::uno::Reference<css::datatransfer::clipboard::XClipboard> m_xSystemClipboard;
411 #endif
412
413 osl::Condition m_inExecuteCondtion; // Set when code returns to Application::Execute,
414 // i.e. no nested message loops run
415
416 Link<LinkParamNone*,void> maDeInitHook;
417
418 // LOK & headless backend specific hooks
419 LibreOfficeKitPollCallback mpPollCallback = nullptr;
420 LibreOfficeKitWakeCallback mpWakeCallback = nullptr;
421 void *mpPollClosure = nullptr;
422
423 void registerCacheOwner(CacheOwner&);
424 void deregisterCacheOwner(CacheOwner&);
425 void dropCaches();
426 void dumpState(rtl::OStringBuffer &rState);
427 };
428
429 css::uno::Reference<css::i18n::XCharacterClassification> const& ImplGetCharClass();
430
431 void ImplDeInitSVData();
432 VCL_PLUGIN_PUBLIC basegfx::SystemDependentDataManager& ImplGetSystemDependentDataManager();
433 VCL_PLUGIN_PUBLIC vcl::Window* ImplGetDefaultWindow();
434 vcl::Window* ImplGetDefaultContextWindow();
435 const std::locale& ImplGetResLocale();
436 VCL_PLUGIN_PUBLIC OUString VclResId(TranslateId sContextAndId);
437 DockingManager* ImplGetDockingManager();
438 void GenerateAutoMnemonicsOnHierarchy(const vcl::Window* pWindow);
439
440 VCL_PLUGIN_PUBLIC ImplSVHelpData& ImplGetSVHelpData();
441
442 VCL_DLLPUBLIC bool ImplCallPreNotify( NotifyEvent& rEvt );
443
444 VCL_PLUGIN_PUBLIC ImplSVData* ImplGetSVData();
445 VCL_PLUGIN_PUBLIC void ImplHideSplash();
446
447 const FieldUnitStringList& ImplGetFieldUnits();
448 const FieldUnitStringList& ImplGetCleanedFieldUnits();
449
450 struct ImplSVEvent
451 {
452 void* mpData;
453 Link<void*,void> maLink;
454 VclPtr<vcl::Window> mpInstanceRef;
455 VclPtr<vcl::Window> mpWindow;
456 bool mbCall;
457 };
458
459 extern int nImplSysDialog;
460
GetSalData()461 inline SalData* GetSalData() { return ImplGetSVData()->mpSalData; }
SetSalData(SalData * pData)462 inline void SetSalData(SalData* pData) { ImplGetSVData()->mpSalData = pData; }
GetSalInstance()463 inline SalInstance* GetSalInstance() { return ImplGetSVData()->mpDefInst; }
464
465 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
466