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
49class BMessage;
50
51class DecorAddOn;
52class DrawingEngine;
53class HWInterface;
54class ServerApp;
55class Window;
56class WorkspacesView;
57struct server_read_only_memory;
58
59namespace BPrivate {
60	class LinkSender;
61};
62
63
64class Desktop : public DesktopObservable, public MessageLooper,
65	public ScreenOwner {
66public:
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; }
274private:
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
330private:
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