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 49 class BMessage; 50 51 class DecorAddOn; 52 class DrawingEngine; 53 class HWInterface; 54 class ServerApp; 55 class Window; 56 class WorkspacesView; 57 struct server_read_only_memory; 58 59 namespace BPrivate { 60 class LinkSender; 61 }; 62 63 64 class Desktop : public DesktopObservable, public MessageLooper, 65 public ScreenOwner { 66 public: 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; } 272 private: 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 328 private: 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 389