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