1 /* 2 * Copyright (c) 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 144 // some hooks to inform the client window 145 // TODO: move this to ServerWindow maybe? 146 void WorkspaceActivated(int32 index, bool active); 147 void WorkspacesChanged(uint32 oldWorkspaces, 148 uint32 newWorkspaces); 149 void Activated(bool active); 150 151 // changing some properties 152 void SetTitle(const char* name, BRegion& dirty); 153 154 void SetFocus(bool focus); 155 bool IsFocus() const { return fIsFocus; } 156 157 void SetHidden(bool hidden); 158 inline bool IsHidden() const { return fHidden; } 159 160 void SetMinimized(bool minimized); 161 inline bool IsMinimized() const { return fMinimized; } 162 163 void SetCurrentWorkspace(int32 index) 164 { fCurrentWorkspace = index; } 165 bool IsVisible() const; 166 167 bool IsDragging() const { return fIsDragging; } 168 bool IsResizing() const { return fIsResizing; } 169 170 void SetSizeLimits(int32 minWidth, int32 maxWidth, 171 int32 minHeight, int32 maxHeight); 172 173 void GetSizeLimits(int32* minWidth, int32* maxWidth, 174 int32* minHeight, int32* maxHeight) const; 175 176 // 0.0 -> left .... 1.0 -> right 177 bool SetTabLocation(float location, BRegion& dirty); 178 float TabLocation() const; 179 180 bool SetDecoratorSettings(const BMessage& settings, 181 BRegion& dirty); 182 bool GetDecoratorSettings(BMessage* settings); 183 184 void HighlightDecorator(bool active); 185 186 void FontsChanged(BRegion* updateRegion); 187 188 void SetLook(window_look look, 189 BRegion* updateRegion); 190 void SetFeel(window_feel feel); 191 void SetFlags(uint32 flags, BRegion* updateRegion); 192 193 window_look Look() const { return fLook; } 194 window_feel Feel() const { return fFeel; } 195 uint32 Flags() const { return fFlags; } 196 197 // window manager stuff 198 uint32 Workspaces() const { return fWorkspaces; } 199 void SetWorkspaces(uint32 workspaces) 200 { fWorkspaces = workspaces; } 201 bool InWorkspace(int32 index) const; 202 203 bool SupportsFront(); 204 205 bool IsModal() const; 206 bool IsFloating() const; 207 bool IsNormal() const; 208 209 bool HasModal() const; 210 211 Window* Frontmost(Window* first = NULL, 212 int32 workspace = -1); 213 Window* Backmost(Window* first = NULL, 214 int32 workspace = -1); 215 216 bool AddToSubset(Window* window); 217 void RemoveFromSubset(Window* window); 218 bool HasInSubset(const Window* window) const; 219 bool SameSubset(Window* window); 220 uint32 SubsetWorkspaces() const; 221 bool InSubsetWorkspace(int32 index) const; 222 223 bool HasWorkspacesViews() const 224 { return fWorkspacesViewCount != 0; } 225 void AddWorkspacesView() 226 { fWorkspacesViewCount++; } 227 void RemoveWorkspacesView() 228 { fWorkspacesViewCount--; } 229 void FindWorkspacesViews( 230 BObjectList<WorkspacesView>& list) const; 231 232 static bool IsValidLook(window_look look); 233 static bool IsValidFeel(window_feel feel); 234 static bool IsModalFeel(window_feel feel); 235 static bool IsFloatingFeel(window_feel feel); 236 237 static uint32 ValidWindowFlags(); 238 static uint32 ValidWindowFlags(window_feel feel); 239 240 protected: 241 friend class Desktop; 242 // TODO: for now (list management) 243 244 void _ShiftPartOfRegion(BRegion* region, 245 BRegion* regionToShift, int32 xOffset, 246 int32 yOffset); 247 248 // different types of drawing 249 void _TriggerContentRedraw(BRegion& dirty); 250 void _DrawBorder(); 251 252 // handling update sessions 253 void _TransferToUpdateSession( 254 BRegion* contentDirtyRegion); 255 void _SendUpdateMessage(); 256 257 void _UpdateContentRegion(); 258 259 click_type _ActionFor(const BMessage* message) const; 260 261 void _ObeySizeLimits(); 262 void _PropagatePosition(); 263 264 BString fTitle; 265 // TODO: no fp rects anywhere 266 BRect fFrame; 267 268 window_anchor fAnchor[kListCount]; 269 270 // the visible region is only recalculated from the 271 // Desktop thread, when using it, Desktop::ReadLockClipping() 272 // has to be called 273 274 BRegion fVisibleRegion; 275 BRegion fVisibleContentRegion; 276 // our part of the "global" dirty region 277 // it is calculated from the desktop thread, 278 // but we can write to it when we read locked 279 // the clipping, since it is local and the desktop 280 // thread is blocked 281 BRegion fDirtyRegion; 282 uint32 fDirtyCause; 283 284 // caching local regions 285 BRegion fBorderRegion; 286 BRegion fContentRegion; 287 BRegion fEffectiveDrawingRegion; 288 289 bool fVisibleContentRegionValid : 1; 290 bool fBorderRegionValid : 1; 291 bool fContentRegionValid : 1; 292 bool fEffectiveDrawingRegionValid : 1; 293 294 ::RegionPool fRegionPool; 295 296 BObjectList<Window> fSubsets; 297 298 // TODO: remove those some day (let the decorator handle that stuff) 299 bool fIsClosing : 1; 300 bool fIsMinimizing : 1; 301 bool fIsZooming : 1; 302 bool fIsResizing : 1; 303 bool fIsSlidingTab : 1; 304 bool fIsDragging : 1; 305 bool fActivateOnMouseUp : 1; 306 307 ::Decorator* fDecorator; 308 View* fTopView; 309 ::ServerWindow* fWindow; 310 DrawingEngine* fDrawingEngine; 311 ::Desktop* fDesktop; 312 313 BPoint fLastMousePosition; 314 bigtime_t fLastMoveTime; 315 316 // The synchronization, which client drawing commands 317 // belong to the redraw of which dirty region is handled 318 // through an UpdateSession. When the client has 319 // been informed that it should redraw stuff, then 320 // this is the current update session. All new 321 // redraw requests from the Desktop will go 322 // into the pending update session. 323 class UpdateSession { 324 public: 325 UpdateSession(); 326 virtual ~UpdateSession(); 327 328 void Include(BRegion* additionalDirty); 329 void Exclude(BRegion* dirtyInNextSession); 330 331 inline BRegion& DirtyRegion() 332 { return fDirtyRegion; } 333 334 void MoveBy(int32 x, int32 y); 335 336 void SetUsed(bool used); 337 inline bool IsUsed() const 338 { return fInUse; } 339 340 void AddCause(uint8 cause); 341 inline bool IsExpose() const 342 { return fCause & UPDATE_EXPOSE; } 343 inline bool IsRequest() const 344 { return fCause & UPDATE_REQUEST; } 345 346 private: 347 BRegion fDirtyRegion; 348 bool fInUse; 349 uint8 fCause; 350 }; 351 352 BRegion fDecoratorRegion; 353 354 UpdateSession fUpdateSessions[2]; 355 UpdateSession* fCurrentUpdateSession; 356 UpdateSession* fPendingUpdateSession; 357 // these two flags are supposed to ensure a sane 358 // and consistent update session 359 bool fUpdateRequested : 1; 360 bool fInUpdate : 1; 361 bool fUpdatesEnabled : 1; 362 363 bool fHidden : 1; 364 bool fMinimized : 1; 365 bool fIsFocus : 1; 366 367 window_look fLook; 368 window_feel fFeel; 369 uint32 fOriginalFlags; 370 uint32 fFlags; 371 uint32 fWorkspaces; 372 int32 fCurrentWorkspace; 373 374 int32 fMinWidth; 375 int32 fMaxWidth; 376 int32 fMinHeight; 377 int32 fMaxHeight; 378 379 int32 fWorkspacesViewCount; 380 }; 381 382 #endif // WINDOW_H 383