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 ClickTarget; 31 class ClientLooper; 32 class Decorator; 33 class Desktop; 34 class DrawingEngine; 35 class EventDispatcher; 36 class Screen; 37 class WindowBehaviour; 38 class WorkspacesView; 39 40 // TODO: move this into a proper place 41 #define AS_REDRAW 'rdrw' 42 43 enum { 44 UPDATE_REQUEST = 0x01, 45 UPDATE_EXPOSE = 0x02, 46 }; 47 48 49 class Window { 50 public: 51 Window(const BRect& frame, const char *name, 52 window_look look, window_feel feel, 53 uint32 flags, uint32 workspaces, 54 ::ServerWindow* window, 55 DrawingEngine* drawingEngine); 56 virtual ~Window(); 57 58 status_t InitCheck() const; 59 60 BRect Frame() const { return fFrame; } 61 const char* Title() const { return fTitle.String(); } 62 63 window_anchor& Anchor(int32 index); 64 Window* NextWindow(int32 index) const; 65 Window* PreviousWindow(int32 index) const; 66 67 ::Desktop* Desktop() const { return fDesktop; } 68 ::Decorator* Decorator() const { return fDecorator; } 69 ::ServerWindow* ServerWindow() const { return fWindow; } 70 ::EventTarget& EventTarget() const 71 { return fWindow->EventTarget(); } 72 73 bool ReloadDecor(); 74 75 void SetScreen(const ::Screen* screen); 76 const ::Screen* Screen() const; 77 78 // setting and getting the "hard" clipping, you need to have 79 // WriteLock()ed the clipping! 80 void SetClipping(BRegion* stillAvailableOnScreen); 81 // you need to have ReadLock()ed the clipping! 82 inline BRegion& VisibleRegion() { return fVisibleRegion; } 83 BRegion& VisibleContentRegion(); 84 85 // TODO: not protected by a lock, but noone should need this anyways 86 // make private? when used inside Window, it has the ReadLock() 87 void GetFullRegion(BRegion* region); 88 void GetBorderRegion(BRegion* region); 89 void GetContentRegion(BRegion* region); 90 91 void MoveBy(int32 x, int32 y); 92 void ResizeBy(int32 x, int32 y, 93 BRegion* dirtyRegion); 94 95 void ScrollViewBy(View* view, int32 dx, int32 dy); 96 97 void SetTopView(View* topView); 98 View* TopView() const { return fTopView; } 99 View* ViewAt(const BPoint& where); 100 101 virtual bool IsOffscreenWindow() const { return false; } 102 103 void GetEffectiveDrawingRegion(View* view, 104 BRegion& region); 105 bool DrawingRegionChanged(View* view) const; 106 107 // generic version, used by the Desktop 108 void ProcessDirtyRegion(BRegion& regionOnScreen); 109 void RedrawDirtyRegion(); 110 111 // can be used from inside classes that don't 112 // need to know about Desktop (first version uses Desktop) 113 void MarkDirty(BRegion& regionOnScreen); 114 // these versions do not use the Desktop 115 void MarkContentDirty(BRegion& regionOnScreen); 116 void MarkContentDirtyAsync(BRegion& regionOnScreen); 117 // shortcut for invalidating just one view 118 void InvalidateView(View* view, BRegion& viewRegion); 119 120 void DisableUpdateRequests(); 121 void EnableUpdateRequests(); 122 123 void BeginUpdate(BPrivate::PortLink& link); 124 void EndUpdate(); 125 bool InUpdate() const 126 { return fInUpdate; } 127 128 bool NeedsUpdate() const 129 { return fUpdateRequested; } 130 131 DrawingEngine* GetDrawingEngine() const 132 { return fDrawingEngine; } 133 134 // managing a region pool 135 ::RegionPool* RegionPool() 136 { return &fRegionPool; } 137 inline BRegion* GetRegion() 138 { return fRegionPool.GetRegion(); } 139 inline BRegion* GetRegion(const BRegion& copy) 140 { return fRegionPool.GetRegion(copy); } 141 inline void RecycleRegion(BRegion* region) 142 { fRegionPool.Recycle(region); } 143 144 void CopyContents(BRegion* region, 145 int32 xOffset, int32 yOffset); 146 147 void MouseDown(BMessage* message, BPoint where, 148 const ClickTarget& lastClickTarget, 149 int32& clickCount, 150 ClickTarget& _clickTarget); 151 void MouseUp(BMessage* message, BPoint where, 152 int32* _viewToken); 153 void MouseMoved(BMessage* message, BPoint where, 154 int32* _viewToken, bool isLatestMouseMoved, 155 bool isFake); 156 157 void ModifiersChanged(int32 modifiers); 158 159 // some hooks to inform the client window 160 // TODO: move this to ServerWindow maybe? 161 void WorkspaceActivated(int32 index, bool active); 162 void WorkspacesChanged(uint32 oldWorkspaces, 163 uint32 newWorkspaces); 164 void Activated(bool active); 165 166 // changing some properties 167 void SetTitle(const char* name, BRegion& dirty); 168 169 void SetFocus(bool focus); 170 bool IsFocus() const { return fIsFocus; } 171 172 void SetHidden(bool hidden); 173 inline bool IsHidden() const { return fHidden; } 174 175 void SetMinimized(bool minimized); 176 inline bool IsMinimized() const { return fMinimized; } 177 178 void SetCurrentWorkspace(int32 index) 179 { fCurrentWorkspace = index; } 180 int32 CurrentWorkspace() const 181 { return fCurrentWorkspace; } 182 bool IsVisible() const; 183 184 bool IsDragging() const; 185 bool IsResizing() const; 186 187 void SetSizeLimits(int32 minWidth, int32 maxWidth, 188 int32 minHeight, int32 maxHeight); 189 190 void GetSizeLimits(int32* minWidth, int32* maxWidth, 191 int32* minHeight, int32* maxHeight) const; 192 193 // 0.0 -> left .... 1.0 -> right 194 bool SetTabLocation(float location, BRegion& dirty); 195 float TabLocation() const; 196 197 bool SetDecoratorSettings(const BMessage& settings, 198 BRegion& dirty); 199 bool GetDecoratorSettings(BMessage* settings); 200 201 void HighlightDecorator(bool active); 202 203 void FontsChanged(BRegion* updateRegion); 204 205 void SetLook(window_look look, 206 BRegion* updateRegion); 207 void SetFeel(window_feel feel); 208 void SetFlags(uint32 flags, BRegion* updateRegion); 209 210 window_look Look() const { return fLook; } 211 window_feel Feel() const { return fFeel; } 212 uint32 Flags() const { return fFlags; } 213 214 // window manager stuff 215 uint32 Workspaces() const { return fWorkspaces; } 216 void SetWorkspaces(uint32 workspaces) 217 { fWorkspaces = workspaces; } 218 bool InWorkspace(int32 index) const; 219 220 bool SupportsFront(); 221 222 bool IsModal() const; 223 bool IsFloating() const; 224 bool IsNormal() const; 225 226 bool HasModal() const; 227 228 Window* Frontmost(Window* first = NULL, 229 int32 workspace = -1); 230 Window* Backmost(Window* first = NULL, 231 int32 workspace = -1); 232 233 bool AddToSubset(Window* window); 234 void RemoveFromSubset(Window* window); 235 bool HasInSubset(const Window* window) const; 236 bool SameSubset(Window* window); 237 uint32 SubsetWorkspaces() const; 238 bool InSubsetWorkspace(int32 index) const; 239 240 bool HasWorkspacesViews() const 241 { return fWorkspacesViewCount != 0; } 242 void AddWorkspacesView() 243 { fWorkspacesViewCount++; } 244 void RemoveWorkspacesView() 245 { fWorkspacesViewCount--; } 246 void FindWorkspacesViews( 247 BObjectList<WorkspacesView>& list) const; 248 249 static bool IsValidLook(window_look look); 250 static bool IsValidFeel(window_feel feel); 251 static bool IsModalFeel(window_feel feel); 252 static bool IsFloatingFeel(window_feel feel); 253 254 static uint32 ValidWindowFlags(); 255 static uint32 ValidWindowFlags(window_feel feel); 256 257 protected: 258 void _ShiftPartOfRegion(BRegion* region, 259 BRegion* regionToShift, int32 xOffset, 260 int32 yOffset); 261 262 // different types of drawing 263 void _TriggerContentRedraw(BRegion& dirty); 264 void _DrawBorder(); 265 266 // handling update sessions 267 void _TransferToUpdateSession( 268 BRegion* contentDirtyRegion); 269 void _SendUpdateMessage(); 270 271 void _UpdateContentRegion(); 272 273 void _ObeySizeLimits(); 274 void _PropagatePosition(); 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 fContentRegion; 299 BRegion fEffectiveDrawingRegion; 300 301 bool fVisibleContentRegionValid : 1; 302 bool fContentRegionValid : 1; 303 bool fEffectiveDrawingRegionValid : 1; 304 305 ::RegionPool fRegionPool; 306 307 BObjectList<Window> fSubsets; 308 309 WindowBehaviour* fWindowBehaviour; 310 ::Decorator* fDecorator; 311 View* fTopView; 312 ::ServerWindow* fWindow; 313 DrawingEngine* fDrawingEngine; 314 ::Desktop* fDesktop; 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 UpdateSession fUpdateSessions[2]; 353 UpdateSession* fCurrentUpdateSession; 354 UpdateSession* fPendingUpdateSession; 355 // these two flags are supposed to ensure a sane 356 // and consistent update session 357 bool fUpdateRequested : 1; 358 bool fInUpdate : 1; 359 bool fUpdatesEnabled : 1; 360 361 bool fHidden : 1; 362 bool fMinimized : 1; 363 bool fIsFocus : 1; 364 365 window_look fLook; 366 window_feel fFeel; 367 uint32 fOriginalFlags; 368 uint32 fFlags; 369 uint32 fWorkspaces; 370 int32 fCurrentWorkspace; 371 372 int32 fMinWidth; 373 int32 fMaxWidth; 374 int32 fMinHeight; 375 int32 fMaxHeight; 376 377 int32 fWorkspacesViewCount; 378 379 friend class DecorManager; 380 }; 381 382 #endif // WINDOW_H 383