Layer.cpp revision 45ca1c948cba0471b3107e037489e54500215c50
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	// TODO: Decorator class should have a method witch
114	// returns the minimum frame width.
115	if (!frame.IsValid())
116		fFrame.Set(0, 0, 5, 5);
117
118	if (!fDriver)
119		CRITICAL("You MUST have a valid driver to init a Layer object\n");
120
121	STRACE(("Layer(%s) successfuly created\n", GetName()));
122}
123
124//! Destructor frees all allocated heap space
125Layer::~Layer(void)
126{
127	delete fLayerData;
128	delete fName;
129
130	// TODO: uncomment!
131	//PruneTree();
132
133//	fServerWin->RemoveChild(fDriver);
134//	delete fDriver;
135}
136
137/*!
138	\brief Adds a child layer to the current one
139	\param layer a new child layer
140	\param serverWin the serverwindow to which the layer will belong
141
142	Unlike the BView version, if the layer already belongs to another, then
143	it spits an error to stdout and returns.
144*/
145void
146Layer::AddChild(Layer* layer, ServerWindow* serverWin)
147{
148	STRACE(("Layer(%s)::AddChild(%s) START\n", GetName(), layer->GetName()));
149
150	if (layer->fParent != NULL) {
151		printf("ERROR: AddChild(): Layer already has a parent\n");
152		return;
153	}
154
155	// 1) attach layer to the tree structure
156	layer->fParent = this;
157
158	// if we have children already, bump the current front child back one and
159	// make the new child the frontmost layer
160	if (fBottomChild) {
161		layer->fUpperSibling = fBottomChild;
162		fBottomChild->fLowerSibling	= layer;
163	} else {
164		fTopChild = layer;
165	}
166	fBottomChild = layer;
167
168	// if we have no RootLayer yet, then there is no need to set any parameters --
169	// they will be set when the RootLayer for this tree will be added
170	// to the main tree structure.
171	if (!fRootLayer) {
172		STRACE(("Layer(%s)::AddChild(%s) END\n", GetName(), layer->GetName()));
173		return;
174	}
175
176	// 2) Iterate over the newly-added layer and all its children, setting the
177	//	root layer and server window and also rebuilding the full-size region
178	//	for every descendant of the newly-added layer
179
180	//c = short for: current
181	Layer* c = layer;
182	Layer* stop = layer;
183	while (true) {
184		// action block
185
186		// 2.1) set the RootLayer for this object.
187		c->SetRootLayer(c->fParent->fRootLayer);
188
189		// 2.2) this Layer must know if it has a ServerWindow object attached.
190		c->fServerWin=serverWin;
191
192		// 2.3) we are attached to the main tree so build our full region.
193		c->RebuildFullRegion();
194
195		// tree parsing algorithm
196		if (c->fTopChild) {
197			// go deep
198			c = c->fTopChild;
199		} else {
200			// go right or up
201
202			if (c == stop) // out trip is over
203				break;
204
205			if (c->fLowerSibling) {
206				// go right
207				c = c->fLowerSibling;
208			} else {
209				// go up
210				while (!c->fParent->fLowerSibling && c->fParent != stop)
211					c = c->fParent;
212
213				if (c->fParent == stop) // that's enough!
214					break;
215
216				c = c->fParent->fLowerSibling;
217			}
218		}
219	}
220
221	STRACE(("Layer(%s)::AddChild(%s) END\n", GetName(), layer->GetName()));
222}
223
224/*!
225	\brief Removes a child layer from the current one
226	\param layer the layer to remove
227
228	If the layer does not belong to the the current layer, then this function
229	spits out an error to stdout and returns
230*/
231void
232Layer::RemoveChild(Layer *layer)
233{
234	STRACE(("Layer(%s)::RemoveChild(%s) START\n", GetName(), layer->GetName()));
235
236	if (!layer->fParent) {
237		printf("ERROR: RemoveChild(): Layer doesn't have a fParent\n");
238		return;
239	}
240
241	if (layer->fParent != this) {
242		printf("ERROR: RemoveChild(): Layer is not a child of this layer\n");
243		return;
244	}
245
246	// 1) remove this layer from the main tree.
247
248	// Take care of fParent
249	layer->fParent = NULL;
250
251	if (fTopChild == layer)
252		fTopChild = layer->fLowerSibling;
253
254	if (fBottomChild == layer)
255		fBottomChild = layer->fUpperSibling;
256
257	// Take care of siblings
258	if (layer->fUpperSibling != NULL)
259		layer->fUpperSibling->fLowerSibling	= layer->fLowerSibling;
260
261	if (layer->fLowerSibling != NULL)
262		layer->fLowerSibling->fUpperSibling = layer->fUpperSibling;
263
264	layer->fUpperSibling = NULL;
265	layer->fLowerSibling = NULL;
266
267	// 2) Iterate over all of the removed-layer's descendants and unset the
268	//	root layer, server window, and all redraw-related regions
269
270	Layer* c = layer; //c = short for: current
271	Layer* stop = layer;
272
273	while (true) {
274		// action block
275		{
276			// 2.1) set the RootLayer for this object.
277			c->SetRootLayer(NULL);
278			// 2.2) this Layer must know if it has a ServerWindow object attached.
279			c->fServerWin = NULL;
280			// 2.3) we were removed from the main tree so clear our full region.
281			c->fFull.MakeEmpty();
282			// 2.4) clear fullVisible region.
283			c->fFullVisible.MakeEmpty();
284			// 2.5) we don't have a visible region anymore.
285			c->fVisible.MakeEmpty();
286		}
287
288		// tree parsing algorithm
289		if (c->fTopChild) {
290			// go deep
291			c = c->fTopChild;
292		} else {
293			// go right or up
294			if (c == stop) // out trip is over
295				break;
296
297			if (c->fLowerSibling) {
298				// go right
299				c = c->fLowerSibling;
300			} else {
301				// go up
302				while(!c->fParent->fLowerSibling && c->fParent != stop)
303					c = c->fParent;
304
305				if (c->fParent == stop) // that enough!
306					break;
307
308				c = c->fParent->fLowerSibling;
309			}
310		}
311	}
312	STRACE(("Layer(%s)::RemoveChild(%s) END\n", GetName(), layer->GetName()));
313}
314
315//! Removes the calling layer from the tree
316void
317Layer::RemoveSelf()
318{
319	// A Layer removes itself from the tree (duh)
320	if (fParent == NULL) {
321		printf("ERROR: RemoveSelf(): Layer doesn't have a fParent\n");
322		return;
323	}
324	fParent->RemoveChild(this);
325}
326
327/*!
328	\brief Determins if the calling layer has the passed layer as a child
329	\return true if the child is owned by the caller, false if not
330*/
331bool
332Layer::HasChild(Layer* layer)
333{
334	for (Layer *lay = VirtualTopChild(); lay; lay = VirtualLowerSibling()) {
335		if (lay == layer)
336			return true;
337	}
338	return false;
339}
340
341//! Returns the number of children
342uint32
343Layer::CountChildren(void) const
344{
345	uint32 count = 0;
346	Layer *lay = VirtualTopChild();
347	while (lay != NULL) {
348		lay	= VirtualLowerSibling();
349		count++;
350	}
351	return count;
352}
353
354/*!
355	\brief Finds a child of the caller based on its token ID
356	\param token ID of the layer to find
357	\return Pointer to the layer or NULL if not found
358*/
359Layer*
360Layer::FindLayer(const int32 token)
361{
362	// recursive search for a layer based on its view token
363	Layer* lay;
364	Layer* trylay;
365
366	// Search child layers first
367	for (lay = VirtualTopChild(); lay; lay = VirtualLowerSibling()) {
368		if (lay->fViewToken == token)
369			return lay;
370	}
371
372	// Hmmm... not in this layer's children. Try lower descendants
373	for (lay = VirtualTopChild(); lay != NULL; lay = VirtualLowerSibling()) {
374		trylay = lay->FindLayer(token);
375		if (trylay)
376			return trylay;
377	}
378
379	// Well, we got this far in the function,
380	// so apparently there is no match to be found
381	return NULL;
382}
383
384/*!
385	\brief Returns the layer at the given point
386	\param pt The point to look the layer at
387	\return The layer containing the point or NULL if no layer found
388*/
389Layer*
390Layer::LayerAt(const BPoint &pt)
391{
392	if (fVisible.Contains(pt))
393		return this;
394
395	if (fFullVisible.Contains(pt)) {
396		Layer *lay = NULL;
397		for (Layer* child = VirtualBottomChild(); child; child = VirtualUpperSibling()) {
398			lay = child->LayerAt(pt);
399			if (lay)
400				return lay;
401		}
402	}
403
404	return NULL;
405}
406
407// VirtualTopChild
408Layer*
409Layer::VirtualTopChild() const
410{
411	fCurrent = fTopChild;
412	return fCurrent;
413}
414
415// VirtualLowerSibling
416Layer*
417Layer::VirtualLowerSibling() const
418{
419	fCurrent = fCurrent->fLowerSibling;
420	return fCurrent;
421}
422
423// VirtualUpperSibling
424Layer*
425Layer::VirtualUpperSibling() const
426{
427	fCurrent = fCurrent->fUpperSibling;
428	return fCurrent;
429}
430
431// VirtualBottomChild
432Layer*
433Layer::VirtualBottomChild() const
434{
435	fCurrent = fBottomChild;
436	return fCurrent;
437}
438
439
440//! Rebuilds the layer's "completely visible" region
441void
442Layer::RebuildFullRegion(void)
443{
444	STRACE(("Layer(%s)::RebuildFullRegion()\n", GetName()));
445
446	if (fParent)
447		fFull.Set(fParent->ConvertToTop(fFrame ));
448	else
449		fFull.Set(fFrame);
450
451	// TODO: restrict to screen coordinates
452
453	// TODO: Convert to screen coordinates
454
455	LayerData *ld;
456	ld = fLayerData;
457	do {
458		// clip to user region
459		if (const BRegion* userClipping = ld->ClippingRegion())
460			fFull.IntersectWith(userClipping);
461
462	} while ((ld = ld->prevState));
463}
464
465// StartRebuildRegions
466void
467Layer::StartRebuildRegions( const BRegion& reg, Layer *target, uint32 action, BPoint& pt)
468{
469	STRACE(("Layer(%s)::StartRebuildRegions() START\n", GetName()));
470	RBTRACE(("\n\nLayer(%s)::StartRebuildRegions() START\n", GetName()));
471	if (!fParent)
472		fFullVisible = fFull;
473
474	BRegion oldVisible = fVisible;
475
476	fVisible = fFullVisible;
477
478	// Rebuild regions for children...
479	for (Layer *lay = VirtualBottomChild(); lay; lay = VirtualUpperSibling()) {
480		if (lay == target)
481			lay->RebuildRegions(reg, action, pt, BPoint(0.0f, 0.0f));
482		else
483			lay->RebuildRegions(reg, B_LAYER_NONE, pt, BPoint(0.0f, 0.0f));
484	}
485
486	#ifdef DEBUG_LAYER_REBUILD
487		printf("\nSRR: Layer(%s) ALMOST done regions:\n", GetName());
488		printf("\tVisible Region:\n");
489		fVisible.PrintToStream();
490		printf("\tFull Visible Region:\n");
491		fFullVisible.PrintToStream();
492	#endif
493
494	BRegion redrawReg(fVisible);
495
496	// if this is the first time
497	if (oldVisible.CountRects() > 0)
498		redrawReg.Exclude(&oldVisible);
499
500	if (redrawReg.CountRects() > 0)
501		fRootLayer->fRedrawReg.Include(&redrawReg);
502
503	#ifdef DEBUG_LAYER_REBUILD
504		printf("\nLayer(%s)::StartRebuildRegions() DONE. Results:\n", GetName());
505		printf("\tRedraw Region:\n");
506		fRootLayer->fRedrawReg.PrintToStream();
507		printf("\tCopy Region:\n");
508		for (int32 k=0; k<fRootLayer->fCopyRegList.CountItems(); k++) {
509			((BRegion*)(fRootLayer->fCopyRegList.ItemAt(k)))->PrintToStream();
510			((BPoint*)(fRootLayer->fCopyList.ItemAt(k)))->PrintToStream();
511		}
512		printf("\n");
513	#endif
514
515	STRACE(("Layer(%s)::StartRebuildRegions() END\n", GetName()));
516	RBTRACE(("Layer(%s)::StartRebuildRegions() END\n", GetName()));
517}
518
519// RebuildRegions
520void
521Layer::RebuildRegions( const BRegion& reg, uint32 action, BPoint pt, BPoint ptOffset)
522{
523	STRACE(("Layer(%s)::RebuildRegions() START\n", GetName()));
524
525	// TODO:/NOTE: this method must be executed as quickly as possible.
526
527	// Currently SendView[Moved/Resized]Msg() simply constructs a message and calls
528	// ServerWindow::SendMessageToClient(). This involves the alternative use of
529	// kernel and this code in the CPU, so there are a lot of context switches.
530	// This is NOT good at all!
531
532	// One alternative would be the use of a BMessageQueue per ServerWindows OR only
533	// one for app_server which will be emptied as soon as this critical operation ended.
534	// Talk to DW, Gabe.
535
536	BRegion	oldRegion;
537	uint32 newAction = action;
538	BPoint newPt = pt;
539	BPoint newOffset = ptOffset; // used for resizing only
540
541	BPoint dummyNewLocation;
542
543	RRLabel1:
544	switch(action) {
545		case B_LAYER_NONE: {
546			RBTRACE(("1) Layer(%s): Action B_LAYER_NONE\n", GetName()));
547			STRACE(("1) Layer(%s): Action B_LAYER_NONE\n", GetName()));
548			oldRegion = fVisible;
549			break;
550		}
551		case B_LAYER_MOVE: {
552			RBTRACE(("1) Layer(%s): Action B_LAYER_MOVE\n", GetName()));
553			STRACE(("1) Layer(%s): Action B_LAYER_MOVE\n", GetName()));
554			oldRegion = fFullVisible;
555			fFrame.OffsetBy(pt.x, pt.y);
556			fFull.OffsetBy(pt.x, pt.y);
557
558			// TODO: investigate combining frame event messages for efficiency
559			//SendViewMovedMsg();
560			AddToViewsWithInvalidCoords();
561
562			newAction	= B_LAYER_SIMPLE_MOVE;
563			break;
564		}
565		case B_LAYER_SIMPLE_MOVE: {
566			RBTRACE(("1) Layer(%s): Action B_LAYER_SIMPLE_MOVE\n", GetName()));
567			STRACE(("1) Layer(%s): Action B_LAYER_SIMPLE_MOVE\n", GetName()));
568			fFull.OffsetBy(pt.x, pt.y);
569
570			break;
571		}
572		case B_LAYER_RESIZE: {
573			RBTRACE(("1) Layer(%s): Action B_LAYER_RESIZE\n", GetName()));
574			STRACE(("1) Layer(%s): Action B_LAYER_RESIZE\n", GetName()));
575			oldRegion	= fVisible;
576
577			fFrame.right	+= pt.x;
578			fFrame.bottom	+= pt.y;
579			RebuildFullRegion();
580
581			// TODO: investigate combining frame event messages for efficiency
582			//SendViewResizedMsg();
583			AddToViewsWithInvalidCoords();
584
585
586			newAction = B_LAYER_MASK_RESIZE;
587			break;
588		}
589		case B_LAYER_MASK_RESIZE: {
590			RBTRACE(("1) Layer(%s): Action B_LAYER_MASK_RESIZE\n", GetName()));
591			STRACE(("1) Layer(%s): Action B_LAYER_MASK_RESIZE\n", GetName()));
592			oldRegion = fVisible;
593
594			BPoint offset, rSize;
595			BPoint coords[2];
596
597			ResizeOthers(pt.x, pt.y, coords, NULL);
598			offset = coords[0];
599			rSize = coords[1];
600			newOffset = offset + ptOffset;
601
602			if (!(rSize.x == 0.0f && rSize.y == 0.0f)) {
603				fFrame.OffsetBy(offset);
604				fFrame.right += rSize.x;
605				fFrame.bottom += rSize.y;
606				RebuildFullRegion();
607
608				// TODO: investigate combining frame event messages for efficiency
609				//SendViewResizedMsg();
610				AddToViewsWithInvalidCoords();
611
612				newAction = B_LAYER_MASK_RESIZE;
613				newPt = rSize;
614				dummyNewLocation = newOffset;
615			} else {
616				if (!(offset.x == 0.0f && offset.y == 0.0f)) {
617					pt = newOffset;
618					action = B_LAYER_MOVE;
619					newPt = pt;
620					goto RRLabel1;
621				} else {
622					pt = ptOffset;
623					action = B_LAYER_MOVE;
624					newPt = pt;
625					goto RRLabel1;
626				}
627			}
628			break;
629		}
630	}
631
632	if (!IsHidden()) {
633		#ifdef DEBUG_LAYER_REBUILD
634			printf("Layer(%s) real action START\n", GetName());
635			fFull.PrintToStream();
636		#endif
637		fFullVisible.MakeEmpty();
638		fVisible = fFull;
639
640		if (fParent && fVisible.CountRects() > 0) {
641			// not the usual case, but support fot this is needed.
642			if (fParent->fAdFlags & B_LAYER_CHILDREN_DEPENDANT) {
643				#ifdef DEBUG_LAYER_REBUILD
644					printf("   B_LAYER_CHILDREN_DEPENDANT Parent\n");
645				#endif
646
647				// because we're skipping one level, we need to do out
648				// parent business as well.
649
650				// our visible area is relative to our parent's parent.
651				if (fParent->fParent)
652					fVisible.IntersectWith(&(fParent->fParent->fVisible));
653
654				// exclude parent's visible area which could be composed by
655				// prior siblings' visible areas.
656				if (fVisible.CountRects() > 0)
657					fVisible.Exclude(&(fParent->fVisible));
658
659				// we have a final visible area. Include it to our parent's one,
660				// exclude from parent's parent.
661				if (fVisible.CountRects() > 0) {
662					fParent->fFullVisible.Include(&fVisible);
663
664					if (fParent->fParent)
665						fParent->fParent->fVisible.Exclude(&fVisible);
666				}
667			} else {
668				// for 95+% of cases
669
670				#ifdef DEBUG_LAYER_REBUILD
671					printf("   (!)B_LAYER_CHILDREN_DEPENDANT Parent\n");
672				#endif
673
674				// the visible area is the one common with parent's one.
675				fVisible.IntersectWith(&(fParent->fVisible));
676
677				// exclude from parent's visible area. we're the owners now.
678				if (fVisible.CountRects() > 0)
679					fParent->fVisible.Exclude(&fVisible);
680			}
681		}
682		fFullVisible = fVisible;
683	}
684
685	// Rebuild regions for children...
686	for(Layer *lay = VirtualBottomChild(); lay != NULL; lay = VirtualUpperSibling())
687		lay->RebuildRegions(reg, newAction, newPt, newOffset);
688
689	#ifdef DEBUG_LAYER_REBUILD
690		printf("\nLayer(%s) ALMOST done regions:\n", GetName());
691		printf("\tVisible Region:\n");
692		fVisible.PrintToStream();
693		printf("\tFull Visible Region:\n");
694		fFullVisible.PrintToStream();
695	#endif
696
697	if(!IsHidden()) {
698		switch(action) {
699			case B_LAYER_NONE: {
700				RBTRACE(("2) Layer(%s): Action B_LAYER_NONE\n", GetName()));
701				BRegion r(fVisible);
702				if (oldRegion.CountRects() > 0)
703					r.Exclude(&oldRegion);
704
705				if(r.CountRects() > 0)
706					fRootLayer->fRedrawReg.Include(&r);
707				break;
708			}
709			case B_LAYER_MOVE: {
710				RBTRACE(("2) Layer(%s): Action B_LAYER_MOVE\n", GetName()));
711				BRegion redrawReg;
712				BRegion	*copyReg = new BRegion();
713				BRegion	screenReg(fRootLayer->Bounds());
714
715				oldRegion.OffsetBy(pt.x, pt.y);
716				oldRegion.IntersectWith(&fFullVisible);
717
718				*copyReg = oldRegion;
719				copyReg->IntersectWith(&screenReg);
720				if (copyReg->CountRects() > 0 && !(pt.x == 0.0f && pt.y == 0.0f)) {
721					copyReg->OffsetBy(-pt.x, -pt.y);
722					BPoint		*point = new BPoint(pt);
723					fRootLayer->fCopyRegList.AddItem(copyReg);
724					fRootLayer->fCopyList.AddItem(point);
725				} else {
726					delete copyReg;
727				}
728
729				redrawReg	= fFullVisible;
730				redrawReg.Exclude(&oldRegion);
731				if (redrawReg.CountRects() > 0 && !(pt.x == 0.0f && pt.y == 0.0f)) {
732					fRootLayer->fRedrawReg.Include(&redrawReg);
733				}
734
735				break;
736			}
737			case B_LAYER_RESIZE: {
738				RBTRACE(("2) Layer(%s): Action B_LAYER_RESIZE\n", GetName()));
739				BRegion redrawReg;
740
741				redrawReg = fVisible;
742				redrawReg.Exclude(&oldRegion);
743				if(redrawReg.CountRects() > 0)
744					fRootLayer->fRedrawReg.Include(&redrawReg);
745
746				break;
747			}
748			case B_LAYER_MASK_RESIZE: {
749				RBTRACE(("2) Layer(%s): Action B_LAYER_MASK_RESIZE\n", GetName()));
750				BRegion redrawReg;
751				BRegion	*copyReg = new BRegion();
752
753				oldRegion.OffsetBy(dummyNewLocation.x, dummyNewLocation.y);
754
755				redrawReg	= fVisible;
756				redrawReg.Exclude(&oldRegion);
757				if (redrawReg.CountRects() > 0)
758					fRootLayer->fRedrawReg.Include(&redrawReg);
759
760				*copyReg = fVisible;
761				copyReg->IntersectWith(&oldRegion);
762				copyReg->OffsetBy(-dummyNewLocation.x, -dummyNewLocation.y);
763				if (copyReg->CountRects() > 0
764					&& !(dummyNewLocation.x == 0.0f && dummyNewLocation.y == 0.0f)) {
765					fRootLayer->fCopyRegList.AddItem(copyReg);
766					fRootLayer->fCopyList.AddItem(new BPoint(dummyNewLocation));
767				}
768
769				break;
770			}
771			default:
772				RBTRACE(("2) Layer(%s): Action default\n", GetName()));
773				break;
774		}
775	}
776/*	if (IsHidden()) {
777		fFullVisible.MakeEmpty();
778		fVisible.MakeEmpty();
779	}
780*/
781
782	STRACE(("Layer(%s)::RebuildRegions() END\n", GetName()));
783}
784
785// ResizeOthers
786uint32
787Layer::ResizeOthers(float x, float y, BPoint coords[], BPoint *ptOffset)
788{
789	STRACE(("Layer(%s)::ResizeOthers() START\n", GetName()));
790	uint32 rmask = fResizeMode;
791
792	// offset
793	coords[0].x	= 0.0f;
794	coords[0].y	= 0.0f;
795
796	// resize by width/height
797	coords[1].x	= 0.0f;
798	coords[1].y	= 0.0f;
799
800	if ((rmask & 0x00000f00UL)>>8 == _VIEW_LEFT_ &&
801		(rmask & 0x0000000fUL)>>0 == _VIEW_RIGHT_) {
802		coords[1].x		= x;
803	} else if ((rmask & 0x00000f00UL)>>8 == _VIEW_LEFT_) {
804	} else if ((rmask & 0x0000000fUL)>>0 == _VIEW_RIGHT_) {
805		coords[0].x		= x;
806	} else if ((rmask & 0x00000f00UL)>>8 == _VIEW_CENTER_) {
807		coords[0].x		= x/2;
808	} else {
809		// illegal flag. Do nothing.
810	}
811
812
813	if ((rmask & 0x0000f000UL)>>12 == _VIEW_TOP_ &&
814		(rmask & 0x000000f0UL)>>4 == _VIEW_BOTTOM_) {
815		coords[1].y		= y;
816	} else if ((rmask & 0x0000f000UL)>>12 == _VIEW_TOP_) {
817	} else if ((rmask & 0x000000f0UL)>>4 == _VIEW_BOTTOM_) {
818		coords[0].y		= y;
819	} else if ((rmask & 0x0000f000UL)>>12 == _VIEW_CENTER_) {
820		coords[0].y		= y/2;
821	} else {
822		// illegal flag. Do nothing.
823	}
824
825	STRACE(("Layer(%s)::ResizeOthers() END\n", GetName()));
826	return 0UL;
827}
828
829// Redraw
830void
831Layer::Redraw(const BRegion& reg, Layer *startFrom)
832{
833	STRACE(("Layer(%s)::Redraw();\n", GetName()));
834	if (IsHidden())
835		// this layer has nothing visible on screen, so bail out.
836		return;
837
838	BRegion *pReg = const_cast<BRegion*>(&reg);
839
840	if (pReg->CountRects() > 0)
841		RequestDraw(reg, startFrom);
842
843	STRACE(("Layer(%s)::Redraw() ENDED\n", GetName()));
844}
845
846// Draw
847void
848Layer::Draw(const BRect &r)
849{
850	// TODO/NOTE: this should be an empty method! the next lines are for testing only
851
852#ifdef DEBUG_LAYER
853	printf("Layer(%s)::Draw: ", GetName());
854	r.PrintToStream();
855#endif
856
857	// TODO: don't do this if ViewColor() is B_TRANSPARENT_COLOR
858	fDriver->FillRect(r, fLayerData->ViewColor());
859//	RGBColor c(rand()%255,rand()%255,rand()%255);
860//	fDriver->FillRect(r, c);
861
862	// empty HOOK function.
863}
864
865// EmptyGlobals
866void
867Layer::EmptyGlobals()
868{
869	fRootLayer->fRedrawReg.MakeEmpty();
870
871	int32 count = fRootLayer->fCopyRegList.CountItems();
872	for (int32 i = 0; i < count; i++)
873		delete (BRegion*)fRootLayer->fCopyRegList.ItemAt(i);
874	fRootLayer->fCopyRegList.MakeEmpty();
875
876	count = fRootLayer->fCopyList.CountItems();
877	for (int32 i = 0; i < count; i++)
878		delete (BPoint*)fRootLayer->fCopyList.ItemAt(i);
879	fRootLayer->fCopyList.MakeEmpty();
880}
881
882/*!
883	\brief Shows the layer
884	\param invalidate Invalidate the region when showing the layer. defaults to true
885*/
886void
887Layer::Show(bool invalidate)
888{
889	STRACE(("Layer(%s)::Show()\n", GetName()));
890	if( !IsHidden() )
891		return;
892
893	fHidden	= false;
894
895	if(invalidate)
896		GetRootLayer()->GoInvalidate(this, fFull);
897}
898
899/*!
900	\brief Shows the layer
901	\param invalidate Invalidate the region when hiding the layer. defaults to true
902*/
903void
904Layer::Hide(bool invalidate)
905{
906	STRACE(("Layer(%s)::Hide()\n", GetName()));
907	if ( IsHidden() )
908		return;
909
910	fHidden	= true;
911
912	if(invalidate)
913		GetRootLayer()->GoInvalidate(this, fFullVisible);
914}
915
916//! Returns true if the layer is hidden
917bool
918Layer::IsHidden(void) const
919{
920	if (fHidden)
921		return true;
922	else {
923		if (fParent)
924			return fParent->IsHidden();
925	}
926
927	return false;
928}
929
930//! Matches the BView call of the same name
931BRect
932Layer::Bounds(void) const
933{
934	BRect r(fFrame);
935//	r.OffsetTo(fBoundsLeftTop);
936	r.OffsetTo(BoundsOrigin());
937	return r;
938}
939
940//! Matches the BView call of the same name
941BRect
942Layer::Frame(void) const
943{
944	return fFrame;
945}
946
947//! Moves the layer by specified values, complete with redraw
948void
949Layer::MoveBy(float x, float y)
950{
951	STRACE(("Layer(%s)::MoveBy() START\n", GetName()));
952	if (!fParent) {
953		CRITICAL("ERROR: in Layer::MoveBy()! - No parent!\n");
954		return;
955	}
956
957	BPortLink	msg(-1, -1);
958	msg.StartMessage(AS_ROOTLAYER_LAYER_MOVE);
959	msg.Attach<Layer*>(this);
960	msg.Attach<float>(x);
961	msg.Attach<float>(y);
962	GetRootLayer()->EnqueueMessage(msg);
963
964	STRACE(("Layer(%s)::MoveBy() END\n", GetName()));
965}
966
967//! Resize the layer by the specified amount, complete with redraw
968void
969Layer::ResizeBy(float x, float y)
970{
971	STRACE(("Layer(%s)::ResizeBy() START\n", GetName()));
972
973	if(!fParent)
974	{
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