1 /* 2 * Copyright 2001-2015, 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 * Joseph Groover <looncraz@looncraz.net> 13 */ 14 #ifndef DESKTOP_H 15 #define DESKTOP_H 16 17 18 #include <AutoDeleter.h> 19 #include <Autolock.h> 20 #include <InterfaceDefs.h> 21 #include <List.h> 22 #include <Menu.h> 23 #include <ObjectList.h> 24 #include <Region.h> 25 #include <String.h> 26 #include <Window.h> 27 28 #include <ServerProtocolStructs.h> 29 30 #include "CursorManager.h" 31 #include "DelayedMessage.h" 32 #include "DesktopListener.h" 33 #include "DesktopSettings.h" 34 #include "EventDispatcher.h" 35 #include "MessageLooper.h" 36 #include "MultiLocker.h" 37 #include "Screen.h" 38 #include "ScreenManager.h" 39 #include "ServerCursor.h" 40 #include "StackAndTile.h" 41 #include "VirtualScreen.h" 42 #include "WindowList.h" 43 #include "Workspace.h" 44 #include "WorkspacePrivate.h" 45 46 47 class BMessage; 48 49 class DecorAddOn; 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, 66 const char* targetScreen); 67 virtual ~Desktop(); 68 69 void RegisterListener(DesktopListener* listener); 70 71 status_t Init(); 72 73 uid_t UserID() const { return fUserID; } 74 const char* TargetScreen() { return fTargetScreen; } 75 virtual port_id MessagePort() const { return fMessagePort; } 76 area_id SharedReadOnlyArea() const 77 { return fSharedReadOnlyArea; } 78 79 ::EventDispatcher& EventDispatcher() { return fEventDispatcher; } 80 81 void BroadcastToAllApps(int32 code); 82 void BroadcastToAllWindows(int32 code); 83 84 int32 GetAllWindowTargets(DelayedMessage& message); 85 int32 GetAllAppTargets(DelayedMessage& message); 86 87 filter_result KeyEvent(uint32 what, int32 key, 88 int32 modifiers); 89 // Locking 90 bool LockSingleWindow() 91 { return fWindowLock.ReadLock(); } 92 void UnlockSingleWindow() 93 { fWindowLock.ReadUnlock(); } 94 95 bool LockAllWindows() 96 { return fWindowLock.WriteLock(); } 97 void UnlockAllWindows() 98 { fWindowLock.WriteUnlock(); } 99 100 const MultiLocker& WindowLocker() { return fWindowLock; } 101 102 // Mouse and cursor methods 103 104 void SetCursor(ServerCursor* cursor); 105 ServerCursorReference Cursor() const; 106 void SetManagementCursor(ServerCursor* newCursor); 107 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 status_t SetBrightness(int32 id, float brightness); 131 132 MultiLocker& ScreenLocker() { return fScreenLock; } 133 134 status_t LockDirectScreen(team_id team); 135 status_t UnlockDirectScreen(team_id team); 136 137 const ::VirtualScreen& VirtualScreen() const 138 { return fVirtualScreen; } 139 DrawingEngine* GetDrawingEngine() const 140 { return fVirtualScreen.DrawingEngine(); } 141 ::HWInterface* HWInterface() const 142 { return fVirtualScreen.HWInterface(); } 143 144 void RebuildAndRedrawAfterWindowChange( 145 Window* window, BRegion& dirty); 146 // the window lock must be held when calling 147 // this function 148 149 // ScreenOwner implementation 150 virtual void ScreenRemoved(Screen* screen) {} 151 virtual void ScreenAdded(Screen* screen) {} 152 virtual void ScreenChanged(Screen* screen); 153 virtual bool ReleaseScreen(Screen* screen) { return false; } 154 155 // Workspace methods 156 157 void SetWorkspaceAsync(int32 index, 158 bool moveFocusWindow = false); 159 void SetWorkspace(int32 index, 160 bool moveFocusWindow = false); 161 int32 CurrentWorkspace() 162 { return fCurrentWorkspace; } 163 Workspace::Private& WorkspaceAt(int32 index) 164 { return fWorkspaces[index]; } 165 status_t SetWorkspacesLayout(int32 columns, int32 rows); 166 BRect WorkspaceFrame(int32 index) const; 167 168 void StoreWorkspaceConfiguration(int32 index); 169 170 void AddWorkspacesView(WorkspacesView* view); 171 void RemoveWorkspacesView(WorkspacesView* view); 172 173 // Window methods 174 175 void SelectWindow(Window* window); 176 void ActivateWindow(Window* window); 177 void SendWindowBehind(Window* window, 178 Window* behindOf = NULL, 179 bool sendStack = true); 180 181 void ShowWindow(Window* window); 182 void HideWindow(Window* window, 183 bool fromMinimize = false); 184 void MinimizeWindow(Window* window, bool minimize); 185 186 void MoveWindowBy(Window* window, float x, float y, 187 int32 workspace = -1); 188 void ResizeWindowBy(Window* window, float x, 189 float y); 190 bool SetWindowTabLocation(Window* window, 191 float location, bool isShifting); 192 bool SetWindowDecoratorSettings(Window* window, 193 const BMessage& settings); 194 195 void SetWindowWorkspaces(Window* window, 196 uint32 workspaces); 197 198 void AddWindow(Window* window); 199 void RemoveWindow(Window* window); 200 201 bool AddWindowToSubset(Window* subset, 202 Window* window); 203 void RemoveWindowFromSubset(Window* subset, 204 Window* window); 205 206 void FontsChanged(Window* window); 207 void ColorUpdated(Window* window, color_which which, 208 rgb_color color); 209 210 void SetWindowLook(Window* window, window_look look); 211 void SetWindowFeel(Window* window, window_feel feel); 212 void SetWindowFlags(Window* window, uint32 flags); 213 void SetWindowTitle(Window* window, 214 const char* title); 215 216 Window* FocusWindow() const { return fFocus; } 217 Window* FrontWindow() const { return fFront; } 218 Window* BackWindow() const { return fBack; } 219 220 Window* WindowAt(BPoint where); 221 222 Window* MouseEventWindow() const 223 { return fMouseEventWindow; } 224 void SetMouseEventWindow(Window* window); 225 226 void SetViewUnderMouse(const Window* window, 227 int32 viewToken); 228 int32 ViewUnderMouse(const Window* window); 229 230 EventTarget* KeyboardEventTarget(); 231 232 void SetFocusWindow(Window* window = NULL); 233 void SetFocusLocked(const Window* window); 234 235 Window* FindWindowByClientToken(int32 token, 236 team_id teamID); 237 EventTarget* FindTarget(BMessenger& messenger); 238 239 void MarkDirty(BRegion& region); 240 void Redraw(); 241 void RedrawBackground(); 242 243 bool ReloadDecor(DecorAddOn* oldDecor); 244 245 BRegion& BackgroundRegion() 246 { return fBackgroundRegion; } 247 248 void MinimizeApplication(team_id team); 249 void BringApplicationToFront(team_id team); 250 void WindowAction(int32 windowToken, int32 action); 251 252 void WriteWindowList(team_id team, 253 BPrivate::LinkSender& sender); 254 void WriteWindowInfo(int32 serverToken, 255 BPrivate::LinkSender& sender); 256 void WriteApplicationOrder(int32 workspace, 257 BPrivate::LinkSender& sender); 258 void WriteWindowOrder(int32 workspace, 259 BPrivate::LinkSender& sender); 260 261 //! The window lock must be held when accessing a window list! 262 WindowList& CurrentWindows(); 263 WindowList& AllWindows(); 264 265 Window* WindowForClientLooperPort(port_id port); 266 267 StackAndTile* GetStackAndTile() { return &fStackAndTile; } 268 private: 269 WindowList& _Windows(int32 index); 270 271 void _FlushPendingColors(); 272 273 void _LaunchInputServer(); 274 void _GetLooperName(char* name, size_t size); 275 void _PrepareQuit(); 276 void _DispatchMessage(int32 code, 277 BPrivate::LinkReceiver &link); 278 279 void _UpdateFloating(int32 previousWorkspace = -1, 280 int32 nextWorkspace = -1, 281 Window* mouseEventWindow = NULL); 282 void _UpdateBack(); 283 void _UpdateFront(bool updateFloating = true); 284 void _UpdateFronts(bool updateFloating = true); 285 bool _WindowHasModal(Window* window) const; 286 bool _WindowCanHaveFocus(Window* window) const; 287 288 void _WindowChanged(Window* window); 289 void _WindowRemoved(Window* window); 290 291 void _ShowWindow(Window* window, 292 bool affectsOtherWindows = true); 293 void _HideWindow(Window* window); 294 295 void _UpdateSubsetWorkspaces(Window* window, 296 int32 previousIndex = -1, 297 int32 newIndex = -1); 298 void _ChangeWindowWorkspaces(Window* window, 299 uint32 oldWorkspaces, uint32 newWorkspaces); 300 void _BringWindowsToFront(WindowList& windows, 301 int32 list, bool wereVisible); 302 Window* _LastFocusSubsetWindow(Window* window); 303 bool _CheckSendFakeMouseMoved( 304 const Window* lastWindowUnderMouse); 305 void _SendFakeMouseMoved(Window* window = NULL); 306 307 Screen* _DetermineScreenFor(BRect frame); 308 void _RebuildClippingForAllWindows( 309 BRegion& stillAvailableOnScreen); 310 void _TriggerWindowRedrawing( 311 BRegion& newDirtyRegion); 312 void _SetBackground(BRegion& background); 313 314 status_t _ActivateApp(team_id team); 315 316 void _SuspendDirectFrameBufferAccess(); 317 void _ResumeDirectFrameBufferAccess(); 318 319 void _ScreenChanged(Screen* screen); 320 void _SetCurrentWorkspaceConfiguration(); 321 void _SetWorkspace(int32 index, 322 bool moveFocusWindow = false); 323 324 private: 325 friend class DesktopSettings; 326 friend class LockedDesktopSettings; 327 328 uid_t fUserID; 329 char* fTargetScreen; 330 ::VirtualScreen fVirtualScreen; 331 ObjectDeleter<DesktopSettingsPrivate> 332 fSettings; 333 port_id fMessagePort; 334 ::EventDispatcher fEventDispatcher; 335 area_id fSharedReadOnlyArea; 336 server_read_only_memory* fServerReadOnlyMemory; 337 338 BLocker fApplicationsLock; 339 BObjectList<ServerApp> fApplications; 340 341 sem_id fShutdownSemaphore; 342 int32 fShutdownCount; 343 344 ::Workspace::Private fWorkspaces[kMaxWorkspaces]; 345 MultiLocker fScreenLock; 346 BLocker fDirectScreenLock; 347 team_id fDirectScreenTeam; 348 int32 fCurrentWorkspace; 349 int32 fPreviousWorkspace; 350 351 WindowList fAllWindows; 352 WindowList fSubsetWindows; 353 WindowList fFocusList; 354 Window* fLastWorkspaceFocus[kMaxWorkspaces]; 355 356 BObjectList<WorkspacesView> fWorkspacesViews; 357 BLocker fWorkspacesLock; 358 359 CursorManager fCursorManager; 360 ServerCursorReference fCursor; 361 ServerCursorReference fManagementCursor; 362 363 MultiLocker fWindowLock; 364 365 BRegion fBackgroundRegion; 366 BRegion fScreenRegion; 367 368 Window* fMouseEventWindow; 369 const Window* fWindowUnderMouse; 370 const Window* fLockedFocusWindow; 371 int32 fViewUnderMouse; 372 BPoint fLastMousePosition; 373 int32 fLastMouseButtons; 374 375 Window* fFocus; 376 Window* fFront; 377 Window* fBack; 378 379 StackAndTile fStackAndTile; 380 381 BMessage fPendingColors; 382 }; 383 384 #endif // DESKTOP_H 385