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 UserID()75 uid_t UserID() const { return fUserID; } TargetScreen()76 const char* TargetScreen() { return fTargetScreen; } MessagePort()77 virtual port_id MessagePort() const { return fMessagePort; } SharedReadOnlyArea()78 area_id SharedReadOnlyArea() const 79 { return fSharedReadOnlyArea; } 80 EventDispatcher()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 LockSingleWindow()92 bool LockSingleWindow() 93 { return fWindowLock.ReadLock(); } UnlockSingleWindow()94 void UnlockSingleWindow() 95 { fWindowLock.ReadUnlock(); } 96 LockAllWindows()97 bool LockAllWindows() 98 { return fWindowLock.WriteLock(); } UnlockAllWindows()99 void UnlockAllWindows() 100 { fWindowLock.WriteUnlock(); } 101 WindowLocker()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 GetCursorManager()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 ScreenLocker()134 MultiLocker& ScreenLocker() { return fScreenLock; } 135 136 status_t LockDirectScreen(team_id team); 137 status_t UnlockDirectScreen(team_id team); 138 VirtualScreen()139 const ::VirtualScreen& VirtualScreen() const 140 { return fVirtualScreen; } GetDrawingEngine()141 DrawingEngine* GetDrawingEngine() const 142 { return fVirtualScreen.DrawingEngine(); } HWInterface()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 ScreenRemoved(Screen * screen)152 virtual void ScreenRemoved(Screen* screen) {} ScreenAdded(Screen * screen)153 virtual void ScreenAdded(Screen* screen) {} 154 virtual void ScreenChanged(Screen* screen); ReleaseScreen(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); CurrentWorkspace()163 int32 CurrentWorkspace() 164 { return fCurrentWorkspace; } WorkspaceAt(int32 index)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 FocusWindow()220 Window* FocusWindow() const { return fFocus; } FrontWindow()221 Window* FrontWindow() const { return fFront; } BackWindow()222 Window* BackWindow() const { return fBack; } 223 224 Window* WindowAt(BPoint where); 225 MouseEventWindow()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& dirtyRegion, BRegion& exposeRegion); MarkDirty(BRegion & region)244 void MarkDirty(BRegion& region) 245 { return MarkDirty(region, region); } 246 void Redraw(); 247 void RedrawBackground(); 248 249 bool ReloadDecor(DecorAddOn* oldDecor); 250 BackgroundRegion()251 BRegion& BackgroundRegion() 252 { return fBackgroundRegion; } 253 254 void MinimizeApplication(team_id team); 255 void BringApplicationToFront(team_id team); 256 void WindowAction(int32 windowToken, int32 action); 257 258 void WriteWindowList(team_id team, 259 BPrivate::LinkSender& sender); 260 void WriteWindowInfo(int32 serverToken, 261 BPrivate::LinkSender& sender); 262 void WriteApplicationOrder(int32 workspace, 263 BPrivate::LinkSender& sender); 264 void WriteWindowOrder(int32 workspace, 265 BPrivate::LinkSender& sender); 266 267 //! The window lock must be held when accessing a window list! 268 WindowList& CurrentWindows(); 269 WindowList& AllWindows(); 270 271 Window* WindowForClientLooperPort(port_id port); 272 GetStackAndTile()273 StackAndTile* GetStackAndTile() { return &fStackAndTile; } 274 private: 275 WindowList& _Windows(int32 index); 276 277 void _FlushPendingColors(); 278 279 void _LaunchInputServer(); 280 void _GetLooperName(char* name, size_t size); 281 void _PrepareQuit(); 282 void _DispatchMessage(int32 code, 283 BPrivate::LinkReceiver &link); 284 285 void _UpdateFloating(int32 previousWorkspace = -1, 286 int32 nextWorkspace = -1, 287 Window* mouseEventWindow = NULL); 288 void _UpdateBack(); 289 void _UpdateFront(bool updateFloating = true); 290 void _UpdateFronts(bool updateFloating = true); 291 bool _WindowHasModal(Window* window) const; 292 bool _WindowCanHaveFocus(Window* window) const; 293 294 void _WindowChanged(Window* window); 295 void _WindowRemoved(Window* window); 296 297 void _ShowWindow(Window* window, 298 bool affectsOtherWindows = true); 299 void _HideWindow(Window* window); 300 301 void _UpdateSubsetWorkspaces(Window* window, 302 int32 previousIndex = -1, 303 int32 newIndex = -1); 304 void _ChangeWindowWorkspaces(Window* window, 305 uint32 oldWorkspaces, uint32 newWorkspaces); 306 void _BringWindowsToFront(WindowList& windows, 307 int32 list, bool wereVisible); 308 Window* _LastFocusSubsetWindow(Window* window); 309 bool _CheckSendFakeMouseMoved( 310 const Window* lastWindowUnderMouse); 311 void _SendFakeMouseMoved(Window* window = NULL); 312 313 Screen* _DetermineScreenFor(BRect frame); 314 void _RebuildClippingForAllWindows( 315 BRegion& stillAvailableOnScreen); 316 void _TriggerWindowRedrawing( 317 BRegion& dirtyRegion, BRegion& exposeRegion); 318 void _SetBackground(BRegion& background); 319 320 status_t _ActivateApp(team_id team); 321 322 void _SuspendDirectFrameBufferAccess(); 323 void _ResumeDirectFrameBufferAccess(); 324 325 void _ScreenChanged(Screen* screen); 326 void _SetCurrentWorkspaceConfiguration(); 327 void _SetWorkspace(int32 index, 328 bool moveFocusWindow = false); 329 330 private: 331 friend class DesktopSettings; 332 friend class LockedDesktopSettings; 333 334 uid_t fUserID; 335 char* fTargetScreen; 336 ::VirtualScreen fVirtualScreen; 337 ObjectDeleter<DesktopSettingsPrivate> 338 fSettings; 339 port_id fMessagePort; 340 ::EventDispatcher fEventDispatcher; 341 area_id fSharedReadOnlyArea; 342 server_read_only_memory* fServerReadOnlyMemory; 343 344 BLocker fApplicationsLock; 345 BObjectList<ServerApp> fApplications; 346 347 sem_id fShutdownSemaphore; 348 int32 fShutdownCount; 349 350 ::Workspace::Private fWorkspaces[kMaxWorkspaces]; 351 MultiLocker fScreenLock; 352 BLocker fDirectScreenLock; 353 team_id fDirectScreenTeam; 354 int32 fCurrentWorkspace; 355 int32 fPreviousWorkspace; 356 357 WindowList fAllWindows; 358 WindowList fSubsetWindows; 359 WindowList fFocusList; 360 Window* fLastWorkspaceFocus[kMaxWorkspaces]; 361 362 BObjectList<WorkspacesView> fWorkspacesViews; 363 BLocker fWorkspacesLock; 364 365 CursorManager fCursorManager; 366 ServerCursorReference fCursor; 367 ServerCursorReference fManagementCursor; 368 369 MultiLocker fWindowLock; 370 371 BRegion fBackgroundRegion; 372 BRegion fScreenRegion; 373 374 Window* fMouseEventWindow; 375 const Window* fWindowUnderMouse; 376 const Window* fLockedFocusWindow; 377 int32 fViewUnderMouse; 378 BPoint fLastMousePosition; 379 int32 fLastMouseButtons; 380 381 Window* fFocus; 382 Window* fFront; 383 Window* fBack; 384 385 StackAndTile fStackAndTile; 386 387 BMessage fPendingColors; 388 }; 389 390 #endif // DESKTOP_H 391