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