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