1 /* 2 * Copyright 2001-2011, Haiku, Inc. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * DarkWyrm <bpmagic@columbus.rr.com> 7 * Adi Oanca <adioanca@gmail.com> 8 * Stephan Aßmus <superstippi@gmx.de> 9 * Axel Dörfler <axeld@pinc-software.de> 10 * Brecht Machiels <brecht@mos6581.org> 11 * Clemens Zeidler <haiku@clemens-zeidler.de> 12 */ 13 #ifndef WINDOW_H 14 #define WINDOW_H 15 16 17 #include "RegionPool.h" 18 #include "ServerWindow.h" 19 #include "View.h" 20 #include "WindowList.h" 21 22 #include <AutoDeleter.h> 23 #include <ObjectList.h> 24 #include <Referenceable.h> 25 #include <Region.h> 26 #include <String.h> 27 28 29 class Window; 30 31 32 typedef BObjectList<Window> StackWindows; 33 34 35 class WindowStack : public BReferenceable { 36 public: 37 WindowStack(::Decorator* decorator); 38 ~WindowStack(); 39 40 void SetDecorator(::Decorator* decorator); 41 ::Decorator* Decorator(); 42 43 const StackWindows& WindowList() const { return fWindowList; } 44 const StackWindows& LayerOrder() const { return fWindowLayerOrder; } 45 46 Window* TopLayerWindow() const; 47 48 int32 CountWindows(); 49 Window* WindowAt(int32 index); 50 bool AddWindow(Window* window, 51 int32 position = -1); 52 bool RemoveWindow(Window* window); 53 54 bool MoveToTopLayer(Window* window); 55 bool Move(int32 from, int32 to); 56 private: 57 ObjectDeleter< ::Decorator> 58 fDecorator; 59 60 StackWindows fWindowList; 61 StackWindows fWindowLayerOrder; 62 }; 63 64 65 namespace BPrivate { 66 class PortLink; 67 }; 68 69 class ClickTarget; 70 class ClientLooper; 71 class Decorator; 72 class Desktop; 73 class DrawingEngine; 74 class EventDispatcher; 75 class Screen; 76 class WindowBehaviour; 77 class WorkspacesView; 78 79 // TODO: move this into a proper place 80 #define AS_REDRAW 'rdrw' 81 82 enum { 83 UPDATE_REQUEST = 0x01, 84 UPDATE_EXPOSE = 0x02, 85 }; 86 87 88 class Window { 89 public: 90 Window(const BRect& frame, const char *name, 91 window_look look, window_feel feel, 92 uint32 flags, uint32 workspaces, 93 ::ServerWindow* window, 94 DrawingEngine* drawingEngine); 95 virtual ~Window(); 96 97 status_t InitCheck() const; 98 99 BRect Frame() const { return fFrame; } 100 const char* Title() const { return fTitle.String(); } 101 102 window_anchor& Anchor(int32 index); 103 Window* NextWindow(int32 index) const; 104 Window* PreviousWindow(int32 index) const; 105 106 ::Desktop* Desktop() const { return fDesktop; } 107 ::Decorator* Decorator() const; 108 ::ServerWindow* ServerWindow() const { return fWindow; } 109 ::EventTarget& EventTarget() const 110 { return fWindow->EventTarget(); } 111 112 bool ReloadDecor(); 113 114 void SetScreen(const ::Screen* screen); 115 const ::Screen* Screen() const; 116 117 // setting and getting the "hard" clipping, you need to have 118 // WriteLock()ed the clipping! 119 void SetClipping(BRegion* stillAvailableOnScreen); 120 // you need to have ReadLock()ed the clipping! 121 inline BRegion& VisibleRegion() { return fVisibleRegion; } 122 BRegion& VisibleContentRegion(); 123 124 // TODO: not protected by a lock, but noone should need this anyways 125 // make private? when used inside Window, it has the ReadLock() 126 void GetFullRegion(BRegion* region); 127 void GetBorderRegion(BRegion* region); 128 void GetContentRegion(BRegion* region); 129 130 void MoveBy(int32 x, int32 y, bool moveStack = true); 131 void ResizeBy(int32 x, int32 y, 132 BRegion* dirtyRegion, 133 bool resizeStack = true); 134 135 void ScrollViewBy(View* view, int32 dx, int32 dy); 136 137 void SetTopView(View* topView); 138 View* TopView() const { return fTopView.Get(); } 139 View* ViewAt(const BPoint& where); 140 141 virtual bool IsOffscreenWindow() const { return false; } 142 143 void GetEffectiveDrawingRegion(View* view, 144 BRegion& region); 145 bool DrawingRegionChanged(View* view) const; 146 147 // generic version, used by the Desktop 148 void ProcessDirtyRegion(BRegion& regionOnScreen); 149 void RedrawDirtyRegion(); 150 151 // can be used from inside classes that don't 152 // need to know about Desktop (first version uses Desktop) 153 void MarkDirty(BRegion& regionOnScreen); 154 // these versions do not use the Desktop 155 void MarkContentDirty(BRegion& regionOnScreen); 156 void MarkContentDirtyAsync(BRegion& regionOnScreen); 157 // shortcut for invalidating just one view 158 void InvalidateView(View* view, BRegion& viewRegion); 159 160 void DisableUpdateRequests(); 161 void EnableUpdateRequests(); 162 163 void BeginUpdate(BPrivate::PortLink& link); 164 void EndUpdate(); 165 bool InUpdate() const 166 { return fInUpdate; } 167 168 bool NeedsUpdate() const 169 { return fUpdateRequested; } 170 171 DrawingEngine* GetDrawingEngine() const 172 { return fDrawingEngine.Get(); } 173 174 // managing a region pool 175 ::RegionPool* RegionPool() 176 { return &fRegionPool; } 177 inline BRegion* GetRegion() 178 { return fRegionPool.GetRegion(); } 179 inline BRegion* GetRegion(const BRegion& copy) 180 { return fRegionPool.GetRegion(copy); } 181 inline void RecycleRegion(BRegion* region) 182 { fRegionPool.Recycle(region); } 183 184 void CopyContents(BRegion* region, 185 int32 xOffset, int32 yOffset); 186 187 void MouseDown(BMessage* message, BPoint where, 188 const ClickTarget& lastClickTarget, 189 int32& clickCount, 190 ClickTarget& _clickTarget); 191 void MouseUp(BMessage* message, BPoint where, 192 int32* _viewToken); 193 void MouseMoved(BMessage* message, BPoint where, 194 int32* _viewToken, bool isLatestMouseMoved, 195 bool isFake); 196 197 void ModifiersChanged(int32 modifiers); 198 199 // some hooks to inform the client window 200 // TODO: move this to ServerWindow maybe? 201 void WorkspaceActivated(int32 index, bool active); 202 void WorkspacesChanged(uint32 oldWorkspaces, 203 uint32 newWorkspaces); 204 void Activated(bool active); 205 206 // changing some properties 207 void SetTitle(const char* name, BRegion& dirty); 208 209 void SetFocus(bool focus); 210 bool IsFocus() const { return fIsFocus; } 211 212 void SetHidden(bool hidden); 213 inline bool IsHidden() const { return fHidden; } 214 215 void SetShowLevel(int32 showLevel); 216 inline int32 ShowLevel() const { return fShowLevel; } 217 218 void SetMinimized(bool minimized); 219 inline bool IsMinimized() const { return fMinimized; } 220 221 void SetCurrentWorkspace(int32 index) 222 { fCurrentWorkspace = index; } 223 int32 CurrentWorkspace() const 224 { return fCurrentWorkspace; } 225 bool IsVisible() const; 226 227 bool IsDragging() const; 228 bool IsResizing() const; 229 230 void SetSizeLimits(int32 minWidth, int32 maxWidth, 231 int32 minHeight, int32 maxHeight); 232 233 void GetSizeLimits(int32* minWidth, int32* maxWidth, 234 int32* minHeight, int32* maxHeight) const; 235 236 // 0.0 -> left .... 1.0 -> right 237 bool SetTabLocation(float location, bool isShifting, 238 BRegion& dirty); 239 float TabLocation() const; 240 241 bool SetDecoratorSettings(const BMessage& settings, 242 BRegion& dirty); 243 bool GetDecoratorSettings(BMessage* settings); 244 245 void HighlightDecorator(bool active); 246 247 void FontsChanged(BRegion* updateRegion); 248 void ColorsChanged(BRegion* updateRegion); 249 250 void SetLook(window_look look, 251 BRegion* updateRegion); 252 void SetFeel(window_feel feel); 253 void SetFlags(uint32 flags, BRegion* updateRegion); 254 255 window_look Look() const { return fLook; } 256 window_feel Feel() const { return fFeel; } 257 uint32 Flags() const { return fFlags; } 258 259 // window manager stuff 260 uint32 Workspaces() const { return fWorkspaces; } 261 void SetWorkspaces(uint32 workspaces) 262 { fWorkspaces = workspaces; } 263 bool InWorkspace(int32 index) const; 264 265 bool SupportsFront(); 266 267 bool IsModal() const; 268 bool IsFloating() const; 269 bool IsNormal() const; 270 271 bool HasModal() const; 272 273 Window* Frontmost(Window* first = NULL, 274 int32 workspace = -1); 275 Window* Backmost(Window* first = NULL, 276 int32 workspace = -1); 277 278 bool AddToSubset(Window* window); 279 void RemoveFromSubset(Window* window); 280 bool HasInSubset(const Window* window) const; 281 bool SameSubset(Window* window); 282 uint32 SubsetWorkspaces() const; 283 bool InSubsetWorkspace(int32 index) const; 284 285 bool HasWorkspacesViews() const 286 { return fWorkspacesViewCount != 0; } 287 void AddWorkspacesView() 288 { fWorkspacesViewCount++; } 289 void RemoveWorkspacesView() 290 { fWorkspacesViewCount--; } 291 void FindWorkspacesViews( 292 BObjectList<WorkspacesView>& list) const; 293 294 static bool IsValidLook(window_look look); 295 static bool IsValidFeel(window_feel feel); 296 static bool IsModalFeel(window_feel feel); 297 static bool IsFloatingFeel(window_feel feel); 298 299 static uint32 ValidWindowFlags(); 300 static uint32 ValidWindowFlags(window_feel feel); 301 302 // Window stack methods. 303 WindowStack* GetWindowStack(); 304 305 bool DetachFromWindowStack( 306 bool ownStackNeeded = true); 307 bool AddWindowToStack(Window* window); 308 Window* StackedWindowAt(const BPoint& where); 309 Window* TopLayerStackWindow(); 310 311 int32 PositionInStack() const; 312 bool MoveToTopStackLayer(); 313 bool MoveToStackPosition(int32 index, 314 bool isMoving); 315 protected: 316 void _ShiftPartOfRegion(BRegion* region, 317 BRegion* regionToShift, int32 xOffset, 318 int32 yOffset); 319 320 // different types of drawing 321 void _TriggerContentRedraw(BRegion& dirty); 322 void _DrawBorder(); 323 324 // handling update sessions 325 void _TransferToUpdateSession( 326 BRegion* contentDirtyRegion); 327 void _SendUpdateMessage(); 328 329 void _UpdateContentRegion(); 330 331 void _ObeySizeLimits(); 332 void _PropagatePosition(); 333 334 BString fTitle; 335 // TODO: no fp rects anywhere 336 BRect fFrame; 337 const ::Screen* fScreen; 338 339 window_anchor fAnchor[kListCount]; 340 341 // the visible region is only recalculated from the 342 // Desktop thread, when using it, Desktop::ReadLockClipping() 343 // has to be called 344 345 BRegion fVisibleRegion; 346 BRegion fVisibleContentRegion; 347 // our part of the "global" dirty region 348 // it is calculated from the desktop thread, 349 // but we can write to it when we read locked 350 // the clipping, since it is local and the desktop 351 // thread is blocked 352 BRegion fDirtyRegion; 353 uint32 fDirtyCause; 354 355 // caching local regions 356 BRegion fContentRegion; 357 BRegion fEffectiveDrawingRegion; 358 359 bool fVisibleContentRegionValid : 1; 360 bool fContentRegionValid : 1; 361 bool fEffectiveDrawingRegionValid : 1; 362 363 ::RegionPool fRegionPool; 364 365 BObjectList<Window> fSubsets; 366 367 ObjectDeleter<WindowBehaviour> 368 fWindowBehaviour; 369 ObjectDeleter<View> fTopView; 370 ::ServerWindow* fWindow; 371 ObjectDeleter<DrawingEngine> 372 fDrawingEngine; 373 ::Desktop* fDesktop; 374 375 // The synchronization, which client drawing commands 376 // belong to the redraw of which dirty region is handled 377 // through an UpdateSession. When the client has 378 // been informed that it should redraw stuff, then 379 // this is the current update session. All new 380 // redraw requests from the Desktop will go 381 // into the pending update session. 382 class UpdateSession { 383 public: 384 UpdateSession(); 385 virtual ~UpdateSession(); 386 387 void Include(BRegion* additionalDirty); 388 void Exclude(BRegion* dirtyInNextSession); 389 390 inline BRegion& DirtyRegion() 391 { return fDirtyRegion; } 392 393 void MoveBy(int32 x, int32 y); 394 395 void SetUsed(bool used); 396 inline bool IsUsed() const 397 { return fInUse; } 398 399 void AddCause(uint8 cause); 400 inline bool IsExpose() const 401 { return fCause & UPDATE_EXPOSE; } 402 inline bool IsRequest() const 403 { return fCause & UPDATE_REQUEST; } 404 405 private: 406 BRegion fDirtyRegion; 407 bool fInUse; 408 uint8 fCause; 409 }; 410 411 UpdateSession fUpdateSessions[2]; 412 UpdateSession* fCurrentUpdateSession; 413 UpdateSession* fPendingUpdateSession; 414 // these two flags are supposed to ensure a sane 415 // and consistent update session 416 bool fUpdateRequested : 1; 417 bool fInUpdate : 1; 418 bool fUpdatesEnabled : 1; 419 420 bool fHidden : 1; 421 int32 fShowLevel; 422 bool fMinimized : 1; 423 bool fIsFocus : 1; 424 425 window_look fLook; 426 window_feel fFeel; 427 uint32 fOriginalFlags; 428 uint32 fFlags; 429 uint32 fWorkspaces; 430 int32 fCurrentWorkspace; 431 432 int32 fMinWidth; 433 int32 fMaxWidth; 434 int32 fMinHeight; 435 int32 fMaxHeight; 436 437 int32 fWorkspacesViewCount; 438 439 friend class DecorManager; 440 441 private: 442 WindowStack* _InitWindowStack(); 443 444 BReference<WindowStack> fCurrentStack; 445 }; 446 447 448 #endif // WINDOW_H 449