xref: /haiku/src/servers/app/Desktop.h (revision 508f54795f39c3e7552d87c95aae9dd8ec6f505b)
1 /*
2  * Copyright 2001-2009, 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  */
12 #ifndef DESKTOP_H
13 #define DESKTOP_H
14 
15 
16 #include "CursorManager.h"
17 #include "DesktopSettings.h"
18 #include "EventDispatcher.h"
19 #include "MessageLooper.h"
20 #include "Screen.h"
21 #include "ScreenManager.h"
22 #include "ServerCursor.h"
23 #include "VirtualScreen.h"
24 #include "WindowList.h"
25 #include "Workspace.h"
26 #include "WorkspacePrivate.h"
27 
28 #include <ObjectList.h>
29 
30 #include <Autolock.h>
31 #include <InterfaceDefs.h>
32 #include <List.h>
33 #include <Menu.h>
34 #include <Region.h>
35 #include <Window.h>
36 
37 
38 #define USE_MULTI_LOCKER 1
39 
40 #if USE_MULTI_LOCKER
41 #  include "MultiLocker.h"
42 #else
43 #  include <Locker.h>
44 #endif
45 
46 
47 class BMessage;
48 
49 class DrawingEngine;
50 class HWInterface;
51 class ServerApp;
52 class Window;
53 class WorkspacesView;
54 struct server_read_only_memory;
55 
56 namespace BPrivate {
57 	class LinkSender;
58 };
59 
60 
61 class Desktop : public MessageLooper, public ScreenOwner {
62 public:
63 								Desktop(uid_t userID, const char* targetScreen);
64 	virtual						~Desktop();
65 
66 			status_t			Init();
67 
68 			uid_t				UserID() const { return fUserID; }
69 			const char*			TargetScreen() { return fTargetScreen; }
70 	virtual port_id				MessagePort() const { return fMessagePort; }
71 			area_id				SharedReadOnlyArea() const
72 									{ return fSharedReadOnlyArea; }
73 
74 			::EventDispatcher&	EventDispatcher() { return fEventDispatcher; }
75 
76 			void				BroadcastToAllApps(int32 code);
77 			void				BroadcastToAllWindows(int32 code);
78 
79 	// Locking
80 #if USE_MULTI_LOCKER
81 			bool				LockSingleWindow()
82 									{ return fWindowLock.ReadLock(); }
83 			void				UnlockSingleWindow()
84 									{ fWindowLock.ReadUnlock(); }
85 
86 			bool				LockAllWindows()
87 									{ return fWindowLock.WriteLock(); }
88 			void				UnlockAllWindows()
89 									{ fWindowLock.WriteUnlock(); }
90 
91 			const MultiLocker&	WindowLocker() { return fWindowLock; }
92 #else // USE_MULTI_LOCKER
93 			bool				LockSingleWindow()
94 									{ return fWindowLock.Lock(); }
95 			void				UnlockSingleWindow()
96 									{ fWindowLock.Unlock(); }
97 
98 			bool				LockAllWindows()
99 									{ return fWindowLock.Lock(); }
100 			void				UnlockAllWindows()
101 									{ fWindowLock.Unlock(); }
102 #endif // USE_MULTI_LOCKER
103 
104 	// Mouse and cursor methods
105 
106 			void				SetCursor(ServerCursor* cursor);
107 			ServerCursorReference Cursor() const;
108 			void				SetLastMouseState(const BPoint& position,
109 									int32 buttons, Window* windowUnderMouse);
110 									// for use by the mouse filter only
111 									// both mouse position calls require
112 									// the Desktop object to be locked
113 									// already
114 			void				GetLastMouseState(BPoint* position,
115 									int32* buttons) const;
116 									// for use by ServerWindow
117 
118 			CursorManager&		GetCursorManager() { return fCursorManager; }
119 
120 	// Screen and drawing related methods
121 
122 			status_t			SetScreenMode(int32 workspace, int32 id,
123 									const display_mode& mode, bool makeDefault);
124 			status_t			GetScreenMode(int32 workspace, int32 id,
125 									display_mode& mode);
126 			status_t			GetScreenFrame(int32 workspace, int32 id,
127 									BRect& frame);
128 			void				RevertScreenModes(uint32 workspaces);
129 
130 			MultiLocker&		ScreenLocker() { return fScreenLock; }
131 
132 			status_t			LockDirectScreen(team_id team);
133 			status_t			UnlockDirectScreen(team_id team);
134 
135 			const ::VirtualScreen& VirtualScreen() const
136 									{ return fVirtualScreen; }
137 			DrawingEngine*		GetDrawingEngine() const
138 									{ return fVirtualScreen.DrawingEngine(); }
139 			::HWInterface*		HWInterface() const
140 									{ return fVirtualScreen.HWInterface(); }
141 
142 	// ScreenOwner implementation
143 	virtual	void				ScreenRemoved(Screen* screen) {}
144 	virtual	void				ScreenAdded(Screen* screen) {}
145 	virtual	bool				ReleaseScreen(Screen* screen) { return false; }
146 
147 	// Workspace methods
148 
149 			void				SetWorkspaceAsync(int32 index,
150 									bool moveFocusWindow = false);
151 			void				SetWorkspace(int32 index,
152 									bool moveFocusWindow = false);
153 			int32				CurrentWorkspace()
154 									{ return fCurrentWorkspace; }
155 			Workspace::Private&	WorkspaceAt(int32 index)
156 									{ return fWorkspaces[index]; }
157 			status_t			SetWorkspacesLayout(int32 columns, int32 rows);
158 			BRect				WorkspaceFrame(int32 index) const;
159 
160 			void				StoreWorkspaceConfiguration(int32 index);
161 
162 			void				AddWorkspacesView(WorkspacesView* view);
163 			void				RemoveWorkspacesView(WorkspacesView* view);
164 
165 	// Window methods
166 
167 			void				SelectWindow(Window* window);
168 			void				ActivateWindow(Window* window);
169 			void				SendWindowBehind(Window* window,
170 									Window* behindOf = NULL);
171 
172 			void				ShowWindow(Window* window);
173 			void				HideWindow(Window* window);
174 
175 			void				MoveWindowBy(Window* window, float x, float y,
176 									int32 workspace = -1);
177 			void				ResizeWindowBy(Window* window, float x,
178 									float y);
179 			bool				SetWindowTabLocation(Window* window,
180 									float location);
181 			bool				SetWindowDecoratorSettings(Window* window,
182 									const BMessage& settings);
183 
184 			void				SetWindowWorkspaces(Window* window,
185 									uint32 workspaces);
186 
187 			void				AddWindow(Window* window);
188 			void				RemoveWindow(Window* window);
189 
190 			bool				AddWindowToSubset(Window* subset,
191 									Window* window);
192 			void				RemoveWindowFromSubset(Window* subset,
193 									Window* window);
194 
195 			void				FontsChanged(Window* window);
196 
197 			void				SetWindowLook(Window* window, window_look look);
198 			void				SetWindowFeel(Window* window, window_feel feel);
199 			void				SetWindowFlags(Window* window, uint32 flags);
200 			void				SetWindowTitle(Window* window,
201 									const char* title);
202 
203 			Window*				FocusWindow() const { return fFocus; }
204 			Window*				FrontWindow() const { return fFront; }
205 			Window*				BackWindow() const { return fBack; }
206 
207 			Window*				WindowAt(BPoint where);
208 
209 			Window*				MouseEventWindow() const
210 									{ return fMouseEventWindow; }
211 			void				SetMouseEventWindow(Window* window);
212 
213 			void				SetViewUnderMouse(const Window* window,
214 									int32 viewToken);
215 			int32				ViewUnderMouse(const Window* window);
216 
217 			EventTarget*		KeyboardEventTarget();
218 
219 			void				SetFocusWindow(Window* window = NULL);
220 			void				SetFocusLocked(const Window* window);
221 
222 			Window*				FindWindowByClientToken(int32 token,
223 									team_id teamID);
224 			EventTarget*		FindTarget(BMessenger& messenger);
225 
226 			void				MarkDirty(BRegion& region);
227 			void				Redraw();
228 			void				RedrawBackground();
229 
230 			BRegion&			BackgroundRegion()
231 									{ return fBackgroundRegion; }
232 
233 			void				MinimizeApplication(team_id team);
234 			void				BringApplicationToFront(team_id team);
235 			void				WindowAction(int32 windowToken, int32 action);
236 
237 			void				WriteWindowList(team_id team,
238 									BPrivate::LinkSender& sender);
239 			void				WriteWindowInfo(int32 serverToken,
240 									BPrivate::LinkSender& sender);
241 			void				WriteApplicationOrder(int32 workspace,
242 									BPrivate::LinkSender& sender);
243 			void				WriteWindowOrder(int32 workspace,
244 									BPrivate::LinkSender& sender);
245 
246 private:
247 			void				_LaunchInputServer();
248 			void				_GetLooperName(char* name, size_t size);
249 			void				_PrepareQuit();
250 			void				_DispatchMessage(int32 code,
251 									BPrivate::LinkReceiver &link);
252 
253 			WindowList&			_CurrentWindows();
254 			WindowList&			_Windows(int32 index);
255 
256 			void				_UpdateFloating(int32 previousWorkspace = -1,
257 									int32 nextWorkspace = -1,
258 									Window* mouseEventWindow = NULL);
259 			void				_UpdateBack();
260 			void				_UpdateFront(bool updateFloating = true);
261 			void				_UpdateFronts(bool updateFloating = true);
262 			bool				_WindowHasModal(Window* window);
263 
264 			void				_WindowChanged(Window* window);
265 			void				_WindowRemoved(Window* window);
266 
267 			void				_ShowWindow(Window* window,
268 									bool affectsOtherWindows = true);
269 			void				_HideWindow(Window* window);
270 
271 			void				_UpdateSubsetWorkspaces(Window* window,
272 									int32 previousIndex = -1,
273 									int32 newIndex = -1);
274 			void				_ChangeWindowWorkspaces(Window* window,
275 									uint32 oldWorkspaces, uint32 newWorkspaces);
276 			void				_BringWindowsToFront(WindowList& windows,
277 									int32 list, bool wereVisible);
278 			Window*				_LastFocusSubsetWindow(Window* window);
279 			void				_SendFakeMouseMoved(Window* window = NULL);
280 
281 			Screen*				_DetermineScreenFor(BRect frame);
282 			void				_RebuildClippingForAllWindows(
283 									BRegion& stillAvailableOnScreen);
284 			void				_TriggerWindowRedrawing(
285 									BRegion& newDirtyRegion);
286 			void				_SetBackground(BRegion& background);
287 			void				_RebuildAndRedrawAfterWindowChange(
288 									Window* window, BRegion& dirty);
289 
290 			status_t			_ActivateApp(team_id team);
291 
292 			void				_SuspendDirectFrameBufferAccess();
293 			void				_ResumeDirectFrameBufferAccess();
294 
295 			void				_ScreenChanged(Screen* screen);
296 			void				_SetCurrentWorkspaceConfiguration();
297 			void				_SetWorkspace(int32 index,
298 									bool moveFocusWindow = false);
299 
300 private:
301 	friend class DesktopSettings;
302 	friend class LockedDesktopSettings;
303 
304 			uid_t				fUserID;
305 			const char*			fTargetScreen;
306 			::VirtualScreen		fVirtualScreen;
307 			DesktopSettingsPrivate*	fSettings;
308 			port_id				fMessagePort;
309 			::EventDispatcher	fEventDispatcher;
310 			port_id				fInputPort;
311 			area_id				fSharedReadOnlyArea;
312 			server_read_only_memory* fServerReadOnlyMemory;
313 
314 			BLocker				fApplicationsLock;
315 			BObjectList<ServerApp> fApplications;
316 
317 			sem_id				fShutdownSemaphore;
318 			int32				fShutdownCount;
319 
320 			::Workspace::Private fWorkspaces[kMaxWorkspaces];
321 			MultiLocker			fScreenLock;
322 			BLocker				fDirectScreenLock;
323 			team_id				fDirectScreenTeam;
324 			int32				fCurrentWorkspace;
325 			int32				fPreviousWorkspace;
326 
327 			WindowList			fAllWindows;
328 			WindowList			fSubsetWindows;
329 			WindowList			fFocusList;
330 			Window*				fLastWorkspaceFocus[kMaxWorkspaces];
331 
332 			BObjectList<WorkspacesView> fWorkspacesViews;
333 			BLocker				fWorkspacesLock;
334 
335 			CursorManager		fCursorManager;
336 
337 #if USE_MULTI_LOCKER
338 			MultiLocker			fWindowLock;
339 #else
340 			BLocker				fWindowLock;
341 #endif
342 
343 			BRegion				fBackgroundRegion;
344 			BRegion				fScreenRegion;
345 
346 			Window*				fMouseEventWindow;
347 			const Window*		fWindowUnderMouse;
348 			const Window*		fLockedFocusWindow;
349 			int32				fViewUnderMouse;
350 			BPoint				fLastMousePosition;
351 			int32				fLastMouseButtons;
352 
353 			Window*				fFocus;
354 			Window*				fFront;
355 			Window*				fBack;
356 };
357 
358 #endif	// DESKTOP_H
359