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