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