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