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