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