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