Layer.cpp revision 0f0232c767bdcd3a37520ef3cfdf15ea984334ee
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@myrealbox.com>
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
64enum {
65	B_LAYER_ACTION_NONE = 0,
66	B_LAYER_ACTION_MOVE,
67	B_LAYER_ACTION_RESIZE
68};
69
70Layer::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	fVisible(),
87	fFullVisible(),
88	fFull(),
89
90	fClipReg(&fVisible),
91
92	fServerWin(NULL),
93	fName(new BString(name)),
94	fViewToken(token),
95
96	fFlags(flags),
97	fResizeMode(resize),
98	fEventMask(0UL),
99	fEventOptions(0UL),
100	fHidden(false),
101	fIsTopLayer(false),
102
103	fAdFlags(0),
104	fClassID(AS_LAYER_CLASS),
105
106	fFrameAction(B_LAYER_ACTION_NONE),
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()) {
118char helper[1024];
119sprintf(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);
121CRITICAL(helper);
122		fFrame.Set(0, 0, 10, 10);
123	}
124
125	if (!fDriver)
126		CRITICAL("You MUST have a valid driver to init a Layer object\n");
127
128	STRACE(("Layer(%s) successfuly created\n", GetName()));
129}
130
131//! Destructor frees all allocated heap space
132Layer::~Layer()
133{
134	delete fLayerData;
135	delete fName;
136
137	// TODO: uncomment!
138	//PruneTree();
139
140//	fServerWin->RemoveChild(fDriver);
141//	delete fDriver;
142}
143
144/*!
145	\brief Adds a child layer to the current one
146	\param layer a new child layer
147	\param serverWin the serverwindow to which the layer will belong
148
149	Unlike the BView version, if the layer already belongs to another, then
150	it spits an error to stdout and returns.
151*/
152void
153Layer::AddChild(Layer* layer, ServerWindow* serverWin)
154{
155	STRACE(("Layer(%s)::AddChild(%s) START\n", GetName(), layer->GetName()));
156
157	if (layer->fParent != NULL) {
158		printf("ERROR: AddChild(): Layer already has a parent\n");
159		return;
160	}
161
162	// 1) attach layer to the tree structure
163	layer->fParent = this;
164
165	// if we have children already, bump the current front child back one and
166	// make the new child the frontmost layer
167	if (fBottomChild) {
168		layer->fUpperSibling = fBottomChild;
169		fBottomChild->fLowerSibling	= layer;
170	} else {
171		fTopChild = layer;
172	}
173	fBottomChild = layer;
174
175	// if we have no RootLayer yet, then there is no need to set any parameters --
176	// they will be set when the RootLayer for this tree will be added
177	// to the main tree structure.
178	if (!fRootLayer) {
179		STRACE(("Layer(%s)::AddChild(%s) END\n", GetName(), layer->GetName()));
180		return;
181	}
182
183	// 2) Iterate over the newly-added layer and all its children, setting the
184	//	root layer and server window and also rebuilding the full-size region
185	//	for every descendant of the newly-added layer
186
187	//c = short for: current
188	Layer* c = layer;
189	Layer* stop = layer;
190	while (true) {
191		// action block
192
193		// 2.1) set the RootLayer for this object.
194		c->SetRootLayer(c->fParent->fRootLayer);
195
196		// 2.2) this Layer must know if it has a ServerWindow object attached.
197		c->fServerWin=serverWin;
198
199		// 2.3) we are attached to the main tree so build our full region.
200		c->RebuildFullRegion();
201
202		// tree parsing algorithm
203		if (c->fTopChild) {
204			// go deep
205			c = c->fTopChild;
206		} else {
207			// go right or up
208
209			if (c == stop) // out trip is over
210				break;
211
212			if (c->fLowerSibling) {
213				// go right
214				c = c->fLowerSibling;
215			} else {
216				// go up
217				while (!c->fParent->fLowerSibling && c->fParent != stop)
218					c = c->fParent;
219
220				if (c->fParent == stop) // that's enough!
221					break;
222
223				c = c->fParent->fLowerSibling;
224			}
225		}
226	}
227
228	STRACE(("Layer(%s)::AddChild(%s) END\n", GetName(), layer->GetName()));
229}
230
231/*!
232	\brief Removes a child layer from the current one
233	\param layer the layer to remove
234
235	If the layer does not belong to the the current layer, then this function
236	spits out an error to stdout and returns
237*/
238void
239Layer::RemoveChild(Layer *layer)
240{
241	STRACE(("Layer(%s)::RemoveChild(%s) START\n", GetName(), layer->GetName()));
242
243	if (!layer->fParent) {
244		printf("ERROR: RemoveChild(): Layer doesn't have a fParent\n");
245		return;
246	}
247
248	if (layer->fParent != this) {
249		printf("ERROR: RemoveChild(): Layer is not a child of this layer\n");
250		return;
251	}
252
253	// 1) remove this layer from the main tree.
254
255	// Take care of fParent
256	layer->fParent = NULL;
257
258	if (fTopChild == layer)
259		fTopChild = layer->fLowerSibling;
260
261	if (fBottomChild == layer)
262		fBottomChild = layer->fUpperSibling;
263
264	// Take care of siblings
265	if (layer->fUpperSibling != NULL)
266		layer->fUpperSibling->fLowerSibling	= layer->fLowerSibling;
267
268	if (layer->fLowerSibling != NULL)
269		layer->fLowerSibling->fUpperSibling = layer->fUpperSibling;
270
271	layer->fUpperSibling = NULL;
272	layer->fLowerSibling = NULL;
273
274	// 2) Iterate over all of the removed-layer's descendants and unset the
275	//	root layer, server window, and all redraw-related regions
276
277	Layer* c = layer; //c = short for: current
278	Layer* stop = layer;
279
280	while (true) {
281		// action block
282		{
283			// 2.1) set the RootLayer for this object.
284			c->SetRootLayer(NULL);
285			// 2.2) this Layer must know if it has a ServerWindow object attached.
286			c->fServerWin = NULL;
287			// 2.3) we were removed from the main tree so clear our full region.
288			c->fFull.MakeEmpty();
289			// 2.4) clear fullVisible region.
290			c->fFullVisible.MakeEmpty();
291			// 2.5) we don't have a visible region anymore.
292			c->fVisible.MakeEmpty();
293		}
294
295		// tree parsing algorithm
296		if (c->fTopChild) {
297			// go deep
298			c = c->fTopChild;
299		} else {
300			// go right or up
301			if (c == stop) // out trip is over
302				break;
303
304			if (c->fLowerSibling) {
305				// go right
306				c = c->fLowerSibling;
307			} else {
308				// go up
309				while(!c->fParent->fLowerSibling && c->fParent != stop)
310					c = c->fParent;
311
312				if (c->fParent == stop) // that enough!
313					break;
314
315				c = c->fParent->fLowerSibling;
316			}
317		}
318	}
319	STRACE(("Layer(%s)::RemoveChild(%s) END\n", GetName(), layer->GetName()));
320}
321
322//! Removes the calling layer from the tree
323void
324Layer::RemoveSelf()
325{
326	// A Layer removes itself from the tree (duh)
327	if (fParent == NULL) {
328		printf("ERROR: RemoveSelf(): Layer doesn't have a fParent\n");
329		return;
330	}
331	fParent->RemoveChild(this);
332}
333
334/*!
335	\brief Determins if the calling layer has the passed layer as a child
336	\return true if the child is owned by the caller, false if not
337*/
338bool
339Layer::HasChild(Layer* layer)
340{
341	for (Layer *lay = TopChild(); lay; lay = LowerSibling()) {
342		if (lay == layer)
343			return true;
344	}
345	return false;
346}
347
348//! Returns the number of children
349uint32
350Layer::CountChildren(void) const
351{
352	uint32 count = 0;
353	Layer *lay = TopChild();
354	while (lay != NULL) {
355		lay	= LowerSibling();
356		count++;
357	}
358	return count;
359}
360
361/*!
362	\brief Finds a child of the caller based on its token ID
363	\param token ID of the layer to find
364	\return Pointer to the layer or NULL if not found
365*/
366Layer*
367Layer::FindLayer(const int32 token)
368{
369	// recursive search for a layer based on its view token
370	Layer* lay;
371	Layer* trylay;
372
373	// Search child layers first
374	for (lay = TopChild(); lay; lay = LowerSibling()) {
375		if (lay->fViewToken == token)
376			return lay;
377	}
378
379	// Hmmm... not in this layer's children. Try lower descendants
380	for (lay = TopChild(); lay != NULL; lay = LowerSibling()) {
381		trylay = lay->FindLayer(token);
382		if (trylay)
383			return trylay;
384	}
385
386	// Well, we got this far in the function,
387	// so apparently there is no match to be found
388	return NULL;
389}
390
391/*!
392	\brief Returns the layer at the given point
393	\param pt The point to look the layer at
394	\return The layer containing the point or NULL if no layer found
395*/
396Layer*
397Layer::LayerAt(const BPoint &pt)
398{
399	if (fVisible.Contains(pt))
400		return this;
401
402	if (fFullVisible.Contains(pt)) {
403		Layer *lay = NULL;
404		for (Layer* child = BottomChild(); child; child = UpperSibling()) {
405			lay = child->LayerAt(pt);
406			if (lay)
407				return lay;
408		}
409	}
410
411	return NULL;
412}
413
414// TopChild
415Layer*
416Layer::TopChild() const
417{
418	fCurrent = fTopChild;
419	return fCurrent;
420}
421
422// LowerSibling
423Layer*
424Layer::LowerSibling() const
425{
426	fCurrent = fCurrent->fLowerSibling;
427	return fCurrent;
428}
429
430// UpperSibling
431Layer*
432Layer::UpperSibling() const
433{
434	fCurrent = fCurrent->fUpperSibling;
435	return fCurrent;
436}
437
438// BottomChild
439Layer*
440Layer::BottomChild() const
441{
442	fCurrent = fBottomChild;
443	return fCurrent;
444}
445
446
447//! Rebuilds the layer's "completely visible" region
448void
449Layer::RebuildFullRegion(void)
450{
451	STRACE(("Layer(%s)::RebuildFullRegion()\n", GetName()));
452
453	if (fParent)
454		fFull.Set(fParent->ConvertToTop(fFrame ));
455	else
456		fFull.Set(fFrame);
457
458	// TODO: restrict to screen coordinates
459
460	// TODO: Convert to screen coordinates
461
462	LayerData *ld;
463	ld = fLayerData;
464	do {
465		// clip to user region
466		if (const BRegion* userClipping = ld->ClippingRegion())
467			fFull.IntersectWith(userClipping);
468
469	} while ((ld = ld->prevState));
470}
471
472// StartRebuildRegions
473void
474Layer::StartRebuildRegions( const BRegion& reg, Layer *target, uint32 action, BPoint& pt)
475{
476	STRACE(("Layer(%s)::StartRebuildRegions() START\n", GetName()));
477	RBTRACE(("\n\nLayer(%s)::StartRebuildRegions() START\n", GetName()));
478	if (!fParent)
479		fFullVisible = fFull;
480
481	BRegion oldVisible = fVisible;
482
483	fVisible = fFullVisible;
484
485	// Rebuild regions for children...
486	for (Layer *lay = BottomChild(); lay; lay = UpperSibling()) {
487		if (lay == target)
488			lay->RebuildRegions(reg, action, pt, BPoint(0.0f, 0.0f));
489		else
490			lay->RebuildRegions(reg, B_LAYER_NONE, pt, BPoint(0.0f, 0.0f));
491	}
492
493	#ifdef DEBUG_LAYER_REBUILD
494		printf("\nSRR: Layer(%s) ALMOST done regions:\n", GetName());
495		printf("\tVisible Region:\n");
496		fVisible.PrintToStream();
497		printf("\tFull Visible Region:\n");
498		fFullVisible.PrintToStream();
499	#endif
500
501	BRegion redrawReg(fVisible);
502
503	// if this is the first time
504	if (oldVisible.CountRects() > 0)
505		redrawReg.Exclude(&oldVisible);
506
507	if (redrawReg.CountRects() > 0)
508		fRootLayer->fRedrawReg.Include(&redrawReg);
509
510	#ifdef DEBUG_LAYER_REBUILD
511		printf("\nLayer(%s)::StartRebuildRegions() DONE. Results:\n", GetName());
512		printf("\tRedraw Region:\n");
513		fRootLayer->fRedrawReg.PrintToStream();
514		printf("\tCopy Region:\n");
515		for (int32 k=0; k<fRootLayer->fCopyRegList.CountItems(); k++) {
516			((BRegion*)(fRootLayer->fCopyRegList.ItemAt(k)))->PrintToStream();
517			((BPoint*)(fRootLayer->fCopyList.ItemAt(k)))->PrintToStream();
518		}
519		printf("\n");
520	#endif
521
522	STRACE(("Layer(%s)::StartRebuildRegions() END\n", GetName()));
523	RBTRACE(("Layer(%s)::StartRebuildRegions() END\n", GetName()));
524}
525
526// RebuildRegions
527void
528Layer::RebuildRegions( const BRegion& reg, uint32 action, BPoint pt, BPoint ptOffset)
529{
530	STRACE(("Layer(%s)::RebuildRegions() START\n", GetName()));
531
532	// TODO:/NOTE: this method must be executed as quickly as possible.
533
534	// Currently SendView[Moved/Resized]Msg() simply constructs a message and calls
535	// ServerWindow::SendMessageToClient(). This involves the alternative use of
536	// kernel and this code in the CPU, so there are a lot of context switches.
537	// This is NOT good at all!
538
539	// One alternative would be the use of a BMessageQueue per ServerWindows OR only
540	// one for app_server which will be emptied as soon as this critical operation ended.
541	// Talk to DW, Gabe.
542
543	BRegion	oldRegion;
544	uint32 newAction = action;
545	BPoint newPt = pt;
546	BPoint newOffset = ptOffset; // used for resizing only
547
548	BPoint dummyNewLocation;
549
550	RRLabel1:
551	switch(action) {
552		case B_LAYER_NONE: {
553			RBTRACE(("1) Layer(%s): Action B_LAYER_NONE\n", GetName()));
554			STRACE(("1) Layer(%s): Action B_LAYER_NONE\n", GetName()));
555			oldRegion = fVisible;
556			break;
557		}
558		case B_LAYER_MOVE: {
559			RBTRACE(("1) Layer(%s): Action B_LAYER_MOVE\n", GetName()));
560			STRACE(("1) Layer(%s): Action B_LAYER_MOVE\n", GetName()));
561			oldRegion = fFullVisible;
562			fFrame.OffsetBy(pt.x, pt.y);
563			fFull.OffsetBy(pt.x, pt.y);
564
565			// TODO: investigate combining frame event messages for efficiency
566			//SendViewMovedMsg();
567			AddToViewsWithInvalidCoords();
568
569			newAction	= B_LAYER_SIMPLE_MOVE;
570			break;
571		}
572		case B_LAYER_SIMPLE_MOVE: {
573			RBTRACE(("1) Layer(%s): Action B_LAYER_SIMPLE_MOVE\n", GetName()));
574			STRACE(("1) Layer(%s): Action B_LAYER_SIMPLE_MOVE\n", GetName()));
575			fFull.OffsetBy(pt.x, pt.y);
576
577			break;
578		}
579		case B_LAYER_RESIZE: {
580			RBTRACE(("1) Layer(%s): Action B_LAYER_RESIZE\n", GetName()));
581			STRACE(("1) Layer(%s): Action B_LAYER_RESIZE\n", GetName()));
582			oldRegion	= fVisible;
583
584			fFrame.right	+= pt.x;
585			fFrame.bottom	+= pt.y;
586			RebuildFullRegion();
587
588			// TODO: investigate combining frame event messages for efficiency
589			//SendViewResizedMsg();
590			AddToViewsWithInvalidCoords();
591
592			newAction = B_LAYER_MASK_RESIZE;
593			break;
594		}
595		case B_LAYER_MASK_RESIZE: {
596			RBTRACE(("1) Layer(%s): Action B_LAYER_MASK_RESIZE\n", GetName()));
597			STRACE(("1) Layer(%s): Action B_LAYER_MASK_RESIZE\n", GetName()));
598			oldRegion = fVisible;
599
600			BPoint offset, rSize;
601			BPoint coords[2];
602
603			ResizeOthers(pt.x, pt.y, coords, NULL);
604			offset = coords[0];
605			rSize = coords[1];
606			newOffset = offset + ptOffset;
607
608			if (!(rSize.x == 0.0f && rSize.y == 0.0f)) {
609				fFrame.OffsetBy(offset);
610				fFrame.right += rSize.x;
611				fFrame.bottom += rSize.y;
612				RebuildFullRegion();
613
614				// TODO: investigate combining frame event messages for efficiency
615				//SendViewResizedMsg();
616				AddToViewsWithInvalidCoords();
617
618				newAction = B_LAYER_MASK_RESIZE;
619				newPt = rSize;
620				dummyNewLocation = newOffset;
621			} else {
622				if (!(offset.x == 0.0f && offset.y == 0.0f)) {
623					pt = newOffset;
624					action = B_LAYER_MOVE;
625					newPt = pt;
626					goto RRLabel1;
627				} else {
628					pt = ptOffset;
629					action = B_LAYER_MOVE;
630					newPt = pt;
631					goto RRLabel1;
632				}
633			}
634			break;
635		}
636	}
637
638	if (!IsHidden()) {
639		#ifdef DEBUG_LAYER_REBUILD
640			printf("Layer(%s) real action START\n", GetName());
641			fFull.PrintToStream();
642		#endif
643		fFullVisible.MakeEmpty();
644		fVisible = fFull;
645
646		if (fParent && fVisible.CountRects() > 0) {
647			// not the usual case, but support fot this is needed.
648			if (fParent->fAdFlags & B_LAYER_CHILDREN_DEPENDANT) {
649				#ifdef DEBUG_LAYER_REBUILD
650					printf("   B_LAYER_CHILDREN_DEPENDANT Parent\n");
651				#endif
652
653				// because we're skipping one level, we need to do out
654				// parent business as well.
655
656				// our visible area is relative to our parent's parent.
657				if (fParent->fParent)
658					fVisible.IntersectWith(&(fParent->fParent->fVisible));
659
660				// exclude parent's visible area which could be composed by
661				// prior siblings' visible areas.
662				if (fVisible.CountRects() > 0)
663					fVisible.Exclude(&(fParent->fVisible));
664
665				// we have a final visible area. Include it to our parent's one,
666				// exclude from parent's parent.
667				if (fVisible.CountRects() > 0) {
668					fParent->fFullVisible.Include(&fVisible);
669
670					if (fParent->fParent)
671						fParent->fParent->fVisible.Exclude(&fVisible);
672				}
673			} else {
674				// for 95+% of cases
675
676				#ifdef DEBUG_LAYER_REBUILD
677					printf("   (!)B_LAYER_CHILDREN_DEPENDANT Parent\n");
678				#endif
679
680				// the visible area is the one common with parent's one.
681				fVisible.IntersectWith(&(fParent->fVisible));
682
683				// exclude from parent's visible area. we're the owners now.
684				if (fVisible.CountRects() > 0)
685					fParent->fVisible.Exclude(&fVisible);
686			}
687		}
688		fFullVisible = fVisible;
689	}
690
691	// Rebuild regions for children...
692	for(Layer *lay = BottomChild(); lay != NULL; lay = UpperSibling())
693		lay->RebuildRegions(reg, newAction, newPt, newOffset);
694
695	#ifdef DEBUG_LAYER_REBUILD
696		printf("\nLayer(%s) ALMOST done regions:\n", GetName());
697		printf("\tVisible Region:\n");
698		fVisible.PrintToStream();
699		printf("\tFull Visible Region:\n");
700		fFullVisible.PrintToStream();
701	#endif
702
703	if(!IsHidden()) {
704		switch(action) {
705			case B_LAYER_NONE: {
706				RBTRACE(("2) Layer(%s): Action B_LAYER_NONE\n", GetName()));
707				BRegion r(fVisible);
708				if (oldRegion.CountRects() > 0)
709					r.Exclude(&oldRegion);
710
711				if(r.CountRects() > 0)
712					fRootLayer->fRedrawReg.Include(&r);
713				break;
714			}
715			case B_LAYER_MOVE: {
716				RBTRACE(("2) Layer(%s): Action B_LAYER_MOVE\n", GetName()));
717				BRegion redrawReg;
718				BRegion	*copyReg = new BRegion();
719				BRegion	screenReg(fRootLayer->Bounds());
720
721				oldRegion.OffsetBy(pt.x, pt.y);
722				oldRegion.IntersectWith(&fFullVisible);
723
724				*copyReg = oldRegion;
725				copyReg->IntersectWith(&screenReg);
726				if (copyReg->CountRects() > 0 && !(pt.x == 0.0f && pt.y == 0.0f)) {
727					copyReg->OffsetBy(-pt.x, -pt.y);
728					BPoint		*point = new BPoint(pt);
729					fRootLayer->fCopyRegList.AddItem(copyReg);
730					fRootLayer->fCopyList.AddItem(point);
731				} else {
732					delete copyReg;
733				}
734
735				redrawReg	= fFullVisible;
736				redrawReg.Exclude(&oldRegion);
737				if (redrawReg.CountRects() > 0 && !(pt.x == 0.0f && pt.y == 0.0f)) {
738					fRootLayer->fRedrawReg.Include(&redrawReg);
739				}
740
741				break;
742			}
743			case B_LAYER_RESIZE: {
744				RBTRACE(("2) Layer(%s): Action B_LAYER_RESIZE\n", GetName()));
745				BRegion redrawReg;
746
747				redrawReg = fVisible;
748				redrawReg.Exclude(&oldRegion);
749				if(redrawReg.CountRects() > 0)
750					fRootLayer->fRedrawReg.Include(&redrawReg);
751
752				break;
753			}
754			case B_LAYER_MASK_RESIZE: {
755				RBTRACE(("2) Layer(%s): Action B_LAYER_MASK_RESIZE\n", GetName()));
756				BRegion redrawReg;
757				BRegion	*copyReg = new BRegion();
758
759				oldRegion.OffsetBy(dummyNewLocation.x, dummyNewLocation.y);
760
761				redrawReg	= fVisible;
762				redrawReg.Exclude(&oldRegion);
763				if (redrawReg.CountRects() > 0)
764					fRootLayer->fRedrawReg.Include(&redrawReg);
765
766				*copyReg = fVisible;
767				copyReg->IntersectWith(&oldRegion);
768				copyReg->OffsetBy(-dummyNewLocation.x, -dummyNewLocation.y);
769				if (copyReg->CountRects() > 0
770					&& !(dummyNewLocation.x == 0.0f && dummyNewLocation.y == 0.0f)) {
771					fRootLayer->fCopyRegList.AddItem(copyReg);
772					fRootLayer->fCopyList.AddItem(new BPoint(dummyNewLocation));
773				}
774
775				break;
776			}
777			default:
778				RBTRACE(("2) Layer(%s): Action default\n", GetName()));
779				break;
780		}
781	}
782/*	if (IsHidden()) {
783		fFullVisible.MakeEmpty();
784		fVisible.MakeEmpty();
785	}
786*/
787
788	STRACE(("Layer(%s)::RebuildRegions() END\n", GetName()));
789}
790
791// ResizeOthers
792uint32
793Layer::ResizeOthers(float x, float y, BPoint coords[], BPoint *ptOffset)
794{
795	STRACE(("Layer(%s)::ResizeOthers() START\n", GetName()));
796	uint32 rmask = fResizeMode;
797
798	// offset
799	coords[0].x	= 0.0f;
800	coords[0].y	= 0.0f;
801
802	// resize by width/height
803	coords[1].x	= 0.0f;
804	coords[1].y	= 0.0f;
805
806	if ((rmask & 0x00000f00UL)>>8 == _VIEW_LEFT_ &&
807		(rmask & 0x0000000fUL)>>0 == _VIEW_RIGHT_) {
808		coords[1].x		= x;
809	} else if ((rmask & 0x00000f00UL)>>8 == _VIEW_LEFT_) {
810	} else if ((rmask & 0x0000000fUL)>>0 == _VIEW_RIGHT_) {
811		coords[0].x		= x;
812	} else if ((rmask & 0x00000f00UL)>>8 == _VIEW_CENTER_) {
813		coords[0].x		= x/2;
814	} else {
815		// illegal flag. Do nothing.
816	}
817
818
819	if ((rmask & 0x0000f000UL)>>12 == _VIEW_TOP_ &&
820		(rmask & 0x000000f0UL)>>4 == _VIEW_BOTTOM_) {
821		coords[1].y		= y;
822	} else if ((rmask & 0x0000f000UL)>>12 == _VIEW_TOP_) {
823	} else if ((rmask & 0x000000f0UL)>>4 == _VIEW_BOTTOM_) {
824		coords[0].y		= y;
825	} else if ((rmask & 0x0000f000UL)>>12 == _VIEW_CENTER_) {
826		coords[0].y		= y/2;
827	} else {
828		// illegal flag. Do nothing.
829	}
830
831	STRACE(("Layer(%s)::ResizeOthers() END\n", GetName()));
832	return 0UL;
833}
834
835// Redraw
836void
837Layer::Redraw(const BRegion& reg, Layer *startFrom)
838{
839	STRACE(("Layer(%s)::Redraw();\n", GetName()));
840	if (IsHidden())
841		// this layer has nothing visible on screen, so bail out.
842		return;
843
844	BRegion *pReg = const_cast<BRegion*>(&reg);
845
846	if (pReg->CountRects() > 0)
847		RequestDraw(reg, startFrom);
848
849	STRACE(("Layer(%s)::Redraw() ENDED\n", GetName()));
850}
851
852// Draw
853void
854Layer::Draw(const BRect &rect)
855{
856#ifdef DEBUG_LAYER
857	printf("Layer(%s)::Draw: ", GetName());
858	rect.PrintToStream();
859#endif
860
861	if (!ViewColor().IsTransparentMagic())
862		fDriver->FillRect(rect, ViewColor());
863}
864
865// EmptyGlobals
866void
867Layer::EmptyGlobals()
868{
869	fRootLayer->fRedrawReg.MakeEmpty();
870
871	int32 count = fRootLayer->fCopyRegList.CountItems();
872	for (int32 i = 0; i < count; i++)
873		delete (BRegion*)fRootLayer->fCopyRegList.ItemAt(i);
874	fRootLayer->fCopyRegList.MakeEmpty();
875
876	count = fRootLayer->fCopyList.CountItems();
877	for (int32 i = 0; i < count; i++)
878		delete (BPoint*)fRootLayer->fCopyList.ItemAt(i);
879	fRootLayer->fCopyList.MakeEmpty();
880}
881
882/*!
883	\brief Shows the layer
884	\param invalidate Invalidate the region when showing the layer. defaults to true
885*/
886void
887Layer::Show(bool invalidate)
888{
889	STRACE(("Layer(%s)::Show()\n", GetName()));
890	if(!IsHidden())
891		return;
892
893	fHidden	= false;
894
895// NOTE: I added this here and it solves the invalid region problem
896// for Windows that have been resized before they were shown. -Stephan
897RebuildFullRegion();
898SendViewCoordUpdateMsg();
899
900	if (invalidate)
901		GetRootLayer()->GoInvalidate(this, fFull);
902}
903
904/*!
905	\brief Shows the layer
906	\param invalidate Invalidate the region when hiding the layer. defaults to true
907*/
908void
909Layer::Hide(bool invalidate)
910{
911	STRACE(("Layer(%s)::Hide()\n", GetName()));
912	if (IsHidden())
913		return;
914
915	fHidden	= true;
916
917	if (invalidate)
918		GetRootLayer()->GoInvalidate(this, fFullVisible);
919}
920
921//! Returns true if the layer is hidden
922bool
923Layer::IsHidden(void) const
924{
925	if (fHidden)
926		return true;
927	else {
928		if (fParent)
929			return fParent->IsHidden();
930	}
931
932	return false;
933}
934
935
936void
937Layer::PushState()
938{
939	LayerData *data = new LayerData();
940	data->prevState = fLayerData;
941	fLayerData = data;
942}
943
944
945void
946Layer::PopState()
947{
948	if (fLayerData->prevState == NULL) {
949		fprintf(stderr, "WARNING: User called BView(%s)::PopState(), but there is NO state on stack!\n", fName->String());
950		return;
951	}
952
953	LayerData *data = fLayerData;
954	fLayerData = fLayerData->prevState;
955	data->prevState = NULL;
956	delete data;
957}
958
959
960//! Matches the BView call of the same name
961BRect
962Layer::Bounds(void) const
963{
964	BRect r(fFrame);
965//	r.OffsetTo(fBoundsLeftTop);
966	r.OffsetTo(BoundsOrigin());
967	return r;
968}
969
970//! Matches the BView call of the same name
971BRect
972Layer::Frame(void) const
973{
974	return fFrame;
975}
976
977//! Moves the layer by specified values, complete with redraw
978void
979Layer::MoveBy(float x, float y)
980{
981	STRACE(("Layer(%s)::MoveBy() START\n", GetName()));
982	if (!fParent) {
983		CRITICAL("ERROR: in Layer::MoveBy()! - No parent!\n");
984		return;
985	}
986
987	BPrivate::PortLink msg(-1, -1);
988	msg.StartMessage(AS_ROOTLAYER_LAYER_MOVE);
989	msg.Attach<Layer*>(this);
990	msg.Attach<float>(x);
991	msg.Attach<float>(y);
992	GetRootLayer()->EnqueueMessage(msg);
993
994	STRACE(("Layer(%s)::MoveBy() END\n", GetName()));
995}
996
997//! Resize the layer by the specified amount, complete with redraw
998void
999Layer::ResizeBy(float x, float y)
1000{
1001	STRACE(("Layer(%s)::ResizeBy() START\n", GetName()));
1002
1003	if (!fParent) {
1004		printf("ERROR: in Layer::ResizeBy()! - No parent!\n");
1005		return;
1006	}
1007
1008	BPrivate::PortLink msg(-1, -1);
1009	msg.StartMessage(AS_ROOTLAYER_LAYER_RESIZE);
1010	msg.Attach<Layer*>(this);
1011	msg.Attach<float>(x);
1012	msg.Attach<float>(y);
1013	GetRootLayer()->EnqueueMessage(msg);
1014
1015	STRACE(("Layer(%s)::ResizeBy() END\n", GetName()));
1016}
1017
1018// BoundsOrigin
1019BPoint
1020Layer::BoundsOrigin() const
1021{
1022	BPoint origin(0,0);
1023	float scale = Scale();
1024
1025	LayerData *ld = fLayerData;
1026	do {
1027		origin += ld->Origin();
1028	} while ((ld = ld->prevState));
1029
1030	origin.x *= scale;
1031	origin.y *= scale;
1032
1033	return origin;
1034}
1035
1036float
1037Layer::Scale() const
1038{
1039	float scale = 1.0f;
1040
1041	LayerData *ld = fLayerData;
1042	do {
1043		scale += ld->Scale();
1044	} while ((ld = ld->prevState));
1045
1046	return scale;
1047}
1048
1049//! Converts the passed point to parent coordinates
1050BPoint
1051Layer::ConvertToParent(BPoint pt)
1052{
1053	pt -= BoundsOrigin();
1054	pt += fFrame.LeftTop();
1055	return pt;
1056}
1057
1058//! Converts the passed rectangle to parent coordinates
1059BRect
1060Layer::ConvertToParent(BRect rect)
1061{
1062//	rect.OffsetBy(fFrame.LeftTop());
1063//	return rect;
1064	rect.OffsetBy(-BoundsOrigin().x, -BoundsOrigin().y);
1065	rect.OffsetBy(fFrame.LeftTop());
1066	return rect;
1067}
1068
1069//! Converts the passed region to parent coordinates
1070BRegion
1071Layer::ConvertToParent(BRegion* reg)
1072{
1073	// TODO: wouldn't it be more efficient to use the copy
1074	// constructor for BRegion and then call OffsetBy()?
1075	BRegion newreg;
1076	for (int32 i = 0; i < reg->CountRects(); i++)
1077		newreg.Include(ConvertToParent(reg->RectAt(i)));
1078	return newreg;
1079}
1080
1081//! Converts the passed point from parent coordinates
1082BPoint
1083Layer::ConvertFromParent(BPoint pt)
1084{
1085//	return pt - fFrame.LeftTop();
1086	pt -= fFrame.LeftTop();
1087	pt += BoundsOrigin();
1088	return pt;
1089}
1090
1091//! Converts the passed rectangle from parent coordinates
1092BRect
1093Layer::ConvertFromParent(BRect rect)
1094{
1095//	rect.OffsetBy(-fFrame.left, -fFrame.top);
1096//	return rect;
1097	rect.OffsetBy(-fFrame.left, -fFrame.top);
1098	rect.OffsetBy(BoundsOrigin());
1099	return rect;
1100}
1101
1102//! Converts the passed region from parent coordinates
1103BRegion
1104Layer::ConvertFromParent(BRegion *reg)
1105{
1106	BRegion newreg;
1107	for(int32 i=0; i<reg->CountRects();i++)
1108		newreg.Include(ConvertFromParent(reg->RectAt(i)));
1109	return newreg;
1110}
1111
1112// ConvertToTop
1113BPoint
1114Layer::ConvertToTop(BPoint pt)
1115{
1116	if (fParent) {
1117//		return (fParent->ConvertToTop(pt + fFrame.LeftTop()));
1118		pt = ConvertToParent(pt);
1119		return fParent->ConvertToTop(pt);
1120	} else
1121		return pt;
1122}
1123
1124//! Converts the passed rectangle to screen coordinates
1125BRect
1126Layer::ConvertToTop(BRect rect)
1127{
1128	if (fParent) {
1129//		return fParent->ConvertToTop(rect.OffsetByCopy(fFrame.LeftTop()));
1130		rect = ConvertToParent(rect);
1131		return fParent->ConvertToTop(rect);
1132	} else
1133		return rect;
1134}
1135
1136//! Converts the passed region to screen coordinates
1137BRegion
1138Layer::ConvertToTop(BRegion *reg)
1139{
1140	BRegion newreg;
1141	for (int32 i = 0; i < reg->CountRects();i++)
1142		newreg.Include(ConvertToTop(reg->RectAt(i)));
1143	return newreg;
1144}
1145
1146// ConvertFromTop
1147BPoint
1148Layer::ConvertFromTop(BPoint pt)
1149{
1150	if (fParent) {
1151//		return fParent->ConvertFromTop(pt-fFrame.LeftTop());
1152		pt = ConvertFromParent(pt);
1153		return fParent->ConvertFromTop(pt);
1154	} else
1155		return pt;
1156}
1157
1158//! Converts the passed rectangle from screen coordinates
1159BRect
1160Layer::ConvertFromTop(BRect rect)
1161{
1162	if (fParent) {
1163//		return fParent->ConvertFromTop(rect.OffsetByCopy(-fFrame.LeftTop().x,
1164//														 -fFrame.LeftTop().y));
1165		rect = ConvertFromParent(rect);
1166		return fParent->ConvertFromTop(rect);
1167	} else
1168		return rect;
1169}
1170
1171//! Converts the passed region from screen coordinates
1172BRegion
1173Layer::ConvertFromTop(BRegion *reg)
1174{
1175	BRegion newreg;
1176
1177	for (int32 i = 0; i < reg->CountRects(); i++)
1178		newreg.Include(ConvertFromTop(reg->RectAt(i)));
1179
1180	return newreg;
1181}
1182
1183//! Recursively deletes all children of the calling layer
1184void
1185Layer::PruneTree(void)
1186{
1187	Layer* lay;
1188	Layer* nextlay;
1189
1190	lay = fTopChild;
1191	fTopChild = NULL;
1192
1193	while (lay != NULL) {
1194		if (lay->fTopChild != NULL)
1195			lay->PruneTree();
1196
1197		nextlay = lay->fLowerSibling;
1198		lay->fLowerSibling = NULL;
1199
1200		delete lay;
1201		lay = nextlay;
1202	}
1203	// Man, this thing is short. Elegant, ain't it? :P
1204}
1205
1206//! Prints information about the layer's current state
1207void
1208Layer::PrintToStream()
1209{
1210	printf("\n----------- Layer %s -----------\n",fName->String());
1211	printf("\t Parent: %s\n", fParent? fParent->GetName():"NULL");
1212	printf("\t us: %s\t ls: %s\n",
1213				fUpperSibling? fUpperSibling->GetName():"NULL",
1214				fLowerSibling? fLowerSibling->GetName():"NULL");
1215	printf("\t topChild: %s\t bottomChild: %s\n",
1216				fTopChild? fTopChild->GetName():"NULL",
1217				fBottomChild? fBottomChild->GetName():"NULL");
1218
1219	printf("Frame: (%f, %f, %f, %f)", fFrame.left, fFrame.top, fFrame.right, fFrame.bottom);
1220	printf("Token: %ld\n",fViewToken);
1221	printf("Hidden - direct: %s\n", fHidden?"true":"false");
1222	printf("Hidden - indirect: %s\n", IsHidden()?"true":"false");
1223	printf("ResizingMode: %lx\n", fResizeMode);
1224	printf("Flags: %lx\n", fFlags);
1225
1226	if (fLayerData)
1227		fLayerData->PrintToStream();
1228	else
1229		printf(" NO LayerData valid pointer\n");
1230}
1231
1232//! Prints pointer info kept by the current layer
1233void
1234Layer::PrintNode()
1235{
1236	printf("-----------\nLayer %s\n",fName->String());
1237	if(fParent)
1238		printf("Parent: %s (%p)\n",fParent->GetName(), fParent);
1239	else
1240		printf("Parent: NULL\n");
1241	if(fUpperSibling)
1242		printf("Upper sibling: %s (%p)\n",fUpperSibling->GetName(), fUpperSibling);
1243	else
1244		printf("Upper sibling: NULL\n");
1245	if(fLowerSibling)
1246		printf("Lower sibling: %s (%p)\n",fLowerSibling->GetName(), fLowerSibling);
1247	else
1248		printf("Lower sibling: NULL\n");
1249	if(fTopChild)
1250		printf("Top child: %s (%p)\n",fTopChild->GetName(), fTopChild);
1251	else
1252		printf("Top child: NULL\n");
1253	if(fBottomChild)
1254		printf("Bottom child: %s (%p)\n",fBottomChild->GetName(), fBottomChild);
1255	else
1256		printf("Bottom child: NULL\n");
1257	printf("Visible Areas: "); fVisible.PrintToStream();
1258}
1259
1260//! Prints the tree hierarchy from the current layer down
1261void
1262Layer::PrintTree()
1263{
1264	printf("\n Tree structure:\n");
1265	printf("\t%s\t%s\n", GetName(), IsHidden()? "Hidden": "NOT hidden");
1266	for(Layer *lay = BottomChild(); lay != NULL; lay = UpperSibling())
1267		printf("\t%s\t%s\n", lay->GetName(), lay->IsHidden()? "Hidden": "NOT hidden");
1268}
1269
1270// UpdateStart
1271void
1272Layer::UpdateStart()
1273{
1274	// During updates we only want to draw what's in the update region
1275	if (fClassID == AS_WINBORDER_CLASS) {
1276		// NOTE: don't worry, RooLayer is locked here.
1277		WinBorder	*wb = (WinBorder*)this;
1278
1279		wb->fInUpdate = true;
1280		wb->fRequestSent = false;
1281		wb->yUpdateReg = wb->fUpdateReg;
1282		wb->fUpdateReg.MakeEmpty();
1283wb->cnt--;
1284if (wb->cnt != 0)
1285	CRITICAL("Layer::UpdateStart(): wb->cnt != 0 -> Not Allowed!");
1286	}
1287}
1288
1289// UpdateEnd
1290void
1291Layer::UpdateEnd()
1292{
1293	// The usual case. Drawing is permitted in the whole visible area.
1294	if (fClassID == AS_WINBORDER_CLASS) {
1295		WinBorder	*wb = (WinBorder*)this;
1296
1297		wb->yUpdateReg.MakeEmpty();
1298
1299		wb->fInUpdate = false;
1300
1301		if (wb->zUpdateReg.CountRects() > 0) {
1302			BRegion		reg(wb->zUpdateReg);
1303			wb->RequestDraw(reg, NULL);
1304		}
1305	}
1306}
1307
1308// move_layer
1309void
1310Layer::move_layer(float x, float y)
1311{
1312	fFrameAction = B_LAYER_ACTION_MOVE;
1313
1314/*	if (fClassID == AS_WINBORDER_CLASS) {
1315		WinBorder	*wb = (WinBorder*)this;
1316		wb->zUpdateReg.OffsetBy(x, y);
1317		wb->yUpdateReg.OffsetBy(x, y);
1318		wb->fUpdateReg.OffsetBy(x, y);
1319	}*/
1320
1321	BPoint pt(x, y);
1322	BRect rect(fFull.Frame().OffsetByCopy(pt));
1323
1324if (!fParent) {
1325printf("no parent in Layer::move_layer() (%s)\n", GetName());
1326fFrameAction = B_LAYER_ACTION_NONE;
1327return;
1328}
1329	fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_MOVE, pt);
1330
1331	fDriver->CopyRegionList(&fRootLayer->fCopyRegList,
1332							&fRootLayer->fCopyList,
1333							fRootLayer->fCopyRegList.CountItems(),
1334							&fFullVisible);
1335
1336	fParent->Redraw(fRootLayer->fRedrawReg, this);
1337
1338	SendViewCoordUpdateMsg();
1339
1340	EmptyGlobals();
1341
1342	fFrameAction = B_LAYER_ACTION_NONE;
1343}
1344
1345// resize_layer
1346void
1347Layer::resize_layer(float x, float y)
1348{
1349	fFrameAction = B_LAYER_ACTION_RESIZE;
1350
1351	BPoint pt(x,y);
1352	BRect rect(fFull.Frame());
1353	rect.right += x;
1354	rect.bottom += y;
1355
1356if (!fParent) {
1357printf("no parent in Layer::resize_layer() (%s)\n", GetName());
1358fFrameAction = B_LAYER_ACTION_NONE;
1359return;
1360}
1361
1362	fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_RESIZE, pt);
1363
1364	fDriver->CopyRegionList(&fRootLayer->fCopyRegList, &fRootLayer->fCopyList, fRootLayer->fCopyRegList.CountItems(), &fFullVisible);
1365	fParent->Redraw(fRootLayer->fRedrawReg, this);
1366
1367	SendViewCoordUpdateMsg();
1368
1369	EmptyGlobals();
1370
1371	fFrameAction = B_LAYER_ACTION_NONE;
1372}
1373
1374// FullInvalidate
1375void
1376Layer::FullInvalidate(const BRect &rect)
1377{
1378	FullInvalidate(BRegion(rect));
1379}
1380
1381// FullInvalidate
1382void
1383Layer::FullInvalidate(const BRegion& region)
1384{
1385	STRACE(("Layer(%s)::FullInvalidate():\n", GetName()));
1386
1387#ifdef DEBUG_LAYER
1388	region.PrintToStream();
1389	printf("\n");
1390#endif
1391
1392	BPoint pt(0,0);
1393	StartRebuildRegions(region, NULL,/* B_LAYER_INVALIDATE, pt); */B_LAYER_NONE, pt);
1394
1395	Redraw(fRootLayer->fRedrawReg);
1396
1397	EmptyGlobals();
1398}
1399
1400// Invalidate
1401void
1402Layer::Invalidate(const BRegion& region)
1403{
1404	STRACE(("Layer(%s)::Invalidate():\n", GetName()));
1405#ifdef DEBUG_LAYER
1406	region.PrintToStream();
1407	printf("\n");
1408#endif
1409
1410	fRootLayer->fRedrawReg	= region;
1411
1412	Redraw(fRootLayer->fRedrawReg);
1413
1414	EmptyGlobals();
1415}
1416
1417// RequestDraw
1418void
1419Layer::RequestDraw(const BRegion &reg, Layer *startFrom)
1420{
1421	STRACE(("Layer(%s)::RequestDraw()\n", GetName()));
1422
1423	// do not redraw any child until you must
1424	int redraw = false;
1425	if (!startFrom)
1426		redraw = true;
1427
1428	if (HasClient() && IsTopLayer()) {
1429		// calculate the minimum region/rectangle to be updated with
1430		// a single message to the client.
1431		BRegion	updateReg(fFullVisible);
1432		if (fFlags & B_FULL_UPDATE_ON_RESIZE
1433			&& fFrameAction	== B_LAYER_ACTION_RESIZE) {
1434			// do nothing
1435		} else {
1436			updateReg.IntersectWith(&reg);
1437		}
1438		if (updateReg.CountRects() > 0) {
1439			fOwner->zUpdateReg.Include(&updateReg);
1440			if (!fOwner->fInUpdate && !fOwner->fRequestSent) {
1441				fOwner->fUpdateReg = fOwner->zUpdateReg;
1442fOwner->cnt++;
1443if (fOwner->cnt != 1)
1444	CRITICAL("Layer::RequestDraw(): fOwner->cnt != 1 -> Not Allowed!");
1445				fOwner->zUpdateReg.MakeEmpty();
1446				SendUpdateMsg(fOwner->fUpdateReg);
1447				fOwner->fRequestSent = true;
1448			}
1449		}
1450	}
1451
1452	if (fVisible.CountRects() > 0) {
1453		BRegion	updateReg(fVisible);
1454		// calculate the update region
1455		if (fFlags & B_FULL_UPDATE_ON_RESIZE
1456			&& fFrameAction	== B_LAYER_ACTION_RESIZE) {
1457			// do nothing
1458		} else {
1459			updateReg.IntersectWith(&reg);
1460		}
1461
1462		if (updateReg.CountRects() > 0) {
1463			fDriver->ConstrainClippingRegion(&updateReg);
1464			Draw(updateReg.Frame());
1465			fDriver->ConstrainClippingRegion(NULL);
1466		}
1467	}
1468
1469	for (Layer *lay = BottomChild(); lay != NULL; lay = UpperSibling()) {
1470		if (lay == startFrom)
1471			redraw = true;
1472
1473		if (redraw && !(lay->IsHidden())) {
1474			// no need to go deeper if not even the FullVisible region intersects
1475			// Update one.
1476
1477			BRegion common(lay->fFullVisible);
1478			common.IntersectWith(&reg);
1479
1480			if (common.CountRects() > 0)
1481				lay->RequestDraw(reg, NULL);
1482		}
1483	}
1484}
1485
1486/*!
1487	\brief Returns the layer's ServerWindow
1488
1489	If the layer's ServerWindow has not been assigned, it attempts to find
1490	the owning ServerWindow in the tree.
1491*/
1492ServerWindow*
1493Layer::SearchForServerWindow()
1494{
1495	if (!fServerWin)
1496		fServerWin=fParent->SearchForServerWindow();
1497
1498	return fServerWin;
1499}
1500
1501//! Sends an _UPDATE_ message to the client BWindow
1502void
1503Layer::SendUpdateMsg(BRegion& reg)
1504{
1505	BMessage msg;
1506	msg.what = _UPDATE_;
1507	msg.AddRect("_rect", ConvertFromTop(reg.Frame()) );
1508	msg.AddRect("debug_rect", reg.Frame() );
1509//	msg.AddInt32("_token",fViewToken);
1510
1511	fOwner->Window()->SendMessageToClient(&msg);
1512}
1513
1514// AddToViewsWithInvalidCoords
1515void
1516Layer::AddToViewsWithInvalidCoords() const
1517{
1518	if (fServerWin) {
1519		fServerWin->ClientViewsWithInvalidCoords().AddInt32("_token", fViewToken);
1520		fServerWin->ClientViewsWithInvalidCoords().AddPoint("where", fFrame.LeftTop());
1521		fServerWin->ClientViewsWithInvalidCoords().AddFloat("width", fFrame.Width());
1522		fServerWin->ClientViewsWithInvalidCoords().AddFloat("height", fFrame.Height());
1523	}
1524}
1525
1526// SendViewCoordUpdateMsg
1527void
1528Layer::SendViewCoordUpdateMsg() const
1529{
1530	if (fServerWin && !fServerWin->ClientViewsWithInvalidCoords().IsEmpty()) {
1531		fServerWin->SendMessageToClient(&fServerWin->ClientViewsWithInvalidCoords());
1532		fServerWin->ClientViewsWithInvalidCoords().MakeEmpty();
1533	}
1534}
1535
1536// SetViewColor
1537void
1538Layer::SetViewColor(const RGBColor& color)
1539{
1540	fViewColor = color;
1541}
1542
1543// SetBackgroundBitmap
1544void
1545Layer::SetBackgroundBitmap(const ServerBitmap* bitmap)
1546{
1547	// TODO: What about reference counting?
1548	// "Release" old fBackgroundBitmap and "Aquire" new one?
1549	fBackgroundBitmap = bitmap;
1550}
1551
1552// SetOverlayBitmap
1553void
1554Layer::SetOverlayBitmap(const ServerBitmap* bitmap)
1555{
1556	// TODO: What about reference counting?
1557	// "Release" old fOverlayBitmap and "Aquire" new one?
1558	fOverlayBitmap = bitmap;
1559}
1560
1561#ifdef NEW_CLIPPING
1562void
1563Layer::ConvertToScreen2(BRect* rect) const
1564{
1565	if (GetRootLayer())
1566		if (fParent) {
1567			rect->OffsetBy(-fOrigin.x, -fOrigin.y);
1568			rect->OffsetBy(fFrame.left, fFrame.top);
1569
1570			fParent->ConvertToScreen2(rect);
1571		}
1572}
1573
1574void
1575Layer::ConvertToScreen2(BRegion* reg) const
1576{
1577	if (GetRootLayer())
1578		if (fParent) {
1579			reg->OffsetBy(-fOrigin.x, -fOrigin.y);
1580			reg->OffsetBy(fFrame.left, fFrame.top);
1581
1582			fParent->ConvertToScreen2(reg);
1583		}
1584}
1585#endif
1586
1587