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