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 * Brecht Machiels <brecht@mos6581.org> 11 */ 12 #ifndef DESKTOP_H 13 #define DESKTOP_H 14 15 16 #include "CursorManager.h" 17 #include "DesktopSettings.h" 18 #include "EventDispatcher.h" 19 #include "MessageLooper.h" 20 #include "Screen.h" 21 #include "ScreenManager.h" 22 #include "ServerCursor.h" 23 #include "VirtualScreen.h" 24 #include "WindowList.h" 25 #include "Workspace.h" 26 #include "WorkspacePrivate.h" 27 28 #include <ObjectList.h> 29 30 #include <Autolock.h> 31 #include <InterfaceDefs.h> 32 #include <List.h> 33 #include <Menu.h> 34 #include <Region.h> 35 #include <Window.h> 36 37 38 #define USE_MULTI_LOCKER 1 39 40 #if USE_MULTI_LOCKER 41 # include "MultiLocker.h" 42 #else 43 # include <Locker.h> 44 #endif 45 46 47 class BMessage; 48 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 MessageLooper, public ScreenOwner { 62 public: 63 Desktop(uid_t userID, const char* targetScreen); 64 virtual ~Desktop(); 65 66 status_t Init(); 67 68 uid_t UserID() const { return fUserID; } 69 const char* TargetScreen() { return fTargetScreen; } 70 virtual port_id MessagePort() const { return fMessagePort; } 71 area_id SharedReadOnlyArea() const 72 { return fSharedReadOnlyArea; } 73 74 ::EventDispatcher& EventDispatcher() { return fEventDispatcher; } 75 76 void BroadcastToAllApps(int32 code); 77 void BroadcastToAllWindows(int32 code); 78 79 // Locking 80 #if USE_MULTI_LOCKER 81 bool LockSingleWindow() 82 { return fWindowLock.ReadLock(); } 83 void UnlockSingleWindow() 84 { fWindowLock.ReadUnlock(); } 85 86 bool LockAllWindows() 87 { return fWindowLock.WriteLock(); } 88 void UnlockAllWindows() 89 { fWindowLock.WriteUnlock(); } 90 91 const MultiLocker& WindowLocker() { return fWindowLock; } 92 #else // USE_MULTI_LOCKER 93 bool LockSingleWindow() 94 { return fWindowLock.Lock(); } 95 void UnlockSingleWindow() 96 { fWindowLock.Unlock(); } 97 98 bool LockAllWindows() 99 { return fWindowLock.Lock(); } 100 void UnlockAllWindows() 101 { fWindowLock.Unlock(); } 102 #endif // USE_MULTI_LOCKER 103 104 // Mouse and cursor methods 105 106 void SetCursor(ServerCursor* cursor); 107 ServerCursorReference Cursor() const; 108 void SetLastMouseState(const BPoint& position, 109 int32 buttons, Window* windowUnderMouse); 110 // for use by the mouse filter only 111 // both mouse position calls require 112 // the Desktop object to be locked 113 // already 114 void GetLastMouseState(BPoint* position, 115 int32* buttons) const; 116 // for use by ServerWindow 117 118 CursorManager& GetCursorManager() { return fCursorManager; } 119 120 // Screen and drawing related methods 121 122 status_t SetScreenMode(int32 workspace, int32 id, 123 const display_mode& mode, bool makeDefault); 124 status_t GetScreenMode(int32 workspace, int32 id, 125 display_mode& mode); 126 status_t GetScreenFrame(int32 workspace, int32 id, 127 BRect& frame); 128 void RevertScreenModes(uint32 workspaces); 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 // ScreenOwner implementation 143 virtual void ScreenRemoved(Screen* screen) {} 144 virtual void ScreenAdded(Screen* screen) {} 145 virtual bool ReleaseScreen(Screen* screen) { return false; } 146 147 // Workspace methods 148 149 void SetWorkspaceAsync(int32 index); 150 void SetWorkspace(int32 index); 151 int32 CurrentWorkspace() 152 { return fCurrentWorkspace; } 153 Workspace::Private& WorkspaceAt(int32 index) 154 { return fWorkspaces[index]; } 155 status_t SetWorkspacesLayout(int32 columns, int32 rows); 156 BRect WorkspaceFrame(int32 index) const; 157 158 void StoreWorkspaceConfiguration(int32 index); 159 160 void AddWorkspacesView(WorkspacesView* view); 161 void RemoveWorkspacesView(WorkspacesView* view); 162 163 // Window methods 164 165 void SelectWindow(Window* window); 166 void ActivateWindow(Window* window); 167 void SendWindowBehind(Window* window, 168 Window* behindOf = NULL); 169 170 void ShowWindow(Window* window); 171 void HideWindow(Window* window); 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); 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 BRegion& BackgroundRegion() 229 { return fBackgroundRegion; } 230 231 void MinimizeApplication(team_id team); 232 void BringApplicationToFront(team_id team); 233 void WindowAction(int32 windowToken, int32 action); 234 235 void WriteWindowList(team_id team, 236 BPrivate::LinkSender& sender); 237 void WriteWindowInfo(int32 serverToken, 238 BPrivate::LinkSender& sender); 239 void WriteApplicationOrder(int32 workspace, 240 BPrivate::LinkSender& sender); 241 void WriteWindowOrder(int32 workspace, 242 BPrivate::LinkSender& sender); 243 244 private: 245 void _LaunchInputServer(); 246 void _GetLooperName(char* name, size_t size); 247 void _PrepareQuit(); 248 void _DispatchMessage(int32 code, 249 BPrivate::LinkReceiver &link); 250 251 WindowList& _CurrentWindows(); 252 WindowList& _Windows(int32 index); 253 254 void _UpdateFloating(int32 previousWorkspace = -1, 255 int32 nextWorkspace = -1, 256 Window* mouseEventWindow = NULL); 257 void _UpdateBack(); 258 void _UpdateFront(bool updateFloating = true); 259 void _UpdateFronts(bool updateFloating = true); 260 bool _WindowHasModal(Window* window); 261 262 void _WindowChanged(Window* window); 263 void _WindowRemoved(Window* window); 264 265 void _ShowWindow(Window* window, 266 bool affectsOtherWindows = true); 267 void _HideWindow(Window* window); 268 269 void _UpdateSubsetWorkspaces(Window* window, 270 int32 previousIndex = -1, 271 int32 newIndex = -1); 272 void _ChangeWindowWorkspaces(Window* window, 273 uint32 oldWorkspaces, uint32 newWorkspaces); 274 void _BringWindowsToFront(WindowList& windows, 275 int32 list, bool wereVisible); 276 Window* _LastFocusSubsetWindow(Window* window); 277 void _SendFakeMouseMoved(Window* window = NULL); 278 279 Screen* _DetermineScreenFor(BRect frame); 280 void _RebuildClippingForAllWindows( 281 BRegion& stillAvailableOnScreen); 282 void _TriggerWindowRedrawing( 283 BRegion& newDirtyRegion); 284 void _SetBackground(BRegion& background); 285 void _RebuildAndRedrawAfterWindowChange( 286 Window* window, BRegion& dirty); 287 288 status_t _ActivateApp(team_id team); 289 290 void _SuspendDirectFrameBufferAccess(); 291 void _ResumeDirectFrameBufferAccess(); 292 293 void _ScreenChanged(Screen* screen); 294 void _SetCurrentWorkspaceConfiguration(); 295 void _SetWorkspace(int32 index); 296 297 private: 298 friend class DesktopSettings; 299 friend class LockedDesktopSettings; 300 301 uid_t fUserID; 302 const char* fTargetScreen; 303 ::VirtualScreen fVirtualScreen; 304 DesktopSettingsPrivate* fSettings; 305 port_id fMessagePort; 306 ::EventDispatcher fEventDispatcher; 307 port_id fInputPort; 308 area_id fSharedReadOnlyArea; 309 server_read_only_memory* fServerReadOnlyMemory; 310 311 BLocker fApplicationsLock; 312 BObjectList<ServerApp> fApplications; 313 314 sem_id fShutdownSemaphore; 315 int32 fShutdownCount; 316 317 ::Workspace::Private fWorkspaces[kMaxWorkspaces]; 318 MultiLocker fScreenLock; 319 BLocker fDirectScreenLock; 320 team_id fDirectScreenTeam; 321 int32 fCurrentWorkspace; 322 int32 fPreviousWorkspace; 323 324 WindowList fAllWindows; 325 WindowList fSubsetWindows; 326 WindowList fFocusList; 327 328 BObjectList<WorkspacesView> fWorkspacesViews; 329 BLocker fWorkspacesLock; 330 331 CursorManager fCursorManager; 332 333 #if USE_MULTI_LOCKER 334 MultiLocker fWindowLock; 335 #else 336 BLocker fWindowLock; 337 #endif 338 339 BRegion fBackgroundRegion; 340 BRegion fScreenRegion; 341 342 Window* fMouseEventWindow; 343 const Window* fWindowUnderMouse; 344 const Window* fLockedFocusWindow; 345 int32 fViewUnderMouse; 346 BPoint fLastMousePosition; 347 int32 fLastMouseButtons; 348 349 Window* fFocus; 350 Window* fFront; 351 Window* fBack; 352 }; 353 354 #endif // DESKTOP_H 355