xref: /haiku/src/servers/app/Window.h (revision cfc3fa87da824bdf593eb8b817a83b6376e77935)
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