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