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 * Brecht Machiels <brecht@mos6581.org> 11 */ 12 #ifndef WINDOW_H 13 #define WINDOW_H 14 15 16 #include "Decorator.h" 17 #include "RegionPool.h" 18 #include "ServerWindow.h" 19 #include "View.h" 20 #include "WindowList.h" 21 22 #include <ObjectList.h> 23 #include <Region.h> 24 #include <String.h> 25 26 namespace BPrivate { 27 class PortLink; 28 }; 29 30 class ClientLooper; 31 class Decorator; 32 class Desktop; 33 class DrawingEngine; 34 class EventDispatcher; 35 class Screen; 36 class WorkspacesView; 37 38 // TODO: move this into a proper place 39 #define AS_REDRAW 'rdrw' 40 41 enum { 42 UPDATE_REQUEST = 0x01, 43 UPDATE_EXPOSE = 0x02, 44 }; 45 46 47 class Window { 48 public: 49 Window(const BRect& frame, const char *name, 50 window_look look, window_feel feel, 51 uint32 flags, uint32 workspaces, 52 ::ServerWindow* window, 53 DrawingEngine* drawingEngine); 54 virtual ~Window(); 55 56 status_t InitCheck() const; 57 58 BRect Frame() const { return fFrame; } 59 const char* Title() const { return fTitle.String(); } 60 61 window_anchor& Anchor(int32 index); 62 Window* NextWindow(int32 index) const; 63 Window* PreviousWindow(int32 index) const; 64 65 ::Desktop* Desktop() const { return fDesktop; } 66 ::Decorator* Decorator() const { return fDecorator; } 67 ::ServerWindow* ServerWindow() const { return fWindow; } 68 ::EventTarget& EventTarget() const 69 { return fWindow->EventTarget(); } 70 71 void SetScreen(const ::Screen* screen); 72 const ::Screen* Screen() const; 73 74 // setting and getting the "hard" clipping, you need to have 75 // WriteLock()ed the clipping! 76 void SetClipping(BRegion* stillAvailableOnScreen); 77 // you need to have ReadLock()ed the clipping! 78 inline BRegion& VisibleRegion() { return fVisibleRegion; } 79 BRegion& VisibleContentRegion(); 80 81 // TODO: not protected by a lock, but noone should need this anyways 82 // make private? when used inside Window, it has the ReadLock() 83 void GetFullRegion(BRegion* region); 84 void GetBorderRegion(BRegion* region); 85 void GetContentRegion(BRegion* region); 86 87 void MoveBy(int32 x, int32 y); 88 void ResizeBy(int32 x, int32 y, 89 BRegion* dirtyRegion); 90 91 void ScrollViewBy(View* view, int32 dx, int32 dy); 92 93 void SetTopView(View* topView); 94 View* TopView() const { return fTopView; } 95 View* ViewAt(const BPoint& where); 96 97 virtual bool IsOffscreenWindow() const { return false; } 98 99 void GetEffectiveDrawingRegion(View* view, 100 BRegion& region); 101 bool DrawingRegionChanged(View* view) const; 102 103 // generic version, used by the Desktop 104 void ProcessDirtyRegion(BRegion& regionOnScreen); 105 void RedrawDirtyRegion(); 106 107 // can be used from inside classes that don't 108 // need to know about Desktop (first version uses Desktop) 109 void MarkDirty(BRegion& regionOnScreen); 110 // these versions do not use the Desktop 111 void MarkContentDirty(BRegion& regionOnScreen); 112 void MarkContentDirtyAsync(BRegion& regionOnScreen); 113 // shortcut for invalidating just one view 114 void InvalidateView(View* view, BRegion& viewRegion); 115 116 void DisableUpdateRequests(); 117 void EnableUpdateRequests(); 118 119 void BeginUpdate(BPrivate::PortLink& link); 120 void EndUpdate(); 121 bool InUpdate() const 122 { return fInUpdate; } 123 124 bool NeedsUpdate() const 125 { return fUpdateRequested; } 126 127 DrawingEngine* GetDrawingEngine() const 128 { return fDrawingEngine; } 129 130 // managing a region pool 131 ::RegionPool* RegionPool() 132 { return &fRegionPool; } 133 inline BRegion* GetRegion() 134 { return fRegionPool.GetRegion(); } 135 inline BRegion* GetRegion(const BRegion& copy) 136 { return fRegionPool.GetRegion(copy); } 137 inline void RecycleRegion(BRegion* region) 138 { fRegionPool.Recycle(region); } 139 140 void CopyContents(BRegion* region, 141 int32 xOffset, int32 yOffset); 142 143 void MouseDown(BMessage* message, BPoint where, 144 int32* _viewToken); 145 void MouseUp(BMessage* message, BPoint where, 146 int32* _viewToken); 147 void MouseMoved(BMessage* message, BPoint where, 148 int32* _viewToken, bool isLatestMouseMoved, 149 bool isFake); 150 151 // some hooks to inform the client window 152 // TODO: move this to ServerWindow maybe? 153 void WorkspaceActivated(int32 index, bool active); 154 void WorkspacesChanged(uint32 oldWorkspaces, 155 uint32 newWorkspaces); 156 void Activated(bool active); 157 158 // changing some properties 159 void SetTitle(const char* name, BRegion& dirty); 160 161 void SetFocus(bool focus); 162 bool IsFocus() const { return fIsFocus; } 163 164 void SetHidden(bool hidden); 165 inline bool IsHidden() const { return fHidden; } 166 167 void SetMinimized(bool minimized); 168 inline bool IsMinimized() const { return fMinimized; } 169 170 void SetCurrentWorkspace(int32 index) 171 { fCurrentWorkspace = index; } 172 bool IsVisible() const; 173 174 bool IsDragging() const { return fIsDragging; } 175 bool IsResizing() const { return fIsResizing; } 176 177 void SetSizeLimits(int32 minWidth, int32 maxWidth, 178 int32 minHeight, int32 maxHeight); 179 180 void GetSizeLimits(int32* minWidth, int32* maxWidth, 181 int32* minHeight, int32* maxHeight) const; 182 183 // 0.0 -> left .... 1.0 -> right 184 bool SetTabLocation(float location, BRegion& dirty); 185 float TabLocation() const; 186 187 bool SetDecoratorSettings(const BMessage& settings, 188 BRegion& dirty); 189 bool GetDecoratorSettings(BMessage* settings); 190 191 void HighlightDecorator(bool active); 192 193 void FontsChanged(BRegion* updateRegion); 194 195 void SetLook(window_look look, 196 BRegion* updateRegion); 197 void SetFeel(window_feel feel); 198 void SetFlags(uint32 flags, BRegion* updateRegion); 199 200 window_look Look() const { return fLook; } 201 window_feel Feel() const { return fFeel; } 202 uint32 Flags() const { return fFlags; } 203 204 // window manager stuff 205 uint32 Workspaces() const { return fWorkspaces; } 206 void SetWorkspaces(uint32 workspaces) 207 { fWorkspaces = workspaces; } 208 bool InWorkspace(int32 index) const; 209 210 bool SupportsFront(); 211 212 bool IsModal() const; 213 bool IsFloating() const; 214 bool IsNormal() const; 215 216 bool HasModal() const; 217 218 Window* Frontmost(Window* first = NULL, 219 int32 workspace = -1); 220 Window* Backmost(Window* first = NULL, 221 int32 workspace = -1); 222 223 bool AddToSubset(Window* window); 224 void RemoveFromSubset(Window* window); 225 bool HasInSubset(const Window* window) const; 226 bool SameSubset(Window* window); 227 uint32 SubsetWorkspaces() const; 228 bool InSubsetWorkspace(int32 index) const; 229 230 bool HasWorkspacesViews() const 231 { return fWorkspacesViewCount != 0; } 232 void AddWorkspacesView() 233 { fWorkspacesViewCount++; } 234 void RemoveWorkspacesView() 235 { fWorkspacesViewCount--; } 236 void FindWorkspacesViews( 237 BObjectList<WorkspacesView>& list) const; 238 239 static bool IsValidLook(window_look look); 240 static bool IsValidFeel(window_feel feel); 241 static bool IsModalFeel(window_feel feel); 242 static bool IsFloatingFeel(window_feel feel); 243 244 static uint32 ValidWindowFlags(); 245 static uint32 ValidWindowFlags(window_feel feel); 246 247 protected: 248 void _ShiftPartOfRegion(BRegion* region, 249 BRegion* regionToShift, int32 xOffset, 250 int32 yOffset); 251 252 // different types of drawing 253 void _TriggerContentRedraw(BRegion& dirty); 254 void _DrawBorder(); 255 256 // handling update sessions 257 void _TransferToUpdateSession( 258 BRegion* contentDirtyRegion); 259 void _SendUpdateMessage(); 260 261 void _UpdateContentRegion(); 262 263 int32 _ExtractButtons( 264 const BMessage* message) const; 265 int32 _ExtractModifiers( 266 const BMessage* message) const; 267 click_type _ActionFor(const BMessage* message) const; 268 click_type _ActionFor(const BMessage* message, 269 int32 buttons, int32 modifiers) const; 270 271 void _ObeySizeLimits(); 272 void _PropagatePosition(); 273 274 void _AlterDeltaForSnap(BPoint& delta, 275 bigtime_t now); 276 277 BString fTitle; 278 // TODO: no fp rects anywhere 279 BRect fFrame; 280 const ::Screen* fScreen; 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