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