1 /* 2 * Copyright 2001-2009, 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 */ 11 #ifndef DESKTOP_H 12 #define DESKTOP_H 13 14 15 #include "CursorManager.h" 16 #include "DesktopSettings.h" 17 #include "EventDispatcher.h" 18 #include "MessageLooper.h" 19 #include "Screen.h" 20 #include "ScreenManager.h" 21 #include "ServerCursor.h" 22 #include "VirtualScreen.h" 23 #include "WindowList.h" 24 #include "Workspace.h" 25 #include "WorkspacePrivate.h" 26 27 #include <ObjectList.h> 28 29 #include <Autolock.h> 30 #include <InterfaceDefs.h> 31 #include <List.h> 32 #include <Menu.h> 33 #include <Region.h> 34 #include <Window.h> 35 36 37 #define USE_MULTI_LOCKER 1 38 39 #if USE_MULTI_LOCKER 40 # include "MultiLocker.h" 41 #else 42 # include <Locker.h> 43 #endif 44 45 46 class BMessage; 47 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 MessageLooper, public ScreenOwner { 61 public: 62 Desktop(uid_t userID); 63 virtual ~Desktop(); 64 65 status_t Init(); 66 67 uid_t UserID() const { return fUserID; } 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 // Locking 78 #if USE_MULTI_LOCKER 79 bool LockSingleWindow() 80 { return fWindowLock.ReadLock(); } 81 void UnlockSingleWindow() 82 { fWindowLock.ReadUnlock(); } 83 84 bool LockAllWindows() 85 { return fWindowLock.WriteLock(); } 86 void UnlockAllWindows() 87 { fWindowLock.WriteUnlock(); } 88 89 const MultiLocker& WindowLocker() { return fWindowLock; } 90 #else // USE_MULTI_LOCKER 91 bool LockSingleWindow() 92 { return fWindowLock.Lock(); } 93 void UnlockSingleWindow() 94 { fWindowLock.Unlock(); } 95 96 bool LockAllWindows() 97 { return fWindowLock.Lock(); } 98 void UnlockAllWindows() 99 { fWindowLock.Unlock(); } 100 #endif // USE_MULTI_LOCKER 101 102 // Mouse and cursor methods 103 104 void SetCursor(ServerCursor* cursor); 105 ServerCursorReference Cursor() const; 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 MultiLocker& ScreenLocker() { return fScreenLock; } 129 130 status_t LockDirectScreen(team_id team); 131 status_t UnlockDirectScreen(team_id team); 132 133 const ::VirtualScreen& VirtualScreen() const 134 { return fVirtualScreen; } 135 DrawingEngine* GetDrawingEngine() const 136 { return fVirtualScreen.DrawingEngine(); } 137 ::HWInterface* HWInterface() const 138 { return fVirtualScreen.HWInterface(); } 139 140 // ScreenOwner implementation 141 virtual void ScreenRemoved(Screen* screen) {} 142 virtual void ScreenAdded(Screen* screen) {} 143 virtual bool ReleaseScreen(Screen* screen) { return false; } 144 145 // Workspace methods 146 147 void SetWorkspaceAsync(int32 index); 148 void SetWorkspace(int32 index); 149 int32 CurrentWorkspace() 150 { return fCurrentWorkspace; } 151 Workspace::Private& WorkspaceAt(int32 index) 152 { return fWorkspaces[index]; } 153 status_t SetWorkspacesLayout(int32 columns, int32 rows); 154 BRect WorkspaceFrame(int32 index) const; 155 156 void StoreWorkspaceConfiguration(int32 index); 157 158 void AddWorkspacesView(WorkspacesView* view); 159 void RemoveWorkspacesView(WorkspacesView* view); 160 161 // Window methods 162 163 void ActivateWindow(Window* window); 164 void SendWindowBehind(Window* window, 165 Window* behindOf = NULL); 166 167 void ShowWindow(Window* window); 168 void HideWindow(Window* window); 169 170 void MoveWindowBy(Window* window, float x, float y, 171 int32 workspace = -1); 172 void ResizeWindowBy(Window* window, float x, 173 float y); 174 bool SetWindowTabLocation(Window* window, 175 float location); 176 bool SetWindowDecoratorSettings(Window* window, 177 const BMessage& settings); 178 179 void SetWindowWorkspaces(Window* window, 180 uint32 workspaces); 181 182 void AddWindow(Window* window); 183 void RemoveWindow(Window* window); 184 185 bool AddWindowToSubset(Window* subset, 186 Window* window); 187 void RemoveWindowFromSubset(Window* subset, 188 Window* window); 189 190 void FontsChanged(Window* window); 191 192 void SetWindowLook(Window* window, window_look look); 193 void SetWindowFeel(Window* window, window_feel feel); 194 void SetWindowFlags(Window* window, uint32 flags); 195 void SetWindowTitle(Window* window, 196 const char* title); 197 198 Window* FocusWindow() const { return fFocus; } 199 Window* FrontWindow() const { return fFront; } 200 Window* BackWindow() const { return fBack; } 201 202 Window* WindowAt(BPoint where); 203 204 Window* MouseEventWindow() const 205 { return fMouseEventWindow; } 206 void SetMouseEventWindow(Window* window); 207 208 void SetViewUnderMouse(const Window* window, 209 int32 viewToken); 210 int32 ViewUnderMouse(const Window* window); 211 212 EventTarget* KeyboardEventTarget(); 213 214 void SetFocusWindow(Window* window = NULL); 215 void SetFocusLocked(const Window* window); 216 217 Window* FindWindowByClientToken(int32 token, 218 team_id teamID); 219 EventTarget* FindTarget(BMessenger& messenger); 220 221 void MarkDirty(BRegion& region); 222 void Redraw(); 223 void RedrawBackground(); 224 225 BRegion& BackgroundRegion() 226 { return fBackgroundRegion; } 227 228 void MinimizeApplication(team_id team); 229 void BringApplicationToFront(team_id team); 230 void WindowAction(int32 windowToken, int32 action); 231 232 void WriteWindowList(team_id team, 233 BPrivate::LinkSender& sender); 234 void WriteWindowInfo(int32 serverToken, 235 BPrivate::LinkSender& sender); 236 void WriteApplicationOrder(int32 workspace, 237 BPrivate::LinkSender& sender); 238 void WriteWindowOrder(int32 workspace, 239 BPrivate::LinkSender& sender); 240 241 private: 242 void _LaunchInputServer(); 243 void _GetLooperName(char* name, size_t size); 244 void _PrepareQuit(); 245 void _DispatchMessage(int32 code, 246 BPrivate::LinkReceiver &link); 247 248 WindowList& _CurrentWindows(); 249 WindowList& _Windows(int32 index); 250 251 void _UpdateFloating(int32 previousWorkspace = -1, 252 int32 nextWorkspace = -1, 253 Window* mouseEventWindow = NULL); 254 void _UpdateBack(); 255 void _UpdateFront(bool updateFloating = true); 256 void _UpdateFronts(bool updateFloating = true); 257 bool _WindowHasModal(Window* window); 258 259 void _WindowChanged(Window* window); 260 void _WindowRemoved(Window* window); 261 262 void _ShowWindow(Window* window, 263 bool affectsOtherWindows = true); 264 void _HideWindow(Window* window); 265 266 void _UpdateSubsetWorkspaces(Window* window, 267 int32 previousIndex = -1, 268 int32 newIndex = -1); 269 void _ChangeWindowWorkspaces(Window* window, 270 uint32 oldWorkspaces, uint32 newWorkspaces); 271 void _BringWindowsToFront(WindowList& windows, 272 int32 list, bool wereVisible); 273 Window* _LastFocusSubsetWindow(Window* window); 274 void _SendFakeMouseMoved(Window* window = NULL); 275 276 Screen* _DetermineScreenFor(BRect frame); 277 void _RebuildClippingForAllWindows( 278 BRegion& stillAvailableOnScreen); 279 void _TriggerWindowRedrawing( 280 BRegion& newDirtyRegion); 281 void _SetBackground(BRegion& background); 282 void _RebuildAndRedrawAfterWindowChange( 283 Window* window, BRegion& dirty); 284 285 status_t _ActivateApp(team_id team); 286 287 void _SuspendDirectFrameBufferAccess(); 288 void _ResumeDirectFrameBufferAccess(); 289 290 void _ScreenChanged(Screen* screen); 291 void _SetCurrentWorkspaceConfiguration(); 292 void _SetWorkspace(int32 index); 293 294 private: 295 friend class DesktopSettings; 296 friend class LockedDesktopSettings; 297 298 uid_t fUserID; 299 ::VirtualScreen fVirtualScreen; 300 DesktopSettingsPrivate* fSettings; 301 port_id fMessagePort; 302 ::EventDispatcher fEventDispatcher; 303 port_id fInputPort; 304 area_id fSharedReadOnlyArea; 305 server_read_only_memory* fServerReadOnlyMemory; 306 307 BLocker fApplicationsLock; 308 BObjectList<ServerApp> fApplications; 309 310 sem_id fShutdownSemaphore; 311 int32 fShutdownCount; 312 313 ::Workspace::Private fWorkspaces[kMaxWorkspaces]; 314 MultiLocker fScreenLock; 315 BLocker fDirectScreenLock; 316 team_id fDirectScreenTeam; 317 int32 fCurrentWorkspace; 318 int32 fPreviousWorkspace; 319 320 WindowList fAllWindows; 321 WindowList fSubsetWindows; 322 WindowList fFocusList; 323 324 BObjectList<WorkspacesView> fWorkspacesViews; 325 BLocker fWorkspacesLock; 326 327 CursorManager fCursorManager; 328 329 #if USE_MULTI_LOCKER 330 MultiLocker fWindowLock; 331 #else 332 BLocker fWindowLock; 333 #endif 334 335 BRegion fBackgroundRegion; 336 BRegion fScreenRegion; 337 338 Window* fMouseEventWindow; 339 const Window* fWindowUnderMouse; 340 const Window* fLockedFocusWindow; 341 int32 fViewUnderMouse; 342 BPoint fLastMousePosition; 343 int32 fLastMouseButtons; 344 345 Window* fFocus; 346 Window* fFront; 347 Window* fBack; 348 }; 349 350 #endif // DESKTOP_H 351