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