xref: /haiku/src/servers/app/Layer.cpp (revision fef6144999c2fa611f59ee6ffe6dd7999501385c)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2005, Haiku, Inc.
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		Layer.cpp
23 //	Author:			DarkWyrm <bpmagic@columbus.rr.com>
24 //					Adi Oanca <adioanca@cotty.iren.ro>
25 //					Stephan Aßmus <superstippi@gmx.de>
26 //	Description:	Class used for rendering to the frame buffer. One layer per
27 //					view on screen and also for window decorators
28 //
29 //------------------------------------------------------------------------------
30 #include <string.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 
34 #include <AppDefs.h>
35 #include <Message.h>
36 #include <Region.h>
37 #include <View.h>
38 
39 #include "DebugInfoManager.h"
40 #include "DisplayDriver.h"
41 #include "LayerData.h"
42 #include "PortLink.h"
43 #include "RootLayer.h"
44 #include "ServerProtocol.h"
45 #include "ServerWindow.h"
46 #include "WinBorder.h"
47 #include "Layer.h"
48 #include "ServerBitmap.h"
49 
50 //#define DEBUG_LAYER
51 #ifdef DEBUG_LAYER
52 #	define STRACE(x) printf x
53 #else
54 #	define STRACE(x) ;
55 #endif
56 
57 //#define DEBUG_LAYER_REBUILD
58 #ifdef DEBUG_LAYER_REBUILD
59 #	define RBTRACE(x) printf x
60 #else
61 #	define RBTRACE(x) ;
62 #endif
63 
64 Layer::Layer(BRect frame, const char* name, int32 token,
65 			 uint32 resize, uint32 flags, DisplayDriver* driver)
66 	:
67 	fFrame(frame), // in parent coordinates
68 //	fBoundsLeftTop(0.0, 0.0),
69 
70 	// Layer does not start out as a part of the tree
71 	fOwner(NULL),
72 
73 	fParent(NULL),
74 	fPreviousSibling(NULL),
75 	fNextSibling(NULL),
76 	fFirstChild(NULL),
77 	fLastChild(NULL),
78 
79 	fCurrent(NULL),
80 
81 	// all regions (fVisible, fFullVisible, fFull) start empty
82 #ifndef NEW_CLIPPING
83 	fVisible(),
84 	fFullVisible(),
85 	fFull(),
86 	fFrameAction(B_LAYER_ACTION_NONE),
87 	fClipReg(&fVisible),
88 #else
89 	fVisible2(),
90 	fFullVisible2(),
91 	fClipReg(&fVisible2),
92 #endif
93 
94 	fServerWin(NULL),
95 	fName(name),
96 	fViewToken(token),
97 
98 	fFlags(flags),
99 	fResizeMode(resize),
100 	fEventMask(0UL),
101 	fEventOptions(0UL),
102 	fHidden(false),
103 	fIsTopLayer(false),
104 
105 	fAdFlags(0),
106 	fClassID(AS_LAYER_CLASS),
107 
108 	fDriver(driver),
109 	fLayerData(new LayerData()),
110 
111 	fRootLayer(NULL),
112 
113 	fViewColor(255, 255, 255, 255),
114 	fBackgroundBitmap(NULL),
115 	fOverlayBitmap(NULL)
116 {
117 	if (!frame.IsValid()) {
118 char helper[1024];
119 sprintf(helper, "Layer::Layer(BRect(%.1f, %.1f, %.1f, %.1f), name: %s, token: %ld) - frame is invalid\n",
120 		frame.left, frame.top, frame.right, frame.bottom, name, token);
121 CRITICAL(helper);
122 		fFrame.Set(0, 0, 1, 1);
123 	}
124 
125 	if (!fDriver)
126 		CRITICAL("You MUST have a valid driver to init a Layer object\n");
127 
128 	// NOTE: This flag is forwarded to a LayerData setting, even
129 	// though it is actually not part of a "state". However,
130 	// it is an important detail of a graphics context, and we
131 	// have no other means to pass this setting on to the DisplayDriver
132 	// other than through the LayerData. If we ever add a flag
133 	// B_ANTI_ALIASING to the view flags, it would have to be passed
134 	// in the same way. Though when breaking binary compatibility,
135 	// we might want to make this an actual part of a "state" (with
136 	// a different API to set these).
137 	// Note that the flag is also tested (updated) in Push/PopState and
138 	// SetFlags().
139 	fLayerData->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
140 
141 	STRACE(("Layer(%s) successfuly created\n", Name()));
142 }
143 
144 //! Destructor frees all allocated heap space
145 Layer::~Layer()
146 {
147 	delete fLayerData;
148 
149 	// TODO: uncomment!
150 	//PruneTree();
151 }
152 
153 /*!
154 	\brief Adds a child layer to the current one
155 	\param layer a new child layer
156 	\param serverWin the serverwindow to which the layer will belong
157 
158 	Unlike the BView version, if the layer already belongs to another, then
159 	it spits an error to stdout and returns.
160 */
161 void
162 Layer::AddChild(Layer* layer, ServerWindow* serverWin)
163 {
164 	STRACE(("Layer(%s)::AddChild(%s) START\n", Name(), layer->Name()));
165 
166 	if (layer->fParent != NULL) {
167 		printf("ERROR: AddChild(): Layer already has a parent\n");
168 		return;
169 	}
170 
171 	// 1) attach layer to the tree structure
172 	layer->fParent = this;
173 
174 	// if we have children already, bump the current last child back one and
175 	// make the new child the last layer
176 	if (fLastChild) {
177 		layer->fPreviousSibling = fLastChild;
178 		fLastChild->fNextSibling = layer;
179 	} else {
180 		fFirstChild = layer;
181 	}
182 	fLastChild = layer;
183 
184 	// if we have no RootLayer yet, then there is no need to set any parameters --
185 	// they will be set when the RootLayer for this tree will be added
186 	// to the main tree structure.
187 	if (!fRootLayer) {
188 		STRACE(("Layer(%s)::AddChild(%s) END\n", Name(), layer->Name()));
189 		return;
190 	}
191 
192 	// 2) Iterate over the newly-added layer and all its children, setting the
193 	//	root layer and server window and also rebuilding the full-size region
194 	//	for every descendant of the newly-added layer
195 
196 	//c = short for: current
197 	Layer* c = layer;
198 	Layer* stop = layer;
199 	while (true) {
200 		// action block
201 
202 		// 2.1) set the RootLayer for this object.
203 		c->SetRootLayer(c->fParent->fRootLayer);
204 
205 		// 2.2) this Layer must know if it has a ServerWindow object attached.
206 		c->fServerWin=serverWin;
207 
208 		// 2.3) we are attached to the main tree so build our full region.
209 #ifndef NEW_CLIPPING
210 		c->RebuildFullRegion();
211 #endif
212 		// tree parsing algorithm
213 		if (c->fFirstChild) {
214 			// go deep
215 			c = c->fFirstChild;
216 		} else {
217 			// go right or up
218 
219 			if (c == stop) // our trip is over
220 				break;
221 
222 			if (c->fNextSibling) {
223 				// go right
224 				c = c->fNextSibling;
225 			} else {
226 				// go up
227 				while (!c->fParent->fNextSibling && c->fParent != stop)
228 					c = c->fParent;
229 
230 				if (c->fParent == stop) // that's enough!
231 					break;
232 
233 				c = c->fParent->fNextSibling;
234 			}
235 		}
236 	}
237 
238 	STRACE(("Layer(%s)::AddChild(%s) END\n", Name(), layer->Name()));
239 }
240 
241 /*!
242 	\brief Removes a child layer from the current one
243 	\param layer the layer to remove
244 
245 	If the layer does not belong to the the current layer, then this function
246 	spits out an error to stdout and returns
247 */
248 void
249 Layer::RemoveChild(Layer *layer)
250 {
251 	STRACE(("Layer(%s)::RemoveChild(%s) START\n", Name(), layer->Name()));
252 
253 	if (!layer->fParent) {
254 		printf("ERROR: RemoveChild(): Layer doesn't have a parent\n");
255 		return;
256 	}
257 
258 	if (layer->fParent != this) {
259 		printf("ERROR: RemoveChild(): Layer is not a child of this layer\n");
260 		return;
261 	}
262 
263 	// 1) remove this layer from the main tree.
264 
265 	// Take care of fParent
266 	layer->fParent = NULL;
267 
268 	if (fFirstChild == layer)
269 		fFirstChild = layer->fNextSibling;
270 
271 	if (fLastChild == layer)
272 		fLastChild = layer->fPreviousSibling;
273 
274 	// Take care of siblings
275 	if (layer->fPreviousSibling != NULL)
276 		layer->fPreviousSibling->fNextSibling	= layer->fNextSibling;
277 
278 	if (layer->fNextSibling != NULL)
279 		layer->fNextSibling->fPreviousSibling = layer->fPreviousSibling;
280 
281 	layer->fPreviousSibling = NULL;
282 	layer->fNextSibling = NULL;
283 
284 #ifdef NEW_CLIPPING
285 	layer->clear_visible_regions();
286 #endif
287 
288 	// 2) Iterate over all of the removed-layer's descendants and unset the
289 	//	root layer, server window, and all redraw-related regions
290 
291 	Layer* c = layer; //c = short for: current
292 	Layer* stop = layer;
293 
294 	while (true) {
295 		// action block
296 		{
297 			// 2.1) set the RootLayer for this object.
298 			c->SetRootLayer(NULL);
299 			// 2.2) this Layer must know if it has a ServerWindow object attached.
300 			c->fServerWin = NULL;
301 			// 2.3) we were removed from the main tree so clear our full region.
302 #ifndef NEW_CLIPPING
303 			c->fFull.MakeEmpty();
304 			// 2.4) clear fullVisible region.
305 			c->fFullVisible.MakeEmpty();
306 			// 2.5) we don't have a visible region anymore.
307 			c->fVisible.MakeEmpty();
308 #endif
309 		}
310 
311 		// tree parsing algorithm
312 		if (c->fFirstChild) {
313 			// go deep
314 			c = c->fFirstChild;
315 		} else {
316 			// go right or up
317 			if (c == stop) // out trip is over
318 				break;
319 
320 			if (c->fNextSibling) {
321 				// go right
322 				c = c->fNextSibling;
323 			} else {
324 				// go up
325 				while(!c->fParent->fNextSibling && c->fParent != stop)
326 					c = c->fParent;
327 
328 				if (c->fParent == stop) // that enough!
329 					break;
330 
331 				c = c->fParent->fNextSibling;
332 			}
333 		}
334 	}
335 	STRACE(("Layer(%s)::RemoveChild(%s) END\n", Name(), layer->Name()));
336 }
337 
338 //! Removes the calling layer from the tree
339 void
340 Layer::RemoveSelf()
341 {
342 	// A Layer removes itself from the tree (duh)
343 	if (fParent == NULL) {
344 		printf("ERROR: RemoveSelf(): Layer doesn't have a parent\n");
345 		return;
346 	}
347 	fParent->RemoveChild(this);
348 }
349 
350 /*!
351 	\return true if the child is owned by this Layer, false if not
352 */
353 bool
354 Layer::HasChild(Layer* layer)
355 {
356 	for (Layer* child = FirstChild(); child; child = NextChild()) {
357 		if (child == layer)
358 			return true;
359 	}
360 	return false;
361 }
362 
363 //! Returns the number of children
364 uint32
365 Layer::CountChildren() const
366 {
367 	uint32 count = 0;
368 	Layer* child = FirstChild();
369 	while (child != NULL) {
370 		child = NextChild();
371 		count++;
372 	}
373 	return count;
374 }
375 
376 /*!
377 	\brief Finds a child of the caller based on its token ID
378 	\param token ID of the layer to find
379 	\return Pointer to the layer or NULL if not found
380 */
381 Layer*
382 Layer::FindLayer(const int32 token)
383 {
384 	// (recursive) search for a layer based on its view token
385 
386 	// iterate only over direct child layers first
387 	for (Layer* child = FirstChild(); child; child = NextChild()) {
388 		if (child->fViewToken == token)
389 			return child;
390 	}
391 
392 	// try a recursive search
393 	for (Layer* child = FirstChild(); child; child = NextChild()) {
394 		if (Layer* layer = child->FindLayer(token))
395 			return layer;
396 	}
397 
398 	return NULL;
399 }
400 
401 /*!
402 	\brief Returns the layer at the given point
403 	\param pt The point to look the layer at
404 	\return The layer containing the point or NULL if no layer found
405 */
406 Layer*
407 Layer::LayerAt(const BPoint &pt)
408 {
409 	//printf("%p:%s:LayerAt(x = %g, y = %g)\n", this, Name(), pt.x, pt.y);
410 #ifndef NEW_CLIPPING
411 	if (fVisible.Contains(pt))
412 		return this;
413 
414 	if (fFullVisible.Contains(pt)) {
415 		for (Layer* child = LastChild(); child; child = PreviousChild()) {
416 			if (Layer* layer = child->LayerAt(pt))
417 				return layer;
418 		}
419 	}
420 #else
421 	if (fVisible2.Contains(pt))
422 		return this;
423 
424 	if (fFullVisible2.Contains(pt)) {
425 		for (Layer* child = LastChild(); child; child = PreviousChild()) {
426 			if (Layer* layer = child->LayerAt(pt))
427 				return layer;
428 		}
429 	}
430 #endif
431 	return NULL;
432 }
433 
434 // FirstChild
435 Layer*
436 Layer::FirstChild() const
437 {
438 	fCurrent = fFirstChild;
439 	return fCurrent;
440 }
441 
442 // NextChild
443 Layer*
444 Layer::NextChild() const
445 {
446 	fCurrent = fCurrent->fNextSibling;
447 	return fCurrent;
448 }
449 
450 // PreviousChild
451 Layer*
452 Layer::PreviousChild() const
453 {
454 	fCurrent = fCurrent->fPreviousSibling;
455 	return fCurrent;
456 }
457 
458 // LastChild
459 Layer*
460 Layer::LastChild() const
461 {
462 	fCurrent = fLastChild;
463 	return fCurrent;
464 }
465 
466 // SetName
467 void
468 Layer::SetName(const char* name)
469 {
470 	fName.SetTo(name);
471 }
472 
473 // SetFlags
474 void
475 Layer::SetFlags(uint32 flags)
476 {
477 	fFlags = flags;
478 	fLayerData->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
479 }
480 
481 #ifndef NEW_CLIPPING
482 
483 //! Rebuilds the layer's "completely visible" region
484 void
485 Layer::RebuildFullRegion(void)
486 {
487 	STRACE(("Layer(%s)::RebuildFullRegion()\n", Name()));
488 
489 	if (fParent)
490 		fFull.Set(fParent->ConvertToTop(fFrame ));
491 	else
492 		fFull.Set(fFrame);
493 
494 	// TODO: restrict to screen coordinates
495 
496 	// TODO: Convert to screen coordinates
497 
498 	LayerData *ld;
499 	ld = fLayerData;
500 	do {
501 		// clip to user region
502 		if (const BRegion* userClipping = ld->ClippingRegion())
503 			fFull.IntersectWith(userClipping);
504 
505 	} while ((ld = ld->prevState));
506 }
507 
508 // StartRebuildRegions
509 void
510 Layer::StartRebuildRegions( const BRegion& reg, Layer *target, uint32 action, BPoint& pt)
511 {
512 	STRACE(("Layer(%s)::StartRebuildRegions() START\n", Name()));
513 	RBTRACE(("\n\nLayer(%s)::StartRebuildRegions() START\n", Name()));
514 	if (!fParent)
515 		fFullVisible = fFull;
516 
517 	BRegion oldVisible = fVisible;
518 
519 	fVisible = fFullVisible;
520 
521 	// Rebuild regions for children...
522 	for (Layer *lay = LastChild(); lay; lay = PreviousChild()) {
523 		if (lay == target)
524 			lay->RebuildRegions(reg, action, pt, BPoint(0.0f, 0.0f));
525 		else
526 			lay->RebuildRegions(reg, B_LAYER_NONE, pt, BPoint(0.0f, 0.0f));
527 	}
528 
529 	#ifdef DEBUG_LAYER_REBUILD
530 		printf("\nSRR: Layer(%s) ALMOST done regions:\n", Name());
531 		printf("\tVisible Region:\n");
532 		fVisible.PrintToStream();
533 		printf("\tFull Visible Region:\n");
534 		fFullVisible.PrintToStream();
535 	#endif
536 
537 	BRegion redrawReg(fVisible);
538 
539 	// if this is the first time
540 	if (oldVisible.CountRects() > 0)
541 		redrawReg.Exclude(&oldVisible);
542 
543 	if (redrawReg.CountRects() > 0)
544 		fRootLayer->fRedrawReg.Include(&redrawReg);
545 
546 	#ifdef DEBUG_LAYER_REBUILD
547 		printf("\nLayer(%s)::StartRebuildRegions() DONE. Results:\n", Name());
548 		printf("\tRedraw Region:\n");
549 		fRootLayer->fRedrawReg.PrintToStream();
550 		printf("\tCopy Region:\n");
551 		for (int32 k=0; k<fRootLayer->fCopyRegList.CountItems(); k++) {
552 			((BRegion*)(fRootLayer->fCopyRegList.ItemAt(k)))->PrintToStream();
553 			((BPoint*)(fRootLayer->fCopyList.ItemAt(k)))->PrintToStream();
554 		}
555 		printf("\n");
556 	#endif
557 
558 	STRACE(("Layer(%s)::StartRebuildRegions() END\n", Name()));
559 	RBTRACE(("Layer(%s)::StartRebuildRegions() END\n", Name()));
560 }
561 
562 // RebuildRegions
563 void
564 Layer::RebuildRegions( const BRegion& reg, uint32 action, BPoint pt, BPoint ptOffset)
565 {
566 	STRACE(("Layer(%s)::RebuildRegions() START\n", Name()));
567 
568 	// TODO:/NOTE: this method must be executed as quickly as possible.
569 
570 	// Currently SendView[Moved/Resized]Msg() simply constructs a message and calls
571 	// ServerWindow::SendMessageToClient(). This involves the alternative use of
572 	// kernel and this code in the CPU, so there are a lot of context switches.
573 	// This is NOT good at all!
574 
575 	// One alternative would be the use of a BMessageQueue per ServerWindows OR only
576 	// one for app_server which will be emptied as soon as this critical operation ended.
577 	// Talk to DW, Gabe.
578 
579 	BRegion	oldRegion;
580 	uint32 newAction = action;
581 	BPoint newPt = pt;
582 	BPoint newOffset = ptOffset; // used for resizing only
583 
584 	BPoint dummyNewLocation;
585 
586 	RRLabel1:
587 	switch(action) {
588 		case B_LAYER_NONE: {
589 			RBTRACE(("1) Layer(%s): Action B_LAYER_NONE\n", Name()));
590 			STRACE(("1) Layer(%s): Action B_LAYER_NONE\n", Name()));
591 			oldRegion = fVisible;
592 			break;
593 		}
594 		case B_LAYER_MOVE: {
595 			RBTRACE(("1) Layer(%s): Action B_LAYER_MOVE\n", Name()));
596 			STRACE(("1) Layer(%s): Action B_LAYER_MOVE\n", Name()));
597 			oldRegion = fFullVisible;
598 			fFrame.OffsetBy(pt.x, pt.y);
599 			fFull.OffsetBy(pt.x, pt.y);
600 
601 			// TODO: investigate combining frame event messages for efficiency
602 			//SendViewMovedMsg();
603 			AddToViewsWithInvalidCoords();
604 
605 			newAction	= B_LAYER_SIMPLE_MOVE;
606 			break;
607 		}
608 		case B_LAYER_SIMPLE_MOVE: {
609 			RBTRACE(("1) Layer(%s): Action B_LAYER_SIMPLE_MOVE\n", Name()));
610 			STRACE(("1) Layer(%s): Action B_LAYER_SIMPLE_MOVE\n", Name()));
611 			fFull.OffsetBy(pt.x, pt.y);
612 
613 			break;
614 		}
615 		case B_LAYER_RESIZE: {
616 			RBTRACE(("1) Layer(%s): Action B_LAYER_RESIZE\n", Name()));
617 			STRACE(("1) Layer(%s): Action B_LAYER_RESIZE\n", Name()));
618 			oldRegion	= fVisible;
619 
620 			fFrame.right	+= pt.x;
621 			fFrame.bottom	+= pt.y;
622 			RebuildFullRegion();
623 
624 			// TODO: investigate combining frame event messages for efficiency
625 			//SendViewResizedMsg();
626 			AddToViewsWithInvalidCoords();
627 
628 			newAction = B_LAYER_MASK_RESIZE;
629 			break;
630 		}
631 		case B_LAYER_MASK_RESIZE: {
632 			RBTRACE(("1) Layer(%s): Action B_LAYER_MASK_RESIZE\n", Name()));
633 			STRACE(("1) Layer(%s): Action B_LAYER_MASK_RESIZE\n", Name()));
634 			oldRegion = fVisible;
635 
636 			BPoint offset, rSize;
637 			BPoint coords[2];
638 
639 			ResizeOthers(pt.x, pt.y, coords, NULL);
640 			offset = coords[0];
641 			rSize = coords[1];
642 			newOffset = offset + ptOffset;
643 
644 			if (!(rSize.x == 0.0f && rSize.y == 0.0f)) {
645 				fFrame.OffsetBy(offset);
646 				fFrame.right += rSize.x;
647 				fFrame.bottom += rSize.y;
648 				RebuildFullRegion();
649 
650 				// TODO: investigate combining frame event messages for efficiency
651 				//SendViewResizedMsg();
652 				AddToViewsWithInvalidCoords();
653 
654 				newAction = B_LAYER_MASK_RESIZE;
655 				newPt = rSize;
656 				dummyNewLocation = newOffset;
657 			} else {
658 				if (!(offset.x == 0.0f && offset.y == 0.0f)) {
659 					pt = newOffset;
660 					action = B_LAYER_MOVE;
661 					newPt = pt;
662 					goto RRLabel1;
663 				} else {
664 					pt = ptOffset;
665 					action = B_LAYER_MOVE;
666 					newPt = pt;
667 					goto RRLabel1;
668 				}
669 			}
670 			break;
671 		}
672 	}
673 
674 	if (!IsHidden()) {
675 		#ifdef DEBUG_LAYER_REBUILD
676 			printf("Layer(%s) real action START\n", Name());
677 			fFull.PrintToStream();
678 		#endif
679 		fFullVisible.MakeEmpty();
680 		fVisible = fFull;
681 
682 		if (fParent && fVisible.CountRects() > 0) {
683 			// not the usual case, but support fot this is needed.
684 			if (fParent->fAdFlags & B_LAYER_CHILDREN_DEPENDANT) {
685 				#ifdef DEBUG_LAYER_REBUILD
686 					printf("   B_LAYER_CHILDREN_DEPENDANT Parent\n");
687 				#endif
688 
689 				// because we're skipping one level, we need to do out
690 				// parent business as well.
691 
692 				// our visible area is relative to our parent's parent.
693 				if (fParent->fParent)
694 					fVisible.IntersectWith(&(fParent->fParent->fVisible));
695 
696 				// exclude parent's visible area which could be composed by
697 				// prior siblings' visible areas.
698 				if (fVisible.CountRects() > 0)
699 					fVisible.Exclude(&(fParent->fVisible));
700 
701 				// we have a final visible area. Include it to our parent's one,
702 				// exclude from parent's parent.
703 				if (fVisible.CountRects() > 0) {
704 					fParent->fFullVisible.Include(&fVisible);
705 
706 					if (fParent->fParent)
707 						fParent->fParent->fVisible.Exclude(&fVisible);
708 				}
709 			} else {
710 				// for 95+% of cases
711 
712 				#ifdef DEBUG_LAYER_REBUILD
713 					printf("   (!)B_LAYER_CHILDREN_DEPENDANT Parent\n");
714 				#endif
715 
716 				// the visible area is the one common with parent's one.
717 				fVisible.IntersectWith(&(fParent->fVisible));
718 
719 				// exclude from parent's visible area. we're the owners now.
720 				if (fVisible.CountRects() > 0)
721 					fParent->fVisible.Exclude(&fVisible);
722 			}
723 		}
724 		fFullVisible = fVisible;
725 	}
726 
727 	// Rebuild regions for children...
728 	for(Layer *lay = LastChild(); lay != NULL; lay = PreviousChild())
729 		lay->RebuildRegions(reg, newAction, newPt, newOffset);
730 
731 	#ifdef DEBUG_LAYER_REBUILD
732 		printf("\nLayer(%s) ALMOST done regions:\n", Name());
733 		printf("\tVisible Region:\n");
734 		fVisible.PrintToStream();
735 		printf("\tFull Visible Region:\n");
736 		fFullVisible.PrintToStream();
737 	#endif
738 
739 	if(!IsHidden()) {
740 		switch(action) {
741 			case B_LAYER_NONE: {
742 				RBTRACE(("2) Layer(%s): Action B_LAYER_NONE\n", Name()));
743 				BRegion r(fVisible);
744 				if (oldRegion.CountRects() > 0)
745 					r.Exclude(&oldRegion);
746 
747 				if(r.CountRects() > 0)
748 					fRootLayer->fRedrawReg.Include(&r);
749 				break;
750 			}
751 			case B_LAYER_MOVE: {
752 				RBTRACE(("2) Layer(%s): Action B_LAYER_MOVE\n", Name()));
753 				BRegion redrawReg;
754 				BRegion	*copyReg = new BRegion();
755 				BRegion	screenReg(fRootLayer->Bounds());
756 
757 				oldRegion.OffsetBy(pt.x, pt.y);
758 				oldRegion.IntersectWith(&fFullVisible);
759 
760 				*copyReg = oldRegion;
761 				copyReg->IntersectWith(&screenReg);
762 				if (copyReg->CountRects() > 0 && !(pt.x == 0.0f && pt.y == 0.0f)) {
763 					copyReg->OffsetBy(-pt.x, -pt.y);
764 					BPoint		*point = new BPoint(pt);
765 					fRootLayer->fCopyRegList.AddItem(copyReg);
766 					fRootLayer->fCopyList.AddItem(point);
767 				} else {
768 					delete copyReg;
769 				}
770 
771 				redrawReg	= fFullVisible;
772 				redrawReg.Exclude(&oldRegion);
773 				if (redrawReg.CountRects() > 0 && !(pt.x == 0.0f && pt.y == 0.0f)) {
774 					fRootLayer->fRedrawReg.Include(&redrawReg);
775 				}
776 
777 				break;
778 			}
779 			case B_LAYER_RESIZE: {
780 				RBTRACE(("2) Layer(%s): Action B_LAYER_RESIZE\n", Name()));
781 				BRegion redrawReg;
782 
783 				redrawReg = fVisible;
784 				redrawReg.Exclude(&oldRegion);
785 				if(redrawReg.CountRects() > 0)
786 					fRootLayer->fRedrawReg.Include(&redrawReg);
787 
788 				break;
789 			}
790 			case B_LAYER_MASK_RESIZE: {
791 				RBTRACE(("2) Layer(%s): Action B_LAYER_MASK_RESIZE\n", Name()));
792 				BRegion redrawReg;
793 				BRegion	*copyReg = new BRegion();
794 
795 				oldRegion.OffsetBy(dummyNewLocation.x, dummyNewLocation.y);
796 
797 				redrawReg	= fVisible;
798 				redrawReg.Exclude(&oldRegion);
799 				if (redrawReg.CountRects() > 0)
800 					fRootLayer->fRedrawReg.Include(&redrawReg);
801 
802 				*copyReg = fVisible;
803 				copyReg->IntersectWith(&oldRegion);
804 				copyReg->OffsetBy(-dummyNewLocation.x, -dummyNewLocation.y);
805 				if (copyReg->CountRects() > 0
806 					&& !(dummyNewLocation.x == 0.0f && dummyNewLocation.y == 0.0f)) {
807 					fRootLayer->fCopyRegList.AddItem(copyReg);
808 					fRootLayer->fCopyList.AddItem(new BPoint(dummyNewLocation));
809 				}
810 
811 				break;
812 			}
813 			default:
814 				RBTRACE(("2) Layer(%s): Action default\n", Name()));
815 				break;
816 		}
817 	}
818 /*	if (IsHidden()) {
819 		fFullVisible.MakeEmpty();
820 		fVisible.MakeEmpty();
821 	}
822 */
823 
824 	STRACE(("Layer(%s)::RebuildRegions() END\n", Name()));
825 }
826 
827 // ResizeOthers
828 uint32
829 Layer::ResizeOthers(float x, float y, BPoint coords[], BPoint *ptOffset)
830 {
831 	STRACE(("Layer(%s)::ResizeOthers() START\n", Name()));
832 	uint32 rmask = fResizeMode;
833 
834 	// offset
835 	coords[0].x	= 0.0f;
836 	coords[0].y	= 0.0f;
837 
838 	// resize by width/height
839 	coords[1].x	= 0.0f;
840 	coords[1].y	= 0.0f;
841 
842 	if ((rmask & 0x00000f00UL)>>8 == _VIEW_LEFT_ &&
843 		(rmask & 0x0000000fUL)>>0 == _VIEW_RIGHT_) {
844 		coords[1].x		= x;
845 	} else if ((rmask & 0x00000f00UL)>>8 == _VIEW_LEFT_) {
846 	} else if ((rmask & 0x0000000fUL)>>0 == _VIEW_RIGHT_) {
847 		coords[0].x		= x;
848 	} else if ((rmask & 0x00000f00UL)>>8 == _VIEW_CENTER_) {
849 		coords[0].x		= x/2;
850 	} else {
851 		// illegal flag. Do nothing.
852 	}
853 
854 
855 	if ((rmask & 0x0000f000UL)>>12 == _VIEW_TOP_ &&
856 		(rmask & 0x000000f0UL)>>4 == _VIEW_BOTTOM_) {
857 		coords[1].y		= y;
858 	} else if ((rmask & 0x0000f000UL)>>12 == _VIEW_TOP_) {
859 	} else if ((rmask & 0x000000f0UL)>>4 == _VIEW_BOTTOM_) {
860 		coords[0].y		= y;
861 	} else if ((rmask & 0x0000f000UL)>>12 == _VIEW_CENTER_) {
862 		coords[0].y		= y/2;
863 	} else {
864 		// illegal flag. Do nothing.
865 	}
866 
867 	STRACE(("Layer(%s)::ResizeOthers() END\n", Name()));
868 	return 0UL;
869 }
870 
871 #endif
872 
873 // Redraw
874 void
875 Layer::Redraw(const BRegion& reg, Layer *startFrom)
876 {
877 	STRACE(("Layer(%s)::Redraw();\n", Name()));
878 	if (IsHidden())
879 		// this layer has nothing visible on screen, so bail out.
880 		return;
881 
882 	BRegion *pReg = const_cast<BRegion*>(&reg);
883 
884 	if (pReg->CountRects() > 0)
885 		RequestDraw(reg, startFrom);
886 
887 	STRACE(("Layer(%s)::Redraw() ENDED\n", Name()));
888 }
889 
890 // Draw
891 void
892 Layer::Draw(const BRect &rect)
893 {
894 #ifdef DEBUG_LAYER
895 	printf("Layer(%s)::Draw: ", Name());
896 	rect.PrintToStream();
897 #endif
898 
899 	if (!ViewColor().IsTransparentMagic())
900 		fDriver->FillRect(rect, ViewColor());
901 }
902 
903 #ifndef NEW_CLIPPING
904 // EmptyGlobals
905 void
906 Layer::EmptyGlobals()
907 {
908 	fRootLayer->fRedrawReg.MakeEmpty();
909 
910 	int32 count = fRootLayer->fCopyRegList.CountItems();
911 	for (int32 i = 0; i < count; i++)
912 		delete (BRegion*)fRootLayer->fCopyRegList.ItemAt(i);
913 	fRootLayer->fCopyRegList.MakeEmpty();
914 
915 	count = fRootLayer->fCopyList.CountItems();
916 	for (int32 i = 0; i < count; i++)
917 		delete (BPoint*)fRootLayer->fCopyList.ItemAt(i);
918 	fRootLayer->fCopyList.MakeEmpty();
919 }
920 #endif
921 
922 /*!
923 	\brief Shows the layer
924 	\param invalidate Invalidate the region when showing the layer. defaults to true
925 */
926 void
927 Layer::Show(bool invalidate)
928 {
929 	STRACE(("Layer(%s)::Show()\n", Name()));
930 	if(!IsHidden()) {
931 		// an ancestor may be hidden. OK, we're not visible,
932 		// but we're changing our visibility state
933 		fHidden	= false;
934 		return;
935 	}
936 
937 	fHidden	= false;
938 
939 	SendViewCoordUpdateMsg();
940 
941 // NOTE: I added this here and it solves the invalid region problem
942 // for Windows that have been resized before they were shown. -Stephan
943 #ifndef NEW_CLIPPING
944 RebuildFullRegion();
945 
946 	if (invalidate)
947 		GetRootLayer()->GoInvalidate(this, fFull);
948 #else
949 	if (invalidate) {
950 		// compute the region this layer wants for itself
951 		BRegion	invalidRegion;
952 		get_user_regions(invalidRegion);
953 		if (invalidRegion.CountRects() > 0)
954 			GetRootLayer()->GoInvalidate(this, invalidRegion);
955 	}
956 #endif
957 }
958 
959 /*!
960 	\brief Shows the layer
961 	\param invalidate Invalidate the region when hiding the layer. defaults to true
962 */
963 void
964 Layer::Hide(bool invalidate)
965 {
966 	STRACE(("Layer(%s)::Hide()\n", Name()));
967 	if (IsHidden()) {
968 		// an ancestor may be hidden. OK, we're not visible,
969 		// but we're changing our visibility state
970 		fHidden	= true;
971 		return;
972 	}
973 
974 	fHidden	= true;
975 #ifndef NEW_CLIPPING
976 	if (invalidate)
977 		GetRootLayer()->GoInvalidate(this, fFullVisible);
978 #else
979 	if (invalidate && fFullVisible2.CountRects() > 0) {
980 		GetRootLayer()->GoInvalidate(this, fFullVisible2);
981 	}
982 #endif
983 }
984 
985 //! Returns true if the layer is hidden
986 bool
987 Layer::IsHidden(void) const
988 {
989 	if (fHidden)
990 		return true;
991 
992 	if (fParent)
993 			return fParent->IsHidden();
994 
995 	return fHidden;
996 }
997 
998 
999 void
1000 Layer::PushState()
1001 {
1002 	LayerData *data = new LayerData(fLayerData);
1003 	fLayerData = data;
1004 
1005 	fLayerData->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
1006 }
1007 
1008 
1009 void
1010 Layer::PopState()
1011 {
1012 	if (fLayerData->prevState == NULL) {
1013 		fprintf(stderr, "WARNING: User called BView(%s)::PopState(), but there is NO state on stack!\n", Name());
1014 		return;
1015 	}
1016 
1017 	LayerData *data = fLayerData;
1018 	fLayerData = fLayerData->prevState;
1019 	data->prevState = NULL;
1020 	delete data;
1021 
1022 	fLayerData->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
1023 }
1024 
1025 
1026 //! Matches the BView call of the same name
1027 BRect
1028 Layer::Bounds(void) const
1029 {
1030 	BRect r(fFrame);
1031 //	r.OffsetTo(fBoundsLeftTop);
1032 	r.OffsetTo(BoundsOrigin());
1033 	return r;
1034 }
1035 
1036 //! Matches the BView call of the same name
1037 BRect
1038 Layer::Frame(void) const
1039 {
1040 	return fFrame;
1041 }
1042 
1043 //! Moves the layer by specified values, complete with redraw
1044 void
1045 Layer::MoveBy(float x, float y)
1046 {
1047 	STRACE(("Layer(%s)::MoveBy() START\n", Name()));
1048 	if (!fParent) {
1049 		CRITICAL("ERROR: in Layer::MoveBy()! - No parent!\n");
1050 		return;
1051 	}
1052 
1053 	BPrivate::PortLink msg(-1, -1);
1054 	msg.StartMessage(AS_ROOTLAYER_LAYER_MOVE);
1055 	msg.Attach<Layer*>(this);
1056 	msg.Attach<float>(x);
1057 	msg.Attach<float>(y);
1058 	GetRootLayer()->EnqueueMessage(msg);
1059 
1060 	STRACE(("Layer(%s)::MoveBy() END\n", Name()));
1061 }
1062 
1063 //! Resize the layer by the specified amount, complete with redraw
1064 void
1065 Layer::ResizeBy(float x, float y)
1066 {
1067 	STRACE(("Layer(%s)::ResizeBy() START\n", Name()));
1068 
1069 	if (!fParent) {
1070 		printf("ERROR: in Layer::ResizeBy()! - No parent!\n");
1071 		return;
1072 	}
1073 
1074 	BPrivate::PortLink msg(-1, -1);
1075 	msg.StartMessage(AS_ROOTLAYER_LAYER_RESIZE);
1076 	msg.Attach<Layer*>(this);
1077 	msg.Attach<float>(x);
1078 	msg.Attach<float>(y);
1079 	GetRootLayer()->EnqueueMessage(msg);
1080 
1081 	STRACE(("Layer(%s)::ResizeBy() END\n", Name()));
1082 }
1083 
1084 //! scrolls the layer by the specified amount, complete with redraw
1085 void
1086 Layer::ScrollBy(float x, float y)
1087 {
1088 	STRACE(("Layer(%s)::ScrollBy() START\n", Name()));
1089 
1090 	BPrivate::PortLink msg(-1, -1);
1091 	msg.StartMessage(AS_ROOTLAYER_LAYER_SCROLL);
1092 	msg.Attach<Layer*>(this);
1093 	msg.Attach<float>(x);
1094 	msg.Attach<float>(y);
1095 	GetRootLayer()->EnqueueMessage(msg);
1096 
1097 	STRACE(("Layer(%s)::ScrollBy() END\n", Name()));
1098 }
1099 
1100 // BoundsOrigin
1101 BPoint
1102 Layer::BoundsOrigin() const
1103 {
1104 	BPoint origin(0,0);
1105 	float scale = Scale();
1106 
1107 	LayerData *ld = fLayerData;
1108 	do {
1109 		origin += ld->Origin();
1110 	} while ((ld = ld->prevState));
1111 
1112 	origin.x *= scale;
1113 	origin.y *= scale;
1114 
1115 	return origin;
1116 }
1117 
1118 float
1119 Layer::Scale() const
1120 {
1121 	float scale = 1.0f;
1122 
1123 	LayerData *ld = fLayerData;
1124 	do {
1125 		scale *= ld->Scale();
1126 	} while ((ld = ld->prevState));
1127 
1128 	return scale;
1129 }
1130 
1131 //! Converts the passed point to parent coordinates
1132 BPoint
1133 Layer::ConvertToParent(BPoint pt)
1134 {
1135 #ifndef NEW_CLIPPING
1136 	pt -= BoundsOrigin();
1137 	pt += fFrame.LeftTop();
1138 	return pt;
1139 #else
1140 	ConvertToParent2(&pt);
1141 	return pt;
1142 #endif
1143 }
1144 
1145 //! Converts the passed rectangle to parent coordinates
1146 BRect
1147 Layer::ConvertToParent(BRect rect)
1148 {
1149 #ifndef NEW_CLIPPING
1150 //	rect.OffsetBy(fFrame.LeftTop());
1151 //	return rect;
1152 	rect.OffsetBy(-BoundsOrigin().x, -BoundsOrigin().y);
1153 	rect.OffsetBy(fFrame.LeftTop());
1154 	return rect;
1155 #else
1156 	ConvertToParent2(&rect);
1157 	return rect;
1158 #endif
1159 }
1160 
1161 //! Converts the passed region to parent coordinates
1162 BRegion
1163 Layer::ConvertToParent(BRegion* reg)
1164 {
1165 #ifndef NEW_CLIPPING
1166 	// TODO: wouldn't it be more efficient to use the copy
1167 	// constructor for BRegion and then call OffsetBy()?
1168 	BRegion newreg;
1169 	for (int32 i = 0; i < reg->CountRects(); i++)
1170 		newreg.Include(ConvertToParent(reg->RectAt(i)));
1171 	return newreg;
1172 #else
1173 	BRegion newReg(*reg);
1174 	ConvertToParent2(&newReg);
1175 	return newReg;
1176 #endif
1177 }
1178 
1179 //! Converts the passed point from parent coordinates
1180 BPoint
1181 Layer::ConvertFromParent(BPoint pt)
1182 {
1183 #ifndef NEW_CLIPPING
1184 //	return pt - fFrame.LeftTop();
1185 	pt -= fFrame.LeftTop();
1186 	pt += BoundsOrigin();
1187 	return pt;
1188 #else
1189 	ConvertFromParent2(&pt);
1190 	return pt;
1191 #endif
1192 }
1193 
1194 //! Converts the passed rectangle from parent coordinates
1195 BRect
1196 Layer::ConvertFromParent(BRect rect)
1197 {
1198 #ifndef NEW_CLIPPING
1199 //	rect.OffsetBy(-fFrame.left, -fFrame.top);
1200 //	return rect;
1201 	rect.OffsetBy(-fFrame.left, -fFrame.top);
1202 	rect.OffsetBy(BoundsOrigin());
1203 	return rect;
1204 #else
1205 	ConvertFromParent2(&rect);
1206 	return rect;
1207 #endif
1208 }
1209 
1210 //! Converts the passed region from parent coordinates
1211 BRegion
1212 Layer::ConvertFromParent(BRegion *reg)
1213 {
1214 #ifndef NEW_CLIPPING
1215 	BRegion newreg;
1216 	for(int32 i=0; i<reg->CountRects();i++)
1217 		newreg.Include(ConvertFromParent(reg->RectAt(i)));
1218 	return newreg;
1219 #else
1220 	BRegion newReg(*reg);
1221 	ConvertFromParent2(&newReg);
1222 	return newReg;
1223 #endif
1224 }
1225 
1226 // ConvertToTop
1227 BPoint
1228 Layer::ConvertToTop(BPoint pt)
1229 {
1230 #ifndef NEW_CLIPPING
1231 	if (fParent) {
1232 //		return (fParent->ConvertToTop(pt + fFrame.LeftTop()));
1233 		pt = ConvertToParent(pt);
1234 		return fParent->ConvertToTop(pt);
1235 	} else
1236 		return pt;
1237 #else
1238 	ConvertToScreen2(&pt);
1239 	return pt;
1240 #endif
1241 }
1242 
1243 //! Converts the passed rectangle to screen coordinates
1244 BRect
1245 Layer::ConvertToTop(BRect rect)
1246 {
1247 #ifndef NEW_CLIPPING
1248 	if (fParent) {
1249 //		return fParent->ConvertToTop(rect.OffsetByCopy(fFrame.LeftTop()));
1250 		rect = ConvertToParent(rect);
1251 		return fParent->ConvertToTop(rect);
1252 	} else
1253 		return rect;
1254 #else
1255 	ConvertToScreen2(&rect);
1256 	return rect;
1257 #endif
1258 }
1259 
1260 //! Converts the passed region to screen coordinates
1261 BRegion
1262 Layer::ConvertToTop(BRegion *reg)
1263 {
1264 #ifndef NEW_CLIPPING
1265 	BRegion newreg;
1266 	for (int32 i = 0; i < reg->CountRects();i++)
1267 		newreg.Include(ConvertToTop(reg->RectAt(i)));
1268 	return newreg;
1269 #else
1270 	BRegion newReg(*reg);
1271 	ConvertToScreen2(&newReg);
1272 	return newReg;
1273 #endif
1274 }
1275 
1276 // ConvertFromTop
1277 BPoint
1278 Layer::ConvertFromTop(BPoint pt)
1279 {
1280 #ifndef NEW_CLIPPING
1281 	if (fParent) {
1282 //		return fParent->ConvertFromTop(pt-fFrame.LeftTop());
1283 		pt = ConvertFromParent(pt);
1284 		return fParent->ConvertFromTop(pt);
1285 	} else
1286 		return pt;
1287 #else
1288 	ConvertFromScreen2(&pt);
1289 	return pt;
1290 #endif
1291 }
1292 
1293 //! Converts the passed rectangle from screen coordinates
1294 BRect
1295 Layer::ConvertFromTop(BRect rect)
1296 {
1297 #ifndef NEW_CLIPPING
1298 	if (fParent) {
1299 //		return fParent->ConvertFromTop(rect.OffsetByCopy(-fFrame.LeftTop().x,
1300 //														 -fFrame.LeftTop().y));
1301 		rect = ConvertFromParent(rect);
1302 		return fParent->ConvertFromTop(rect);
1303 	} else
1304 		return rect;
1305 #else
1306 	ConvertFromScreen2(&rect);
1307 	return rect;
1308 #endif
1309 }
1310 
1311 //! Converts the passed region from screen coordinates
1312 BRegion
1313 Layer::ConvertFromTop(BRegion *reg)
1314 {
1315 #ifndef NEW_CLIPPING
1316 	BRegion newreg;
1317 
1318 	for (int32 i = 0; i < reg->CountRects(); i++)
1319 		newreg.Include(ConvertFromTop(reg->RectAt(i)));
1320 
1321 	return newreg;
1322 #else
1323 	BRegion newReg(*reg);
1324 	ConvertFromScreen2(&newReg);
1325 	return newReg;
1326 #endif
1327 }
1328 
1329 //! Recursively deletes all children of the calling layer
1330 void
1331 Layer::PruneTree(void)
1332 {
1333 
1334 	Layer* lay;
1335 	Layer* nextlay;
1336 
1337 	lay = fFirstChild;
1338 	fFirstChild = NULL;
1339 
1340 	while (lay != NULL) {
1341 		if (lay->fFirstChild != NULL)
1342 			lay->PruneTree();
1343 
1344 		nextlay = lay->fNextSibling;
1345 		lay->fNextSibling = NULL;
1346 
1347 		delete lay;
1348 		lay = nextlay;
1349 	}
1350 	// Man, this thing is short. Elegant, ain't it? :P
1351 }
1352 
1353 //! Prints information about the layer's current state
1354 void
1355 Layer::PrintToStream()
1356 {
1357 	printf("\n *** Layer %s:\n", Name());
1358 	printf("\t Parent: %s", fParent ? fParent->Name() : "<no parent>");
1359 
1360 	printf("\t us: %s\t ls: %s\n",
1361 		fPreviousSibling ? fPreviousSibling->Name() : "<none>",
1362 		fNextSibling ? fNextSibling->Name() : "<none>");
1363 
1364 	printf("\t topChild: %s\t bottomChild: %s\n",
1365 		fFirstChild ? fFirstChild->Name() : "<none>",
1366 		fLastChild ? fLastChild->Name() : "<none>");
1367 
1368 	printf("Frame: (%f, %f, %f, %f)\n", fFrame.left, fFrame.top, fFrame.right, fFrame.bottom);
1369 	printf("LocalOrigin: (%f, %f)\n", BoundsOrigin().x, BoundsOrigin().y);
1370 	printf("Token: %ld\n", fViewToken);
1371 	printf("Hidden - direct: %s ", fHidden?"true":"false");
1372 	printf("Hidden - indirect: %s\n", IsHidden()?"true":"false");
1373 	printf("ResizingMode: %lx ", fResizeMode);
1374 	printf("Flags: %lx\n", fFlags);
1375 
1376 	if (fLayerData)
1377 		fLayerData->PrintToStream();
1378 	else
1379 		printf(" NO LayerData valid pointer\n");
1380 }
1381 
1382 //! Prints pointer info kept by the current layer
1383 void
1384 Layer::PrintNode()
1385 {
1386 	printf("-----------\nLayer %s\n", Name());
1387 	if (fParent)
1388 		printf("Parent: %s (%p)\n", fParent->Name(), fParent);
1389 	else
1390 		printf("Parent: NULL\n");
1391 
1392 	if (fPreviousSibling)
1393 		printf("Upper sibling: %s (%p)\n", fPreviousSibling->Name(), fPreviousSibling);
1394 	else
1395 		printf("Upper sibling: NULL\n");
1396 
1397 	if (fNextSibling)
1398 		printf("Lower sibling: %s (%p)\n", fNextSibling->Name(), fNextSibling);
1399 	else
1400 		printf("Lower sibling: NULL\n");
1401 
1402 	if (fFirstChild)
1403 		printf("Top child: %s (%p)\n", fFirstChild->Name(), fFirstChild);
1404 	else
1405 		printf("Top child: NULL\n");
1406 
1407 	if (fLastChild)
1408 		printf("Bottom child: %s (%p)\n", fLastChild->Name(), fLastChild);
1409 	else
1410 		printf("Bottom child: NULL\n");
1411 #ifndef NEW_CLIPPING
1412 	printf("Visible Areas: "); fVisible.PrintToStream();
1413 #endif
1414 }
1415 
1416 //! Prints the tree hierarchy from the current layer down
1417 void
1418 Layer::PrintTree()
1419 {
1420 	printf("\n Tree structure:\n");
1421 	printf("\t%s\t%s\n", Name(), IsHidden()? "Hidden": "NOT hidden");
1422 	for(Layer *lay = LastChild(); lay != NULL; lay = PreviousChild())
1423 		printf("\t%s\t%s\n", lay->Name(), lay->IsHidden()? "Hidden": "NOT hidden");
1424 }
1425 
1426 // RequestDraw
1427 void
1428 Layer::RequestDraw(const BRegion &reg, Layer *startFrom)
1429 {
1430 	STRACE(("Layer(%s)::RequestDraw()\n", Name()));
1431 
1432 	// do not redraw any child until you must
1433 	int redraw = false;
1434 	if (!startFrom)
1435 		redraw = true;
1436 
1437 #ifndef NEW_CLIPPING
1438 	if (HasClient() && IsTopLayer()) {
1439 		// calculate the minimum region/rectangle to be updated with
1440 		// a single message to the client.
1441 		BRegion	updateReg(fFullVisible);
1442 
1443 		if (fFlags & B_FULL_UPDATE_ON_RESIZE
1444 			&& fFrameAction	== B_LAYER_ACTION_RESIZE)
1445 		{
1446 			// do nothing
1447 		} else {
1448 			updateReg.IntersectWith(&reg);
1449 		}
1450 		if (updateReg.CountRects() > 0) {
1451 			fOwner->fCumulativeRegion.Include(&updateReg);
1452 			if (!fOwner->InUpdate() && !fOwner->fRequestSent) {
1453 				fOwner->fInUpdateRegion = fOwner->fCumulativeRegion;
1454 fOwner->cnt++;
1455 if (fOwner->cnt != 1)
1456 	CRITICAL("Layer::RequestDraw(): fOwner->cnt != 1 -> Not Allowed!");
1457 				fOwner->fCumulativeRegion.MakeEmpty();
1458 				fOwner->fRequestSent = true;
1459 				SendUpdateMsg(fOwner->fInUpdateRegion);
1460 			}
1461 		}
1462 	}
1463 
1464 	if (fVisible.CountRects() > 0) {
1465 		BRegion	updateReg(fVisible);
1466 		// calculate the update region
1467 		if (fFlags & B_FULL_UPDATE_ON_RESIZE && fFrameAction == B_LAYER_ACTION_RESIZE) {
1468 			// do nothing
1469 		} else {
1470 			updateReg.IntersectWith(&reg);
1471 		}
1472 
1473 		if (updateReg.CountRects() > 0) {
1474 			fDriver->ConstrainClippingRegion(&updateReg);
1475 			Draw(updateReg.Frame());
1476 			fDriver->ConstrainClippingRegion(NULL);
1477 		}
1478 	}
1479 
1480 	for (Layer *lay = LastChild(); lay != NULL; lay = PreviousChild()) {
1481 		if (lay == startFrom)
1482 			redraw = true;
1483 
1484 		if (redraw && !(lay->IsHidden())) {
1485 			// no need to go deeper if not even the FullVisible region intersects
1486 			// Update one.
1487 			BRegion common(lay->fFullVisible);
1488 			common.IntersectWith(&reg);
1489 
1490 			if (common.CountRects() > 0)
1491 				lay->RequestDraw(reg, NULL);
1492 		}
1493 	}
1494 #else
1495 	if (HasClient() && IsTopLayer()) {
1496 		// calculate the minimum region/rectangle to be updated with
1497 		// a single message to the client.
1498 		BRegion	updateReg(fFullVisible2);
1499 
1500 		updateReg.IntersectWith(&reg);
1501 
1502 		if (updateReg.CountRects() > 0) {
1503 			fOwner->fCumulativeRegion.Include(&updateReg);
1504 			if (!fOwner->InUpdate() && !fOwner->fRequestSent) {
1505 				fOwner->fInUpdateRegion = fOwner->fCumulativeRegion;
1506 fOwner->cnt++;
1507 if (fOwner->cnt != 1)
1508 	CRITICAL("Layer::RequestDraw(): fOwner->cnt != 1 -> Not Allowed!");
1509 				fOwner->fCumulativeRegion.MakeEmpty();
1510 				fOwner->fRequestSent = true;
1511 				SendUpdateMsg(fOwner->fInUpdateRegion);
1512 			}
1513 		}
1514 	}
1515 
1516 	if (fVisible2.CountRects() > 0) {
1517 		BRegion	updateReg(fVisible2);
1518 			updateReg.IntersectWith(&reg);
1519 
1520 		if (updateReg.CountRects() > 0) {
1521 			fDriver->ConstrainClippingRegion(&updateReg);
1522 			Draw(updateReg.Frame());
1523 			fDriver->ConstrainClippingRegion(NULL);
1524 		}
1525 	}
1526 
1527 	for (Layer *lay = LastChild(); lay != NULL; lay = PreviousChild()) {
1528 		if (lay == startFrom)
1529 			redraw = true;
1530 
1531 		if (redraw && !(lay->IsHidden())) {
1532 			// no need to go deeper if not even the FullVisible region intersects
1533 			// Update one.
1534 			BRegion common(lay->fFullVisible2);
1535 			common.IntersectWith(&reg);
1536 
1537 			if (common.CountRects() > 0)
1538 				lay->RequestDraw(reg, NULL);
1539 		}
1540 	}
1541 #endif
1542 }
1543 
1544 #ifndef NEW_CLIPPING
1545 
1546 // move_layer
1547 void
1548 Layer::move_layer(float x, float y)
1549 {
1550 /*	if (fClassID == AS_WINBORDER_CLASS) {
1551 		WinBorder	*wb = (WinBorder*)this;
1552 		wb->fCumulativeRegion.OffsetBy(x, y);
1553 		wb->fInUpdateRegion.OffsetBy(x, y);
1554 		wb->fSavedForUpdateRegion.OffsetBy(x, y);
1555 	}*/
1556 
1557 	fFrameAction = B_LAYER_ACTION_MOVE;
1558 
1559 	BPoint pt(x, y);
1560 	BRect rect(fFull.Frame().OffsetByCopy(pt));
1561 
1562 if (!fParent) {
1563 printf("no parent in Layer::move_layer() (%s)\n", Name());
1564 fFrameAction = B_LAYER_ACTION_NONE;
1565 return;
1566 }
1567 
1568 	fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_MOVE, pt);
1569 
1570 	fDriver->CopyRegionList(&fRootLayer->fCopyRegList,
1571 							&fRootLayer->fCopyList,
1572 							fRootLayer->fCopyRegList.CountItems(),
1573 							&fFullVisible);
1574 
1575 	fParent->Redraw(fRootLayer->fRedrawReg, this);
1576 
1577 	// redraw workspaces layer
1578 	if (dynamic_cast<WinBorder*>(this) != NULL && fRootLayer->WorkspacesLayer() != NULL) {
1579 		fRootLayer->GoRedraw(fRootLayer->WorkspacesLayer(), fRootLayer->WorkspacesLayer()->fVisible);
1580 	}
1581 
1582 	SendViewCoordUpdateMsg();
1583 
1584 	EmptyGlobals();
1585 
1586 	fFrameAction = B_LAYER_ACTION_NONE;
1587 }
1588 
1589 // resize_layer
1590 void
1591 Layer::resize_layer(float x, float y)
1592 {
1593 	fFrameAction = B_LAYER_ACTION_RESIZE;
1594 
1595 	BPoint pt(x,y);
1596 
1597 	BRect rect(fFull.Frame());
1598 	rect.right += x;
1599 	rect.bottom += y;
1600 
1601 if (!fParent) {
1602 printf("no parent in Layer::resize_layer() (%s)\n", Name());
1603 fFrameAction = B_LAYER_ACTION_NONE;
1604 return;
1605 }
1606 
1607 	fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_RESIZE, pt);
1608 
1609 	fDriver->CopyRegionList(&fRootLayer->fCopyRegList, &fRootLayer->fCopyList, fRootLayer->fCopyRegList.CountItems(), &fFullVisible);
1610 
1611 	fParent->Redraw(fRootLayer->fRedrawReg, this);
1612 
1613 	// redraw workspaces layer
1614 	if (dynamic_cast<WinBorder*>(this) != NULL && fRootLayer->WorkspacesLayer() != NULL) {
1615 		fRootLayer->GoRedraw(fRootLayer->WorkspacesLayer(), fRootLayer->WorkspacesLayer()->fVisible);
1616 	}
1617 
1618 	SendViewCoordUpdateMsg();
1619 
1620 	EmptyGlobals();
1621 
1622 	fFrameAction = B_LAYER_ACTION_NONE;
1623 }
1624 
1625 // FullInvalidate
1626 void
1627 Layer::FullInvalidate(const BRect &rect)
1628 {
1629 	FullInvalidate(BRegion(rect));
1630 }
1631 
1632 // FullInvalidate
1633 void
1634 Layer::FullInvalidate(const BRegion& region)
1635 {
1636 	STRACE(("Layer(%s)::FullInvalidate():\n", Name()));
1637 
1638 #ifdef DEBUG_LAYER
1639 	region.PrintToStream();
1640 	printf("\n");
1641 #endif
1642 
1643 	BPoint pt(0,0);
1644 	StartRebuildRegions(region, NULL,/* B_LAYER_INVALIDATE, pt); */B_LAYER_NONE, pt);
1645 
1646 	Redraw(fRootLayer->fRedrawReg);
1647 
1648 	EmptyGlobals();
1649 }
1650 
1651 // Invalidate
1652 void
1653 Layer::Invalidate(const BRegion& region)
1654 {
1655 	STRACE(("Layer(%s)::Invalidate():\n", Name()));
1656 #ifdef DEBUG_LAYER
1657 	region.PrintToStream();
1658 	printf("\n");
1659 #endif
1660 
1661 	fRootLayer->fRedrawReg	= region;
1662 
1663 	Redraw(fRootLayer->fRedrawReg);
1664 
1665 	EmptyGlobals();
1666 }
1667 
1668 #endif // 5 methods
1669 
1670 
1671 /*!
1672 	\brief Returns the layer's ServerWindow
1673 
1674 	If the layer's ServerWindow has not been assigned, it attempts to find
1675 	the owning ServerWindow in the tree.
1676 */
1677 ServerWindow*
1678 Layer::SearchForServerWindow()
1679 {
1680 	if (!fServerWin)
1681 		fServerWin=fParent->SearchForServerWindow();
1682 
1683 	return fServerWin;
1684 }
1685 
1686 //! Sends an _UPDATE_ message to the client BWindow
1687 void
1688 Layer::SendUpdateMsg(BRegion& reg)
1689 {
1690 	BMessage msg;
1691 	msg.what = _UPDATE_;
1692 #ifndef NEW_CLIPPING
1693 	msg.AddRect("_rect", ConvertFromTop(reg.Frame()));
1694 #else
1695 	BRect	rect(reg.Frame());
1696 	ConvertFromScreen2(&rect);
1697 	msg.AddRect("_rect", rect );
1698 #endif
1699 	msg.AddRect("debug_rect", reg.Frame());
1700 //	msg.AddInt32("_token",fViewToken);
1701 
1702 	fOwner->Window()->SendMessageToClient(&msg);
1703 }
1704 
1705 // AddToViewsWithInvalidCoords
1706 void
1707 Layer::AddToViewsWithInvalidCoords() const
1708 {
1709 	if (fServerWin) {
1710 		fServerWin->ClientViewsWithInvalidCoords().AddInt32("_token", fViewToken);
1711 		fServerWin->ClientViewsWithInvalidCoords().AddPoint("where", fFrame.LeftTop());
1712 		fServerWin->ClientViewsWithInvalidCoords().AddFloat("width", fFrame.Width());
1713 		fServerWin->ClientViewsWithInvalidCoords().AddFloat("height", fFrame.Height());
1714 	}
1715 }
1716 
1717 // SendViewCoordUpdateMsg
1718 void
1719 Layer::SendViewCoordUpdateMsg() const
1720 {
1721 	if (fServerWin && !fServerWin->ClientViewsWithInvalidCoords().IsEmpty()) {
1722 		fServerWin->SendMessageToClient(&fServerWin->ClientViewsWithInvalidCoords());
1723 		fServerWin->ClientViewsWithInvalidCoords().MakeEmpty();
1724 	}
1725 }
1726 
1727 // SetViewColor
1728 void
1729 Layer::SetViewColor(const RGBColor& color)
1730 {
1731 	fViewColor = color;
1732 }
1733 
1734 // SetBackgroundBitmap
1735 void
1736 Layer::SetBackgroundBitmap(const ServerBitmap* bitmap)
1737 {
1738 	// TODO: What about reference counting?
1739 	// "Release" old fBackgroundBitmap and "Aquire" new one?
1740 	fBackgroundBitmap = bitmap;
1741 }
1742 
1743 // SetOverlayBitmap
1744 void
1745 Layer::SetOverlayBitmap(const ServerBitmap* bitmap)
1746 {
1747 	// TODO: What about reference counting?
1748 	// "Release" old fOverlayBitmap and "Aquire" new one?
1749 	fOverlayBitmap = bitmap;
1750 }
1751 
1752 void
1753 Layer::CopyBits(BRect& src, BRect& dst, int32 xOffset, int32 yOffset) {
1754 
1755 	BPrivate::PortLink msg(-1, -1);
1756 	msg.StartMessage(AS_ROOTLAYER_LAYER_COPYBITS);
1757 	msg.Attach<Layer*>(this);
1758 	msg.Attach<BRect>(src);
1759 	msg.Attach<BRect>(dst);
1760 	msg.Attach<int32>(xOffset);
1761 	msg.Attach<int32>(yOffset);
1762 	GetRootLayer()->EnqueueMessage(msg);
1763 }
1764 
1765 void
1766 Layer::do_CopyBits(BRect& src, BRect& dst, int32 xOffset, int32 yOffset) {
1767 	// NOTE: The correct behaviour is this:
1768 	// * The region that is copied is the
1769 	//   src rectangle, no matter if it fits
1770 	//   into the dst rectangle. It is copied
1771 	//   by the offset dst.LeftTop() - src.LeftTop()
1772 	// * The dst rectangle is used for invalidation:
1773 	//   Any area in the dst rectangle that could
1774 	//   not be copied from src (because either the
1775 	//   src rectangle was not big enough, or because there
1776 	//   were parts cut off by the current layer clipping),
1777 	//   are triggering BView::Draw() to be called
1778 	//   and for these parts only.
1779 
1780 	// TODO: having moved this into Layer broke
1781 	// offscreen windows (bitmaps)
1782 	// -> move back into ServerWindow...
1783 	if (!GetRootLayer())
1784 		return;
1785 
1786 #ifndef NEW_CLIPPING
1787 
1788 	// the region that is going to be copied
1789 	BRegion copyRegion(src);
1790 	// apply the current clipping of the layer
1791 
1792 	copyRegion.IntersectWith(&fVisible);
1793 
1794 	// offset the region to the destination
1795 	// and apply the current clipping there as well
1796 	copyRegion.OffsetBy(xOffset, yOffset);
1797 	copyRegion.IntersectWith(&fVisible);
1798 
1799 	// the region at the destination that needs invalidation
1800 	GetRootLayer()->fRedrawReg.Set(dst);
1801 	// exclude the region drawn by the copy operation
1802 	GetRootLayer()->fRedrawReg.Exclude(&copyRegion);
1803 	// apply the current clipping as well
1804 	GetRootLayer()->fRedrawReg.IntersectWith(&fVisible);
1805 
1806 	// move the region back for the actual operation
1807 	copyRegion.OffsetBy(-xOffset, -yOffset);
1808 
1809 	GetDisplayDriver()->CopyRegion(&copyRegion, xOffset, yOffset);
1810 
1811 	// trigger the redraw
1812 	GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, NULL);
1813 #else
1814 	// the region that is going to be copied
1815 	BRegion copyRegion(src);
1816 	// apply the current clipping of the layer
1817 
1818 	copyRegion.IntersectWith(&fVisible2);
1819 
1820 	// offset the region to the destination
1821 	// and apply the current clipping there as well
1822 	copyRegion.OffsetBy(xOffset, yOffset);
1823 	copyRegion.IntersectWith(&fVisible2);
1824 
1825 	// the region at the destination that needs invalidation
1826 	GetRootLayer()->fRedrawReg.Set(dst);
1827 	// exclude the region drawn by the copy operation
1828 	GetRootLayer()->fRedrawReg.Exclude(&copyRegion);
1829 	// apply the current clipping as well
1830 	GetRootLayer()->fRedrawReg.IntersectWith(&fVisible2);
1831 
1832 	// move the region back for the actual operation
1833 	copyRegion.OffsetBy(-xOffset, -yOffset);
1834 
1835 	GetDisplayDriver()->CopyRegion(&copyRegion, xOffset, yOffset);
1836 
1837 	// trigger the redraw
1838 	GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, NULL);
1839 #endif
1840 
1841 }
1842 
1843 #ifdef NEW_CLIPPING
1844 
1845 void
1846 Layer::MovedByHook(float dx, float dy)
1847 {
1848 	if (Window() && Flags() & B_FRAME_EVENTS && !IsTopLayer()) {
1849 		BMessage msg(B_VIEW_MOVED);
1850 		msg.AddInt64("when", system_time());
1851 		msg.AddPoint("where", Frame().LeftTop());
1852 		Window()->SendMessageToClient(&msg, fViewToken, false);
1853 	}
1854 }
1855 
1856 void
1857 Layer::ResizedByHook(float dx, float dy, bool automatic)
1858 {
1859 	if (Window() && Flags() & B_FRAME_EVENTS && !IsTopLayer()) {
1860 		BMessage msg(B_VIEW_RESIZED);
1861 		msg.AddInt64("when", system_time());
1862 		msg.AddFloat("width", Frame().Width());
1863 		msg.AddFloat("height", Frame().Height());
1864 		msg.AddPoint("where", Frame().LeftTop());
1865 		Window()->SendMessageToClient(&msg, fViewToken, false);
1866 	}
1867 }
1868 
1869 void
1870 Layer::ScrolledByHook(float dx, float dy)
1871 {
1872 	// empty.
1873 }
1874 
1875 
1876 void
1877 Layer::GetWantedRegion(BRegion& reg) const
1878 {
1879 	// this is the same as get_user_region.
1880 	// because get_user_region modifies nothing.
1881 	const_cast<Layer*>(this)->Layer::get_user_regions(reg);
1882 }
1883 
1884 //! converts a point from local to parent's coordinate system
1885 void
1886 Layer::ConvertToParent2(BPoint* pt) const
1887 {
1888 	if (fParent) {
1889 		BPoint origin = BoundsOrigin();
1890 		pt->x -= origin.x;
1891 		pt->y -= origin.y;
1892 		pt->x += fFrame.left;
1893 		pt->y += fFrame.top;
1894 	}
1895 }
1896 
1897 //! converts a rect from local to parent's coordinate system
1898 void
1899 Layer::ConvertToParent2(BRect* rect) const
1900 {
1901 	if (fParent) {
1902 		BPoint origin = BoundsOrigin();
1903 		rect->OffsetBy(-origin.x, -origin.y);
1904 		rect->OffsetBy(fFrame.left, fFrame.top);
1905 	}
1906 }
1907 
1908 //! converts a region from local to parent's coordinate system
1909 void
1910 Layer::ConvertToParent2(BRegion* reg) const
1911 {
1912 	if (fParent) {
1913 		BPoint origin = BoundsOrigin();
1914 		reg->OffsetBy(-origin.x, -origin.y);
1915 		reg->OffsetBy(fFrame.left, fFrame.top);
1916 	}
1917 }
1918 
1919 //! converts a point from parent's to local coordinate system
1920 void
1921 Layer::ConvertFromParent2(BPoint* pt) const
1922 {
1923 	if (fParent) {
1924 		BPoint origin = BoundsOrigin();
1925 		pt->x += origin.x;
1926 		pt->y += origin.y;
1927 		pt->x -= fFrame.left;
1928 		pt->y -= fFrame.top;
1929 	}
1930 }
1931 
1932 //! converts a rect from parent's to local coordinate system
1933 void
1934 Layer::ConvertFromParent2(BRect* rect) const
1935 {
1936 	if (fParent) {
1937 		BPoint origin = BoundsOrigin();
1938 		rect->OffsetBy(origin.x, origin.y);
1939 		rect->OffsetBy(-fFrame.left, -fFrame.top);
1940 	}
1941 }
1942 
1943 //! converts a region from parent's to local coordinate system
1944 void
1945 Layer::ConvertFromParent2(BRegion* reg) const
1946 {
1947 	if (fParent) {
1948 		BPoint origin = BoundsOrigin();
1949 		reg->OffsetBy(origin.x, origin.y);
1950 		reg->OffsetBy(-fFrame.left, -fFrame.top);
1951 	}
1952 }
1953 
1954 //! converts a point from local to screen coordinate system
1955 void
1956 Layer::ConvertToScreen2(BPoint* pt) const
1957 {
1958 	if (GetRootLayer())
1959 		if (fParent) {
1960 			BPoint origin = BoundsOrigin();
1961 			pt->x -= origin.x;
1962 			pt->y -= origin.y;
1963 			pt->x += fFrame.left;
1964 			pt->y += fFrame.top;
1965 
1966 			fParent->ConvertToScreen2(pt);
1967 		}
1968 }
1969 
1970 //! converts a rect from local to screen coordinate system
1971 void
1972 Layer::ConvertToScreen2(BRect* rect) const
1973 {
1974 	if (GetRootLayer())
1975 		if (fParent) {
1976 			BPoint origin = BoundsOrigin();
1977 			rect->OffsetBy(-origin.x, -origin.y);
1978 			rect->OffsetBy(fFrame.left, fFrame.top);
1979 
1980 			fParent->ConvertToScreen2(rect);
1981 		}
1982 }
1983 
1984 //! converts a region from local to screen coordinate system
1985 void
1986 Layer::ConvertToScreen2(BRegion* reg) const
1987 {
1988 	if (GetRootLayer())
1989 		if (fParent) {
1990 			BPoint origin = BoundsOrigin();
1991 			reg->OffsetBy(-origin.x, -origin.y);
1992 			reg->OffsetBy(fFrame.left, fFrame.top);
1993 
1994 			fParent->ConvertToScreen2(reg);
1995 		}
1996 }
1997 
1998 //! converts a point from screen to local coordinate system
1999 void
2000 Layer::ConvertFromScreen2(BPoint* pt) const
2001 {
2002 	if (GetRootLayer())
2003 		if (fParent) {
2004 			BPoint origin = BoundsOrigin();
2005 			pt->x += origin.x;
2006 			pt->y += origin.y;
2007 			pt->x -= fFrame.left;
2008 			pt->y -= fFrame.top;
2009 
2010 			fParent->ConvertToScreen2(pt);
2011 		}
2012 }
2013 
2014 //! converts a rect from screen to local coordinate system
2015 void
2016 Layer::ConvertFromScreen2(BRect* rect) const
2017 {
2018 	if (GetRootLayer())
2019 		if (fParent) {
2020 			BPoint origin = BoundsOrigin();
2021 			rect->OffsetBy(origin.x, origin.y);
2022 			rect->OffsetBy(-fFrame.left, -fFrame.top);
2023 
2024 			fParent->ConvertFromScreen2(rect);
2025 		}
2026 }
2027 
2028 //! converts a region from screen to local coordinate system
2029 void
2030 Layer::ConvertFromScreen2(BRegion* reg) const
2031 {
2032 	if (GetRootLayer())
2033 		if (fParent) {
2034 			BPoint origin = BoundsOrigin();
2035 			reg->OffsetBy(origin.x, origin.y);
2036 			reg->OffsetBy(-fFrame.left, -fFrame.top);
2037 
2038 			fParent->ConvertFromScreen2(reg);
2039 		}
2040 }
2041 
2042 
2043 void
2044 Layer::do_Hide()
2045 {
2046 	fHidden = true;
2047 
2048 	if (fParent && !fParent->IsHidden() && GetRootLayer()) {
2049 		// save fullVisible so we know what to invalidate
2050 		BRegion invalid(fFullVisible2);
2051 
2052 		clear_visible_regions();
2053 
2054 		if (invalid.Frame().IsValid())
2055 			fParent->do_Invalidate(invalid, this);
2056 	}
2057 }
2058 
2059 void
2060 Layer::do_Show()
2061 {
2062 	fHidden = false;
2063 
2064 	if (fParent && !fParent->IsHidden() && GetRootLayer()) {
2065 		BRegion invalid;
2066 
2067 		get_user_regions(invalid);
2068 
2069 		if (invalid.CountRects() > 0)
2070 			fParent->do_Invalidate(invalid, this);
2071 	}
2072 }
2073 
2074 void
2075 Layer::do_Invalidate(const BRegion &invalid, const Layer *startFrom)
2076 {
2077 	BRegion		localVisible(fFullVisible2);
2078 	localVisible.IntersectWith(&invalid);
2079 	rebuild_visible_regions(invalid, localVisible,
2080 		startFrom? startFrom: LastChild());
2081 
2082 	// add localVisible to our RootLayer's redraw region.
2083 //	GetRootLayer()->fRedrawReg.Include(&localVisible);
2084 	GetRootLayer()->fRedrawReg = localVisible;
2085 	GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, NULL);
2086 //	GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
2087 }
2088 
2089 void
2090 Layer::do_Redraw(const BRegion &invalid, const Layer *startFrom)
2091 {
2092 	BRegion		localVisible(fFullVisible2);
2093 	localVisible.IntersectWith(&invalid);
2094 
2095 	// add localVisible to our RootLayer's redraw region.
2096 //	GetRootLayer()->fRedrawReg.Include(&localVisible);
2097 	GetRootLayer()->fRedrawReg = localVisible;
2098 	GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, NULL);
2099 //	GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
2100 }
2101 
2102 inline void
2103 Layer::resize_layer_frame_by(float x, float y)
2104 {
2105 	uint16		rm = fResizeMode & 0x0000FFFF;
2106 	BRect		newFrame = fFrame;
2107 
2108 	if ((rm & 0x0F00U) == _VIEW_LEFT_ << 8)
2109 		newFrame.left += 0.0f;
2110 	else if ((rm & 0x0F00U) == _VIEW_RIGHT_ << 8)
2111 		newFrame.left += x;
2112 	else if ((rm & 0x0F00U) == _VIEW_CENTER_ << 8)
2113 		newFrame.left += x/2;
2114 
2115 	if ((rm & 0x000FU) == _VIEW_LEFT_)
2116 		newFrame.right += 0.0f;
2117 	else if ((rm & 0x000FU) == _VIEW_RIGHT_)
2118 		newFrame.right += x;
2119 	else if ((rm & 0x000FU) == _VIEW_CENTER_)
2120 		newFrame.right += x/2;
2121 
2122 	if ((rm & 0xF000U) == _VIEW_TOP_ << 12)
2123 		newFrame.top += 0.0f;
2124 	else if ((rm & 0xF000U) == _VIEW_BOTTOM_ << 12)
2125 		newFrame.top += y;
2126 	else if ((rm & 0xF000U) == _VIEW_CENTER_ << 12)
2127 		newFrame.top += y/2;
2128 
2129 	if ((rm & 0x00F0U) == _VIEW_TOP_ << 4)
2130 		newFrame.bottom += 0.0f;
2131 	else if ((rm & 0x00F0U) == _VIEW_BOTTOM_ << 4)
2132 		newFrame.bottom += y;
2133 	else if ((rm & 0x00F0U) == _VIEW_CENTER_ << 4)
2134 		newFrame.bottom += y/2;
2135 
2136 	if (newFrame != fFrame) {
2137 		float		dx, dy;
2138 
2139 		dx	= newFrame.Width() - fFrame.Width();
2140 		dy	= newFrame.Height() - fFrame.Height();
2141 
2142 		fFrame	= newFrame;
2143 
2144 		if (dx != 0.0f || dy != 0.0f) {
2145 			// call hook function
2146 			ResizedByHook(dx, dy, true); // automatic
2147 
2148 			for (Layer *lay = LastChild(); lay; lay = PreviousChild())
2149 				lay->resize_layer_frame_by(dx, dy);
2150 		}
2151 		else
2152 			MovedByHook(dx, dy);
2153 	}
2154 }
2155 
2156 inline void
2157 Layer::rezize_layer_redraw_more(BRegion &reg, float dx, float dy)
2158 {
2159 	if (dx == 0 && dy == 0)
2160 		return;
2161 
2162 	for (Layer *lay = LastChild(); lay; lay = PreviousChild()) {
2163 		uint16		rm = lay->fResizeMode & 0x0000FFFF;
2164 
2165 		if ((rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT || (rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM) {
2166 			// NOTE: this is not exactly corect, but it works :-)
2167 			// Normaly we shoud've used the lay's old, required region - the one returned
2168 			// from get_user_region() with the old frame, and the current one. lay->Bounds()
2169 			// works for the moment so we leave it like this.
2170 
2171 			// calculate the old bounds.
2172 			BRect	oldBounds(lay->Bounds());
2173 			if ((rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT)
2174 				oldBounds.right -=dx;
2175 			if ((rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM)
2176 				oldBounds.bottom -=dy;
2177 
2178 			// compute the region that became visible because we got bigger OR smaller.
2179 			BRegion	regZ(lay->Bounds());
2180 			regZ.Include(oldBounds);
2181 			regZ.Exclude(oldBounds&lay->Bounds());
2182 
2183 			lay->ConvertToScreen2(&regZ);
2184 
2185 			// intersect that with this'(not lay's) fullVisible region
2186 			regZ.IntersectWith(&fFullVisible2);
2187 			reg.Include(&regZ);
2188 
2189 			lay->rezize_layer_redraw_more(reg,
2190 				(rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT? dx: 0,
2191 				(rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM? dy: 0);
2192 
2193 			// above, OR this:
2194 			// reg.Include(&lay->fFullVisible2);
2195 		}
2196 		else
2197 		if (((rm & 0x0F0F) == (uint16)B_FOLLOW_RIGHT && dx != 0) ||
2198 			((rm & 0x0F0F) == (uint16)B_FOLLOW_H_CENTER && dx != 0) ||
2199 			((rm & 0xF0F0) == (uint16)B_FOLLOW_BOTTOM && dy != 0)||
2200 			((rm & 0xF0F0) == (uint16)B_FOLLOW_V_CENTER && dy != 0))
2201 		{
2202 			reg.Include(&lay->fFullVisible2);
2203 		}
2204 	}
2205 }
2206 
2207 inline void
2208 Layer::resize_layer_full_update_on_resize(BRegion &reg, float dx, float dy)
2209 {
2210 	if (dx == 0 && dy == 0)
2211 		return;
2212 
2213 	for (Layer *lay = LastChild(); lay; lay = PreviousChild()) {
2214 		uint16		rm = lay->fResizeMode & 0x0000FFFF;
2215 
2216 		if ((rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT || (rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM) {
2217 			if (lay->fFlags & B_FULL_UPDATE_ON_RESIZE && lay->fVisible2.CountRects() > 0)
2218 				reg.Include(&lay->fVisible2);
2219 
2220 			lay->resize_layer_full_update_on_resize(reg,
2221 				(rm & 0x0F0F) == (uint16)B_FOLLOW_LEFT_RIGHT? dx: 0,
2222 				(rm & 0xF0F0) == (uint16)B_FOLLOW_TOP_BOTTOM? dy: 0);
2223 		}
2224 	}
2225 }
2226 
2227 void
2228 Layer::do_ResizeBy(float dx, float dy)
2229 {
2230 	fFrame.Set(fFrame.left, fFrame.top, fFrame.right+dx, fFrame.bottom+dy);
2231 
2232 	// resize children using their resize_mask.
2233 	for (Layer *lay = LastChild(); lay; lay = PreviousChild())
2234 			lay->resize_layer_frame_by(dx, dy);
2235 
2236 	// call hook function
2237 	if (dx != 0.0f || dy != 0.0f)
2238 		ResizedByHook(dx, dy, false); // manual
2239 
2240 	if (!IsHidden() && GetRootLayer()) {
2241 		BRegion oldFullVisible(fFullVisible2);
2242 		// this is required to invalidate the old border
2243 		BRegion oldVisible(fVisible2);
2244 
2245 		// in case they moved, bottom, right and center aligned layers must be redrawn
2246 		BRegion redrawMore;
2247 		rezize_layer_redraw_more(redrawMore, dx, dy);
2248 
2249 		// we'll invalidate the old area and the new, maxmial one.
2250 		BRegion invalid;
2251 		get_user_regions(invalid);
2252 		invalid.Include(&fFullVisible2);
2253 
2254 		clear_visible_regions();
2255 
2256 		fParent->do_RebuildVisibleRegions(invalid, this);
2257 
2258 		// done rebuilding regions, now redraw regions that became visible
2259 
2260 		// what's invalid, are the differences between to old and the new fullVisible region
2261 		// 1) in case we grow.
2262 		BRegion		redrawReg(fFullVisible2);
2263 		redrawReg.Exclude(&oldFullVisible);
2264 		// 2) in case we shrink
2265 		BRegion		redrawReg2(oldFullVisible);
2266 		redrawReg2.Exclude(&fFullVisible2);
2267 		// 3) combine.
2268 		redrawReg.Include(&redrawReg2);
2269 
2270 		// for center, right and bottom alligned layers, redraw their old positions
2271 		redrawReg.Include(&redrawMore);
2272 
2273 		// layers that had their frame modified must be entirely redrawn.
2274 		rezize_layer_redraw_more(redrawReg, dx, dy);
2275 
2276 		// add redrawReg to our RootLayer's redraw region.
2277 //		GetRootLayer()->fRedrawReg.Include(&redrawReg);
2278 		GetRootLayer()->fRedrawReg = redrawReg;
2279 		// include layer's visible region in case we want a full update on resize
2280 		if (fFlags & B_FULL_UPDATE_ON_RESIZE && fVisible2.Frame().IsValid()) {
2281 			resize_layer_full_update_on_resize(GetRootLayer()->fRedrawReg, dx, dy);
2282 
2283 			GetRootLayer()->fRedrawReg.Include(&fVisible2);
2284 			GetRootLayer()->fRedrawReg.Include(&oldVisible);
2285 		}
2286 		// clear canvas and set invalid regions for affected WinBorders
2287 		GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, NULL);
2288 //	GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
2289 	}
2290 }
2291 
2292 void Layer::do_MoveBy(float dx, float dy)
2293 {
2294 	if (dx == 0.0f && dy == 0.0f)
2295 		return;
2296 
2297 //	fFrame.Set(fFrame.left+dx, fFrame.top+dy, fFrame.right+dx, fFrame.bottom+dy);
2298 	fFrame.OffsetBy(dx, dy);
2299 
2300 	// call hook function
2301 	MovedByHook(dx, dy);
2302 
2303 	if (!IsHidden() && GetRootLayer()) {
2304 		BRegion oldFullVisible(fFullVisible2);
2305 
2306 		// we'll invalidate the old position and the new, maxmial one.
2307 		BRegion invalid;
2308 		get_user_regions(invalid);
2309 		invalid.Include(&fFullVisible2);
2310 
2311 		clear_visible_regions();
2312 
2313 		fParent->do_RebuildVisibleRegions(invalid, this);
2314 
2315 		// done rebuilding regions, now copy common parts and redraw regions that became visible
2316 
2317 		// include the actual and the old fullVisible regions. later, we'll exclude the common parts.
2318 		BRegion		redrawReg(fFullVisible2);
2319 		redrawReg.Include(&oldFullVisible);
2320 
2321 		// offset to layer's new location so that we can calculate the common region.
2322 		oldFullVisible.OffsetBy(dx, dy);
2323 
2324 		// finally we have the region that needs to be redrawn.
2325 		redrawReg.Exclude(&oldFullVisible);
2326 
2327 		// by intersecting the old fullVisible offseted to layer's new location, with the current
2328 		// fullVisible, we'll have the common region which can be copied using HW acceleration.
2329 		oldFullVisible.IntersectWith(&fFullVisible2);
2330 
2331 		// offset back and instruct the HW to do the actual copying.
2332 		oldFullVisible.OffsetBy(-dx, -dy);
2333 		GetDisplayDriver()->CopyRegion(&oldFullVisible, dx, dy);
2334 
2335 		// add redrawReg to our RootLayer's redraw region.
2336 //		GetRootLayer()->fRedrawReg.Include(&redrawReg);
2337 		GetRootLayer()->fRedrawReg = redrawReg;
2338 		GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, NULL);
2339 //	GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
2340 	}
2341 }
2342 
2343 void
2344 Layer::do_ScrollBy(float dx, float dy)
2345 {
2346 	fLayerData->OffsetOrigin(BPoint(dx, dy));
2347 //	fOrigin.Set(fOrigin.x + dx, fOrigin.y + dy);
2348 
2349 	if (!IsHidden() && GetRootLayer()) {
2350 		// set the region to be invalidated.
2351 		BRegion		invalid(fFullVisible2);
2352 
2353 		clear_visible_regions();
2354 
2355 		rebuild_visible_regions(invalid, invalid, LastChild());
2356 
2357 		// for the moment we say that the whole surface needs to be redraw.
2358 		BRegion		redrawReg(fFullVisible2);
2359 
2360 		// offset old region so that we can start comparing.
2361 		invalid.OffsetBy(dx, dy);
2362 
2363 		// compute the common region. we'll use HW acc to copy this to the new location.
2364 		invalid.IntersectWith(&fFullVisible2);
2365 		GetDisplayDriver()->CopyRegion(&invalid, -dx, -dy);
2366 
2367 		// common region goes back to its original location. then, by excluding
2368 		// it from curent fullVisible we'll obtain the region that needs to be redrawn.
2369 		invalid.OffsetBy(-dx, -dy);
2370 		redrawReg.Exclude(&invalid);
2371 
2372 //		GetRootLayer()->fRedrawReg.Include(&redrawReg);
2373 		GetRootLayer()->fRedrawReg = redrawReg;
2374 		GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, NULL);
2375 //	GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
2376 	}
2377 
2378 	if (dx != 0.0f || dy != 0.0f)
2379 		ScrolledByHook(dx, dy);
2380 }
2381 
2382 void
2383 Layer::get_user_regions(BRegion &reg)
2384 {
2385 	// 1) set to frame in screen coords
2386 	BRect screenFrame(Bounds());
2387 	ConvertToScreen2(&screenFrame);
2388 	reg.Set(screenFrame);
2389 
2390 	// 2) intersect with screen region
2391 	BRegion screenReg(GetRootLayer()->Bounds());
2392 	reg.IntersectWith(&screenReg);
2393 
2394 
2395 	// 3) impose user constrained regions
2396 	LayerData *stackData = fLayerData;
2397 	while (stackData) {
2398 		if (stackData->ClippingRegion()) {
2399 			// transform in screen coords
2400 // NOTE: Already is in screen coords, but I leave this here in
2401 // case we change it
2402 //			BRegion screenReg(*stackData->ClippingRegion());
2403 //			ConvertToScreen2(&screenReg);
2404 //			reg.IntersectWith(&screenReg);
2405 			reg.IntersectWith(stackData->ClippingRegion());
2406 		}
2407 		stackData = stackData->prevState;
2408 	}
2409 }
2410 
2411 void
2412 Layer::do_RebuildVisibleRegions(const BRegion &invalid, const Layer *startFrom)
2413 {
2414 	BRegion		localVisible(fFullVisible2);
2415 	localVisible.IntersectWith(&invalid);
2416 	rebuild_visible_regions(invalid, localVisible, startFrom);
2417 }
2418 
2419 void
2420 Layer::rebuild_visible_regions(const BRegion &invalid,
2421 								const BRegion &parentLocalVisible,
2422 								const Layer *startFrom)
2423 {
2424 	// no point in continuing if this layer is hidden. starting from here, all
2425 	// descendants have (and will have) invalid visible regions.
2426 	if (fHidden)
2427 		return;
2428 
2429 	// no need to go deeper if the parent doesn't have a visible region anymore
2430 	// and our fullVisible region is also empty.
2431 	if (!parentLocalVisible.Frame().IsValid() && !(fFullVisible2.CountRects() > 0))
2432 		return;
2433 
2434 	bool fullRebuild = false;
2435 
2436 	// intersect maximum wanted region with the invalid region
2437 	BRegion common;
2438 	get_user_regions(common);
2439 	common.IntersectWith(&invalid);
2440 
2441 	// if the resulted region is not valid, this layer is not in the catchment area
2442 	// of the region being invalidated
2443 	if (!common.CountRects() > 0)
2444 		return;
2445 
2446 	// now intersect with parent's visible part of the region that was/is invalidated
2447 	common.IntersectWith(&parentLocalVisible);
2448 
2449 	// exclude the invalid region
2450 	fFullVisible2.Exclude(&invalid);
2451 	fVisible2.Exclude(&invalid);
2452 
2453 	// put in what's really visible
2454 	fFullVisible2.Include(&common);
2455 
2456 	// this is to allow a layer to hide some parts of itself so children
2457 	// won't take them.
2458 	BRegion unalteredVisible(common);
2459 	bool altered = alter_visible_for_children(common);
2460 
2461 	for (Layer *lay = LastChild(); lay; lay = PreviousChild()) {
2462 		if (lay == startFrom)
2463 			fullRebuild = true;
2464 
2465 		if (fullRebuild)
2466 			lay->rebuild_visible_regions(invalid, common, lay->LastChild());
2467 
2468 		// to let children know much they can take from parent's visible region
2469 		common.Exclude(&lay->fFullVisible2);
2470 		// we've hidden some parts of our visible region from our children,
2471 		// and we must be in sysnc with this region too...
2472 		if (altered)
2473 			unalteredVisible.Exclude(&lay->fFullVisible2);
2474 	}
2475 
2476 	// the visible region of this layer is what left after all its children took
2477 	// what they could.
2478 	if (altered)
2479 		fVisible2.Include(&unalteredVisible);
2480 	else
2481 		fVisible2.Include(&common);
2482 }
2483 
2484 bool
2485 Layer::alter_visible_for_children(BRegion &reg)
2486 {
2487 	// Empty Hook function
2488 	return false;
2489 }
2490 
2491 void
2492 Layer::clear_visible_regions()
2493 {
2494 	// OPT: maybe we should uncomment these lines for performance
2495 	//if (fFullVisible2.CountRects() <= 0)
2496 	//	return;
2497 
2498 	fVisible2.MakeEmpty();
2499 	fFullVisible2.MakeEmpty();
2500 	for (Layer *child = LastChild(); child; child = PreviousChild())
2501 		child->clear_visible_regions();
2502 }
2503 
2504 #endif
2505 
2506