Layer.cpp revision b81c5513c575d21f43b15bc8660968b9e0e703fe
1//------------------------------------------------------------------------------
2//	Copyright (c) 2001-2002, 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 = VirtualTopChild(); lay; lay = VirtualLowerSibling()) {
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 = VirtualTopChild();
354	while (lay != NULL) {
355		lay	= VirtualLowerSibling();
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 = VirtualTopChild(); lay; lay = VirtualLowerSibling()) {
375		if (lay->fViewToken == token)
376			return lay;
377	}
378
379	// Hmmm... not in this layer's children. Try lower descendants
380	for (lay = VirtualTopChild(); lay != NULL; lay = VirtualLowerSibling()) {
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 = VirtualBottomChild(); child; child = VirtualUpperSibling()) {
405			lay = child->LayerAt(pt);
406			if (lay)
407				return lay;
408		}
409	}
410
411	return NULL;
412}
413
414// VirtualTopChild
415Layer*
416Layer::VirtualTopChild() const
417{
418	fCurrent = fTopChild;
419	return fCurrent;
420}
421
422// VirtualLowerSibling
423Layer*
424Layer::VirtualLowerSibling() const
425{
426	fCurrent = fCurrent->fLowerSibling;
427	return fCurrent;
428}
429
430// VirtualUpperSibling
431Layer*
432Layer::VirtualUpperSibling() const
433{
434	fCurrent = fCurrent->fUpperSibling;
435	return fCurrent;
436}
437
438// VirtualBottomChild
439Layer*
440Layer::VirtualBottomChild() 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 = VirtualBottomChild(); lay; lay = VirtualUpperSibling()) {
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 = VirtualBottomChild(); lay != NULL; lay = VirtualUpperSibling())
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	BPortLink 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	BPortLink 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	// TODO: add origin from previous states
1023	return fLayerData->Origin();
1024}
1025
1026//! Converts the passed point to parent coordinates
1027BPoint
1028Layer::ConvertToParent(BPoint pt)
1029{
1030	pt -= BoundsOrigin();
1031	pt += fFrame.LeftTop();
1032	return pt;
1033}
1034
1035//! Converts the passed rectangle to parent coordinates
1036BRect
1037Layer::ConvertToParent(BRect rect)
1038{
1039//	rect.OffsetBy(fFrame.LeftTop());
1040//	return rect;
1041	rect.OffsetBy(-BoundsOrigin().x, -BoundsOrigin().y);
1042	rect.OffsetBy(fFrame.LeftTop());
1043	return rect;
1044}
1045
1046//! Converts the passed region to parent coordinates
1047BRegion
1048Layer::ConvertToParent(BRegion* reg)
1049{
1050	// TODO: wouldn't it be more efficient to use the copy
1051	// constructor for BRegion and then call OffsetBy()?
1052	BRegion newreg;
1053	for (int32 i = 0; i < reg->CountRects(); i++)
1054		newreg.Include(ConvertToParent(reg->RectAt(i)));
1055	return newreg;
1056}
1057
1058//! Converts the passed point from parent coordinates
1059BPoint
1060Layer::ConvertFromParent(BPoint pt)
1061{
1062//	return pt - fFrame.LeftTop();
1063	pt -= fFrame.LeftTop();
1064	pt += BoundsOrigin();
1065	return pt;
1066}
1067
1068//! Converts the passed rectangle from parent coordinates
1069BRect
1070Layer::ConvertFromParent(BRect rect)
1071{
1072//	rect.OffsetBy(-fFrame.left, -fFrame.top);
1073//	return rect;
1074	rect.OffsetBy(-fFrame.left, -fFrame.top);
1075	rect.OffsetBy(BoundsOrigin());
1076	return rect;
1077}
1078
1079//! Converts the passed region from parent coordinates
1080BRegion
1081Layer::ConvertFromParent(BRegion *reg)
1082{
1083	BRegion newreg;
1084	for(int32 i=0; i<reg->CountRects();i++)
1085		newreg.Include(ConvertFromParent(reg->RectAt(i)));
1086	return newreg;
1087}
1088
1089// ConvertToTop
1090BPoint
1091Layer::ConvertToTop(BPoint pt)
1092{
1093	if (fParent) {
1094//		return (fParent->ConvertToTop(pt + fFrame.LeftTop()));
1095		pt = ConvertToParent(pt);
1096		return fParent->ConvertToTop(pt);
1097	} else
1098		return pt;
1099}
1100
1101//! Converts the passed rectangle to screen coordinates
1102BRect
1103Layer::ConvertToTop(BRect rect)
1104{
1105	if (fParent) {
1106//		return fParent->ConvertToTop(rect.OffsetByCopy(fFrame.LeftTop()));
1107		rect = ConvertToParent(rect);
1108		return fParent->ConvertToTop(rect);
1109	} else
1110		return rect;
1111}
1112
1113//! Converts the passed region to screen coordinates
1114BRegion
1115Layer::ConvertToTop(BRegion *reg)
1116{
1117	BRegion newreg;
1118	for (int32 i = 0; i < reg->CountRects();i++)
1119		newreg.Include(ConvertToTop(reg->RectAt(i)));
1120	return newreg;
1121}
1122
1123// ConvertFromTop
1124BPoint
1125Layer::ConvertFromTop(BPoint pt)
1126{
1127	if (fParent) {
1128//		return fParent->ConvertFromTop(pt-fFrame.LeftTop());
1129		pt = ConvertFromParent(pt);
1130		return fParent->ConvertFromTop(pt);
1131	} else
1132		return pt;
1133}
1134
1135//! Converts the passed rectangle from screen coordinates
1136BRect
1137Layer::ConvertFromTop(BRect rect)
1138{
1139	if (fParent) {
1140//		return fParent->ConvertFromTop(rect.OffsetByCopy(-fFrame.LeftTop().x,
1141//														 -fFrame.LeftTop().y));
1142		rect = ConvertFromParent(rect);
1143		return fParent->ConvertFromTop(rect);
1144	} else
1145		return rect;
1146}
1147
1148//! Converts the passed region from screen coordinates
1149BRegion
1150Layer::ConvertFromTop(BRegion *reg)
1151{
1152	BRegion newreg;
1153
1154	for (int32 i = 0; i < reg->CountRects(); i++)
1155		newreg.Include(ConvertFromTop(reg->RectAt(i)));
1156
1157	return newreg;
1158}
1159
1160//! Recursively deletes all children of the calling layer
1161void
1162Layer::PruneTree(void)
1163{
1164	Layer* lay;
1165	Layer* nextlay;
1166
1167	lay = fTopChild;
1168	fTopChild = NULL;
1169
1170	while (lay != NULL) {
1171		if (lay->fTopChild != NULL)
1172			lay->PruneTree();
1173
1174		nextlay = lay->fLowerSibling;
1175		lay->fLowerSibling = NULL;
1176
1177		delete lay;
1178		lay = nextlay;
1179	}
1180	// Man, this thing is short. Elegant, ain't it? :P
1181}
1182
1183//! Prints information about the layer's current state
1184void
1185Layer::PrintToStream()
1186{
1187	printf("\n----------- Layer %s -----------\n",fName->String());
1188	printf("\t Parent: %s\n", fParent? fParent->GetName():"NULL");
1189	printf("\t us: %s\t ls: %s\n",
1190				fUpperSibling? fUpperSibling->GetName():"NULL",
1191				fLowerSibling? fLowerSibling->GetName():"NULL");
1192	printf("\t topChild: %s\t bottomChild: %s\n",
1193				fTopChild? fTopChild->GetName():"NULL",
1194				fBottomChild? fBottomChild->GetName():"NULL");
1195
1196	printf("Frame: (%f, %f, %f, %f)", fFrame.left, fFrame.top, fFrame.right, fFrame.bottom);
1197	printf("Token: %ld\n",fViewToken);
1198	printf("Hidden - direct: %s\n", fHidden?"true":"false");
1199	printf("Hidden - indirect: %s\n", IsHidden()?"true":"false");
1200	printf("ResizingMode: %lx\n", fResizeMode);
1201	printf("Flags: %lx\n", fFlags);
1202
1203	if (fLayerData)
1204		fLayerData->PrintToStream();
1205	else
1206		printf(" NO LayerData valid pointer\n");
1207}
1208
1209//! Prints pointer info kept by the current layer
1210void
1211Layer::PrintNode()
1212{
1213	printf("-----------\nLayer %s\n",fName->String());
1214	if(fParent)
1215		printf("Parent: %s (%p)\n",fParent->GetName(), fParent);
1216	else
1217		printf("Parent: NULL\n");
1218	if(fUpperSibling)
1219		printf("Upper sibling: %s (%p)\n",fUpperSibling->GetName(), fUpperSibling);
1220	else
1221		printf("Upper sibling: NULL\n");
1222	if(fLowerSibling)
1223		printf("Lower sibling: %s (%p)\n",fLowerSibling->GetName(), fLowerSibling);
1224	else
1225		printf("Lower sibling: NULL\n");
1226	if(fTopChild)
1227		printf("Top child: %s (%p)\n",fTopChild->GetName(), fTopChild);
1228	else
1229		printf("Top child: NULL\n");
1230	if(fBottomChild)
1231		printf("Bottom child: %s (%p)\n",fBottomChild->GetName(), fBottomChild);
1232	else
1233		printf("Bottom child: NULL\n");
1234	printf("Visible Areas: "); fVisible.PrintToStream();
1235}
1236
1237//! Prints the tree hierarchy from the current layer down
1238void
1239Layer::PrintTree()
1240{
1241	printf("\n Tree structure:\n");
1242	printf("\t%s\t%s\n", GetName(), IsHidden()? "Hidden": "NOT hidden");
1243	for(Layer *lay = VirtualBottomChild(); lay != NULL; lay = VirtualUpperSibling())
1244		printf("\t%s\t%s\n", lay->GetName(), lay->IsHidden()? "Hidden": "NOT hidden");
1245}
1246
1247// UpdateStart
1248void
1249Layer::UpdateStart()
1250{
1251	// During updates we only want to draw what's in the update region
1252	if (fClassID == AS_WINBORDER_CLASS) {
1253		// NOTE: don't worry, RooLayer is locked here.
1254		WinBorder	*wb = (WinBorder*)this;
1255
1256		wb->fInUpdate = true;
1257		wb->fRequestSent = false;
1258		wb->yUpdateReg = wb->fUpdateReg;
1259		wb->fUpdateReg.MakeEmpty();
1260wb->cnt--;
1261if (wb->cnt != 0)
1262	CRITICAL("Layer::UpdateStart(): wb->cnt != 0 -> Not Allowed!");
1263	}
1264}
1265
1266// UpdateEnd
1267void
1268Layer::UpdateEnd()
1269{
1270	// The usual case. Drawing is permitted in the whole visible area.
1271	if (fClassID == AS_WINBORDER_CLASS) {
1272		WinBorder	*wb = (WinBorder*)this;
1273
1274		wb->yUpdateReg.MakeEmpty();
1275
1276		wb->fInUpdate = false;
1277
1278		if (wb->zUpdateReg.CountRects() > 0) {
1279			BRegion		reg(wb->zUpdateReg);
1280			wb->RequestDraw(reg, NULL);
1281		}
1282	}
1283}
1284
1285// move_layer
1286void
1287Layer::move_layer(float x, float y)
1288{
1289	fFrameAction = B_LAYER_ACTION_MOVE;
1290
1291/*	if (fClassID == AS_WINBORDER_CLASS) {
1292		WinBorder	*wb = (WinBorder*)this;
1293		wb->zUpdateReg.OffsetBy(x, y);
1294		wb->yUpdateReg.OffsetBy(x, y);
1295		wb->fUpdateReg.OffsetBy(x, y);
1296	}*/
1297
1298	BPoint pt(x, y);
1299	BRect rect(fFull.Frame().OffsetByCopy(pt));
1300
1301if (!fParent) {
1302printf("no parent in Layer::move_layer() (%s)\n", GetName());
1303fFrameAction = B_LAYER_ACTION_NONE;
1304return;
1305}
1306	fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_MOVE, pt);
1307
1308	fDriver->CopyRegionList(&fRootLayer->fCopyRegList,
1309							&fRootLayer->fCopyList,
1310							fRootLayer->fCopyRegList.CountItems(),
1311							&fFullVisible);
1312
1313	fParent->Redraw(fRootLayer->fRedrawReg, this);
1314
1315	SendViewCoordUpdateMsg();
1316
1317	EmptyGlobals();
1318
1319	fFrameAction = B_LAYER_ACTION_NONE;
1320}
1321
1322// resize_layer
1323void
1324Layer::resize_layer(float x, float y)
1325{
1326	fFrameAction = B_LAYER_ACTION_RESIZE;
1327
1328	BPoint pt(x,y);
1329	BRect rect(fFull.Frame());
1330	rect.right += x;
1331	rect.bottom += y;
1332
1333if (!fParent) {
1334printf("no parent in Layer::resize_layer() (%s)\n", GetName());
1335fFrameAction = B_LAYER_ACTION_NONE;
1336return;
1337}
1338
1339	fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_RESIZE, pt);
1340
1341	fDriver->CopyRegionList(&fRootLayer->fCopyRegList, &fRootLayer->fCopyList, fRootLayer->fCopyRegList.CountItems(), &fFullVisible);
1342	fParent->Redraw(fRootLayer->fRedrawReg, this);
1343
1344	SendViewCoordUpdateMsg();
1345
1346	EmptyGlobals();
1347
1348	fFrameAction = B_LAYER_ACTION_NONE;
1349}
1350
1351// FullInvalidate
1352void
1353Layer::FullInvalidate(const BRect &rect)
1354{
1355	FullInvalidate(BRegion(rect));
1356}
1357
1358// FullInvalidate
1359void
1360Layer::FullInvalidate(const BRegion& region)
1361{
1362	STRACE(("Layer(%s)::FullInvalidate():\n", GetName()));
1363
1364#ifdef DEBUG_LAYER
1365	region.PrintToStream();
1366	printf("\n");
1367#endif
1368
1369	BPoint pt(0,0);
1370	StartRebuildRegions(region, NULL,/* B_LAYER_INVALIDATE, pt); */B_LAYER_NONE, pt);
1371
1372	Redraw(fRootLayer->fRedrawReg);
1373
1374	EmptyGlobals();
1375}
1376
1377// Invalidate
1378void
1379Layer::Invalidate(const BRegion& region)
1380{
1381	STRACE(("Layer(%s)::Invalidate():\n", GetName()));
1382#ifdef DEBUG_LAYER
1383	region.PrintToStream();
1384	printf("\n");
1385#endif
1386
1387	fRootLayer->fRedrawReg	= region;
1388
1389	Redraw(fRootLayer->fRedrawReg);
1390
1391	EmptyGlobals();
1392}
1393
1394// RequestDraw
1395void
1396Layer::RequestDraw(const BRegion &reg, Layer *startFrom)
1397{
1398	STRACE(("Layer(%s)::RequestDraw()\n", GetName()));
1399
1400	// do not redraw any child until you must
1401	int redraw = false;
1402	if (!startFrom)
1403		redraw = true;
1404
1405	if (HasClient() && IsTopLayer()) {
1406		// calculate the minimum region/rectangle to be updated with
1407		// a single message to the client.
1408		BRegion	updateReg(fFullVisible);
1409		if (fFlags & B_FULL_UPDATE_ON_RESIZE
1410			&& fFrameAction	== B_LAYER_ACTION_RESIZE) {
1411			// do nothing
1412		} else {
1413			updateReg.IntersectWith(&reg);
1414		}
1415		if (updateReg.CountRects() > 0) {
1416			fOwner->zUpdateReg.Include(&updateReg);
1417			if (!fOwner->fInUpdate && !fOwner->fRequestSent) {
1418				fOwner->fUpdateReg = fOwner->zUpdateReg;
1419fOwner->cnt++;
1420if (fOwner->cnt != 1)
1421	CRITICAL("Layer::RequestDraw(): fOwner->cnt != 1 -> Not Allowed!");
1422				fOwner->zUpdateReg.MakeEmpty();
1423				SendUpdateMsg(fOwner->fUpdateReg);
1424				fOwner->fRequestSent = true;
1425			}
1426		}
1427	}
1428
1429	if (fVisible.CountRects() > 0) {
1430		BRegion	updateReg(fVisible);
1431		// calculate the update region
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
1439		if (updateReg.CountRects() > 0) {
1440			fDriver->ConstrainClippingRegion(&updateReg);
1441			Draw(updateReg.Frame());
1442			fDriver->ConstrainClippingRegion(NULL);
1443		}
1444	}
1445
1446	for (Layer *lay = VirtualBottomChild(); lay != NULL; lay = VirtualUpperSibling()) {
1447		if (lay == startFrom)
1448			redraw = true;
1449
1450		if (redraw && !(lay->IsHidden())) {
1451			// no need to go deeper if not even the FullVisible region intersects
1452			// Update one.
1453
1454			BRegion common(lay->fFullVisible);
1455			common.IntersectWith(&reg);
1456
1457			if (common.CountRects() > 0)
1458				lay->RequestDraw(reg, NULL);
1459		}
1460	}
1461}
1462
1463/*!
1464	\brief Returns the layer's ServerWindow
1465
1466	If the layer's ServerWindow has not been assigned, it attempts to find
1467	the owning ServerWindow in the tree.
1468*/
1469ServerWindow*
1470Layer::SearchForServerWindow()
1471{
1472	if (!fServerWin)
1473		fServerWin=fParent->SearchForServerWindow();
1474
1475	return fServerWin;
1476}
1477
1478//! Sends an _UPDATE_ message to the client BWindow
1479void
1480Layer::SendUpdateMsg(BRegion& reg)
1481{
1482	BMessage msg;
1483	msg.what = _UPDATE_;
1484	msg.AddRect("_rect", ConvertFromTop(reg.Frame()) );
1485	msg.AddRect("debug_rect", reg.Frame() );
1486//	msg.AddInt32("_token",fViewToken);
1487
1488	fOwner->Window()->SendMessageToClient(&msg);
1489}
1490
1491// AddToViewsWithInvalidCoords
1492void
1493Layer::AddToViewsWithInvalidCoords() const
1494{
1495	if (fServerWin) {
1496		fServerWin->ClientViewsWithInvalidCoords().AddInt32("_token", fViewToken);
1497		fServerWin->ClientViewsWithInvalidCoords().AddPoint("where", fFrame.LeftTop());
1498		fServerWin->ClientViewsWithInvalidCoords().AddFloat("width", fFrame.Width());
1499		fServerWin->ClientViewsWithInvalidCoords().AddFloat("height", fFrame.Height());
1500	}
1501}
1502
1503// SendViewCoordUpdateMsg
1504void
1505Layer::SendViewCoordUpdateMsg() const
1506{
1507	if (fServerWin && !fServerWin->ClientViewsWithInvalidCoords().IsEmpty()) {
1508		fServerWin->SendMessageToClient(&fServerWin->ClientViewsWithInvalidCoords());
1509		fServerWin->ClientViewsWithInvalidCoords().MakeEmpty();
1510	}
1511}
1512
1513// SetViewColor
1514void
1515Layer::SetViewColor(const RGBColor& color)
1516{
1517	fViewColor = color;
1518}
1519
1520// SetBackgroundBitmap
1521void
1522Layer::SetBackgroundBitmap(const ServerBitmap* bitmap)
1523{
1524	// TODO: What about reference counting?
1525	// "Release" old fBackgroundBitmap and "Aquire" new one?
1526	fBackgroundBitmap = bitmap;
1527}
1528
1529// SetOverlayBitmap
1530void
1531Layer::SetOverlayBitmap(const ServerBitmap* bitmap)
1532{
1533	// TODO: What about reference counting?
1534	// "Release" old fOverlayBitmap and "Aquire" new one?
1535	fOverlayBitmap = bitmap;
1536}
1537
1538
1539/*
1540//! Sends a B_VIEW_MOVED message to the client BWindow
1541void
1542Layer::SendViewMovedMsg()
1543{
1544	if (fServerWin && fFlags & B_FRAME_EVENTS) {
1545		BMessage msg;
1546		msg.what = B_VIEW_MOVED;
1547		// TODO: system_time() ?!?
1548		msg.AddInt64("when", real_time_clock_usecs());
1549		msg.AddInt32("_token", fViewToken);
1550		msg.AddPoint("where", fFrame.LeftTop());
1551
1552		fServerWin->SendMessageToClient(&msg);
1553	}
1554}
1555
1556//! Sends a B_VIEW_RESIZE message to the client BWindow
1557void
1558Layer::SendViewResizedMsg()
1559{
1560	if (fServerWin && fFlags & B_FRAME_EVENTS) {
1561		BMessage msg;
1562		msg.what = B_VIEW_RESIZED;
1563		// TODO: system_time() ?!?
1564		msg.AddInt64("when", real_time_clock_usecs());
1565		msg.AddInt32("_token", fViewToken);
1566		msg.AddFloat("width", fFrame.Width());
1567		msg.AddFloat("height", fFrame.Height());
1568
1569		// no need for that... it's here because of backward compatibility
1570		msg.AddPoint("where", fFrame.LeftTop());
1571
1572		fServerWin->SendMessageToClient(&msg);
1573	}
1574}
1575*/
1576
1577