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