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