Layer.cpp revision ad6b480400e921f46a444359fc92be5251ab6ac4
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 "DisplayDriver.h"
40#include "LayerData.h"
41#include "PortLink.h"
42#include "RootLayer.h"
43#include "ServerProtocol.h"
44#include "ServerWindow.h"
45#include "WinBorder.h"
46
47#include "Layer.h"
48
49//#define DEBUG_LAYER
50#ifdef DEBUG_LAYER
51#	define STRACE(x) printf x
52#else
53#	define STRACE(x) ;
54#endif
55
56//#define DEBUG_LAYER_REBUILD
57#ifdef DEBUG_LAYER_REBUILD
58#	define RBTRACE(x) printf x
59#else
60#	define RBTRACE(x) ;
61#endif
62
63enum {
64	B_LAYER_ACTION_NONE = 0,
65	B_LAYER_ACTION_MOVE,
66	B_LAYER_ACTION_RESIZE
67};
68
69Layer::Layer(BRect frame, const char* name, int32 token,
70			 uint32 resize, uint32 flags, DisplayDriver* driver)
71	: fFrame(frame), // in parent coordinates
72//	  fBoundsLeftTop(0.0, 0.0),
73
74	  // Layer does not start out as a part of the tree
75	  fOwner		(NULL),
76	  fParent		(NULL),
77	  fUpperSibling	(NULL),
78	  fLowerSibling	(NULL),
79	  fTopChild		(NULL),
80	  fBottomChild	(NULL),
81
82	  fCurrent		(NULL),
83
84	  // all regions (fVisible, fFullVisible, fFull) start empty
85	  fVisible		(),
86	  fFullVisible	(),
87	  fFull			(),
88
89	  fClipReg		(&fVisible),
90
91	  clipToPicture	(NULL),
92	  clipToPictureInverse(false),
93
94	  fServerWin	(NULL),
95	  fName			(new BString(name ? name : B_EMPTY_STRING)),
96	  fViewToken	(token),
97
98	  fFlags		(flags),
99	  fResizeMode	(resize),
100	  fEventMask	(0UL),
101	  fEventOptions	(0UL),
102	  fHidden		(false),
103	  fIsTopLayer	(false),
104
105	  fAdFlags		(0),
106	  fClassID		(AS_LAYER_CLASS),
107
108	  fFrameAction	(B_LAYER_ACTION_NONE),
109
110	  fDriver		(driver),
111	  fLayerData	(new LayerData()),
112
113	  fRootLayer	(NULL)
114{
115	// TODO: Decorator class should have a method witch
116	// returns the minimum frame width.
117	if (!frame.IsValid())
118		fFrame.Set(0, 0, 5, 5);
119
120	if (!fDriver)
121		debugger("You MUST have a valid driver to init a Layer object\n");
122
123	STRACE(("Layer(%s) successfuly created\n", GetName()));
124}
125
126//! Destructor frees all allocated heap space
127Layer::~Layer(void)
128{
129	delete fLayerData;
130	delete fName;
131
132	// TODO: uncomment!
133	//PruneTree();
134
135//	fServerWin->RemoveChild(fDriver);
136//	delete fDriver;
137
138	if (clipToPicture) {
139		// TODO: allocate and release a ServerPicture Object.
140	}
141	delete clipToPicture;
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	// clip to user picture region
472	if (clipToPicture) {
473		if(clipToPictureInverse)
474			fFull.Exclude( clipToPicture );
475		else
476			fFull.IntersectWith( clipToPicture );
477	}
478}
479
480// StartRebuildRegions
481void
482Layer::StartRebuildRegions( const BRegion& reg, Layer *target, uint32 action, BPoint& pt)
483{
484	STRACE(("Layer(%s)::StartRebuildRegions() START\n", GetName()));
485	RBTRACE(("\n\nLayer(%s)::StartRebuildRegions() START\n", GetName()));
486	if (!fParent)
487		fFullVisible = fFull;
488
489	BRegion oldVisible = fVisible;
490
491	fVisible = fFullVisible;
492
493	// Rebuild regions for children...
494	for (Layer *lay = VirtualBottomChild(); lay; lay = VirtualUpperSibling()) {
495		if (lay == target)
496			lay->RebuildRegions(reg, action, pt, BPoint(0.0f, 0.0f));
497		else
498			lay->RebuildRegions(reg, B_LAYER_NONE, pt, BPoint(0.0f, 0.0f));
499	}
500
501	#ifdef DEBUG_LAYER_REBUILD
502		printf("\nSRR: Layer(%s) ALMOST done regions:\n", GetName());
503		printf("\tVisible Region:\n");
504		fVisible.PrintToStream();
505		printf("\tFull Visible Region:\n");
506		fFullVisible.PrintToStream();
507	#endif
508
509	BRegion redrawReg(fVisible);
510
511	// if this is the first time
512	if (oldVisible.CountRects() > 0)
513		redrawReg.Exclude(&oldVisible);
514
515	if (redrawReg.CountRects() > 0)
516		fRootLayer->fRedrawReg.Include(&redrawReg);
517
518	#ifdef DEBUG_LAYER_REBUILD
519		printf("\nLayer(%s)::StartRebuildRegions() DONE. Results:\n", GetName());
520		printf("\tRedraw Region:\n");
521		fRootLayer->fRedrawReg.PrintToStream();
522		printf("\tCopy Region:\n");
523		for (int32 k=0; k<fRootLayer->fCopyRegList.CountItems(); k++) {
524			((BRegion*)(fRootLayer->fCopyRegList.ItemAt(k)))->PrintToStream();
525			((BPoint*)(fRootLayer->fCopyList.ItemAt(k)))->PrintToStream();
526		}
527		printf("\n");
528	#endif
529
530	STRACE(("Layer(%s)::StartRebuildRegions() END\n", GetName()));
531	RBTRACE(("Layer(%s)::StartRebuildRegions() END\n", GetName()));
532}
533
534// RebuildRegions
535void
536Layer::RebuildRegions( const BRegion& reg, uint32 action, BPoint pt, BPoint ptOffset)
537{
538	STRACE(("Layer(%s)::RebuildRegions() START\n", GetName()));
539
540	// TODO:/NOTE: this method must be executed as quickly as possible.
541
542	// Currently SendView[Moved/Resized]Msg() simply constructs a message and calls
543	// ServerWindow::SendMessageToClient(). This involves the alternative use of
544	// kernel and this code in the CPU, so there are a lot of context switches.
545	// This is NOT good at all!
546
547	// One alternative would be the use of a BMessageQueue per ServerWindows OR only
548	// one for app_server which will be emptied as soon as this critical operation ended.
549	// Talk to DW, Gabe.
550
551	BRegion	oldRegion;
552	uint32 newAction = action;
553	BPoint newPt = pt;
554	BPoint newOffset = ptOffset; // used for resizing only
555
556	BPoint dummyNewLocation;
557
558	RRLabel1:
559	switch(action) {
560		case B_LAYER_NONE: {
561			RBTRACE(("1) Layer(%s): Action B_LAYER_NONE\n", GetName()));
562			STRACE(("1) Layer(%s): Action B_LAYER_NONE\n", GetName()));
563			oldRegion = fVisible;
564			break;
565		}
566		case B_LAYER_MOVE: {
567			RBTRACE(("1) Layer(%s): Action B_LAYER_MOVE\n", GetName()));
568			STRACE(("1) Layer(%s): Action B_LAYER_MOVE\n", GetName()));
569			oldRegion = fFullVisible;
570			fFrame.OffsetBy(pt.x, pt.y);
571			fFull.OffsetBy(pt.x, pt.y);
572
573			// TODO: investigate combining frame event messages for efficiency
574			//SendViewMovedMsg();
575			AddToViewsWithInvalidCoords();
576
577			newAction	= B_LAYER_SIMPLE_MOVE;
578			break;
579		}
580		case B_LAYER_SIMPLE_MOVE: {
581			RBTRACE(("1) Layer(%s): Action B_LAYER_SIMPLE_MOVE\n", GetName()));
582			STRACE(("1) Layer(%s): Action B_LAYER_SIMPLE_MOVE\n", GetName()));
583			fFull.OffsetBy(pt.x, pt.y);
584
585			break;
586		}
587		case B_LAYER_RESIZE: {
588			RBTRACE(("1) Layer(%s): Action B_LAYER_RESIZE\n", GetName()));
589			STRACE(("1) Layer(%s): Action B_LAYER_RESIZE\n", GetName()));
590			oldRegion	= fVisible;
591
592			fFrame.right	+= pt.x;
593			fFrame.bottom	+= pt.y;
594			RebuildFullRegion();
595
596			// TODO: investigate combining frame event messages for efficiency
597			//SendViewResizedMsg();
598			AddToViewsWithInvalidCoords();
599
600
601			newAction = B_LAYER_MASK_RESIZE;
602			break;
603		}
604		case B_LAYER_MASK_RESIZE: {
605			RBTRACE(("1) Layer(%s): Action B_LAYER_MASK_RESIZE\n", GetName()));
606			STRACE(("1) Layer(%s): Action B_LAYER_MASK_RESIZE\n", GetName()));
607			oldRegion = fVisible;
608
609			BPoint offset, rSize;
610			BPoint coords[2];
611
612			ResizeOthers(pt.x, pt.y, coords, NULL);
613			offset = coords[0];
614			rSize = coords[1];
615			newOffset = offset + ptOffset;
616
617			if (!(rSize.x == 0.0f && rSize.y == 0.0f)) {
618				fFrame.OffsetBy(offset);
619				fFrame.right += rSize.x;
620				fFrame.bottom += rSize.y;
621				RebuildFullRegion();
622
623				// TODO: investigate combining frame event messages for efficiency
624				//SendViewResizedMsg();
625				AddToViewsWithInvalidCoords();
626
627				newAction = B_LAYER_MASK_RESIZE;
628				newPt = rSize;
629				dummyNewLocation = newOffset;
630			} else {
631				if (!(offset.x == 0.0f && offset.y == 0.0f)) {
632					pt = newOffset;
633					action = B_LAYER_MOVE;
634					newPt = pt;
635					goto RRLabel1;
636				} else {
637					pt = ptOffset;
638					action = B_LAYER_MOVE;
639					newPt = pt;
640					goto RRLabel1;
641				}
642			}
643			break;
644		}
645	}
646
647	if (!IsHidden()) {
648		#ifdef DEBUG_LAYER_REBUILD
649			printf("Layer(%s) real action START\n", GetName());
650			fFull.PrintToStream();
651		#endif
652		fFullVisible.MakeEmpty();
653		fVisible = fFull;
654
655		if (fParent && fVisible.CountRects() > 0) {
656			// not the usual case, but support fot this is needed.
657			if (fParent->fAdFlags & B_LAYER_CHILDREN_DEPENDANT) {
658				#ifdef DEBUG_LAYER_REBUILD
659					printf("   B_LAYER_CHILDREN_DEPENDANT Parent\n");
660				#endif
661
662				// because we're skipping one level, we need to do out
663				// parent business as well.
664
665				// our visible area is relative to our parent's parent.
666				if (fParent->fParent)
667					fVisible.IntersectWith(&(fParent->fParent->fVisible));
668
669				// exclude parent's visible area which could be composed by
670				// prior siblings' visible areas.
671				if (fVisible.CountRects() > 0)
672					fVisible.Exclude(&(fParent->fVisible));
673
674				// we have a final visible area. Include it to our parent's one,
675				// exclude from parent's parent.
676				if (fVisible.CountRects() > 0) {
677					fParent->fFullVisible.Include(&fVisible);
678
679					if (fParent->fParent)
680						fParent->fParent->fVisible.Exclude(&fVisible);
681				}
682			} else {
683				// for 95+% of cases
684
685				#ifdef DEBUG_LAYER_REBUILD
686					printf("   (!)B_LAYER_CHILDREN_DEPENDANT Parent\n");
687				#endif
688
689				// the visible area is the one common with parent's one.
690				fVisible.IntersectWith(&(fParent->fVisible));
691
692				// exclude from parent's visible area. we're the owners now.
693				if (fVisible.CountRects() > 0)
694					fParent->fVisible.Exclude(&fVisible);
695			}
696		}
697		fFullVisible = fVisible;
698	}
699
700	// Rebuild regions for children...
701	for(Layer *lay = VirtualBottomChild(); lay != NULL; lay = VirtualUpperSibling())
702		lay->RebuildRegions(reg, newAction, newPt, newOffset);
703
704	#ifdef DEBUG_LAYER_REBUILD
705		printf("\nLayer(%s) ALMOST done regions:\n", GetName());
706		printf("\tVisible Region:\n");
707		fVisible.PrintToStream();
708		printf("\tFull Visible Region:\n");
709		fFullVisible.PrintToStream();
710	#endif
711
712	if(!IsHidden()) {
713		switch(action) {
714			case B_LAYER_NONE: {
715				RBTRACE(("2) Layer(%s): Action B_LAYER_NONE\n", GetName()));
716				BRegion r(fVisible);
717				if (oldRegion.CountRects() > 0)
718					r.Exclude(&oldRegion);
719
720				if(r.CountRects() > 0)
721					fRootLayer->fRedrawReg.Include(&r);
722				break;
723			}
724			case B_LAYER_MOVE: {
725				RBTRACE(("2) Layer(%s): Action B_LAYER_MOVE\n", GetName()));
726				BRegion redrawReg;
727				BRegion	*copyReg = new BRegion();
728				BRegion	screenReg(fRootLayer->Bounds());
729
730				oldRegion.OffsetBy(pt.x, pt.y);
731				oldRegion.IntersectWith(&fFullVisible);
732
733				*copyReg = oldRegion;
734				copyReg->IntersectWith(&screenReg);
735				if (copyReg->CountRects() > 0 && !(pt.x == 0.0f && pt.y == 0.0f)) {
736					copyReg->OffsetBy(-pt.x, -pt.y);
737					BPoint		*point = new BPoint(pt);
738					fRootLayer->fCopyRegList.AddItem(copyReg);
739					fRootLayer->fCopyList.AddItem(point);
740				} else {
741					delete copyReg;
742				}
743
744				redrawReg	= fFullVisible;
745				redrawReg.Exclude(&oldRegion);
746				if (redrawReg.CountRects() > 0 && !(pt.x == 0.0f && pt.y == 0.0f)) {
747					fRootLayer->fRedrawReg.Include(&redrawReg);
748				}
749
750				break;
751			}
752			case B_LAYER_RESIZE: {
753				RBTRACE(("2) Layer(%s): Action B_LAYER_RESIZE\n", GetName()));
754				BRegion redrawReg;
755
756				redrawReg = fVisible;
757				redrawReg.Exclude(&oldRegion);
758				if(redrawReg.CountRects() > 0)
759					fRootLayer->fRedrawReg.Include(&redrawReg);
760
761				break;
762			}
763			case B_LAYER_MASK_RESIZE: {
764				RBTRACE(("2) Layer(%s): Action B_LAYER_MASK_RESIZE\n", GetName()));
765				BRegion redrawReg;
766				BRegion	*copyReg = new BRegion();
767
768				oldRegion.OffsetBy(dummyNewLocation.x, dummyNewLocation.y);
769
770				redrawReg	= fVisible;
771				redrawReg.Exclude(&oldRegion);
772				if (redrawReg.CountRects() > 0)
773					fRootLayer->fRedrawReg.Include(&redrawReg);
774
775				*copyReg = fVisible;
776				copyReg->IntersectWith(&oldRegion);
777				copyReg->OffsetBy(-dummyNewLocation.x, -dummyNewLocation.y);
778				if (copyReg->CountRects() > 0
779					&& !(dummyNewLocation.x == 0.0f && dummyNewLocation.y == 0.0f)) {
780					fRootLayer->fCopyRegList.AddItem(copyReg);
781					fRootLayer->fCopyList.AddItem(new BPoint(dummyNewLocation));
782				}
783
784				break;
785			}
786			default:
787				RBTRACE(("2) Layer(%s): Action default\n", GetName()));
788				break;
789		}
790	}
791/*	if (IsHidden()) {
792		fFullVisible.MakeEmpty();
793		fVisible.MakeEmpty();
794	}
795*/
796
797	STRACE(("Layer(%s)::RebuildRegions() END\n", GetName()));
798}
799
800// ResizeOthers
801uint32
802Layer::ResizeOthers(float x, float y, BPoint coords[], BPoint *ptOffset)
803{
804	STRACE(("Layer(%s)::ResizeOthers() START\n", GetName()));
805	uint32 rmask = fResizeMode;
806
807	// offset
808	coords[0].x	= 0.0f;
809	coords[0].y	= 0.0f;
810
811	// resize by width/height
812	coords[1].x	= 0.0f;
813	coords[1].y	= 0.0f;
814
815	if ((rmask & 0x00000f00UL)>>8 == _VIEW_LEFT_ &&
816		(rmask & 0x0000000fUL)>>0 == _VIEW_RIGHT_) {
817		coords[1].x		= x;
818	} else if ((rmask & 0x00000f00UL)>>8 == _VIEW_LEFT_) {
819	} else if ((rmask & 0x0000000fUL)>>0 == _VIEW_RIGHT_) {
820		coords[0].x		= x;
821	} else if ((rmask & 0x00000f00UL)>>8 == _VIEW_CENTER_) {
822		coords[0].x		= x/2;
823	} else {
824		// illegal flag. Do nothing.
825	}
826
827
828	if ((rmask & 0x0000f000UL)>>12 == _VIEW_TOP_ &&
829		(rmask & 0x000000f0UL)>>4 == _VIEW_BOTTOM_) {
830		coords[1].y		= y;
831	} else if ((rmask & 0x0000f000UL)>>12 == _VIEW_TOP_) {
832	} else if ((rmask & 0x000000f0UL)>>4 == _VIEW_BOTTOM_) {
833		coords[0].y		= y;
834	} else if ((rmask & 0x0000f000UL)>>12 == _VIEW_CENTER_) {
835		coords[0].y		= y/2;
836	} else {
837		// illegal flag. Do nothing.
838	}
839
840	STRACE(("Layer(%s)::ResizeOthers() END\n", GetName()));
841	return 0UL;
842}
843
844// Redraw
845void
846Layer::Redraw(const BRegion& reg, Layer *startFrom)
847{
848	STRACE(("Layer(%s)::Redraw();\n", GetName()));
849	if (IsHidden())
850		// this layer has nothing visible on screen, so bail out.
851		return;
852
853	BRegion *pReg = const_cast<BRegion*>(&reg);
854
855	if (pReg->CountRects() > 0)
856		RequestDraw(reg, startFrom);
857
858	STRACE(("Layer(%s)::Redraw() ENDED\n", GetName()));
859}
860
861// Draw
862void
863Layer::Draw(const BRect &r)
864{
865	// TODO/NOTE: this should be an empty method! the next lines are for testing only
866
867#ifdef DEBUG_LAYER
868	printf("Layer(%s)::Draw: ", GetName());
869	r.PrintToStream();
870#endif
871
872	// TODO: don't do this if ViewColor() is B_TRANSPARENT_COLOR
873	fDriver->FillRect(r, fLayerData->ViewColor());
874//	RGBColor c(rand()%255,rand()%255,rand()%255);
875//	fDriver->FillRect(r, c);
876
877	// empty HOOK function.
878}
879
880// EmptyGlobals
881void
882Layer::EmptyGlobals()
883{
884	fRootLayer->fRedrawReg.MakeEmpty();
885
886	int32 count = fRootLayer->fCopyRegList.CountItems();
887	for (int32 i = 0; i < count; i++)
888		delete (BRegion*)fRootLayer->fCopyRegList.ItemAt(i);
889	fRootLayer->fCopyRegList.MakeEmpty();
890
891	count = fRootLayer->fCopyList.CountItems();
892	for (int32 i = 0; i < count; i++)
893		delete (BPoint*)fRootLayer->fCopyList.ItemAt(i);
894	fRootLayer->fCopyList.MakeEmpty();
895}
896
897/*!
898	\brief Shows the layer
899	\param invalidate Invalidate the region when showing the layer. defaults to true
900*/
901void
902Layer::Show(bool invalidate)
903{
904	STRACE(("Layer(%s)::Show()\n", GetName()));
905	if( !IsHidden() )
906		return;
907
908	fHidden	= false;
909
910	if(invalidate)
911		GetRootLayer()->GoInvalidate(this, fFull);
912}
913
914/*!
915	\brief Shows the layer
916	\param invalidate Invalidate the region when hiding the layer. defaults to true
917*/
918void
919Layer::Hide(bool invalidate)
920{
921	STRACE(("Layer(%s)::Hide()\n", GetName()));
922	if ( IsHidden() )
923		return;
924
925	fHidden	= true;
926
927	if(invalidate)
928		GetRootLayer()->GoInvalidate(this, fFullVisible);
929}
930
931//! Returns true if the layer is hidden
932bool
933Layer::IsHidden(void) const
934{
935	if (fHidden)
936		return true;
937	else {
938		if (fParent)
939			return fParent->IsHidden();
940	}
941
942	return false;
943}
944
945//! Matches the BView call of the same name
946BRect
947Layer::Bounds(void) const
948{
949	BRect r(fFrame);
950//	r.OffsetTo(fBoundsLeftTop);
951	r.OffsetTo(BoundsOrigin());
952	return r;
953}
954
955//! Matches the BView call of the same name
956BRect
957Layer::Frame(void) const
958{
959	return fFrame;
960}
961
962//! Moves the layer by specified values, complete with redraw
963void
964Layer::MoveBy(float x, float y)
965{
966	STRACE(("Layer(%s)::MoveBy() START\n", GetName()));
967	if (!fParent) {
968		debugger("ERROR: in Layer::MoveBy()! - No parent!\n");
969		return;
970	}
971
972	BPortLink	msg(-1, -1);
973	msg.StartMessage(AS_ROOTLAYER_LAYER_MOVE);
974	msg.Attach<Layer*>(this);
975	msg.Attach<float>(x);
976	msg.Attach<float>(y);
977	GetRootLayer()->EnqueueMessage(msg);
978
979	STRACE(("Layer(%s)::MoveBy() END\n", GetName()));
980}
981
982//! Resize the layer by the specified amount, complete with redraw
983void
984Layer::ResizeBy(float x, float y)
985{
986	STRACE(("Layer(%s)::ResizeBy() START\n", GetName()));
987
988	if(!fParent)
989	{
990		printf("ERROR: in Layer::ResizeBy()! - No parent!\n");
991		return;
992	}
993
994	BPortLink	msg(-1, -1);
995	msg.StartMessage(AS_ROOTLAYER_LAYER_RESIZE);
996	msg.Attach<Layer*>(this);
997	msg.Attach<float>(x);
998	msg.Attach<float>(y);
999	GetRootLayer()->EnqueueMessage(msg);
1000
1001	STRACE(("Layer(%s)::ResizeBy() END\n", GetName()));
1002}
1003
1004// BoundsOrigin
1005BPoint
1006Layer::BoundsOrigin() const
1007{
1008	// TODO: add origin from previous states
1009	return fLayerData->Origin();
1010}
1011
1012//! Converts the passed point to parent coordinates
1013BPoint
1014Layer::ConvertToParent(BPoint pt)
1015{
1016	pt -= BoundsOrigin();
1017	pt += fFrame.LeftTop();
1018	return pt;
1019}
1020
1021//! Converts the passed rectangle to parent coordinates
1022BRect
1023Layer::ConvertToParent(BRect rect)
1024{
1025//	rect.OffsetBy(fFrame.LeftTop());
1026//	return rect;
1027	rect.OffsetBy(-BoundsOrigin().x, -BoundsOrigin().y);
1028	rect.OffsetBy(fFrame.LeftTop());
1029	return rect;
1030}
1031
1032//! Converts the passed region to parent coordinates
1033BRegion
1034Layer::ConvertToParent(BRegion* reg)
1035{
1036	// TODO: wouldn't it be more efficient to use the copy
1037	// constructor for BRegion and then call OffsetBy()?
1038	BRegion newreg;
1039	for (int32 i = 0; i < reg->CountRects(); i++)
1040		newreg.Include(ConvertToParent(reg->RectAt(i)));
1041	return newreg;
1042}
1043
1044//! Converts the passed point from parent coordinates
1045BPoint
1046Layer::ConvertFromParent(BPoint pt)
1047{
1048//	return pt - fFrame.LeftTop();
1049	pt -= fFrame.LeftTop();
1050	pt += BoundsOrigin();
1051	return pt;
1052}
1053
1054//! Converts the passed rectangle from parent coordinates
1055BRect
1056Layer::ConvertFromParent(BRect rect)
1057{
1058//	rect.OffsetBy(-fFrame.left, -fFrame.top);
1059//	return rect;
1060	rect.OffsetBy(-fFrame.left, -fFrame.top);
1061	rect.OffsetBy(BoundsOrigin());
1062	return rect;
1063}
1064
1065//! Converts the passed region from parent coordinates
1066BRegion
1067Layer::ConvertFromParent(BRegion *reg)
1068{
1069	BRegion newreg;
1070	for(int32 i=0; i<reg->CountRects();i++)
1071		newreg.Include(ConvertFromParent(reg->RectAt(i)));
1072	return newreg;
1073}
1074
1075// ConvertToTop
1076BPoint
1077Layer::ConvertToTop(BPoint pt)
1078{
1079	if (fParent) {
1080//		return (fParent->ConvertToTop(pt + fFrame.LeftTop()));
1081		pt = ConvertToParent(pt);
1082		return fParent->ConvertToTop(pt);
1083	} else
1084		return pt;
1085}
1086
1087//! Converts the passed rectangle to screen coordinates
1088BRect
1089Layer::ConvertToTop(BRect rect)
1090{
1091	if (fParent) {
1092//		return fParent->ConvertToTop(rect.OffsetByCopy(fFrame.LeftTop()));
1093		rect = ConvertToParent(rect);
1094		return fParent->ConvertToTop(rect);
1095	} else
1096		return rect;
1097}
1098
1099//! Converts the passed region to screen coordinates
1100BRegion
1101Layer::ConvertToTop(BRegion *reg)
1102{
1103	BRegion newreg;
1104	for (int32 i = 0; i < reg->CountRects();i++)
1105		newreg.Include(ConvertToTop(reg->RectAt(i)));
1106	return newreg;
1107}
1108
1109// ConvertFromTop
1110BPoint
1111Layer::ConvertFromTop(BPoint pt)
1112{
1113	if (fParent) {
1114//		return fParent->ConvertFromTop(pt-fFrame.LeftTop());
1115		pt = ConvertFromParent(pt);
1116		return fParent->ConvertFromTop(pt);
1117	} else
1118		return pt;
1119}
1120
1121//! Converts the passed rectangle from screen coordinates
1122BRect
1123Layer::ConvertFromTop(BRect rect)
1124{
1125	if (fParent) {
1126//		return fParent->ConvertFromTop(rect.OffsetByCopy(-fFrame.LeftTop().x,
1127//														 -fFrame.LeftTop().y));
1128		rect = ConvertFromParent(rect);
1129		return fParent->ConvertFromTop(rect);
1130	} else
1131		return rect;
1132}
1133
1134//! Converts the passed region from screen coordinates
1135BRegion
1136Layer::ConvertFromTop(BRegion *reg)
1137{
1138	BRegion newreg;
1139
1140	for (int32 i = 0; i < reg->CountRects(); i++)
1141		newreg.Include(ConvertFromTop(reg->RectAt(i)));
1142
1143	return newreg;
1144}
1145
1146//! Recursively deletes all children of the calling layer
1147void
1148Layer::PruneTree(void)
1149{
1150	Layer* lay;
1151	Layer* nextlay;
1152
1153	lay = fTopChild;
1154	fTopChild = NULL;
1155
1156	while (lay != NULL) {
1157		if (lay->fTopChild != NULL)
1158			lay->PruneTree();
1159
1160		nextlay = lay->fLowerSibling;
1161		lay->fLowerSibling = NULL;
1162
1163		delete lay;
1164		lay = nextlay;
1165	}
1166	// Man, this thing is short. Elegant, ain't it? :P
1167}
1168
1169//! Prints information about the layer's current state
1170void
1171Layer::PrintToStream()
1172{
1173	printf("\n----------- Layer %s -----------\n",fName->String());
1174	printf("\t Parent: %s\n", fParent? fParent->GetName():"NULL");
1175	printf("\t us: %s\t ls: %s\n",
1176				fUpperSibling? fUpperSibling->GetName():"NULL",
1177				fLowerSibling? fLowerSibling->GetName():"NULL");
1178	printf("\t topChild: %s\t bottomChild: %s\n",
1179				fTopChild? fTopChild->GetName():"NULL",
1180				fBottomChild? fBottomChild->GetName():"NULL");
1181
1182	printf("Frame: (%f, %f, %f, %f)", fFrame.left, fFrame.top, fFrame.right, fFrame.bottom);
1183	printf("Token: %ld\n",fViewToken);
1184	printf("Hidden - direct: %s\n", fHidden?"true":"false");
1185	printf("Hidden - indirect: %s\n", IsHidden()?"true":"false");
1186	printf("ResizingMode: %lx\n", fResizeMode);
1187	printf("Flags: %lx\n", fFlags);
1188
1189	if (fLayerData)
1190		fLayerData->PrintToStream();
1191	else
1192		printf(" NO LayerData valid pointer\n");
1193}
1194
1195//! Prints pointer info kept by the current layer
1196void
1197Layer::PrintNode()
1198{
1199	printf("-----------\nLayer %s\n",fName->String());
1200	if(fParent)
1201		printf("Parent: %s (%p)\n",fParent->GetName(), fParent);
1202	else
1203		printf("Parent: NULL\n");
1204	if(fUpperSibling)
1205		printf("Upper sibling: %s (%p)\n",fUpperSibling->GetName(), fUpperSibling);
1206	else
1207		printf("Upper sibling: NULL\n");
1208	if(fLowerSibling)
1209		printf("Lower sibling: %s (%p)\n",fLowerSibling->GetName(), fLowerSibling);
1210	else
1211		printf("Lower sibling: NULL\n");
1212	if(fTopChild)
1213		printf("Top child: %s (%p)\n",fTopChild->GetName(), fTopChild);
1214	else
1215		printf("Top child: NULL\n");
1216	if(fBottomChild)
1217		printf("Bottom child: %s (%p)\n",fBottomChild->GetName(), fBottomChild);
1218	else
1219		printf("Bottom child: NULL\n");
1220	printf("Visible Areas: "); fVisible.PrintToStream();
1221}
1222
1223//! Prints the tree hierarchy from the current layer down
1224void
1225Layer::PrintTree()
1226{
1227	printf("\n Tree structure:\n");
1228	printf("\t%s\t%s\n", GetName(), IsHidden()? "Hidden": "NOT hidden");
1229	for(Layer *lay = VirtualBottomChild(); lay != NULL; lay = VirtualUpperSibling())
1230		printf("\t%s\t%s\n", lay->GetName(), lay->IsHidden()? "Hidden": "NOT hidden");
1231}
1232
1233// UpdateStart
1234void
1235Layer::UpdateStart()
1236{
1237	// During updates we only want to draw what's in the update region
1238	if (fClassID == AS_WINBORDER_CLASS) {
1239		// NOTE: don't worry, RooLayer is locked here.
1240		WinBorder	*wb = (WinBorder*)this;
1241
1242		wb->fInUpdate = true;
1243		wb->fRequestSent = false;
1244		wb->yUpdateReg = wb->fUpdateReg;
1245		wb->fUpdateReg.MakeEmpty();
1246wb->cnt--;
1247if (wb->cnt != 0)
1248	debugger("Adi2: Not Allowed!");
1249	}
1250}
1251
1252// UpdateEnd
1253void
1254Layer::UpdateEnd()
1255{
1256	// The usual case. Drawing is permitted in the whole visible area.
1257	if (fClassID == AS_WINBORDER_CLASS) {
1258		WinBorder	*wb = (WinBorder*)this;
1259
1260		wb->yUpdateReg.MakeEmpty();
1261
1262		wb->fInUpdate = false;
1263
1264		if (wb->zUpdateReg.CountRects() > 0) {
1265			BRegion		reg(wb->zUpdateReg);
1266			wb->RequestDraw(reg, NULL);
1267		}
1268	}
1269}
1270
1271// move_layer
1272void
1273Layer::move_layer(float x, float y)
1274{
1275	fFrameAction = B_LAYER_ACTION_MOVE;
1276
1277/*	if (fClassID == AS_WINBORDER_CLASS) {
1278		WinBorder	*wb = (WinBorder*)this;
1279		wb->zUpdateReg.OffsetBy(x, y);
1280		wb->yUpdateReg.OffsetBy(x, y);
1281		wb->fUpdateReg.OffsetBy(x, y);
1282	}*/
1283
1284	BPoint pt(x, y);
1285	BRect rect(fFull.Frame().OffsetByCopy(pt));
1286
1287if (!fParent) {
1288printf("no parent in Layer::move_layer() (%s)\n", GetName());
1289fFrameAction = B_LAYER_ACTION_NONE;
1290return;
1291}
1292	fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_MOVE, pt);
1293
1294	fDriver->CopyRegionList(&fRootLayer->fCopyRegList,
1295							&fRootLayer->fCopyList,
1296							fRootLayer->fCopyRegList.CountItems(),
1297							&fFullVisible);
1298
1299	fParent->Redraw(fRootLayer->fRedrawReg, this);
1300
1301	SendViewCoordUpdateMsg();
1302
1303	EmptyGlobals();
1304
1305	fFrameAction = B_LAYER_ACTION_NONE;
1306}
1307
1308// resize_layer
1309void
1310Layer::resize_layer(float x, float y)
1311{
1312	fFrameAction = B_LAYER_ACTION_RESIZE;
1313
1314	BPoint pt(x,y);
1315	BRect rect(fFull.Frame());
1316	rect.right += x;
1317	rect.bottom += y;
1318
1319if (!fParent) {
1320printf("no parent in Layer::resize_layer() (%s)\n", GetName());
1321fFrameAction = B_LAYER_ACTION_NONE;
1322return;
1323}
1324
1325	fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_RESIZE, pt);
1326
1327	fDriver->CopyRegionList(&fRootLayer->fCopyRegList, &fRootLayer->fCopyList, fRootLayer->fCopyRegList.CountItems(), &fFullVisible);
1328	fParent->Redraw(fRootLayer->fRedrawReg, this);
1329
1330	SendViewCoordUpdateMsg();
1331
1332	EmptyGlobals();
1333
1334	fFrameAction = B_LAYER_ACTION_NONE;
1335}
1336
1337// FullInvalidate
1338void
1339Layer::FullInvalidate(const BRect &rect)
1340{
1341	FullInvalidate(BRegion(rect));
1342}
1343
1344// FullInvalidate
1345void
1346Layer::FullInvalidate(const BRegion& region)
1347{
1348	STRACE(("Layer(%s)::FullInvalidate():\n", GetName()));
1349
1350#ifdef DEBUG_LAYER
1351	region.PrintToStream();
1352	printf("\n");
1353#endif
1354
1355	BPoint pt(0,0);
1356	StartRebuildRegions(region, NULL,/* B_LAYER_INVALIDATE, pt); */B_LAYER_NONE, pt);
1357
1358	Redraw(fRootLayer->fRedrawReg);
1359
1360	EmptyGlobals();
1361}
1362
1363// Invalidate
1364void
1365Layer::Invalidate(const BRegion& region)
1366{
1367	STRACE(("Layer(%s)::Invalidate():\n", GetName()));
1368#ifdef DEBUG_LAYER
1369	region.PrintToStream();
1370	printf("\n");
1371#endif
1372
1373	fRootLayer->fRedrawReg	= region;
1374
1375	Redraw(fRootLayer->fRedrawReg);
1376
1377	EmptyGlobals();
1378}
1379
1380// RequestDraw
1381void
1382Layer::RequestDraw(const BRegion &reg, Layer *startFrom)
1383{
1384	STRACE(("Layer(%s)::RequestDraw()\n", GetName()));
1385
1386	// do not redraw any child until you must
1387	int redraw = false;
1388	if (!startFrom)
1389		redraw = true;
1390
1391	if (HasClient() && IsTopLayer()) {
1392		// calculate the minimum region/rectangle to be updated with
1393		// a single message to the client.
1394		BRegion	updateReg(fFullVisible);
1395		if (fFlags & B_FULL_UPDATE_ON_RESIZE
1396			&& fFrameAction	== B_LAYER_ACTION_RESIZE) {
1397			// do nothing
1398		} else {
1399			updateReg.IntersectWith(&reg);
1400		}
1401		if (updateReg.CountRects() > 0) {
1402			fOwner->zUpdateReg.Include(&updateReg);
1403			if (!fOwner->fInUpdate && !fOwner->fRequestSent) {
1404				fOwner->fUpdateReg = fOwner->zUpdateReg;
1405fOwner->cnt++;
1406if (fOwner->cnt != 1)
1407	debugger("Adi: Not Allowed!");
1408				fOwner->zUpdateReg.MakeEmpty();
1409				SendUpdateMsg(fOwner->fUpdateReg);
1410				fOwner->fRequestSent = true;
1411			}
1412		}
1413	}
1414
1415	if (fVisible.CountRects() > 0) {
1416		BRegion	updateReg(fVisible);
1417		// calculate the update region
1418		if (fFlags & B_FULL_UPDATE_ON_RESIZE
1419			&& fFrameAction	== B_LAYER_ACTION_RESIZE) {
1420			// do nothing
1421		} else {
1422			updateReg.IntersectWith(&reg);
1423		}
1424
1425		if (updateReg.CountRects() > 0) {
1426			fDriver->ConstrainClippingRegion(&updateReg);
1427			Draw(updateReg.Frame());
1428			fDriver->ConstrainClippingRegion(NULL);
1429		}
1430	}
1431
1432	for (Layer *lay = VirtualBottomChild(); lay != NULL; lay = VirtualUpperSibling()) {
1433		if (lay == startFrom)
1434			redraw = true;
1435
1436		if (redraw && !(lay->IsHidden())) {
1437			// no need to go deeper if not even the FullVisible region intersects
1438			// Update one.
1439
1440			BRegion common(lay->fFullVisible);
1441			common.IntersectWith(&reg);
1442
1443			if (common.CountRects() > 0)
1444				lay->RequestDraw(reg, NULL);
1445		}
1446	}
1447}
1448
1449/*!
1450	\brief Returns the layer's ServerWindow
1451
1452	If the layer's ServerWindow has not been assigned, it attempts to find
1453	the owning ServerWindow in the tree.
1454*/
1455ServerWindow*
1456Layer::SearchForServerWindow()
1457{
1458	if (!fServerWin)
1459		fServerWin=fParent->SearchForServerWindow();
1460
1461	return fServerWin;
1462}
1463
1464//! Sends an _UPDATE_ message to the client BWindow
1465void
1466Layer::SendUpdateMsg(BRegion& reg)
1467{
1468	BMessage msg;
1469	msg.what = _UPDATE_;
1470	msg.AddRect("_rect", ConvertFromTop(reg.Frame()) );
1471	msg.AddRect("debug_rect", reg.Frame() );
1472//	msg.AddInt32("_token",fViewToken);
1473
1474	fOwner->Window()->SendMessageToClient(&msg);
1475}
1476
1477// AddToViewsWithInvalidCoords
1478void
1479Layer::AddToViewsWithInvalidCoords() const
1480{
1481	if (fServerWin) {
1482		fServerWin->fClientViewsWithInvalidCoords.AddInt32("_token", fViewToken);
1483		fServerWin->fClientViewsWithInvalidCoords.AddPoint("where", fFrame.LeftTop());
1484		fServerWin->fClientViewsWithInvalidCoords.AddFloat("width", fFrame.Width());
1485		fServerWin->fClientViewsWithInvalidCoords.AddFloat("height", fFrame.Height());
1486	}
1487}
1488
1489// SendViewCoordUpdateMsg
1490void
1491Layer::SendViewCoordUpdateMsg() const
1492{
1493	if (fServerWin && !fServerWin->fClientViewsWithInvalidCoords.IsEmpty()) {
1494		fServerWin->SendMessageToClient(&fServerWin->fClientViewsWithInvalidCoords);
1495		fServerWin->fClientViewsWithInvalidCoords.MakeEmpty();
1496	}
1497}
1498
1499/*
1500//! Sends a B_VIEW_MOVED message to the client BWindow
1501void
1502Layer::SendViewMovedMsg()
1503{
1504	if (fServerWin && fFlags & B_FRAME_EVENTS) {
1505		BMessage msg;
1506		msg.what = B_VIEW_MOVED;
1507		// TODO: system_time() ?!?
1508		msg.AddInt64("when", real_time_clock_usecs());
1509		msg.AddInt32("_token", fViewToken);
1510		msg.AddPoint("where", fFrame.LeftTop());
1511
1512		fServerWin->SendMessageToClient(&msg);
1513	}
1514}
1515
1516//! Sends a B_VIEW_RESIZE message to the client BWindow
1517void
1518Layer::SendViewResizedMsg()
1519{
1520	if (fServerWin && fFlags & B_FRAME_EVENTS) {
1521		BMessage msg;
1522		msg.what = B_VIEW_RESIZED;
1523		// TODO: system_time() ?!?
1524		msg.AddInt64("when", real_time_clock_usecs());
1525		msg.AddInt32("_token", fViewToken);
1526		msg.AddFloat("width", fFrame.Width());
1527		msg.AddFloat("height", fFrame.Height());
1528
1529		// no need for that... it's here because of backward compatibility
1530		msg.AddPoint("where", fFrame.LeftTop());
1531
1532		fServerWin->SendMessageToClient(&msg);
1533	}
1534}
1535*/
1536
1537