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