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