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