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 bool moveFocusWindow = false); 151 void SetWorkspace(int32 index, 152 bool moveFocusWindow = false); 153 int32 CurrentWorkspace() 154 { return fCurrentWorkspace; } 155 Workspace::Private& WorkspaceAt(int32 index) 156 { return fWorkspaces[index]; } 157 status_t SetWorkspacesLayout(int32 columns, int32 rows); 158 BRect WorkspaceFrame(int32 index) const; 159 160 void StoreWorkspaceConfiguration(int32 index); 161 162 void AddWorkspacesView(WorkspacesView* view); 163 void RemoveWorkspacesView(WorkspacesView* view); 164 165 // Window methods 166 167 void SelectWindow(Window* window); 168 void ActivateWindow(Window* window); 169 void SendWindowBehind(Window* window, 170 Window* behindOf = NULL); 171 172 void ShowWindow(Window* window); 173 void HideWindow(Window* window); 174 175 void MoveWindowBy(Window* window, float x, float y, 176 int32 workspace = -1); 177 void ResizeWindowBy(Window* window, float x, 178 float y); 179 bool SetWindowTabLocation(Window* window, 180 float location); 181 bool SetWindowDecoratorSettings(Window* window, 182 const BMessage& settings); 183 184 void SetWindowWorkspaces(Window* window, 185 uint32 workspaces); 186 187 void AddWindow(Window* window); 188 void RemoveWindow(Window* window); 189 190 bool AddWindowToSubset(Window* subset, 191 Window* window); 192 void RemoveWindowFromSubset(Window* subset, 193 Window* window); 194 195 void FontsChanged(Window* window); 196 197 void SetWindowLook(Window* window, window_look look); 198 void SetWindowFeel(Window* window, window_feel feel); 199 void SetWindowFlags(Window* window, uint32 flags); 200 void SetWindowTitle(Window* window, 201 const char* title); 202 203 Window* FocusWindow() const { return fFocus; } 204 Window* FrontWindow() const { return fFront; } 205 Window* BackWindow() const { return fBack; } 206 207 Window* WindowAt(BPoint where); 208 209 Window* MouseEventWindow() const 210 { return fMouseEventWindow; } 211 void SetMouseEventWindow(Window* window); 212 213 void SetViewUnderMouse(const Window* window, 214 int32 viewToken); 215 int32 ViewUnderMouse(const Window* window); 216 217 EventTarget* KeyboardEventTarget(); 218 219 void SetFocusWindow(Window* window = NULL); 220 void SetFocusLocked(const Window* window); 221 222 Window* FindWindowByClientToken(int32 token, 223 team_id teamID); 224 EventTarget* FindTarget(BMessenger& messenger); 225 226 void MarkDirty(BRegion& region); 227 void Redraw(); 228 void RedrawBackground(); 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 private: 247 void _LaunchInputServer(); 248 void _GetLooperName(char* name, size_t size); 249 void _PrepareQuit(); 250 void _DispatchMessage(int32 code, 251 BPrivate::LinkReceiver &link); 252 253 WindowList& _CurrentWindows(); 254 WindowList& _Windows(int32 index); 255 256 void _UpdateFloating(int32 previousWorkspace = -1, 257 int32 nextWorkspace = -1, 258 Window* mouseEventWindow = NULL); 259 void _UpdateBack(); 260 void _UpdateFront(bool updateFloating = true); 261 void _UpdateFronts(bool updateFloating = true); 262 bool _WindowHasModal(Window* window); 263 264 void _WindowChanged(Window* window); 265 void _WindowRemoved(Window* window); 266 267 void _ShowWindow(Window* window, 268 bool affectsOtherWindows = true); 269 void _HideWindow(Window* window); 270 271 void _UpdateSubsetWorkspaces(Window* window, 272 int32 previousIndex = -1, 273 int32 newIndex = -1); 274 void _ChangeWindowWorkspaces(Window* window, 275 uint32 oldWorkspaces, uint32 newWorkspaces); 276 void _BringWindowsToFront(WindowList& windows, 277 int32 list, bool wereVisible); 278 Window* _LastFocusSubsetWindow(Window* window); 279 void _SendFakeMouseMoved(Window* window = NULL); 280 281 Screen* _DetermineScreenFor(BRect frame); 282 void _RebuildClippingForAllWindows( 283 BRegion& stillAvailableOnScreen); 284 void _TriggerWindowRedrawing( 285 BRegion& newDirtyRegion); 286 void _SetBackground(BRegion& background); 287 void _RebuildAndRedrawAfterWindowChange( 288 Window* window, BRegion& dirty); 289 290 status_t _ActivateApp(team_id team); 291 292 void _SuspendDirectFrameBufferAccess(); 293 void _ResumeDirectFrameBufferAccess(); 294 295 void _ScreenChanged(Screen* screen); 296 void _SetCurrentWorkspaceConfiguration(); 297 void _SetWorkspace(int32 index, 298 bool moveFocusWindow = false); 299 300 private: 301 friend class DesktopSettings; 302 friend class LockedDesktopSettings; 303 304 uid_t fUserID; 305 const char* fTargetScreen; 306 ::VirtualScreen fVirtualScreen; 307 DesktopSettingsPrivate* fSettings; 308 port_id fMessagePort; 309 ::EventDispatcher fEventDispatcher; 310 port_id fInputPort; 311 area_id fSharedReadOnlyArea; 312 server_read_only_memory* fServerReadOnlyMemory; 313 314 BLocker fApplicationsLock; 315 BObjectList<ServerApp> fApplications; 316 317 sem_id fShutdownSemaphore; 318 int32 fShutdownCount; 319 320 ::Workspace::Private fWorkspaces[kMaxWorkspaces]; 321 MultiLocker fScreenLock; 322 BLocker fDirectScreenLock; 323 team_id fDirectScreenTeam; 324 int32 fCurrentWorkspace; 325 int32 fPreviousWorkspace; 326 327 WindowList fAllWindows; 328 WindowList fSubsetWindows; 329 WindowList fFocusList; 330 Window* fLastWorkspaceFocus[kMaxWorkspaces]; 331 332 BObjectList<WorkspacesView> fWorkspacesViews; 333 BLocker fWorkspacesLock; 334 335 CursorManager fCursorManager; 336 337 #if USE_MULTI_LOCKER 338 MultiLocker fWindowLock; 339 #else 340 BLocker fWindowLock; 341 #endif 342 343 BRegion fBackgroundRegion; 344 BRegion fScreenRegion; 345 346 Window* fMouseEventWindow; 347 const Window* fWindowUnderMouse; 348 const Window* fLockedFocusWindow; 349 int32 fViewUnderMouse; 350 BPoint fLastMousePosition; 351 int32 fLastMouseButtons; 352 353 Window* fFocus; 354 Window* fFront; 355 Window* fBack; 356 }; 357 358 #endif // DESKTOP_H 359