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