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