xref: /haiku/src/servers/app/Desktop.h (revision 4c07199d8201fcf267e90be0d24b76799d03cea6)
1 /*
2  * Copyright 2001-2020, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Adrian Oanca, adioanca@cotty.iren.ro
7  *		Stephan Aßmus, superstippi@gmx.de
8  *		Axel Dörfler, axeld@pinc-software.de
9  *		Andrej Spielmann, andrej.spielmann@seh.ox.ac.uk
10  *		Brecht Machiels, brecht@mos6581.org
11  *		Clemens Zeidler, haiku@clemens-zeidler.de
12  *		Joseph Groover, looncraz@looncraz.net
13  *		Tri-Edge AI
14  *		Jacob Secunda, secundja@gmail.com
15  */
16 #ifndef DESKTOP_H
17 #define DESKTOP_H
18 
19 
20 #include <AutoDeleter.h>
21 #include <Autolock.h>
22 #include <InterfaceDefs.h>
23 #include <List.h>
24 #include <Menu.h>
25 #include <ObjectList.h>
26 #include <Region.h>
27 #include <String.h>
28 #include <Window.h>
29 
30 #include <ServerProtocolStructs.h>
31 
32 #include "CursorManager.h"
33 #include "DelayedMessage.h"
34 #include "DesktopListener.h"
35 #include "DesktopSettings.h"
36 #include "EventDispatcher.h"
37 #include "MessageLooper.h"
38 #include "MultiLocker.h"
39 #include "Screen.h"
40 #include "ScreenManager.h"
41 #include "ServerCursor.h"
42 #include "StackAndTile.h"
43 #include "VirtualScreen.h"
44 #include "WindowList.h"
45 #include "Workspace.h"
46 #include "WorkspacePrivate.h"
47 
48 
49 class BMessage;
50 
51 class DecorAddOn;
52 class DrawingEngine;
53 class HWInterface;
54 class ServerApp;
55 class Window;
56 class WorkspacesView;
57 struct server_read_only_memory;
58 
59 namespace BPrivate {
60 	class LinkSender;
61 };
62 
63 
64 class Desktop : public DesktopObservable, public MessageLooper,
65 	public ScreenOwner {
66 public:
67 								Desktop(uid_t userID,
68 									const char* targetScreen);
69 	virtual						~Desktop();
70 
71 			void				RegisterListener(DesktopListener* listener);
72 
73 			status_t			Init();
74 
75 			uid_t				UserID() const { return fUserID; }
76 			const char*			TargetScreen() { return fTargetScreen; }
77 	virtual port_id				MessagePort() const { return fMessagePort; }
78 			area_id				SharedReadOnlyArea() const
79 									{ return fSharedReadOnlyArea; }
80 
81 			::EventDispatcher&	EventDispatcher() { return fEventDispatcher; }
82 
83 			void				BroadcastToAllApps(int32 code);
84 			void				BroadcastToAllWindows(int32 code);
85 
86 			int32				GetAllWindowTargets(DelayedMessage& message);
87 			int32				GetAllAppTargets(DelayedMessage& message);
88 
89 			filter_result		KeyEvent(uint32 what, int32 key,
90 									int32 modifiers);
91 	// Locking
92 			bool				LockSingleWindow()
93 									{ return fWindowLock.ReadLock(); }
94 			void				UnlockSingleWindow()
95 									{ fWindowLock.ReadUnlock(); }
96 
97 			bool				LockAllWindows()
98 									{ return fWindowLock.WriteLock(); }
99 			void				UnlockAllWindows()
100 									{ fWindowLock.WriteUnlock(); }
101 
102 			const MultiLocker&	WindowLocker() { return fWindowLock; }
103 
104 	// Mouse and cursor methods
105 
106 			void				SetCursor(ServerCursor* cursor);
107 			ServerCursorReference Cursor() const;
108 			void				SetManagementCursor(ServerCursor* newCursor);
109 
110 			void				SetLastMouseState(const BPoint& position,
111 									int32 buttons, Window* windowUnderMouse);
112 									// for use by the mouse filter only
113 									// both mouse position calls require
114 									// the Desktop object to be locked
115 									// already
116 			void				GetLastMouseState(BPoint* position,
117 									int32* buttons) const;
118 									// for use by ServerWindow
119 
120 			CursorManager&		GetCursorManager() { return fCursorManager; }
121 
122 	// Screen and drawing related methods
123 
124 			status_t			SetScreenMode(int32 workspace, int32 id,
125 									const display_mode& mode, bool makeDefault);
126 			status_t			GetScreenMode(int32 workspace, int32 id,
127 									display_mode& mode);
128 			status_t			GetScreenFrame(int32 workspace, int32 id,
129 									BRect& frame);
130 			void				RevertScreenModes(uint32 workspaces);
131 
132 			status_t			SetBrightness(int32 id, float brightness);
133 
134 			MultiLocker&		ScreenLocker() { return fScreenLock; }
135 
136 			status_t			LockDirectScreen(team_id team);
137 			status_t			UnlockDirectScreen(team_id team);
138 
139 			const ::VirtualScreen& VirtualScreen() const
140 									{ return fVirtualScreen; }
141 			DrawingEngine*		GetDrawingEngine() const
142 									{ return fVirtualScreen.DrawingEngine(); }
143 			::HWInterface*		HWInterface() const
144 									{ return fVirtualScreen.HWInterface(); }
145 
146 			void				RebuildAndRedrawAfterWindowChange(
147 									Window* window, BRegion& dirty);
148 									// the window lock must be held when calling
149 									// this function
150 
151 	// ScreenOwner implementation
152 	virtual	void				ScreenRemoved(Screen* screen) {}
153 	virtual	void				ScreenAdded(Screen* screen) {}
154 	virtual	void				ScreenChanged(Screen* screen);
155 	virtual	bool				ReleaseScreen(Screen* screen) { return false; }
156 
157 	// Workspace methods
158 
159 			void				SetWorkspaceAsync(int32 index,
160 									bool moveFocusWindow = false);
161 			void				SetWorkspace(int32 index,
162 									bool moveFocusWindow = false);
163 			int32				CurrentWorkspace()
164 									{ return fCurrentWorkspace; }
165 			Workspace::Private&	WorkspaceAt(int32 index)
166 									{ return fWorkspaces[index]; }
167 			status_t			SetWorkspacesLayout(int32 columns, int32 rows);
168 			BRect				WorkspaceFrame(int32 index) const;
169 
170 			void				StoreWorkspaceConfiguration(int32 index);
171 
172 			void				AddWorkspacesView(WorkspacesView* view);
173 			void				RemoveWorkspacesView(WorkspacesView* view);
174 
175 	// Window methods
176 
177 			void				SelectWindow(Window* window);
178 			void				ActivateWindow(Window* window);
179 			void				SendWindowBehind(Window* window,
180 									Window* behindOf = NULL,
181 									bool sendStack = true);
182 
183 			void				ShowWindow(Window* window);
184 			void				HideWindow(Window* window,
185 									bool fromMinimize = false);
186 			void				MinimizeWindow(Window* window, bool minimize);
187 
188 			void				MoveWindowBy(Window* window, float x, float y,
189 									int32 workspace = -1);
190 			void				ResizeWindowBy(Window* window, float x,
191 									float y);
192 			void				SetWindowOutlinesDelta(Window* window,
193 									BPoint delta);
194 			bool				SetWindowTabLocation(Window* window,
195 									float location, bool isShifting);
196 			bool				SetWindowDecoratorSettings(Window* window,
197 									const BMessage& settings);
198 
199 			void				SetWindowWorkspaces(Window* window,
200 									uint32 workspaces);
201 
202 			void				AddWindow(Window* window);
203 			void				RemoveWindow(Window* window);
204 
205 			bool				AddWindowToSubset(Window* subset,
206 									Window* window);
207 			void				RemoveWindowFromSubset(Window* subset,
208 									Window* window);
209 
210 			void				FontsChanged(Window* window);
211 			void				ColorUpdated(Window* window, color_which which,
212 									rgb_color color);
213 
214 			void				SetWindowLook(Window* window, window_look look);
215 			void				SetWindowFeel(Window* window, window_feel feel);
216 			void				SetWindowFlags(Window* window, uint32 flags);
217 			void				SetWindowTitle(Window* window,
218 									const char* title);
219 
220 			Window*				FocusWindow() const { return fFocus; }
221 			Window*				FrontWindow() const { return fFront; }
222 			Window*				BackWindow() const { return fBack; }
223 
224 			Window*				WindowAt(BPoint where);
225 
226 			Window*				MouseEventWindow() const
227 									{ return fMouseEventWindow; }
228 			void				SetMouseEventWindow(Window* window);
229 
230 			void				SetViewUnderMouse(const Window* window,
231 									int32 viewToken);
232 			int32				ViewUnderMouse(const Window* window);
233 
234 			EventTarget*		KeyboardEventTarget();
235 
236 			void				SetFocusWindow(Window* window = NULL);
237 			void				SetFocusLocked(const Window* window);
238 
239 			Window*				FindWindowByClientToken(int32 token,
240 									team_id teamID);
241 			EventTarget*		FindTarget(BMessenger& messenger);
242 
243 			void				MarkDirty(BRegion& dirtyRegion, BRegion& exposeRegion);
244 			void				MarkDirty(BRegion& region)
245 									{ return MarkDirty(region, region); }
246 			void				Redraw();
247 			void				RedrawBackground();
248 
249 			bool				ReloadDecor(DecorAddOn* oldDecor);
250 
251 			BRegion&			BackgroundRegion()
252 									{ return fBackgroundRegion; }
253 
254 			void				MinimizeApplication(team_id team);
255 			void				BringApplicationToFront(team_id team);
256 			void				WindowAction(int32 windowToken, int32 action);
257 
258 			void				WriteWindowList(team_id team,
259 									BPrivate::LinkSender& sender);
260 			void				WriteWindowInfo(int32 serverToken,
261 									BPrivate::LinkSender& sender);
262 			void				WriteApplicationOrder(int32 workspace,
263 									BPrivate::LinkSender& sender);
264 			void				WriteWindowOrder(int32 workspace,
265 									BPrivate::LinkSender& sender);
266 
267 			//! The window lock must be held when accessing a window list!
268 			WindowList&			CurrentWindows();
269 			WindowList&			AllWindows();
270 
271 			Window*				WindowForClientLooperPort(port_id port);
272 
273 			StackAndTile*		GetStackAndTile() { return &fStackAndTile; }
274 private:
275 			WindowList&			_Windows(int32 index);
276 
277 			void				_FlushPendingColors();
278 
279 			void				_LaunchInputServer();
280 			void				_GetLooperName(char* name, size_t size);
281 			void				_PrepareQuit();
282 			void				_DispatchMessage(int32 code,
283 									BPrivate::LinkReceiver &link);
284 
285 			void				_UpdateFloating(int32 previousWorkspace = -1,
286 									int32 nextWorkspace = -1,
287 									Window* mouseEventWindow = NULL);
288 			void				_UpdateBack();
289 			void				_UpdateFront(bool updateFloating = true);
290 			void				_UpdateFronts(bool updateFloating = true);
291 			bool				_WindowHasModal(Window* window) const;
292 			bool				_WindowCanHaveFocus(Window* window) const;
293 
294 			void				_WindowChanged(Window* window);
295 			void				_WindowRemoved(Window* window);
296 
297 			void				_ShowWindow(Window* window,
298 									bool affectsOtherWindows = true);
299 			void				_HideWindow(Window* window);
300 
301 			void				_UpdateSubsetWorkspaces(Window* window,
302 									int32 previousIndex = -1,
303 									int32 newIndex = -1);
304 			void				_ChangeWindowWorkspaces(Window* window,
305 									uint32 oldWorkspaces, uint32 newWorkspaces);
306 			void				_BringWindowsToFront(WindowList& windows,
307 									int32 list, bool wereVisible);
308 			Window*				_LastFocusSubsetWindow(Window* window);
309 			bool				_CheckSendFakeMouseMoved(
310 									const Window* lastWindowUnderMouse);
311 			void				_SendFakeMouseMoved(Window* window = NULL);
312 
313 			Screen*				_DetermineScreenFor(BRect frame);
314 			void				_RebuildClippingForAllWindows(
315 									BRegion& stillAvailableOnScreen);
316 			void				_TriggerWindowRedrawing(
317 									BRegion& dirtyRegion, BRegion& exposeRegion);
318 			void				_SetBackground(BRegion& background);
319 
320 			status_t			_ActivateApp(team_id team);
321 
322 			void				_SuspendDirectFrameBufferAccess();
323 			void				_ResumeDirectFrameBufferAccess();
324 
325 			void				_ScreenChanged(Screen* screen);
326 			void				_SetCurrentWorkspaceConfiguration();
327 			void				_SetWorkspace(int32 index,
328 									bool moveFocusWindow = false);
329 
330 private:
331 	friend class DesktopSettings;
332 	friend class LockedDesktopSettings;
333 
334 			uid_t				fUserID;
335 			char*				fTargetScreen;
336 			::VirtualScreen		fVirtualScreen;
337 			ObjectDeleter<DesktopSettingsPrivate>
338 								fSettings;
339 			port_id				fMessagePort;
340 			::EventDispatcher	fEventDispatcher;
341 			area_id				fSharedReadOnlyArea;
342 			server_read_only_memory* fServerReadOnlyMemory;
343 
344 			BLocker				fApplicationsLock;
345 			BObjectList<ServerApp> fApplications;
346 
347 			sem_id				fShutdownSemaphore;
348 			int32				fShutdownCount;
349 
350 			::Workspace::Private fWorkspaces[kMaxWorkspaces];
351 			MultiLocker			fScreenLock;
352 			BLocker				fDirectScreenLock;
353 			team_id				fDirectScreenTeam;
354 			int32				fCurrentWorkspace;
355 			int32				fPreviousWorkspace;
356 
357 			WindowList			fAllWindows;
358 			WindowList			fSubsetWindows;
359 			WindowList			fFocusList;
360 			Window*				fLastWorkspaceFocus[kMaxWorkspaces];
361 
362 			BObjectList<WorkspacesView> fWorkspacesViews;
363 			BLocker				fWorkspacesLock;
364 
365 			CursorManager		fCursorManager;
366 			ServerCursorReference fCursor;
367 			ServerCursorReference fManagementCursor;
368 
369 			MultiLocker			fWindowLock;
370 
371 			BRegion				fBackgroundRegion;
372 			BRegion				fScreenRegion;
373 
374 			Window*				fMouseEventWindow;
375 			const Window*		fWindowUnderMouse;
376 			const Window*		fLockedFocusWindow;
377 			int32				fViewUnderMouse;
378 			BPoint				fLastMousePosition;
379 			int32				fLastMouseButtons;
380 
381 			Window*				fFocus;
382 			Window*				fFront;
383 			Window*				fBack;
384 
385 			StackAndTile		fStackAndTile;
386 
387 			BMessage			fPendingColors;
388 };
389 
390 #endif	// DESKTOP_H
391