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