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