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