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