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