xref: /haiku/src/kits/interface/View.cpp (revision 67bce78b48ed6d01b5a8eef89f5694c372b7e0a1)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2002, OpenBeOS
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:		View.cpp
23 //	Author:			Adrian Oanca <adioanca@myrealbox.com>
24 //	Description:   A BView object represents a rectangular area within a window.
25 //					The object draws within this rectangle and responds to user
26 //					events that are directed at the window.
27 //------------------------------------------------------------------------------
28 
29 // Standard Includes -----------------------------------------------------------
30 
31 // System Includes -------------------------------------------------------------
32 #include <BeBuild.h>
33 #include <InterfaceDefs.h>
34 #include <PropertyInfo.h>
35 #include <Handler.h>
36 #include <View.h>
37 #include <Window.h>
38 #include <Message.h>
39 #include <MessageQueue.h>
40 #include <Rect.h>
41 #include <Point.h>
42 #include <Region.h>
43 #include <Font.h>
44 #include <ScrollBar.h>
45 #include <Cursor.h>
46 #include <Bitmap.h>
47 #include <Picture.h>
48 #include <Polygon.h>
49 #include <Shape.h>
50 #include <Button.h>
51 #include <Shelf.h>
52 #include <MenuBar.h>
53 
54 // Project Includes ------------------------------------------------------------
55 #include <AppMisc.h>
56 #include <ViewAux.h>
57 #include <TokenSpace.h>
58 #include <MessageUtils.h>
59 #include <Session.h>
60 #include <ColorUtils.h>
61 #include <AppServerLink.h>
62 #include <PortMessage.h>
63 #include <ServerProtocol.h>
64 
65 // Local Includes --------------------------------------------------------------
66 #include <stdio.h>
67 
68 // Local Defines ---------------------------------------------------------------
69 
70 //#define DEBUG_BVIEW
71 #ifdef DEBUG_BVIEW
72 #	include <stdio.h>
73 #	define STRACE(x) printf x
74 #else
75 #	define STRACE(x) ;
76 #endif
77 
78 #ifdef DEBUG_BVIEW
79 #	define BVTRACE PrintToStream()
80 #else
81 #	define BVTRACE ;
82 #endif
83 
84 inline rgb_color _get_rgb_color( uint32 color );
85 inline uint32 _get_uint32_color( rgb_color c );
86 inline rgb_color _set_static_rgb_color( uint8 r, uint8 g, uint8 b, uint8 a=255 );
87 inline void _set_ptr_rgb_color( rgb_color* c, uint8 r, uint8 g, uint8 b, uint8 a=255 );
88 inline bool _rgb_color_are_equal( rgb_color c1, rgb_color c2 );
89 inline bool _is_new_pattern( const pattern& p1, const pattern& p2 );
90 
91 // Globals ---------------------------------------------------------------------
92 static property_info viewPropInfo[] =
93 {
94 	{ "Frame", { B_GET_PROPERTY, 0 },
95 		{ B_DIRECT_SPECIFIER, 0 }, "Returns the view's frame rectangle.",0 },
96 
97 	{ "Frame", { B_SET_PROPERTY, 0 },
98 		{ B_DIRECT_SPECIFIER, 0 }, "Sets the view's frame rectangle.",0 },
99 
100 	{ "Hidden", { B_GET_PROPERTY, 0 },
101 		{ B_DIRECT_SPECIFIER, 0 }, "Returns true if the view is hidden; false otherwise.",0 },
102 
103 	{ "Hidden", { B_SET_PROPERTY, 0 },
104 		{ B_DIRECT_SPECIFIER, 0 }, "Hides or shows the view.",0 },
105 
106 	{ "Shelf", { 0 },
107 		{ B_DIRECT_SPECIFIER, 0 }, "Directs the scripting message to the shelf.",0 },
108 
109 	{ "View", { B_COUNT_PROPERTIES, 0 },
110 		{ B_DIRECT_SPECIFIER, 0 }, "Returns the number of of child views.",0 },
111 
112 	{ "View", { 0 },
113 		{ B_INDEX_SPECIFIER, 0 }, "Directs the scripting message to the specified view.",0 },
114 
115 	{ "View", { 0 },
116 		{ B_REVERSE_INDEX_SPECIFIER, 0 }, "Directs the scripting message to the specified view.",0 },
117 
118 	{ "View", { 0 },
119 		{ B_NAME_SPECIFIER, 0 }, "Directs the scripting message to the specified view.",0 },
120 
121 	{ 0, { 0 }, { 0 }, 0, 0 }
122 };
123 
124 
125 // General Functions
126 //------------------------------------------------------------------------------
127 
128 // Constructors
129 //------------------------------------------------------------------------------
130 
131 BView::BView(BRect frame, const char *name, uint32 resizingMode, uint32 flags)
132 	: BHandler( name )
133 {
134 	InitData( frame, name, resizingMode, flags );
135 }
136 
137 //---------------------------------------------------------------------------
138 
139 BView::BView(BMessage *archive)
140 	: BHandler( archive )
141 {
142 	uint32				resizingMode;
143 	uint32				flags;
144 	BRect				frame;
145 
146 	archive->FindRect("_frame", &frame);
147 	if ( !(archive->FindInt32("_resize_mode", (int32*)&resizingMode) == B_OK) )
148 		resizingMode	= 0;
149 
150 	if ( !(archive->FindInt32("_flags", (int32*)&flags) == B_OK) )
151 		flags			= 0;
152 
153 	InitData( frame, Name(), resizingMode, flags );
154 
155 	font_family			family;
156 	font_style			style;
157 	float				size;
158 	float				shear;
159 	float				rotation;
160 	if ( archive->FindString("_fname", 0, (const char **)&family) == B_OK){
161 
162 		archive->FindString("_fname", 1, (const char **)&style);
163 		archive->FindFloat("_fflt", 0, &size);
164 		archive->FindFloat("_fflt", 1, &shear);
165 		archive->FindFloat("_fflt", 2, &rotation);
166 
167 		BFont			font;
168 
169 		font.SetSize( size );
170 		font.SetShear( shear );
171 		font.SetRotation( rotation );
172 		font.SetFamilyAndStyle( family, style );
173 
174 		SetFont( &font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE |
175 						B_FONT_SHEAR | B_FONT_ROTATION );
176 	}
177 
178 	uint32				highColor;
179 	uint32				lowColor;
180 	uint32				viewColor;
181 	if ( archive->FindInt32("_color", 0, (int32*)&highColor) == B_OK ){
182 		archive->FindInt32("_color", 1, (int32*)&lowColor);
183 		archive->FindInt32("_color", 2, (int32*)&viewColor);
184 
185 		SetHighColor( _get_rgb_color( highColor) );
186 		SetLowColor( _get_rgb_color( lowColor ) );
187 		SetViewColor( _get_rgb_color( viewColor ) );
188 	}
189 
190 	uint32				evMask;
191 	uint32				options;
192 	if ( archive->FindInt32("_evmask", 0, (int32*)&evMask) == B_OK ){
193 		archive->FindInt32("_evmask", 1, (int32*)&options);
194 
195 		SetEventMask( evMask, options );
196 	}
197 
198 	BPoint				origin;
199 	if ( archive->FindPoint("_origin", &origin) == B_OK)
200 		SetOrigin( origin );
201 
202 	float				penSize;
203 
204 	if ( archive->FindFloat("_psize", &penSize) == B_OK )
205 		SetPenSize( penSize );
206 
207 	BPoint				penLocation;
208 	if ( archive->FindPoint("_ploc", &penLocation) == B_OK )
209 		MovePenTo( penLocation );
210 
211 	int16				lineCap;
212 	int16				lineJoin;
213 	float				lineMiter;
214 	if ( archive->FindInt16("_lmcapjoin", 0, &lineCap) == B_OK){
215 		archive->FindInt16("_lmcapjoin", 1, &lineJoin);
216 		archive->FindFloat("_lmmiter", &lineMiter);
217 
218 		SetLineMode( (cap_mode)lineCap, (join_mode)lineJoin, lineMiter );
219 	}
220 
221 	int16				alphaBlend;
222 	int16				modeBlend;
223 	if ( archive->FindInt16("_blend", 0, &alphaBlend) == B_OK ){
224 		archive->FindInt16("_blend", 1, &modeBlend);
225 
226 		SetBlendingMode( (source_alpha)alphaBlend, (alpha_function)modeBlend );
227 	}
228 
229 	uint32				drawingMode;
230 	if ( archive->FindInt32("_dmod", (int32*)&drawingMode) == B_OK )
231 		SetDrawingMode( (drawing_mode)drawingMode );
232 
233 	BMessage			msg;
234 	BArchivable			*obj;
235 	int					i = 0;
236 	while ( archive->FindMessage("_views", i++, &msg) == B_OK){
237 		obj			= instantiate_object(&msg);
238 
239 		BView		*child;
240 		child		= dynamic_cast<BView *>(obj);
241 		if (child)
242 			AddChild( child );
243 	}
244 }
245 
246 //---------------------------------------------------------------------------
247 
248 BArchivable* BView::Instantiate(BMessage* data){
249    if ( !validate_instantiation( data , "BView" ) )
250       return NULL;
251    return new BView(data);
252 }
253 
254 //---------------------------------------------------------------------------
255 
256 status_t BView::Archive(BMessage* data, bool deep) const{
257 	status_t		retval;
258 
259 	retval		= BHandler::Archive( data, deep );
260 	if (retval != B_OK)
261 		return retval;
262 
263 	if ( fState->archivingFlags & B_VIEW_COORD_BIT )
264 		data->AddRect("_frame", Bounds().OffsetToCopy( originX, originY ) );
265 
266 	if ( fState->archivingFlags & B_VIEW_RESIZE_BIT )
267 		data->AddInt32("_resize_mode", ResizingMode() );
268 
269 	if ( fState->archivingFlags & B_VIEW_FLAGS_BIT )
270 		data->AddInt32("_flags", Flags() );
271 
272 	if ( fState->archivingFlags & B_VIEW_EVMASK_BIT ) {
273 		data->AddInt32("_evmask", fEventMask );
274 		data->AddInt32("_evmask", fEventOptions );
275 	}
276 
277 	if ( fState->archivingFlags & B_VIEW_FONT_BIT ){
278 		BFont			font;
279 		font_family		family;
280 		font_style		style;
281 
282 		GetFont( &font );
283 
284 		font.GetFamilyAndStyle( &family, &style );
285 		data->AddString("_fname", family);
286 		data->AddString("_fname", style);
287 
288 		data->AddFloat("_fflt", font.Size());
289 		data->AddFloat("_fflt", font.Shear());
290 		data->AddFloat("_fflt", font.Rotation());
291 	}
292 
293 	if ( fState->archivingFlags & B_VIEW_COLORS_BIT ){
294 		data->AddInt32("_color", _get_uint32_color(HighColor()) );
295 		data->AddInt32("_color", _get_uint32_color(LowColor()) );
296 		data->AddInt32("_color", _get_uint32_color(ViewColor()) );
297 	}
298 /*
299 NOTE: we do not use this flag any more
300 	if ( 1 ){
301 		data->AddInt32("_dbuf", 1);
302 	}
303 */
304 	if ( fState->archivingFlags & B_VIEW_ORIGIN_BIT )
305 		data->AddPoint("_origin", Origin());
306 
307 	if ( fState->archivingFlags & B_VIEW_PEN_SIZE_BIT )
308 		data->AddFloat("_psize", PenSize());
309 
310 	if ( fState->archivingFlags & B_VIEW_PEN_LOC_BIT )
311 		data->AddPoint("_ploc", PenLocation());
312 
313 	if ( fState->archivingFlags & B_VIEW_LINE_MODES_BIT ){
314 		data->AddInt16("_lmcapjoin", (int16)LineCapMode());
315 		data->AddInt16("_lmcapjoin", (int16)LineJoinMode());
316 		data->AddFloat("_lmmiter", LineMiterLimit());
317 	}
318 
319 	if ( fState->archivingFlags & B_VIEW_BLENDING_BIT ){
320 		source_alpha		alphaSrcMode;
321 		alpha_function		alphaFncMode;
322 		GetBlendingMode( &alphaSrcMode, &alphaFncMode);
323 
324 		data->AddInt16("_blend", (int16)alphaSrcMode);
325 		data->AddInt16("_blend", (int16)alphaFncMode);
326 	}
327 
328 	if ( fState->archivingFlags & B_VIEW_DRAW_MODE_BIT )
329 		data->AddInt32("_dmod", DrawingMode());
330 
331 	if (deep){
332 		int					i		= 0;
333 		BView				*child	= NULL;
334 
335 		while ( (child = ChildAt(i++)) != NULL){
336 			BMessage		childArchive;
337 
338 			retval			= child->Archive( &childArchive, deep );
339 			if (retval == B_OK)
340 				data->AddMessage( "_views", &childArchive );
341 		}
342 	}
343 
344 	return retval;
345 }
346 
347 //---------------------------------------------------------------------------
348 
349 BView::~BView(){
350 STRACE(("BView(%s)::~BView()\n", this->Name()));
351 	if (owner)
352 		debugger("Trying to delete a view that belongs to a window. Call RemoveSelf first.");
353 
354 	removeSelf();
355 
356 // TODO: see about BShelf! must I delete it here? is it deleted by the window?
357 
358 		// we also delete all its childern
359 	BView		*child, *_child;
360 
361 	child		= first_child;
362 	while(child){
363 		_child		= child;
364 		child		= child->next_sibling;
365 		deleteView( _child );
366 	}
367 
368 	if (fVerScroller){
369 		fVerScroller->SetTarget( (const char*)NULL );
370 	}
371 	if (fHorScroller){
372 		fHorScroller->SetTarget( (const char*)NULL );
373 	}
374 
375 	SetName( NULL );
376 
377 	if (fPermanentState)
378 		delete fPermanentState;
379 	if (fState)
380 		delete fState;
381 
382 	free( pr_state );
383 	pr_state	= NULL;
384 }
385 
386 //---------------------------------------------------------------------------
387 
388 BRect BView::Bounds() const{
389 		// if we have the actual coordiantes
390 	if (fState->flags & B_VIEW_COORD_BIT)
391 	if (owner){
392 		check_lock();
393 
394 		owner->session->WriteInt32( AS_LAYER_GET_COORD );
395 		owner->session->Sync();
396 
397 		owner->session->ReadFloat( const_cast<float*>(&originX) );
398 		owner->session->ReadFloat( const_cast<float*>(&originY) );
399 		owner->session->ReadRect( const_cast<BRect*>(&fBounds) );
400 
401 		fState->flags		&= ~B_VIEW_COORD_BIT;
402 	}
403 
404 	return fBounds;
405 }
406 
407 //---------------------------------------------------------------------------
408 
409 void BView::ConvertToParent(BPoint* pt) const{
410 	if (!parent)
411 		return;
412 
413 	check_lock_no_pick();
414 
415 	pt->x			+= originX;
416 	pt->y			+= originY;
417 }
418 
419 //---------------------------------------------------------------------------
420 
421 BPoint BView::ConvertToParent(BPoint pt) const{
422 	if (!parent)
423 		return pt;
424 
425 	check_lock_no_pick();
426 
427 	BPoint			p;
428 	p.x				= pt.x + originX;
429 	p.y				= pt.y + originY;
430 
431 	return p;
432 }
433 
434 //---------------------------------------------------------------------------
435 
436 void BView::ConvertFromParent(BPoint* pt) const{
437 	if (!parent)
438 		return;
439 
440 	check_lock_no_pick();
441 
442 	pt->x			-= originX;
443 	pt->y			-= originY;
444 }
445 
446 //---------------------------------------------------------------------------
447 
448 BPoint BView::ConvertFromParent(BPoint pt) const{
449 	if (!parent)
450 		return pt;
451 
452 	check_lock_no_pick();
453 
454 	BPoint			p;
455 	p.x				= pt.x - originX;
456 	p.y				= pt.y - originY;
457 
458 	return p;
459 }
460 
461 //---------------------------------------------------------------------------
462 
463 void BView::ConvertToParent(BRect* r) const{
464 	if (!parent)
465 		return;
466 
467 	check_lock_no_pick();
468 
469 	r->OffsetBy(originX, originY);
470 }
471 
472 //---------------------------------------------------------------------------
473 
474 BRect BView::ConvertToParent(BRect r) const{
475 	if (!parent)
476 		return r;
477 
478 	check_lock_no_pick();
479 
480 	return r.OffsetByCopy(originX, originY);
481 }
482 
483 //---------------------------------------------------------------------------
484 
485 void BView::ConvertFromParent(BRect* r) const{
486 	if (!parent)
487 		return;
488 
489 	check_lock_no_pick();
490 
491 	r->OffsetBy(-originX, -originY);
492 }
493 
494 //---------------------------------------------------------------------------
495 
496 BRect BView::ConvertFromParent(BRect r) const{
497 	if (!parent)
498 		return r;
499 
500 	check_lock_no_pick();
501 
502 	return r.OffsetByCopy(-originX, -originY);
503 }
504 
505 //---------------------------------------------------------------------------
506 
507 
508 
509 void BView::ConvertToScreen(BPoint* pt) const{
510 	if (!parent)
511 		return;
512 
513 	do_owner_check_no_pick();
514 
515 	ConvertToParent( pt );
516 	parent->ConvertToScreen( pt );
517 }
518 
519 //---------------------------------------------------------------------------
520 
521 BPoint BView::ConvertToScreen(BPoint pt) const{
522 	if (!parent)
523 		return pt;
524 
525 	do_owner_check_no_pick();
526 
527 	BPoint	p;
528 
529 	p		= ConvertToParent( pt );
530 	p		= parent->ConvertToScreen( p );
531 
532 	return p;
533 }
534 
535 //---------------------------------------------------------------------------
536 
537 void BView::ConvertFromScreen(BPoint* pt) const{
538 	if (!parent)
539 		return;
540 
541 	do_owner_check_no_pick();
542 
543 	ConvertFromParent( pt );
544 	parent->ConvertFromScreen( pt );
545 }
546 
547 //---------------------------------------------------------------------------
548 
549 BPoint BView::ConvertFromScreen(BPoint pt) const{
550 	if (!parent)
551 		return pt;
552 
553 	do_owner_check_no_pick();
554 
555 	BPoint	p;
556 
557 	p		= ConvertFromParent( pt );
558 	p		= parent->ConvertFromScreen( p );
559 
560 	return p;
561 }
562 
563 //---------------------------------------------------------------------------
564 
565 
566 void BView::ConvertToScreen(BRect* r) const{
567 	if (!parent)
568 		return;
569 
570 	do_owner_check_no_pick();
571 
572 	ConvertToParent( r );
573 	parent->ConvertToScreen( r );
574 }
575 
576 //---------------------------------------------------------------------------
577 
578 BRect BView::ConvertToScreen(BRect r) const{
579 	if (!parent)
580 		return r;
581 
582 	do_owner_check_no_pick();
583 
584 	BRect	rect;
585 
586 	rect	= ConvertToParent( r );
587 	rect	= parent->ConvertToScreen( rect );
588 
589 	return rect;
590 }
591 
592 //---------------------------------------------------------------------------
593 
594 void BView::ConvertFromScreen(BRect* r) const{
595 	if (!parent)
596 		return;
597 
598 	do_owner_check_no_pick();
599 
600 	ConvertFromParent( r );
601 	parent->ConvertFromScreen( r );
602 }
603 
604 //---------------------------------------------------------------------------
605 
606 BRect BView::ConvertFromScreen(BRect r) const{
607 	if (!parent)
608 		return r;
609 
610 	do_owner_check_no_pick();
611 
612 	BRect	rect;
613 
614 	rect	= ConvertFromParent( r );
615 	rect	= parent->ConvertFromScreen( rect );
616 
617 	return rect;
618 }
619 
620 //---------------------------------------------------------------------------
621 
622 uint32 BView::Flags() const {
623 	check_lock_no_pick();
624 	return ( fFlags & ~_RESIZE_MASK_ );
625 }
626 
627 //---------------------------------------------------------------------------
628 
629 void BView::SetFlags( uint32 flags ){
630 	if (Flags() == flags)
631 		return;
632 
633 	if (owner){
634 		if ( flags & B_PULSE_NEEDED ){
635 			check_lock_no_pick();
636 			if ( !owner->fPulseEnabled )
637 				owner->SetPulseRate( 500000 );
638 		}
639 
640 		if ( flags & (	B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE |
641 						B_FRAME_EVENTS | B_SUBPIXEL_PRECISE ) )
642 		{
643 			check_lock();
644 
645 			owner->session->WriteInt32( AS_LAYER_SET_FLAGS );
646 			owner->session->WriteUInt32( flags );
647 		}
648 	}
649 
650 /*	Some useful info:
651 		fFlags is a unsigned long (32 bits)
652 		* bits 1-16 are used for BView's flags
653 		* bits 17-32 are used for BView' resize mask
654 		* _RESIZE_MASK_ is used for that. Look into View.h to see how
655 			it's defined
656 */
657 	fFlags		= (flags & ~_RESIZE_MASK_) | (fFlags & _RESIZE_MASK_);
658 
659 	fState->archivingFlags	|= B_VIEW_FLAGS_BIT;
660 }
661 
662 //---------------------------------------------------------------------------
663 
664 BRect BView::Frame() const {
665 	check_lock_no_pick();
666 
667 	if ( fState->flags & B_VIEW_COORD_BIT ){
668 		Bounds();
669 	}
670 
671 	return Bounds().OffsetToCopy( originX, originY );
672 }
673 
674 //---------------------------------------------------------------------------
675 
676 void BView::Hide(){
677 	if ( owner && fShowLevel == 0){
678 		check_lock();
679 		owner->session->WriteInt32( AS_LAYER_HIDE );
680 	}
681 	fShowLevel++;
682 }
683 
684 //---------------------------------------------------------------------------
685 
686 void BView::Show(){
687 	fShowLevel--;
688 	if (owner && fShowLevel == 0){
689 		check_lock();
690 		owner->session->WriteInt32( AS_LAYER_SHOW );
691 	}
692 }
693 
694 //---------------------------------------------------------------------------
695 
696 bool BView::IsFocus() const {
697 	if (owner){
698 		check_lock_no_pick();
699 		return owner->CurrentFocus() == this;
700 	}
701 	else
702 		return false;
703 }
704 
705 //---------------------------------------------------------------------------
706 
707 bool
708 BView::IsHidden(const BView *lookingFrom) const
709 {
710 	if (fShowLevel > 0)
711 		return true;
712 
713 	// may we be egocentric?
714 	if (lookingFrom == this)
715 		return false;
716 
717 	// we have the same visibility state as our
718 	// parent, if there is one
719 	if (parent)
720 		return parent->IsHidden();
721 
722 	// if we're the top view, and we're interested
723 	// in the "global" view, we're inheriting the
724 	// state of the window's visibility
725 	if (owner && lookingFrom == NULL)
726 		return owner->IsHidden();
727 
728 	return false;
729 }
730 
731 //---------------------------------------------------------------------------
732 
733 bool
734 BView::IsHidden() const
735 {
736 	return IsHidden(NULL);
737 }
738 
739 //---------------------------------------------------------------------------
740 
741 bool BView::IsPrinting() const {
742 	return f_is_printing;
743 }
744 
745 //---------------------------------------------------------------------------
746 
747 BPoint BView::LeftTop() const {
748 	return Bounds().LeftTop();
749 }
750 
751 //---------------------------------------------------------------------------
752 
753 void BView::SetOrigin(BPoint pt) {
754 	SetOrigin( pt.x, pt.y );
755 }
756 
757 //---------------------------------------------------------------------------
758 
759 void BView::SetOrigin(float x, float y) {
760 // TODO: maybe app_server should do a redraw? - WRITE down into specs
761 
762 	if ( x==originX && y==originY )
763 		return;
764 
765 	if (do_owner_check()){
766 		owner->session->WriteInt32( AS_LAYER_SET_ORIGIN );
767 		owner->session->WriteFloat( x );
768 		owner->session->WriteFloat( y );
769 	}
770 
771 		// invalidate this flag, to stay in sync with app_server
772 	fState->flags			|= B_VIEW_ORIGIN_BIT;
773 
774 		// our local coord system origin has changed, so when archiving we'll add this too
775 	fState->archivingFlags	|= B_VIEW_ORIGIN_BIT;
776 }
777 
778 //---------------------------------------------------------------------------
779 
780 BPoint BView::Origin(void) const {
781 
782 	if ( fState->flags & B_VIEW_ORIGIN_BIT ) {
783 			do_owner_check();
784 
785 			owner->session->WriteInt32( AS_LAYER_GET_ORIGIN );
786 			owner->session->Sync();
787 
788 			owner->session->ReadPoint( &fState->coordSysOrigin );
789 
790 			fState->flags			&= ~B_VIEW_ORIGIN_BIT;
791 	}
792 
793 	return fState->coordSysOrigin;
794 }
795 
796 //---------------------------------------------------------------------------
797 
798 void BView::SetResizingMode(uint32 mode) {
799 	if (owner){
800 		check_lock();
801 
802 		owner->session->WriteInt32( AS_LAYER_RESIZE_MODE );
803 		owner->session->WriteInt32( mode );
804 	}
805 
806 		// look at SetFlags() for more info on the below line
807 	fFlags			= (fFlags & ~_RESIZE_MASK_) | (mode & _RESIZE_MASK_);
808 
809 		// our resize mode has changed, so when archiving we'll add this too
810 	fState->archivingFlags	|= B_VIEW_RESIZE_BIT;
811 }
812 
813 //---------------------------------------------------------------------------
814 
815 uint32 BView::ResizingMode() const {
816 	return fFlags & _RESIZE_MASK_;
817 }
818 
819 //---------------------------------------------------------------------------
820 
821 void BView::SetViewCursor(const BCursor *cursor, bool sync) {
822 
823 	if (!cursor)
824 		return;
825 
826 	if (!owner)
827 		debugger("View method requires owner and doesn't have one");
828 
829 	check_lock();
830 
831 	if (sync){
832 		owner->session->WriteInt32( AS_LAYER_CURSOR );
833 		owner->session->WriteInt32( cursor->m_serverToken );
834 		owner->session->Sync();
835 	}
836 	else{
837 		owner->session->WriteInt32( AS_LAYER_CURSOR );
838 		owner->session->WriteInt32( cursor->m_serverToken );
839 	}
840 }
841 
842 //---------------------------------------------------------------------------
843 
844 void BView::Flush(void) const {
845 	if (owner)
846 		owner->Flush();
847 }
848 
849 //---------------------------------------------------------------------------
850 
851 void BView::Sync(void) const {
852 	do_owner_check_no_pick();
853 	owner->Sync();
854 }
855 
856 //---------------------------------------------------------------------------
857 
858 BWindow* BView::Window() const {
859 	return owner;
860 }
861 
862 
863 
864 // Hook Functions
865 //---------------------------------------------------------------------------
866 
867 void BView::AttachedToWindow(){
868 	// HOOK function
869 	STRACE(("\tHOOK: BView(%s)::AttachedToWindow()\n", Name()));
870 }
871 
872 //---------------------------------------------------------------------------
873 
874 void BView::AllAttached(){
875 	// HOOK function
876 	STRACE(("\tHOOK: BView(%s)::AllAttached()\n", Name()));
877 }
878 
879 //---------------------------------------------------------------------------
880 
881 void BView::DetachedFromWindow(){
882 	// HOOK function
883 	STRACE(("\tHOOK: BView(%s)::DetachedFromWindow()\n", Name()));
884 }
885 
886 //---------------------------------------------------------------------------
887 
888 void BView::AllDetached(){
889 	// HOOK function
890 	STRACE(("\tHOOK: BView(%s)::AllDetached()\n", Name()));
891 }
892 
893 //---------------------------------------------------------------------------
894 
895 void BView::Draw(BRect updateRect){
896 	// HOOK function
897 	STRACE(("\tHOOK: BView(%s)::Draw()\n", Name()));
898 }
899 
900 void BView::DrawAfterChildren(BRect r){
901 	// HOOK function
902 	STRACE(("\tHOOK: BView(%s)::DrawAfterChildren()\n", Name()));
903 }
904 
905 void BView::FrameMoved(BPoint new_position){
906 	// HOOK function
907 	STRACE(("\tHOOK: BView(%s)::FrameMoved()\n", Name()));
908 }
909 
910 void BView::FrameResized(float new_width, float new_height){
911 	// HOOK function
912 	STRACE(("\tHOOK: BView(%s)::FrameResized()\n", Name()));
913 }
914 
915 void BView::GetPreferredSize(float* width, float* height){
916 	// HOOK function
917 	STRACE(("\tHOOK: BView(%s)::GetPreferredSize()\n", Name()));
918 	*width				= fBounds.Width();
919 	*height				= fBounds.Height();
920 }
921 
922 void BView::ResizeToPreferred(){
923 	// HOOK function
924 	STRACE(("\tHOOK: BView(%s)::ResizeToPreferred()\n", Name()));
925 
926 	ResizeTo(fBounds.Width(), fBounds.Height());
927 }
928 
929 void BView::KeyDown(const char* bytes, int32 numBytes){
930 	// HOOK function
931 	STRACE(("\tHOOK: BView(%s)::KeyDown()\n", Name()));
932 }
933 
934 void BView::KeyUp(const char* bytes, int32 numBytes){
935 	// HOOK function
936 	STRACE(("\tHOOK: BView(%s)::KeyUp()\n", Name()));
937 }
938 
939 void BView::MouseDown(BPoint where){
940 	// HOOK function
941 	STRACE(("\tHOOK: BView(%s)::MouseDown()\n", Name()));
942 }
943 
944 void BView::MouseUp(BPoint where){
945 	// HOOK function
946 	STRACE(("\tHOOK: BView(%s)::MouseUp()\n", Name()));
947 }
948 
949 void BView::MouseMoved(BPoint where, uint32 code, const BMessage* a_message){
950 	// HOOK function
951 	STRACE(("\tHOOK: BView(%s)::MouseMoved()\n", Name()));
952 }
953 
954 void BView::Pulse(){
955 	// HOOK function
956 	STRACE(("\tHOOK: BView(%s)::Pulse()\n", Name()));
957 }
958 
959 void BView::TargetedByScrollView(BScrollView* scroll_view){
960 	// HOOK function
961 	STRACE(("\tHOOK: BView(%s)::TargetedByScrollView()\n", Name()));
962 }
963 
964 void BView::WindowActivated(bool state){
965 	// HOOK function
966 	STRACE(("\tHOOK: BView(%s)::WindowActivated()\n", Name()));
967 }
968 
969 // Input Functions
970 //---------------------------------------------------------------------------
971 
972 void BView::BeginRectTracking(BRect startRect,
973 									  uint32 style)
974 {
975 	if (do_owner_check()) {
976 		owner->session->WriteInt32( AS_LAYER_BEGIN_RECT_TRACK );
977 		owner->session->WriteRect( startRect );
978 		owner->session->WriteInt32( style );
979 	}
980 }
981 
982 //---------------------------------------------------------------------------
983 
984 void BView::EndRectTracking(){
985 	if (do_owner_check()) {
986 		owner->session->WriteInt32( AS_LAYER_END_RECT_TRACK );
987 	}
988 }
989 
990 //---------------------------------------------------------------------------
991 
992 void BView::DragMessage(BMessage* aMessage, BRect dragRect,
993 								BHandler* reply_to)
994 {
995 	if ( !aMessage || !dragRect.IsValid())
996 		return;
997 
998 	if (!reply_to)
999 		reply_to = this;
1000 
1001 	if (reply_to->Looper())
1002 		debugger("DragMessage: warning - the Handler needs a looper");
1003 
1004 	do_owner_check_no_pick();
1005 
1006 	BPoint			offset;
1007 
1008 	if ( !aMessage->HasInt32("buttons") ){
1009 		BMessage 	*msg 	= owner->CurrentMessage();
1010 		uint32		buttons;
1011 
1012 		if ( msg ){
1013 			if ( msg->FindInt32("buttons", (int32*)&buttons) == B_OK ){
1014 			}
1015 			else{
1016 				BPoint		point;
1017 				GetMouse(&point, &buttons, false);
1018 			}
1019 			BPoint		point;
1020 
1021 			if (msg->FindPoint("be:view_where", &point) == B_OK)
1022 				offset = point - dragRect.LeftTop();
1023 
1024 		}
1025 		else{
1026 			BPoint		point;
1027 			GetMouse(&point, &buttons, false);
1028 		}
1029 		aMessage->AddInt32("buttons", buttons);
1030 	}
1031 
1032 	_set_message_reply_( aMessage, BMessenger( reply_to, reply_to->Looper() ) );
1033 
1034 	int32		bufSize		= aMessage->FlattenedSize();
1035 	char		*buffer		= new char[ bufSize ];
1036 	aMessage->Flatten( buffer, bufSize );
1037 
1038 	owner->session->WriteInt32( AS_LAYER_DRAG_RECT );
1039 	owner->session->WriteRect( dragRect );
1040 	owner->session->WritePoint( offset );
1041 	owner->session->WriteInt32( bufSize );
1042 	owner->session->WriteData( buffer, bufSize );
1043 	owner->session->Sync();
1044 
1045 	delete buffer;
1046 }
1047 
1048 //---------------------------------------------------------------------------
1049 
1050 void BView::DragMessage(BMessage* aMessage, BBitmap* anImage, BPoint offset,
1051 								BHandler* reply_to)
1052 {
1053 	DragMessage( aMessage, anImage, B_OP_COPY, offset, reply_to );
1054 }
1055 
1056 //---------------------------------------------------------------------------
1057 
1058 void BView::DragMessage(BMessage* aMessage, BBitmap* anImage,
1059 								drawing_mode dragMode, BPoint offset,
1060 								BHandler* reply_to)
1061 {
1062 	if ( !aMessage || !anImage )
1063 		return;
1064 
1065 	if (!reply_to)
1066 		reply_to = this;
1067 
1068 	if (reply_to->Looper())
1069 		debugger("DragMessage: warning - the Handler needs a looper");
1070 
1071 	do_owner_check_no_pick();
1072 
1073 	if ( !aMessage->HasInt32("buttons") ){
1074 		BMessage 	*msg 	= owner->CurrentMessage();
1075 		uint32		buttons;
1076 
1077 		if ( msg ){
1078 			if ( msg->FindInt32("buttons", (int32*)&buttons) == B_OK ){
1079 			}
1080 			else{
1081 				BPoint		point;
1082 				GetMouse(&point, &buttons, false);
1083 			}
1084 		}
1085 		else{
1086 			BPoint		point;
1087 			GetMouse(&point, &buttons, false);
1088 		}
1089 		aMessage->AddInt32("buttons", buttons);
1090 	}
1091 
1092 	_set_message_reply_( aMessage, BMessenger( reply_to, reply_to->Looper() ) );
1093 
1094 	int32		bufSize		= aMessage->FlattenedSize();
1095 	char		*buffer		= new char[ bufSize ];
1096 	aMessage->Flatten( buffer, bufSize );
1097 
1098 	owner->session->WriteInt32( AS_LAYER_DRAG_IMAGE );
1099 	owner->session->WriteInt32( anImage->get_server_token() );
1100 	owner->session->WriteInt32( (int32)dragMode );
1101 	owner->session->WritePoint( offset );
1102 	owner->session->WriteInt32( bufSize );
1103 	owner->session->WriteData( buffer, bufSize );
1104 
1105 	delete buffer;
1106 /* TODO: in app_server the bitmap refCount must be incremented
1107  * WRITE this into specs!!!!
1108  */
1109 	delete anImage;
1110 }
1111 
1112 //---------------------------------------------------------------------------
1113 
1114 void BView::GetMouse(BPoint* location, uint32* buttons,
1115 							 bool checkMessageQueue)
1116 {
1117 	do_owner_check();
1118 
1119 	if (checkMessageQueue) {
1120 		BMessageQueue	*mq;
1121 		BMessage		*msg;
1122 		int32			i = 0;
1123 
1124 		mq				= Window()->MessageQueue();
1125 		mq->Lock();
1126 
1127 		while( (msg = mq->FindMessage(i++)) != NULL ) {
1128 			switch (msg->what) {
1129 				case B_MOUSE_UP:
1130 						msg->FindPoint("where", location);
1131 						msg->FindInt32("buttons", (int32*)buttons);
1132 						Window()->DispatchMessage( msg, Window() );
1133 						mq->RemoveMessage( msg );
1134 						delete msg;
1135 						return;
1136 					break;
1137 
1138 				case B_MOUSE_MOVED:
1139 						msg->FindPoint("where", location);
1140 						msg->FindInt32("buttons", (int32*)buttons);
1141 						Window()->DispatchMessage( msg, Window() );
1142 						mq->RemoveMessage( msg );
1143 						delete msg;
1144 						return;
1145 					break;
1146 
1147 				case _UPDATE_:
1148 						Window()->DispatchMessage( msg, Window() );
1149 						mq->RemoveMessage( msg );
1150 						delete msg;
1151 						return;
1152 					break;
1153 
1154 				default:
1155 					break;
1156 			}
1157 		}
1158 		mq->Unlock();
1159 	}
1160 
1161 		// If B_MOUSE_UP or B_MOUSE_MOVED has not been found in the message queue,
1162 		//		tell app_server to send us the current mouse coords and buttons.
1163 	owner->session->WriteInt32( AS_LAYER_GET_MOUSE_COORDS );
1164 	owner->session->Sync();
1165 
1166 	owner->session->ReadPoint( location );
1167 	owner->session->ReadInt32( (int32*)buttons );
1168 }
1169 
1170 //---------------------------------------------------------------------------
1171 
1172 void BView::MakeFocus(bool focusState){
1173 	if (owner){
1174 			// if a view is in focus
1175 		BView		*focus = owner->CurrentFocus();
1176 		if (focus) {
1177 			owner->fFocus	= NULL;
1178 			focus->MakeFocus(false);
1179 			owner->SetPreferredHandler(NULL);
1180 		}
1181 			// if we want to make this view the current focus view
1182 		if (focusState){
1183 			owner->fFocus	= this;
1184 			owner->SetPreferredHandler(this);
1185 		}
1186 	}
1187 }
1188 
1189 //---------------------------------------------------------------------------
1190 
1191 BScrollBar* BView::ScrollBar(orientation posture) const{
1192 	switch (posture) {
1193 		case B_VERTICAL:
1194 				return fVerScroller;
1195 			break;
1196 		case B_HORIZONTAL:
1197 				return fHorScroller;
1198 			break;
1199 		default:
1200 				return NULL;
1201 			break;
1202 	}
1203 }
1204 
1205 //---------------------------------------------------------------------------
1206 
1207 void BView::ScrollBy(float dh, float dv){
1208 		// no reason to process this further if no scroll is intended.
1209 	if ( dh == 0 && dv == 0){
1210 		return;
1211 	}
1212 
1213 	check_lock();
1214 		// if we're attached to a window tell app_server about this change
1215 	if (owner) {
1216 		owner->session->WriteInt32( AS_LAYER_SCROLL );
1217 		owner->session->WriteFloat( dh );
1218 		owner->session->WriteFloat( dv );
1219 
1220 		fState->flags		|= B_VIEW_COORD_BIT;
1221 	}
1222 
1223 		// we modify our bounds rectangle by dh/dv coord units hor/ver.
1224 	fBounds.OffsetBy(dh, dv);
1225 		// then set the new values of the scrollbars
1226 	if (fHorScroller)
1227 		fHorScroller->SetValue( fBounds.top );
1228 	if (fVerScroller)
1229 		fVerScroller->SetValue( fBounds.left );
1230 }
1231 
1232 //---------------------------------------------------------------------------
1233 
1234 void BView::ScrollTo(BPoint where){
1235 	ScrollBy( where.x - fBounds.left, where.y - fBounds.top );
1236 }
1237 
1238 //---------------------------------------------------------------------------
1239 
1240 status_t BView::SetEventMask(uint32 mask, uint32 options){
1241 	if (fEventMask == mask && fEventOptions == options)
1242 		return B_ERROR;
1243 
1244 	fEventMask			= mask;
1245 	fEventOptions		= options;
1246 
1247 	fState->archivingFlags	|= B_VIEW_EVMASK_BIT;
1248 // TODO: modify! contact app_server!
1249 
1250 	return B_OK;
1251 }
1252 
1253 //---------------------------------------------------------------------------
1254 
1255 uint32 BView::EventMask(){
1256 	return fEventMask;
1257 }
1258 
1259 //---------------------------------------------------------------------------
1260 
1261 status_t BView::SetMouseEventMask(uint32 mask, uint32 options){
1262 	if (fEventMask == mask && fEventOptions == options) {
1263 		return B_ERROR;
1264 	}
1265 
1266 	if (owner && owner->CurrentMessage()->what == B_MOUSE_DOWN ) {
1267 			// we'll store the current mask and options in the upper bits of our:
1268 		fEventMask		|= ( ((fEventMask << 16) & 0xFFFF0000) | mask );
1269 		fEventOptions	|= ( ((fEventOptions << 16) & 0xFFFF0000) | options );
1270 	}
1271 
1272 /* TODO: write this in ... where B_MOUSE_UP is handled... :)
1273 	fEventMask		= ((fEventMask >> 16) & 0x0000FFFF);
1274 	fEventOptions	= ((fEventOptions >> 16) & 0x0000FFFF);
1275 */
1276 // TODO: modify! contact app_server!
1277 
1278 	return B_OK;
1279 }
1280 
1281 // Graphic State Functions
1282 //---------------------------------------------------------------------------
1283 void BView::SetLineMode(cap_mode lineCap, join_mode lineJoin,
1284 						float miterLimit)
1285 {
1286 	if (lineCap == fState->lineCap && lineJoin == fState->lineJoin &&
1287 			miterLimit == fState->miterLimit)
1288 		return;
1289 
1290 	if (owner){
1291 		check_lock();
1292 
1293 		owner->session->WriteInt32( AS_LAYER_SET_LINE_MODE );
1294 		owner->session->WriteInt8( (int8)lineCap );
1295 		owner->session->WriteInt8( (int8)lineJoin );
1296 		owner->session->WriteFloat( miterLimit );
1297 
1298 		fState->flags		|= B_VIEW_LINE_MODES_BIT;
1299 	}
1300 
1301 	fState->lineCap			= lineCap;
1302 	fState->lineJoin		= lineJoin;
1303 	fState->miterLimit		= miterLimit;
1304 
1305 	fState->archivingFlags	|= B_VIEW_LINE_MODES_BIT;
1306 }
1307 
1308 //---------------------------------------------------------------------------
1309 
1310 join_mode BView::LineJoinMode() const{
1311 	if (fState->flags & B_VIEW_LINE_MODES_BIT)
1312 		LineMiterLimit();
1313 
1314 	return fState->lineJoin;
1315 }
1316 
1317 //---------------------------------------------------------------------------
1318 
1319 cap_mode BView::LineCapMode() const{
1320 	if (fState->flags & B_VIEW_LINE_MODES_BIT)
1321 		LineMiterLimit();
1322 
1323 	return fState->lineCap;
1324 }
1325 
1326 //---------------------------------------------------------------------------
1327 
1328 float BView::LineMiterLimit() const{
1329 	if (fState->flags & B_VIEW_LINE_MODES_BIT)
1330 	if (owner)
1331 	{
1332 		check_lock();
1333 
1334 		owner->session->WriteInt32( AS_LAYER_GET_LINE_MODE );
1335 		owner->session->Sync();
1336 
1337 		owner->session->ReadInt8( (int8*)&(fState->lineCap) );
1338 		owner->session->ReadInt8( (int8*)&(fState->lineJoin) );
1339 		owner->session->ReadFloat( &(fState->miterLimit) );
1340 
1341 		fState->flags			&= ~B_VIEW_LINE_MODES_BIT;
1342 	}
1343 
1344 	return fState->miterLimit;
1345 }
1346 
1347 //---------------------------------------------------------------------------
1348 
1349 void BView::PushState(){
1350 	do_owner_check();
1351 
1352 	owner->session->WriteInt32( AS_LAYER_PUSH_STATE );
1353 
1354 	initCachedState();
1355 }
1356 
1357 //---------------------------------------------------------------------------
1358 
1359 void BView::PopState(){
1360 	do_owner_check();
1361 
1362 	owner->session->WriteInt32( AS_LAYER_POP_STATE );
1363 
1364 		// this avoids a compiler warning
1365 	uint32 dummy	= 0xffffffffUL;
1366 		// invalidate all flags
1367 	fState->flags	= dummy;
1368 }
1369 
1370 //---------------------------------------------------------------------------
1371 
1372 void BView::SetScale(float scale) const{
1373 	if (scale == fState->scale)
1374 		return;
1375 
1376 	if (owner){
1377 		check_lock();
1378 
1379 		owner->session->WriteInt32( AS_LAYER_SET_SCALE );
1380 		owner->session->WriteFloat( scale );
1381 
1382 			// I think that this flag won't be used after all... in 'flags' of course.
1383 		fState->flags		|= B_VIEW_SCALE_BIT;
1384 	}
1385 
1386 	fState->scale			= scale;
1387 
1388 	fState->archivingFlags	|= B_VIEW_SCALE_BIT;
1389 }
1390 //---------------------------------------------------------------------------
1391 
1392 float BView::Scale() const{
1393 	if (fState->flags & B_VIEW_SCALE_BIT)
1394 	if (owner)
1395 	{
1396 		check_lock();
1397 
1398 		owner->session->WriteInt32( AS_LAYER_GET_SCALE );
1399 		owner->session->Sync();
1400 
1401 		owner->session->ReadFloat( &(fState->scale) );
1402 
1403 		fState->flags			&= ~B_VIEW_SCALE_BIT;
1404 	}
1405 
1406 	return fState->scale;
1407 }
1408 
1409 //---------------------------------------------------------------------------
1410 
1411 void BView::SetDrawingMode(drawing_mode mode){
1412 	if (mode == fState->drawingMode)
1413 		return;
1414 
1415 	if (owner){
1416 		check_lock();
1417 
1418 		owner->session->WriteInt32( AS_LAYER_SET_DRAW_MODE );
1419 		owner->session->WriteInt8( (int8)mode );
1420 
1421 		fState->flags		|= B_VIEW_DRAW_MODE_BIT;
1422 	}
1423 
1424 	fState->drawingMode		= mode;
1425 
1426 	fState->archivingFlags	|= B_VIEW_DRAW_MODE_BIT;
1427 }
1428 
1429 //---------------------------------------------------------------------------
1430 
1431 drawing_mode BView::DrawingMode() const{
1432 	if (fState->flags & B_VIEW_DRAW_MODE_BIT)
1433 	if (owner)
1434 	{
1435 		check_lock();
1436 		int8		drawingMode;
1437 
1438 		owner->session->WriteInt32( AS_LAYER_GET_DRAW_MODE );
1439 		owner->session->Sync();
1440 
1441 		owner->session->ReadInt8( &drawingMode );
1442 
1443 		fState->drawingMode		= (drawing_mode)drawingMode;
1444 
1445 		fState->flags			&= ~B_VIEW_DRAW_MODE_BIT;
1446 	}
1447 
1448 	return fState->drawingMode;
1449 }
1450 
1451 //---------------------------------------------------------------------------
1452 
1453 void BView::SetBlendingMode(source_alpha srcAlpha, alpha_function alphaFunc){
1454 	if (srcAlpha  == fState->alphaSrcMode &&
1455 			alphaFunc == fState->alphaFncMode)
1456 		return;
1457 
1458 	if (owner){
1459 		check_lock();
1460 
1461 		owner->session->WriteInt32( AS_LAYER_SET_BLEND_MODE );
1462 		owner->session->WriteInt8( (int8)srcAlpha );
1463 		owner->session->WriteInt8( (int8)alphaFunc );
1464 
1465 		fState->flags		|= B_VIEW_BLENDING_BIT;
1466 	}
1467 
1468 	fState->alphaSrcMode	= srcAlpha;
1469 	fState->alphaFncMode	= alphaFunc;
1470 
1471 	fState->archivingFlags	|= B_VIEW_BLENDING_BIT;
1472 }
1473 
1474 //---------------------------------------------------------------------------
1475 
1476 void BView::GetBlendingMode(source_alpha* srcAlpha,	alpha_function* alphaFunc) const{
1477 	if (fState->flags & B_VIEW_BLENDING_BIT)
1478 	if (owner)
1479 	{
1480 		check_lock();
1481 		int8		alphaSrcMode, alphaFncMode;
1482 
1483 		owner->session->WriteInt32( AS_LAYER_GET_BLEND_MODE );
1484 		owner->session->Sync();
1485 
1486 		owner->session->ReadInt8( &alphaSrcMode );
1487 		owner->session->ReadInt8( &alphaFncMode );
1488 
1489 		fState->alphaSrcMode	= (source_alpha)alphaSrcMode;
1490 		fState->alphaFncMode	= (alpha_function)alphaFncMode;
1491 
1492 		fState->flags			&= ~B_VIEW_BLENDING_BIT;
1493 	}
1494 
1495 	if (srcAlpha)
1496 		*srcAlpha		= fState->alphaSrcMode;
1497 
1498 	if (alphaFunc)
1499 		*alphaFunc		= fState->alphaFncMode;
1500 }
1501 
1502 //---------------------------------------------------------------------------
1503 
1504 void BView::MovePenTo(BPoint pt){
1505 	MovePenTo( pt.x, pt.y );
1506 }
1507 
1508 //---------------------------------------------------------------------------
1509 
1510 void BView::MovePenTo(float x, float y){
1511 	if (x  == fState->penPosition.x &&
1512 			y == fState->penPosition.y)
1513 		return;
1514 
1515 	if (owner){
1516 		check_lock();
1517 
1518 		owner->session->WriteInt32( AS_LAYER_SET_PEN_LOC );
1519 		owner->session->WriteFloat( x );
1520 		owner->session->WriteFloat( y );
1521 
1522 		fState->flags		|= B_VIEW_PEN_LOC_BIT;
1523 	}
1524 
1525 	fState->penPosition.x	= x;
1526 	fState->penPosition.y	= y;
1527 
1528 	fState->archivingFlags	|= B_VIEW_PEN_LOC_BIT;
1529 }
1530 
1531 //---------------------------------------------------------------------------
1532 
1533 void BView::MovePenBy(float x, float y){
1534 	MovePenTo(fState->penPosition.x + x, fState->penPosition.y + y);
1535 }
1536 
1537 //---------------------------------------------------------------------------
1538 
1539 BPoint BView::PenLocation() const{
1540 	if (fState->flags & B_VIEW_PEN_LOC_BIT)
1541 	if (owner)
1542 	{
1543 		check_lock();
1544 
1545 		owner->session->WriteInt32( AS_LAYER_GET_PEN_LOC );
1546 		owner->session->Sync();
1547 
1548 		owner->session->ReadPoint( &(fState->penPosition) );
1549 
1550 		fState->flags			&= ~B_VIEW_PEN_LOC_BIT;
1551 	}
1552 
1553 	return fState->penPosition;
1554 }
1555 
1556 //---------------------------------------------------------------------------
1557 
1558 void BView::SetPenSize(float size){
1559 	if (size == fState->penSize)
1560 		return;
1561 
1562 	if (owner){
1563 		check_lock();
1564 
1565 		owner->session->WriteInt32( AS_LAYER_SET_PEN_SIZE );
1566 		owner->session->WriteFloat( size );
1567 
1568 		fState->flags		|= B_VIEW_PEN_SIZE_BIT;
1569 	}
1570 
1571 	fState->penSize			= size;
1572 
1573 	fState->archivingFlags	|= B_VIEW_PEN_SIZE_BIT;
1574 }
1575 
1576 //---------------------------------------------------------------------------
1577 
1578 float BView::PenSize() const{
1579 	if (fState->flags & B_VIEW_PEN_SIZE_BIT)
1580 	if (owner)
1581 	{
1582 		check_lock();
1583 
1584 		owner->session->WriteInt32( AS_LAYER_GET_PEN_SIZE );
1585 		owner->session->Sync();
1586 
1587 		owner->session->ReadFloat( &(fState->penSize) );
1588 
1589 		fState->flags			&= ~B_VIEW_PEN_SIZE_BIT;
1590 	}
1591 
1592 	return fState->penSize;
1593 }
1594 
1595 //---------------------------------------------------------------------------
1596 
1597 void BView::SetHighColor(rgb_color a_color){
1598 	if (_rgb_color_are_equal( fState->highColor, a_color ))
1599 		return;
1600 
1601 	if (owner){
1602 		check_lock();
1603 
1604 		owner->session->WriteInt32( AS_LAYER_SET_HIGH_COLOR );
1605 		owner->session->WriteData( &a_color, sizeof(rgb_color) );
1606 
1607 		fState->flags		|= B_VIEW_COLORS_BIT;
1608 	}
1609 
1610 	_set_ptr_rgb_color( &(fState->highColor), a_color.red, a_color.green,
1611 											a_color.blue, a_color.alpha);
1612 
1613 	fState->archivingFlags	|= B_VIEW_COLORS_BIT;
1614 }
1615 
1616 //---------------------------------------------------------------------------
1617 
1618 rgb_color BView::HighColor() const{
1619 	if (fState->flags & B_VIEW_COLORS_BIT)
1620 	if (owner)
1621 	{
1622 		check_lock();
1623 
1624 		owner->session->WriteInt32( AS_LAYER_GET_COLORS );
1625 		owner->session->Sync();
1626 
1627 		owner->session->ReadData( &(fState->highColor), sizeof(rgb_color) );
1628 		owner->session->ReadData( &(fState->lowColor), sizeof(rgb_color) );
1629 		owner->session->ReadData( &(fState->viewColor), sizeof(rgb_color) );
1630 
1631 		fState->flags			&= ~B_VIEW_COLORS_BIT;
1632 	}
1633 
1634 	return fState->highColor;
1635 }
1636 
1637 //---------------------------------------------------------------------------
1638 
1639 void BView::SetLowColor(rgb_color a_color){
1640 	if (_rgb_color_are_equal( fState->lowColor, a_color ))
1641 		return;
1642 
1643 	if (owner){
1644 		check_lock();
1645 
1646 		owner->session->WriteInt32( AS_LAYER_SET_LOW_COLOR );
1647 		owner->session->WriteData( &a_color, sizeof(rgb_color) );
1648 
1649 		fState->flags		|= B_VIEW_COLORS_BIT;
1650 	}
1651 
1652 	_set_ptr_rgb_color( &(fState->lowColor), a_color.red, a_color.green,
1653 											a_color.blue, a_color.alpha);
1654 
1655 	fState->archivingFlags	|= B_VIEW_COLORS_BIT;
1656 }
1657 
1658 //---------------------------------------------------------------------------
1659 
1660 rgb_color BView::LowColor() const{
1661 	if (fState->flags & B_VIEW_COLORS_BIT)
1662 	if (owner){
1663 			// HighColor() contacts app_server and gets the high, low and view colors
1664 		HighColor();
1665 	}
1666 
1667 	return fState->lowColor;
1668 }
1669 
1670 //---------------------------------------------------------------------------
1671 
1672 void BView::SetViewColor(rgb_color c){
1673 	if (_rgb_color_are_equal( fState->viewColor, c ))
1674 		return;
1675 
1676 	if (owner){
1677 		check_lock();
1678 
1679 		owner->session->WriteInt32( AS_LAYER_SET_VIEW_COLOR );
1680 		owner->session->WriteData( &c, sizeof(rgb_color) );
1681 
1682 		fState->flags		|= B_VIEW_COLORS_BIT;
1683 	}
1684 
1685 	_set_ptr_rgb_color( &(fState->viewColor), c.red, c.green,
1686 											c.blue, c.alpha);
1687 
1688 	fState->archivingFlags	|= B_VIEW_COLORS_BIT;
1689 }
1690 
1691 //---------------------------------------------------------------------------
1692 
1693 rgb_color BView::ViewColor() const{
1694 	if (fState->flags & B_VIEW_COLORS_BIT)
1695 	if (owner){
1696 			// HighColor() contacts app_server and gets the high, low and view colors
1697 		HighColor();
1698 	}
1699 
1700 	return fState->viewColor;
1701 }
1702 
1703 //---------------------------------------------------------------------------
1704 
1705 void BView::ForceFontAliasing(bool enable){
1706 	if ( enable == fState->fontAliasing)
1707 		return;
1708 
1709 	if (owner){
1710 		check_lock();
1711 
1712 		owner->session->WriteInt32( AS_LAYER_PRINT_ALIASING );
1713 		owner->session->WriteBool( enable );
1714 
1715 			// I think this flag won't be used...
1716 		fState->flags		|= B_VIEW_FONT_ALIASING_BIT;
1717 	}
1718 
1719 	fState->fontAliasing	= enable;
1720 
1721 	fState->archivingFlags	|= B_VIEW_FONT_ALIASING_BIT;
1722 }
1723 
1724 //---------------------------------------------------------------------------
1725 
1726 void BView::SetFont(const BFont* font, uint32 mask){
1727 
1728 	if (!font || mask == 0)
1729 		return;
1730 
1731 	if ( mask == B_FONT_ALL ){
1732 		fState->font	= *font;
1733 	}
1734 	else{
1735 		if ( mask & B_FONT_FAMILY_AND_STYLE )
1736 			fState->font.SetFamilyAndStyle( font->FamilyAndStyle() );
1737 
1738 		if ( mask & B_FONT_SIZE )
1739 			fState->font.SetSize( font->Size() );
1740 
1741 		if ( mask & B_FONT_SHEAR )
1742 			fState->font.SetShear( font->Shear() );
1743 
1744 		if ( mask & B_FONT_ROTATION )
1745 			fState->font.SetRotation( font->Rotation() );
1746 
1747 		if ( mask & B_FONT_SPACING )
1748 			fState->font.SetSpacing( font->Spacing() );
1749 
1750 		if ( mask & B_FONT_ENCODING )
1751 			fState->font.SetEncoding( font->Encoding() );
1752 
1753 		if ( mask & B_FONT_FACE )
1754 			fState->font.SetFace( font->Face() );
1755 
1756 		if ( mask & B_FONT_FLAGS )
1757 			fState->font.SetFlags( font->Flags() );
1758 	}
1759 
1760 	fState->fontFlags	= mask;
1761 
1762 	if (owner){
1763 		check_lock();
1764 
1765 		setFontState( &(fState->font), fState->fontFlags );
1766 	}
1767 }
1768 
1769 //---------------------------------------------------------------------------
1770 
1771 #if !_PR3_COMPATIBLE_
1772 void BView::GetFont(BFont* font) const{
1773 	*font	= fState->font;
1774 }
1775 
1776 //---------------------------------------------------------------------------
1777 
1778 #else
1779 void BView:GetFont(BFont* font){
1780 	*font	= fState->font;
1781 }
1782 #endif
1783 
1784 //---------------------------------------------------------------------------
1785 
1786 void BView::GetFontHeight(font_height* height) const{
1787 	fState->font.GetHeight( height );
1788 }
1789 
1790 //---------------------------------------------------------------------------
1791 
1792 void BView::SetFontSize(float size){
1793 	fState->font.SetSize( size );
1794 }
1795 
1796 //---------------------------------------------------------------------------
1797 
1798 float BView::StringWidth(const char* string) const{
1799 	return fState->font.StringWidth( string );
1800 }
1801 
1802 //---------------------------------------------------------------------------
1803 
1804 float BView::StringWidth(const char* string, int32 length) const{
1805 	return fState->font.StringWidth( string, length );
1806 }
1807 
1808 //---------------------------------------------------------------------------
1809 
1810 void BView::GetStringWidths(char* stringArray[],int32 lengthArray[],
1811 								int32 numStrings, float widthArray[]) const
1812 {
1813 	fState->font.GetStringWidths( const_cast<const char**>(stringArray),
1814 								  const_cast<const int32*>(lengthArray),
1815 								  numStrings, &*widthArray );
1816 		// ARE these const_cast good?????
1817 }
1818 
1819 //---------------------------------------------------------------------------
1820 
1821 void BView::TruncateString(BString* in_out, uint32 mode, float width) const{
1822 	fState->font.TruncateString( in_out, mode, width);
1823 }
1824 
1825 //---------------------------------------------------------------------------
1826 
1827 void BView::ClipToPicture(BPicture* picture,
1828 						  BPoint where,
1829 						  bool sync)
1830 {
1831 	if ( picture == NULL )
1832 		return;
1833 
1834 	if (do_owner_check()){
1835 
1836 		owner->session->WriteInt32( AS_LAYER_CLIP_TO_PICTURE );
1837 		owner->session->WriteInt32( picture->token );
1838 		owner->session->WritePoint( where );
1839 
1840 		if (sync){
1841 			owner->session->Sync();
1842 		}
1843 
1844 		fState->flags		|= B_VIEW_CLIP_REGION_BIT;
1845 	}
1846 
1847 	fState->archivingFlags	|= B_VIEW_CLIP_REGION_BIT;
1848 }
1849 
1850 //---------------------------------------------------------------------------
1851 
1852 void BView::ClipToInversePicture(BPicture* picture,
1853 								 BPoint where,
1854 								 bool sync)
1855 {
1856 	if ( picture == NULL )
1857 		return;
1858 
1859 	if (do_owner_check()){
1860 
1861 		owner->session->WriteInt32( AS_LAYER_CLIP_TO_INVERSE_PICTURE );
1862 		owner->session->WriteInt32( picture->token );
1863 		owner->session->WritePoint( where );
1864 
1865 		if (sync){
1866 			owner->session->Sync();
1867 		}
1868 
1869 		fState->flags		|= B_VIEW_CLIP_REGION_BIT;
1870 	}
1871 
1872 	fState->archivingFlags	|= B_VIEW_CLIP_REGION_BIT;
1873 }
1874 
1875 //---------------------------------------------------------------------------
1876 
1877 void BView::GetClippingRegion(BRegion* region) const{
1878 	if ( region == NULL )
1879 		return;
1880 
1881 	if (fState->flags & B_VIEW_CLIP_REGION_BIT)
1882 	if (do_owner_check())
1883 	{
1884 		int32					noOfRects;
1885 
1886 		owner->session->WriteInt32( AS_LAYER_GET_CLIP_REGION );
1887 		owner->session->Sync();
1888 		owner->session->ReadInt32( &noOfRects );
1889 
1890 		fState->clippingRegion.MakeEmpty();
1891 		for (int32 i = 0; i < noOfRects; i++){
1892 			BRect				rect;
1893 
1894 			owner->session->ReadRect( &rect );
1895 
1896 			fState->clippingRegion.Include( rect );
1897 		}
1898 
1899 		fState->flags			&= ~B_VIEW_CLIP_REGION_BIT;
1900 	}
1901 
1902 	*region			= fState->clippingRegion;
1903 }
1904 
1905 //---------------------------------------------------------------------------
1906 
1907 void BView::ConstrainClippingRegion(BRegion* region){
1908 	if (do_owner_check()){
1909 		int32		noOfRects = 0;
1910 
1911 		if (region)
1912 			noOfRects	= region->CountRects();
1913 
1914 		owner->session->WriteInt32( AS_LAYER_SET_CLIP_REGION );
1915 			/* '0' means that in the app_server, there won't be any 'local'
1916 			 * clipping region (it will be = NULL)
1917 			 */
1918 // TODO: note this in the specs!!!!!!
1919 		owner->session->WriteInt32( noOfRects );
1920 
1921 		for (int32 i = 0; i<noOfRects; i++){
1922 			owner->session->WriteRect( region->RectAt(i) );
1923 		}
1924 			// we flush here because app_server waits for all the rects
1925 		owner->session->Sync();
1926 
1927 		fState->flags			|= B_VIEW_CLIP_REGION_BIT;
1928 		fState->archivingFlags	|= B_VIEW_CLIP_REGION_BIT;
1929 	}
1930 }
1931 
1932 //---------------------------------------------------------------------------
1933 
1934 
1935 // Drawing Functions
1936 //---------------------------------------------------------------------------
1937 
1938 void BView::DrawBitmapAsync(const BBitmap* aBitmap,	BRect srcRect, BRect dstRect){
1939 	if ( !aBitmap || !srcRect.IsValid() || !dstRect.IsValid())
1940 		return;
1941 
1942 	if (owner){
1943 		check_lock();
1944 
1945 		owner->session->WriteInt32( AS_LAYER_DRAW_BITMAP_ASYNC_IN_RECT );
1946 		owner->session->WriteInt32( aBitmap->get_server_token() );
1947 		owner->session->WriteRect( dstRect );
1948 		owner->session->WriteRect( srcRect );
1949 	}
1950 }
1951 
1952 //---------------------------------------------------------------------------
1953 
1954 void BView::DrawBitmapAsync(const BBitmap* aBitmap, BRect dstRect){
1955 	if ( !aBitmap || !dstRect.IsValid())
1956 		return;
1957 
1958 	DrawBitmapAsync( aBitmap, aBitmap->Bounds(), dstRect);
1959 }
1960 
1961 //---------------------------------------------------------------------------
1962 
1963 void BView::DrawBitmapAsync(const BBitmap* aBitmap){
1964 	DrawBitmapAsync( aBitmap, PenLocation() );
1965 }
1966 
1967 //---------------------------------------------------------------------------
1968 
1969 void BView::DrawBitmapAsync(const BBitmap* aBitmap, BPoint where){
1970 	if ( !aBitmap )
1971 		return;
1972 
1973 	if (owner){
1974 		check_lock();
1975 
1976 		owner->session->WriteInt32( AS_LAYER_DRAW_BITMAP_ASYNC_AT_POINT );
1977 		owner->session->WriteInt32( aBitmap->get_server_token() );
1978 		owner->session->WritePoint( where );
1979 	}
1980 }
1981 
1982 //---------------------------------------------------------------------------
1983 
1984 void BView::DrawBitmap(const BBitmap* aBitmap){
1985 	DrawBitmap( aBitmap, PenLocation() );
1986 }
1987 
1988 //---------------------------------------------------------------------------
1989 
1990 void BView::DrawBitmap(const BBitmap* aBitmap, BPoint where){
1991 	if ( !aBitmap )
1992 		return;
1993 
1994 	if (owner){
1995 		check_lock();
1996 
1997 		owner->session->WriteInt32( AS_LAYER_DRAW_BITMAP_SYNC_AT_POINT );
1998 		owner->session->WriteInt32( aBitmap->get_server_token() );
1999 		owner->session->WritePoint( where );
2000 		owner->session->Sync();
2001 	}
2002 }
2003 
2004 //---------------------------------------------------------------------------
2005 
2006 void BView::DrawBitmap(const BBitmap* aBitmap, BRect dstRect){
2007 	if ( !aBitmap || !dstRect.IsValid())
2008 		return;
2009 
2010 	DrawBitmap( aBitmap, aBitmap->Bounds(), dstRect);
2011 }
2012 
2013 //---------------------------------------------------------------------------
2014 
2015 void BView::DrawBitmap(const BBitmap* aBitmap, BRect srcRect, BRect dstRect){
2016 	if ( !aBitmap || !srcRect.IsValid() || !dstRect.IsValid())
2017 		return;
2018 
2019 	if (owner){
2020 		check_lock();
2021 
2022 		owner->session->WriteInt32( AS_LAYER_DRAW_BITMAP_SYNC_IN_RECT );
2023 		owner->session->WriteInt32( aBitmap->get_server_token() );
2024 		owner->session->WriteRect( dstRect );
2025 		owner->session->WriteRect( srcRect );
2026 		owner->session->Sync();
2027 	}
2028 }
2029 
2030 //---------------------------------------------------------------------------
2031 
2032 void BView::DrawChar(char aChar){
2033 	DrawChar( aChar, PenLocation() );
2034 }
2035 
2036 //---------------------------------------------------------------------------
2037 
2038 void BView::DrawChar(char aChar, BPoint location){
2039 	char		ch[2];
2040 	ch[0]		= aChar;
2041 	ch[1]		= '\0';
2042 
2043 	DrawString( ch, strlen(ch), location );
2044 }
2045 
2046 //---------------------------------------------------------------------------
2047 
2048 void BView::DrawString(const char* aString,
2049 						escapement_delta* delta)
2050 {
2051 	if ( !aString )
2052 		return;
2053 
2054 	DrawString( aString, strlen(aString), PenLocation() );
2055 }
2056 
2057 //---------------------------------------------------------------------------
2058 
2059 void BView::DrawString(const char* aString, BPoint location,
2060 						escapement_delta* delta)
2061 {
2062 	if ( !aString )
2063 		return;
2064 
2065 	DrawString( aString, strlen(aString), location );
2066 }
2067 
2068 //---------------------------------------------------------------------------
2069 
2070 void BView::DrawString(const char* aString, int32 length,
2071 						escapement_delta* delta)
2072 {
2073 	if ( !aString )
2074 		return;
2075 
2076 	DrawString( aString, length, PenLocation() );
2077 }
2078 
2079 //---------------------------------------------------------------------------
2080 
2081 void BView::DrawString(const char* aString, int32 length, BPoint location,
2082 									   escapement_delta* delta)
2083 {
2084 	if ( !aString )
2085 		return;
2086 
2087 	if (owner){
2088 		check_lock();
2089 
2090 		owner->session->WriteInt32( AS_DRAW_STRING );
2091 		owner->session->WritePoint( location );
2092 		owner->session->WriteData( delta, sizeof(escapement_delta) );
2093 		owner->session->WriteString( aString );
2094 
2095 			// this modifies our pen location, so we invalidate the flag.
2096 		fState->flags		|= B_VIEW_PEN_LOC_BIT;
2097 	}
2098 }
2099 
2100 //---------------------------------------------------------------------------
2101 
2102 void BView::StrokeEllipse(BPoint center,
2103 							float xRadius, float yRadius,
2104 							pattern p)
2105 {
2106 	if (owner){
2107 		check_lock();
2108 
2109 		if ( _is_new_pattern( fState->patt, p ) )
2110 			SetPattern( p );
2111 
2112 		owner->session->WriteInt32( AS_STROKE_ELLIPSE );
2113 		owner->session->WritePoint( center );
2114 		owner->session->WriteFloat( xRadius );
2115 		owner->session->WriteFloat( yRadius );
2116 	}
2117 }
2118 
2119 //---------------------------------------------------------------------------
2120 
2121 void BView::StrokeEllipse(BRect r, pattern p) {
2122 	if (owner)
2123 	StrokeEllipse( 	r.LeftTop() + BPoint(r.Width()/2, r.Height()/2),
2124 					r.Width()/2, r.Height()/2, p );
2125 }
2126 
2127 //---------------------------------------------------------------------------
2128 
2129 void BView::FillEllipse(BPoint center,
2130 						float xRadius, float yRadius,
2131 						pattern p)
2132 {
2133 	if (owner){
2134 		check_lock();
2135 
2136 		if ( _is_new_pattern( fState->patt, p ) )
2137 			SetPattern( p );
2138 
2139 		owner->session->WriteInt32( AS_FILL_ELLIPSE );
2140 		owner->session->WritePoint( center );
2141 		owner->session->WriteFloat( xRadius );
2142 		owner->session->WriteFloat( yRadius );
2143 	}
2144 }
2145 
2146 //---------------------------------------------------------------------------
2147 
2148 void BView::FillEllipse(BRect r, pattern p) {
2149 	if (owner)
2150 	FillEllipse( 	r.LeftTop() + BPoint(r.Width()/2, r.Height()/2),
2151 					r.Width()/2, r.Height()/2, p );
2152 
2153 }
2154 
2155 //---------------------------------------------------------------------------
2156 
2157 void BView::StrokeArc(BPoint center,
2158 					  float xRadius, float yRadius,
2159 					  float start_angle, float arc_angle,
2160 					  pattern p)
2161 {
2162 	if (owner){
2163 		check_lock();
2164 
2165 		if ( _is_new_pattern( fState->patt, p ) )
2166 			SetPattern( p );
2167 
2168 		owner->session->WriteInt32( AS_STROKE_ARC );
2169 		owner->session->WritePoint( center );
2170 		owner->session->WriteFloat( xRadius );
2171 		owner->session->WriteFloat( yRadius );
2172 		owner->session->WriteFloat( start_angle );
2173 		owner->session->WriteFloat( arc_angle );
2174 	}
2175 }
2176 
2177 //---------------------------------------------------------------------------
2178 
2179 void BView::StrokeArc(BRect r,
2180 					  float start_angle, float arc_angle,
2181 					  pattern p)
2182 {
2183 	if (owner)
2184 	StrokeArc( 	r.LeftTop() + BPoint(r.Width()/2, r.Height()/2),
2185 				r.Width()/2, r.Height()/2,
2186 				start_angle, arc_angle, p );
2187 }
2188 
2189 //---------------------------------------------------------------------------
2190 
2191 void BView::FillArc(BPoint center,
2192 					float xRadius, float yRadius,
2193 					float start_angle, float arc_angle,
2194 					pattern p)
2195 {
2196 	if (owner){
2197 		check_lock();
2198 
2199 		if ( _is_new_pattern( fState->patt, p ) )
2200 			SetPattern( p );
2201 
2202 		owner->session->WriteInt32( AS_FILL_ARC );
2203 		owner->session->WritePoint( center );
2204 		owner->session->WriteFloat( xRadius );
2205 		owner->session->WriteFloat( yRadius );
2206 		owner->session->WriteFloat( start_angle );
2207 		owner->session->WriteFloat( arc_angle );
2208 	}
2209 }
2210 
2211 //---------------------------------------------------------------------------
2212 
2213 void BView::FillArc(BRect r,
2214 					float start_angle, float arc_angle,
2215 					pattern p)
2216 {
2217 	if (owner)
2218 	FillArc( 	r.LeftTop() + BPoint(r.Width()/2, r.Height()/2),
2219 				r.Width()/2, r.Height()/2,
2220 				start_angle, arc_angle, p );
2221 }
2222 
2223 //---------------------------------------------------------------------------
2224 
2225 void BView::StrokeBezier(BPoint* controlPoints, pattern p){
2226 	if (owner){
2227 		check_lock();
2228 
2229 		if ( _is_new_pattern( fState->patt, p ) )
2230 			SetPattern( p );
2231 
2232 		owner->session->WriteInt32( AS_STROKE_BEZIER );
2233 		owner->session->WritePoint( controlPoints[0] );
2234 		owner->session->WritePoint( controlPoints[1] );
2235 		owner->session->WritePoint( controlPoints[2] );
2236 		owner->session->WritePoint( controlPoints[3] );
2237 	}
2238 }
2239 
2240 //---------------------------------------------------------------------------
2241 
2242 void BView::FillBezier(BPoint* controlPoints, pattern p){
2243 	if (owner){
2244 		check_lock();
2245 
2246 		if ( _is_new_pattern( fState->patt, p ) )
2247 			SetPattern( p );
2248 
2249 		owner->session->WriteInt32( AS_FILL_BEZIER );
2250 		owner->session->WritePoint( controlPoints[0] );
2251 		owner->session->WritePoint( controlPoints[1] );
2252 		owner->session->WritePoint( controlPoints[2] );
2253 		owner->session->WritePoint( controlPoints[3] );
2254 	}
2255 }
2256 
2257 //---------------------------------------------------------------------------
2258 
2259 void BView::StrokePolygon(const BPolygon* aPolygon,
2260 						  bool closed, pattern p)
2261 {
2262 	if ( !aPolygon )
2263 		return;
2264 
2265 	if ( aPolygon->fCount <= 2 )
2266 		return;
2267 
2268 	if (owner){
2269 		check_lock();
2270 
2271 		if ( _is_new_pattern( fState->patt, p ) )
2272 			SetPattern( p );
2273 
2274 		owner->session->WriteInt32( AS_STROKE_POLYGON );
2275 		owner->session->WriteInt8( closed );
2276 		owner->session->WriteInt32( aPolygon->fCount );
2277 		owner->session->WriteData(	aPolygon->fPts,
2278 									aPolygon->fCount * sizeof(BPoint) );
2279 	}
2280 }
2281 
2282 //---------------------------------------------------------------------------
2283 
2284 void BView::StrokePolygon(const BPoint* ptArray, int32 numPts,
2285 						  bool closed, pattern p)
2286 {
2287 	if ( !ptArray )
2288 		return;
2289 
2290 	BPolygon		pol( ptArray, numPts );
2291 	StrokePolygon( &pol, closed, p );
2292 }
2293 
2294 //---------------------------------------------------------------------------
2295 
2296 void BView::StrokePolygon(const BPoint* ptArray, int32 numPts, BRect bounds,
2297 						  bool closed, pattern p)
2298 {
2299 	if ( !ptArray )
2300 		return;
2301 
2302 	BPolygon		pol( ptArray, numPts );
2303 	pol.MapTo( pol.Frame(), bounds);
2304 	StrokePolygon( &pol, closed, p );
2305 }
2306 
2307 //---------------------------------------------------------------------------
2308 
2309 void BView::FillPolygon(const BPolygon* aPolygon,
2310 						pattern p)
2311 {
2312 	if ( !aPolygon )
2313 		return;
2314 
2315 	if ( aPolygon->fCount <= 2 )
2316 		return;
2317 
2318 	if (owner){
2319 		check_lock();
2320 
2321 		if ( _is_new_pattern( fState->patt, p ) )
2322 			SetPattern( p );
2323 
2324 		owner->session->WriteInt32( AS_FILL_POLYGON );
2325 		owner->session->WriteInt32( aPolygon->fCount );
2326 		owner->session->WriteData(	aPolygon->fPts,
2327 									aPolygon->fCount * sizeof(BPoint) );
2328 	}
2329 }
2330 
2331 //---------------------------------------------------------------------------
2332 
2333 void BView::FillPolygon(const BPoint* ptArray, int32 numPts,
2334 						pattern p)
2335 {
2336 	if ( !ptArray )
2337 		return;
2338 
2339 	BPolygon		pol( ptArray, numPts );
2340 	FillPolygon( &pol, p );
2341 }
2342 
2343 //---------------------------------------------------------------------------
2344 
2345 void BView::FillPolygon(const BPoint* ptArray, int32 numPts, BRect bounds,
2346 						pattern p)
2347 {
2348 	if ( !ptArray )
2349 		return;
2350 
2351 	BPolygon		pol( ptArray, numPts );
2352 	pol.MapTo( pol.Frame(), bounds);
2353 	FillPolygon( &pol, p );
2354 }
2355 
2356 //---------------------------------------------------------------------------
2357 
2358 void BView::StrokeRect(BRect r, pattern p){
2359 	if (owner){
2360 		check_lock();
2361 
2362 		if ( _is_new_pattern( fState->patt, p ) )
2363 			SetPattern( p );
2364 
2365 		owner->session->WriteInt32( AS_STROKE_RECT );
2366 		owner->session->WriteRect( r );
2367 	}
2368 }
2369 
2370 //---------------------------------------------------------------------------
2371 
2372 void BView::FillRect(BRect r, pattern p){
2373 	if (owner){
2374 		check_lock();
2375 
2376 		if ( _is_new_pattern( fState->patt, p ) )
2377 			SetPattern( p );
2378 
2379 		owner->session->WriteInt32( AS_FILL_RECT );
2380 		owner->session->WriteRect( r );
2381 	}
2382 }
2383 
2384 //---------------------------------------------------------------------------
2385 
2386 void BView::StrokeRoundRect(BRect r, float xRadius, float yRadius,
2387 							pattern p)
2388 {
2389 	if (owner){
2390 		check_lock();
2391 
2392 		if ( _is_new_pattern( fState->patt, p ) )
2393 			SetPattern( p );
2394 
2395 		owner->session->WriteInt32( AS_STROKE_ROUNDRECT );
2396 		owner->session->WriteRect( r );
2397 		owner->session->WriteFloat( xRadius );
2398 		owner->session->WriteFloat( yRadius );
2399 	}
2400 }
2401 
2402 //---------------------------------------------------------------------------
2403 
2404 void BView::FillRoundRect(BRect r, float xRadius, float yRadius,
2405 						  pattern p)
2406 {
2407 	if (owner){
2408 		check_lock();
2409 
2410 		if ( _is_new_pattern( fState->patt, p ) )
2411 			SetPattern( p );
2412 
2413 		owner->session->WriteInt32( AS_FILL_ROUNDRECT );
2414 		owner->session->WriteRect( r );
2415 		owner->session->WriteFloat( xRadius );
2416 		owner->session->WriteFloat( yRadius );
2417 	}
2418 }
2419 
2420 //---------------------------------------------------------------------------
2421 
2422 void BView::FillRegion(BRegion* a_region, pattern p){
2423 	if ( !a_region )
2424 		return;
2425 
2426 	if (owner){
2427 		check_lock();
2428 
2429 		if ( _is_new_pattern( fState->patt, p ) )
2430 			SetPattern( p );
2431 
2432 		int32			rectsNo = a_region->CountRects();
2433 
2434 		owner->session->WriteInt32( AS_FILL_REGION );
2435 		owner->session->WriteInt32( rectsNo );
2436 
2437 		for (int32 i = 0; i<rectsNo; i++){
2438 			owner->session->WriteRect( a_region->RectAt(i) );
2439 		}
2440 	}
2441 }
2442 
2443 //---------------------------------------------------------------------------
2444 
2445 void BView::StrokeTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
2446 						   BRect bounds, pattern p)
2447 {
2448 	if (owner){
2449 		check_lock();
2450 
2451 		if ( _is_new_pattern( fState->patt, p ) )
2452 			SetPattern( p );
2453 
2454 		owner->session->WriteInt32( AS_STROKE_TRIANGLE );
2455 		owner->session->WritePoint( pt1 );
2456 		owner->session->WritePoint( pt2 );
2457 		owner->session->WritePoint( pt3 );
2458 			// ???: Do we need this?
2459 		owner->session->WriteRect( bounds );
2460 	}
2461 }
2462 
2463 //---------------------------------------------------------------------------
2464 
2465 void BView::StrokeTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
2466 						   pattern p)
2467 {
2468 	if (owner){
2469 			// we construct the smallest rectangle that contains the 3 points
2470 			// for the 1st point
2471 		BRect		bounds(pt1, pt1);
2472 
2473 			// for the 2nd point
2474 		if (pt2.x < bounds.left)
2475 			bounds.left = pt2.x;
2476 
2477 		if (pt2.y < bounds.top)
2478 			bounds.top = pt2.y;
2479 
2480 		if (pt2.x > bounds.right)
2481 			bounds.right = pt2.x;
2482 
2483 		if (pt2.y > bounds.bottom)
2484 			bounds.bottom = pt2.y;
2485 
2486 			// for the 3rd point
2487 		if (pt3.x < bounds.left)
2488 			bounds.left = pt3.x;
2489 
2490 		if (pt3.y < bounds.top)
2491 			bounds.top = pt3.y;
2492 
2493 		if (pt3.x > bounds.right)
2494 			bounds.right = pt3.x;
2495 
2496 		if (pt3.y > bounds.bottom)
2497 			bounds.bottom = pt3.y;
2498 
2499 		StrokeTriangle( pt1, pt2, pt3, bounds, p );
2500 	}
2501 }
2502 
2503 //---------------------------------------------------------------------------
2504 
2505 void BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
2506 						 pattern p)
2507 {
2508 	if (owner){
2509 			// we construct the smallest rectangle that contains the 3 points
2510 			// for the 1st point
2511 		BRect		bounds(pt1, pt1);
2512 
2513 			// for the 2nd point
2514 		if (pt2.x < bounds.left)
2515 			bounds.left = pt2.x;
2516 
2517 		if (pt2.y < bounds.top)
2518 			bounds.top = pt2.y;
2519 
2520 		if (pt2.x > bounds.right)
2521 			bounds.right = pt2.x;
2522 
2523 		if (pt2.y > bounds.bottom)
2524 			bounds.bottom = pt2.y;
2525 
2526 			// for the 3rd point
2527 		if (pt3.x < bounds.left)
2528 			bounds.left = pt3.x;
2529 
2530 		if (pt3.y < bounds.top)
2531 			bounds.top = pt3.y;
2532 
2533 		if (pt3.x > bounds.right)
2534 			bounds.right = pt3.x;
2535 
2536 		if (pt3.y > bounds.bottom)
2537 			bounds.bottom = pt3.y;
2538 
2539 		FillTriangle( pt1, pt2, pt3, bounds, p );
2540 	}
2541 }
2542 
2543 //---------------------------------------------------------------------------
2544 
2545 void BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
2546 						 BRect bounds, pattern p)
2547 {
2548 	if (owner){
2549 		check_lock();
2550 
2551 		if ( _is_new_pattern( fState->patt, p ) )
2552 			SetPattern( p );
2553 
2554 		owner->session->WriteInt32( AS_FILL_TRIANGLE );
2555 		owner->session->WritePoint( pt1 );
2556 		owner->session->WritePoint( pt2 );
2557 		owner->session->WritePoint( pt3 );
2558 			// ???: Do we need this?
2559 		owner->session->WriteRect( bounds );
2560 	}
2561 }
2562 
2563 //---------------------------------------------------------------------------
2564 
2565 void BView::StrokeLine(BPoint toPt, pattern p){
2566 	StrokeLine( PenLocation(), toPt, p);
2567 }
2568 
2569 //---------------------------------------------------------------------------
2570 
2571 void BView::StrokeLine(BPoint pt0, BPoint pt1, pattern p){
2572 	if (owner){
2573 		check_lock();
2574 
2575 		if ( _is_new_pattern( fState->patt, p ) )
2576 			SetPattern( p );
2577 
2578 		owner->session->WriteInt32( AS_STROKE_LINE );
2579 		owner->session->WritePoint( pt0 );
2580 		owner->session->WritePoint( pt1 );
2581 
2582 			// this modifies our pen location, so we invalidate the flag.
2583 		fState->flags		|= B_VIEW_PEN_LOC_BIT;
2584 	}
2585 }
2586 
2587 //---------------------------------------------------------------------------
2588 
2589 void BView::StrokeShape(BShape* shape, pattern p){
2590 	if ( !shape )
2591 		return;
2592 
2593 	shape_data		*sd = (shape_data*)shape->fPrivateData;
2594 	if ( sd->opCount == 0 || sd->ptCount == 0)
2595 		return;
2596 
2597 	if (owner){
2598 		check_lock();
2599 
2600 		if ( _is_new_pattern( fState->patt, p ) )
2601 			SetPattern( p );
2602 
2603 		owner->session->WriteInt32( AS_STROKE_SHAPE );
2604 			// ???: Do we need this?
2605 		owner->session->WriteRect( shape->Bounds() );
2606 		owner->session->WriteInt32( sd->opCount );
2607 		owner->session->WriteInt32( sd->ptCount );
2608 		owner->session->WriteData( sd->opList, sd->opCount );
2609 		owner->session->WriteData( sd->ptList, sd->ptCount );
2610 	}
2611 }
2612 
2613 //---------------------------------------------------------------------------
2614 
2615 void BView::FillShape(BShape* shape, pattern p){
2616 	if ( !shape )
2617 		return;
2618 
2619 	shape_data		*sd = (shape_data*)(shape->fPrivateData);
2620 	if ( sd->opCount == 0 || sd->ptCount == 0)
2621 		return;
2622 
2623 	if (owner){
2624 		check_lock();
2625 
2626 		if ( _is_new_pattern( fState->patt, p ) )
2627 			SetPattern( p );
2628 
2629 		owner->session->WriteInt32( AS_FILL_SHAPE );
2630 			// ???: Do we need this?
2631 		owner->session->WriteRect( shape->Bounds() );
2632 		owner->session->WriteInt32( sd->opCount );
2633 		owner->session->WriteInt32( sd->ptCount );
2634 		owner->session->WriteData( sd->opList, sd->opCount );
2635 		owner->session->WriteData( sd->ptList, sd->ptCount );
2636 	}
2637 }
2638 
2639 //---------------------------------------------------------------------------
2640 
2641 void BView::BeginLineArray(int32 count){
2642 	if (owner){
2643 		if (count <= 0)
2644 			debugger("Calling BeginLineArray with a count <= 0");
2645 
2646 		check_lock_no_pick();
2647 
2648 		if (comm){
2649 			delete comm->array;
2650 			delete comm;
2651 		}
2652 
2653 		comm			= new _array_data_;
2654 
2655 		comm->maxCount	= count;
2656 		comm->count		= 0;
2657 		comm->array		= new _array_hdr_[count];
2658 	}
2659 }
2660 
2661 //---------------------------------------------------------------------------
2662 
2663 void BView::AddLine(BPoint pt0, BPoint pt1, rgb_color col){
2664 	if (owner){
2665 		if (!comm)
2666 			debugger("Can't call AddLine before BeginLineArray");
2667 
2668 		check_lock_no_pick();
2669 
2670 		if (comm->count < comm->maxCount){
2671 			comm->array[ comm->count ].startX	= pt0.x;
2672 			comm->array[ comm->count ].startY	= pt0.y;
2673 			comm->array[ comm->count ].endX		= pt1.x;
2674 			comm->array[ comm->count ].endY		= pt1.y;
2675 			_set_ptr_rgb_color( &(comm->array[ comm->count ].color),
2676 								col.red, col.green, col.blue, col.alpha );
2677 
2678 			comm->count++;
2679 		}
2680 	}
2681 }
2682 
2683 //---------------------------------------------------------------------------
2684 
2685 void BView::EndLineArray(){
2686 	if(owner){
2687 		if (!comm)
2688 			debugger("Can't call EndLineArray before BeginLineArray");
2689 
2690 		check_lock();
2691 
2692 		owner->session->WriteInt32( AS_LAYER_LINE_ARRAY );
2693 		owner->session->WriteInt32( comm->count );
2694 		owner->session->WriteData(	comm->array,
2695 									comm->count * sizeof(_array_hdr_) );
2696 
2697 		delete comm->array;
2698 		delete comm;
2699 		comm = NULL;
2700 	}
2701 }
2702 
2703 //---------------------------------------------------------------------------
2704 
2705 void BView::BeginPicture(BPicture* a_picture){
2706 	if (do_owner_check()){
2707 		if (a_picture && a_picture->usurped == NULL){
2708 			a_picture->usurp(cpicture);
2709 			cpicture = a_picture;
2710 
2711 			owner->session->WriteInt32( AS_LAYER_BEGIN_PICTURE );
2712 		}
2713 	}
2714 }
2715 
2716 //---------------------------------------------------------------------------
2717 
2718 void BView::AppendToPicture(BPicture* a_picture){
2719 	check_lock();
2720 
2721 	if (a_picture && a_picture->usurped == NULL){
2722 		int32 token = a_picture->token;
2723 
2724 		if (token == -1){
2725 			BeginPicture(a_picture);
2726 		}
2727 		else{
2728 			a_picture->usurped = cpicture;
2729 			a_picture->set_token(-1);
2730 			owner->session->WriteInt32(AS_LAYER_APPEND_TO_PICTURE);
2731 			owner->session->WriteInt32( token );
2732 		}
2733 	}
2734 }
2735 
2736 //---------------------------------------------------------------------------
2737 
2738 BPicture* BView::EndPicture(){
2739 	if (do_owner_check()){
2740 		if (cpicture){
2741 			int32			token;
2742 
2743 			owner->session->WriteInt32(AS_LAYER_END_PICTURE);
2744 			owner->session->Sync();
2745 
2746 			owner->session->ReadInt32( &token );
2747 
2748 			BPicture *a_picture = cpicture;
2749 			cpicture = a_picture->step_down();
2750 			a_picture->set_token(token);
2751 
2752 			return a_picture;
2753 		}
2754 		else
2755 			return NULL;
2756 	}
2757 	else
2758 		return NULL;
2759 }
2760 
2761 //---------------------------------------------------------------------------
2762 
2763 void BView::SetViewBitmap(const BBitmap* bitmap,
2764 						  BRect srcRect, BRect dstRect,
2765 						  uint32 followFlags,
2766 						  uint32 options)
2767 {
2768 	setViewImage(bitmap, srcRect, dstRect, followFlags, options);
2769 }
2770 
2771 //---------------------------------------------------------------------------
2772 
2773 void BView::SetViewBitmap(const BBitmap* bitmap,
2774 						  uint32 followFlags,
2775 						  uint32 options)
2776 {
2777 	BRect rect;
2778  	if (bitmap)
2779 		rect = bitmap->Bounds();
2780 
2781  	rect.OffsetTo(0, 0);
2782 
2783 	setViewImage(bitmap, rect, rect, followFlags, options);
2784 }
2785 
2786 //---------------------------------------------------------------------------
2787 
2788 void BView::ClearViewBitmap(){
2789 	setViewImage(NULL, BRect(), BRect(), 0, 0);
2790 }
2791 
2792 //---------------------------------------------------------------------------
2793 
2794 status_t BView::SetViewOverlay(const BBitmap* overlay,
2795 							   BRect srcRect, BRect dstRect,
2796 							   rgb_color* colorKey,
2797 							   uint32 followFlags,
2798 							   uint32 options)
2799 {
2800 	status_t err = setViewImage(overlay, srcRect, dstRect, followFlags,
2801 								options | 0x4);
2802 		// read the color that will be treated as transparent
2803 	owner->session->ReadData( colorKey, sizeof(rgb_color) );
2804 
2805 	return err;
2806 }
2807 
2808 //---------------------------------------------------------------------------
2809 
2810 status_t BView::SetViewOverlay(const BBitmap* overlay, rgb_color* colorKey,
2811 							   uint32 followFlags,
2812 							   uint32 options)
2813 {
2814 	BRect rect;
2815  	if (overlay)
2816 		rect = overlay->Bounds();
2817 
2818  	rect.OffsetTo(0, 0);
2819 
2820 	status_t err = setViewImage(overlay, rect, rect, followFlags,
2821 								options | 0x4);
2822 		// read the color that will be treated as transparent
2823 	owner->session->ReadData( colorKey, sizeof(rgb_color) );
2824 
2825 	return err;
2826 }
2827 
2828 //---------------------------------------------------------------------------
2829 
2830 void BView::ClearViewOverlay(){
2831 	setViewImage(NULL, BRect(), BRect(), 0, 0);
2832 }
2833 
2834 //---------------------------------------------------------------------------
2835 
2836 void BView::CopyBits(BRect src, BRect dst){
2837 	if ( !src.IsValid() || !dst.IsValid() )
2838 		return;
2839 
2840 	if (do_owner_check()){
2841 			owner->session->WriteInt32(AS_LAYER_COPY_BITS);
2842 			owner->session->WriteRect( src );
2843 			owner->session->WriteRect( dst );
2844 	}
2845 }
2846 
2847 //---------------------------------------------------------------------------
2848 
2849 void BView::DrawPicture(const BPicture* a_picture){
2850 	if (!a_picture)
2851 		return;
2852 
2853 	status_t 	err;
2854 
2855 	DrawPictureAsync(a_picture, PenLocation());
2856 	owner->session->WriteInt32( SERVER_TRUE );
2857 	owner->session->Sync();
2858 
2859 	owner->session->ReadInt32( &err );
2860 }
2861 
2862 //---------------------------------------------------------------------------
2863 
2864 void BView::DrawPicture(const BPicture* a_picture, BPoint where){
2865 	if (!a_picture)
2866 		return;
2867 
2868 	status_t 	err;
2869 
2870 	DrawPictureAsync( a_picture, where );
2871 	owner->session->WriteInt32( SERVER_TRUE );
2872 	owner->session->Sync();
2873 
2874 	owner->session->ReadInt32( &err );
2875 }
2876 
2877 //---------------------------------------------------------------------------
2878 
2879 void BView::DrawPicture(const char* filename, long offset, BPoint where){
2880 	if (!filename)
2881 		return;
2882 
2883 	status_t 	err;
2884 
2885 	DrawPictureAsync( filename, offset, where );
2886 	owner->session->WriteInt32( SERVER_TRUE );
2887 	owner->session->Sync();
2888 
2889 	owner->session->ReadInt32( &err );
2890 }
2891 
2892 //---------------------------------------------------------------------------
2893 
2894 void BView::DrawPictureAsync(const BPicture* a_picture){
2895 	if (!a_picture)
2896 		return;
2897 
2898 	DrawPictureAsync(a_picture, PenLocation());
2899 }
2900 
2901 //---------------------------------------------------------------------------
2902 
2903 void BView::DrawPictureAsync(const BPicture* a_picture, BPoint where){
2904 	if (!a_picture)
2905 		return;
2906 
2907 	if (do_owner_check() && a_picture->token > 0) {
2908 		owner->session->WriteInt32( AS_LAYER_DRAW_PICTURE );
2909 		owner->session->WriteInt32( a_picture->token );
2910 		owner->session->WritePoint( where );
2911 	}
2912 }
2913 
2914 //---------------------------------------------------------------------------
2915 
2916 void BView::DrawPictureAsync(const char* filename, long offset, BPoint where){
2917 	if (!filename)
2918 		return;
2919 
2920 // TODO: test, implement
2921 }
2922 
2923 //---------------------------------------------------------------------------
2924 
2925 void BView::Invalidate(BRect invalRect){
2926 	if ( !invalRect.IsValid() )
2927 		return;
2928 
2929 	if (owner){
2930 		check_lock();
2931 
2932 		owner->session->WriteInt32( AS_LAYER_INVAL_RECT );
2933 		owner->session->WriteRect( invalRect );
2934 			// ... because we want to see the results ASAP
2935 		owner->session->Sync();
2936 	}
2937 }
2938 
2939 //---------------------------------------------------------------------------
2940 
2941 void BView::Invalidate(const BRegion* invalRegion){
2942 	if ( !invalRegion )
2943 		return;
2944 
2945 	if (owner){
2946 		check_lock();
2947 		int32				noOfRects = 0;
2948 		noOfRects			= const_cast<BRegion*>(invalRegion)->CountRects();
2949 
2950 		owner->session->WriteInt32( AS_LAYER_INVAL_REGION );
2951 		owner->session->WriteInt32( noOfRects );
2952 
2953 		for (int i=0; i<noOfRects; i++){
2954 			owner->session->WriteRect( const_cast<BRegion*>(invalRegion)->RectAt(i) );
2955 		}
2956 			// ... becasue we want to see the results ASAP
2957 		owner->session->Sync();
2958 	}
2959 }
2960 
2961 //---------------------------------------------------------------------------
2962 
2963 void BView::Invalidate(){
2964 	Invalidate( Bounds() );
2965 }
2966 
2967 //---------------------------------------------------------------------------
2968 
2969 void BView::InvertRect(BRect r){
2970 
2971 	if (owner){
2972 		check_lock();
2973 
2974 		owner->session->WriteInt32( AS_LAYER_INVERT_RECT );
2975 		owner->session->WriteRect( r );
2976 	}
2977 }
2978 
2979 
2980 // View Hierarchy Functions
2981 //---------------------------------------------------------------------------
2982 void BView::AddChild(BView* child, BView* before){
2983 STRACE(("BView(%s)::AddChild(child='%s' before='%s')\n", this->Name(),
2984 		child? child->Name(): "NULL",
2985 		before? before->Name(): "NULL"));
2986 	if ( !child )
2987 		return;
2988 
2989 	if (child->parent != NULL)
2990 		debugger("AddChild failed - the view already belongs to someone else.");
2991 
2992 	bool	lockedByAddChild = false;
2993 	if ( owner && !(owner->IsLocked()) ){
2994 		owner->Lock();
2995 		lockedByAddChild	= true;
2996 	}
2997 
2998 	if ( !addToList( child, before ) )
2999 		debugger("AddChild failed - cannot find 'before' view.");
3000 
3001 	if ( owner ){
3002 		check_lock();
3003 
3004 		STRACE(("BView(%s)::AddChild(child='%s' before='%s')... contacting app_server\n", this->Name(),
3005 				child? child->Name(): "NULL",
3006 				before? before->Name(): "NULL"));
3007 
3008 		child->setOwner( this->owner);
3009 		attachView( child );
3010 
3011 		if ( lockedByAddChild )
3012 			owner->Unlock();
3013 	}
3014 //	BVTRACE;
3015 	PrintTree();
3016 //	PrintToStream();
3017 }
3018 
3019 //---------------------------------------------------------------------------
3020 
3021 bool BView::RemoveChild(BView* child){
3022 STRACE(("BView(%s)::RemoveChild(%s)\n", this->Name(), child->Name() ));
3023 	if (!child)
3024 		return false;
3025 
3026 	bool	rv = child->removeSelf();
3027 //	BVTRACE;
3028 	PrintTree();
3029 	return rv;
3030 }
3031 
3032 //---------------------------------------------------------------------------
3033 
3034 int32 BView::CountChildren() const{
3035 	uint32		noOfChildren 	= 0;
3036 	BView		*aChild			= first_child;
3037 
3038 	while ( aChild != NULL ) {
3039 		noOfChildren++;
3040 		aChild		= aChild->next_sibling;
3041 	}
3042 
3043 	return noOfChildren;
3044 }
3045 
3046 //---------------------------------------------------------------------------
3047 
3048 BView* BView::ChildAt(int32 index) const{
3049 	int32		noOfChildren 	= 0;
3050 	BView		*aChild			= first_child;
3051 
3052 	while ( aChild != NULL && noOfChildren < index ) {
3053 		noOfChildren++;
3054 		aChild		= aChild->next_sibling;
3055 	}
3056 
3057 	return aChild;
3058 }
3059 
3060 //---------------------------------------------------------------------------
3061 
3062 BView* BView::NextSibling() const{
3063 	return next_sibling;
3064 }
3065 
3066 //---------------------------------------------------------------------------
3067 
3068 BView* BView::PreviousSibling() const{
3069 	return prev_sibling;
3070 }
3071 
3072 //---------------------------------------------------------------------------
3073 
3074 bool BView::RemoveSelf(){
3075 	return removeSelf();
3076 }
3077 
3078 //---------------------------------------------------------------------------
3079 
3080 BView* BView::Parent() const{
3081 	return parent;
3082 }
3083 
3084 //---------------------------------------------------------------------------
3085 
3086 BView* BView::FindView(const char* name) const{
3087 	return findView(this, name);
3088 }
3089 
3090 //---------------------------------------------------------------------------
3091 
3092 void BView::MoveBy(float dh, float dv){
3093 	MoveTo( originX + dh, originY + dv );
3094 }
3095 
3096 //---------------------------------------------------------------------------
3097 
3098 void BView::MoveTo(BPoint where){
3099 	MoveTo(where.x, where.y);
3100 }
3101 
3102 //---------------------------------------------------------------------------
3103 
3104 void BView::MoveTo(float x, float y){
3105 
3106 	if ( x == originX && y == originY )
3107 		return;
3108 
3109 		// BeBook sez we should do this. We'll do it without. So...
3110 	/*x		= roundf( x );
3111 	y		= roundf( y );*/
3112 
3113 	check_lock();
3114 
3115 	if (owner){
3116 		owner->session->WriteInt32( AS_LAYER_MOVETO );
3117 		owner->session->WriteFloat( x );
3118 		owner->session->WriteFloat( y );
3119 
3120 		fState->flags		|= B_VIEW_COORD_BIT;
3121 	}
3122 
3123 	originX		= x;
3124 	originY		= y;
3125 }
3126 
3127 //---------------------------------------------------------------------------
3128 
3129 void BView::ResizeBy(float dh, float dv){
3130 	ResizeTo( fBounds.right + dh, fBounds.bottom + dv );
3131 }
3132 
3133 //---------------------------------------------------------------------------
3134 
3135 void BView::ResizeTo(float width, float height){
3136 	if ( width == fBounds.Width() &&
3137 			height == fBounds.Height() )
3138 		return;
3139 
3140 		// BeBook sez we should do this. We'll do it without. So...
3141 	/*width		= roundf( width );
3142 	height		= roundf( height );*/
3143 
3144 	check_lock();
3145 
3146 	if (owner){
3147 		owner->session->WriteInt32( AS_LAYER_RESIZETO );
3148 		owner->session->WriteFloat( width );
3149 		owner->session->WriteFloat( height );
3150 
3151 		fState->flags		|= B_VIEW_COORD_BIT;
3152 	}
3153 
3154 	fBounds.right	= fBounds.left + width;
3155 	fBounds.bottom	= fBounds.top + height;
3156 }
3157 
3158 //---------------------------------------------------------------------------
3159 
3160 // Inherited Methods (virtual)
3161 //---------------------------------------------------------------------------
3162 
3163 status_t BView::GetSupportedSuites(BMessage* data){
3164 	status_t err = B_OK;
3165 	if (!data)
3166 		err = B_BAD_VALUE;
3167 
3168 	if (!err){
3169 		err = data->AddString("Suites", "suite/vnd.Be-view");
3170 		if (!err){
3171 			BPropertyInfo propertyInfo(viewPropInfo);
3172 			err = data->AddFlat("message", &propertyInfo);
3173 			if (!err){
3174 				err = BHandler::GetSupportedSuites(data);
3175 			}
3176 		}
3177 	}
3178 	return err;
3179 }
3180 
3181 //------------------------------------------------------------------------------
3182 
3183 BHandler* BView::ResolveSpecifier(BMessage* msg, int32 index,	BMessage* specifier,
3184 									int32 what,	const char* property)
3185 {
3186 	if (msg->what == B_WINDOW_MOVE_BY)
3187 		return this;
3188 	if (msg->what == B_WINDOW_MOVE_TO)
3189 		return this;
3190 
3191 	BPropertyInfo propertyInfo(viewPropInfo);
3192 	switch (propertyInfo.FindMatch(msg, index, specifier, what, property))
3193 	{
3194 		case B_ERROR:
3195 			break;
3196 		case 0:
3197 		case 1:
3198 		case 2:
3199 		case 3:
3200 		case 5:
3201 			return this;
3202 
3203 		case 4:
3204 			if (fShelf){
3205 				msg->PopSpecifier();
3206 				return fShelf;
3207 			}
3208 			else{
3209 				BMessage		replyMsg(B_MESSAGE_NOT_UNDERSTOOD);
3210 				replyMsg.AddInt32( "error", B_NAME_NOT_FOUND );
3211 				replyMsg.AddString( "message", "This window doesn't have a self");
3212 				msg->SendReply( &replyMsg );
3213 				return NULL;
3214 			}
3215 			break;
3216 		case 6:
3217 		case 7:
3218 		case 8:
3219 			if (first_child){
3220 				BView		*child;
3221 				switch( msg->what ){
3222 					case B_INDEX_SPECIFIER:
3223 						int32	index;
3224 						msg->FindInt32("data", &index);
3225 						child	= ChildAt( index );
3226 						break;
3227 
3228 					case B_REVERSE_INDEX_SPECIFIER:
3229 						int32	rindex;
3230 						msg->FindInt32("data", &rindex);
3231 						child	= ChildAt( CountChildren() - rindex );
3232 						break;
3233 
3234 					case B_NAME_SPECIFIER:
3235 						const char	*name;
3236 						msg->FindString("data", &name);
3237 						child	= FindView( name );
3238 						delete name;
3239 						break;
3240 
3241 					default:
3242 						child	= NULL;
3243 						break;
3244 				}
3245 				if ( child != NULL ){
3246 					msg->PopSpecifier();
3247 					return child;
3248 				}
3249 				else{
3250 					BMessage		replyMsg(B_MESSAGE_NOT_UNDERSTOOD);
3251 					replyMsg.AddInt32( "error", B_BAD_INDEX );
3252 					replyMsg.AddString( "message", "Cannot find view at/with specified index/name.");
3253 					msg->SendReply( &replyMsg );
3254 					return NULL;
3255 				}
3256 			}
3257 			else{
3258 				BMessage		replyMsg(B_MESSAGE_NOT_UNDERSTOOD);
3259 				replyMsg.AddInt32( "error", B_NAME_NOT_FOUND );
3260 				replyMsg.AddString( "message", "This window doesn't have children.");
3261 				msg->SendReply( &replyMsg );
3262 				return NULL;
3263 			}
3264 			break;
3265 	}
3266 
3267 	return BHandler::ResolveSpecifier(msg, index, specifier, what, property);
3268 }
3269 
3270 //---------------------------------------------------------------------------
3271 void BView::MessageReceived( BMessage *msg )
3272 {
3273 	BMessage			specifier;
3274 	int32				what;
3275 	const char*			prop;
3276 	int32				index;
3277 	status_t			err;
3278 
3279 	if (msg->HasSpecifiers()){
3280 
3281 	err = msg->GetCurrentSpecifier(&index, &specifier, &what, &prop);
3282 	if (err == B_OK)
3283 	{
3284 		BMessage			replyMsg;
3285 
3286 		switch (msg->what)
3287 		{
3288 		case B_GET_PROPERTY:{
3289 				replyMsg.what		= B_NO_ERROR;
3290 				replyMsg.AddInt32( "error", B_OK );
3291 
3292 				if (strcmp(prop, "Frame") ==0 )
3293 				{
3294 					replyMsg.AddRect( "result", Frame());
3295 				}
3296 				else if (strcmp(prop, "Hidden") ==0 )
3297 				{
3298 					replyMsg.AddBool( "result", IsHidden());
3299 				}
3300 			}break;
3301 
3302 		case B_SET_PROPERTY:{
3303 				if (strcmp(prop, "Frame") ==0 )
3304 				{
3305 					BRect			newFrame;
3306 					if (msg->FindRect( "data", &newFrame ) == B_OK){
3307 						MoveTo( newFrame.LeftTop() );
3308 						ResizeTo( newFrame.right, newFrame.bottom);
3309 
3310 						replyMsg.what		= B_NO_ERROR;
3311 						replyMsg.AddInt32( "error", B_OK );
3312 					}
3313 					else{
3314 						replyMsg.what		= B_MESSAGE_NOT_UNDERSTOOD;
3315 						replyMsg.AddInt32( "error", B_BAD_SCRIPT_SYNTAX );
3316 						replyMsg.AddString( "message", "Didn't understand the specifier(s)" );
3317 					}
3318 				}
3319 
3320 				else if (strcmp(prop, "Hidden") ==0 )
3321 				{
3322 					bool			newHiddenState;
3323 					if (msg->FindBool( "data", &newHiddenState ) == B_OK){
3324 						if ( !IsHidden() && newHiddenState == true ){
3325 							Hide();
3326 
3327 							replyMsg.what		= B_NO_ERROR;
3328 							replyMsg.AddInt32( "error", B_OK );
3329 
3330 						}
3331 						else if ( IsHidden() && newHiddenState == false ){
3332 							Show();
3333 
3334 							replyMsg.what		= B_NO_ERROR;
3335 							replyMsg.AddInt32( "error", B_OK );
3336 						}
3337 						else{
3338 							replyMsg.what		= B_MESSAGE_NOT_UNDERSTOOD;
3339 							replyMsg.AddInt32( "error", B_BAD_SCRIPT_SYNTAX );
3340 							replyMsg.AddString( "message", "Didn't understand the specifier(s)" );
3341 						}
3342 					}
3343 					else{
3344 						replyMsg.what		= B_MESSAGE_NOT_UNDERSTOOD;
3345 						replyMsg.AddInt32( "error", B_BAD_SCRIPT_SYNTAX );
3346 						replyMsg.AddString( "message", "Didn't understand the specifier(s)" );
3347 					}
3348 				}
3349 			}break;
3350 
3351 		case B_COUNT_PROPERTIES:{
3352 				if (strcmp(prop, "View") ==0 )
3353 				{
3354 					replyMsg.what		= B_NO_ERROR;
3355 					replyMsg.AddInt32( "error", B_OK );
3356 					replyMsg.AddInt32( "result", CountChildren());
3357 				}
3358 
3359 			}break;
3360 		}
3361 		msg->SendReply( &replyMsg );
3362 	}
3363 	else{
3364 		BMessage		replyMsg(B_MESSAGE_NOT_UNDERSTOOD);
3365 		replyMsg.AddInt32( "error" , B_BAD_SCRIPT_SYNTAX );
3366 		replyMsg.AddString( "message", "Didn't understand the specifier(s)" );
3367 
3368 		msg->SendReply( &replyMsg );
3369 	}
3370 
3371 	} // END: if (msg->HasSpecifiers())
3372 	else
3373 		BHandler::MessageReceived( msg );
3374 }
3375 
3376 //---------------------------------------------------------------------------
3377 
3378 status_t BView::Perform(perform_code d, void* arg){
3379 	return B_BAD_VALUE;
3380 }
3381 
3382 // Private Functions
3383 //---------------------------------------------------------------------------
3384 
3385 void BView::InitData(BRect frame, const char *name, uint32 resizingMode, uint32 flags){
3386 
3387 		// Info: The name of the view is set by BHandler constructor
3388 
3389 	// initialize members
3390 	fFlags				= (resizingMode & _RESIZE_MASK_) | (flags & ~_RESIZE_MASK_);
3391 
3392 	originX				= frame.left;
3393 	originY				= frame.top;
3394 
3395 	owner				= NULL;
3396 	parent				= NULL;
3397 	next_sibling		= NULL;
3398 	prev_sibling		= NULL;
3399 	first_child			= NULL;
3400 
3401 	fShowLevel			= 0;
3402 	top_level_view		= false;
3403 
3404 	cpicture			= NULL;
3405 	comm				= NULL;
3406 
3407 	fVerScroller		= NULL;
3408 	fHorScroller		= NULL;
3409 
3410 	f_is_printing		= false;
3411 
3412 	fPermanentState		= NULL;
3413 	fState				= new ViewAttr;
3414 
3415 	fBounds				= frame.OffsetToCopy(0.0, 0.0);
3416 	fShelf				= NULL;
3417 	pr_state			= NULL;
3418 
3419 	fEventMask			= 0;
3420 	fEventOptions		= 0;
3421 
3422 	// call initialization methods.
3423 	initCachedState();
3424 }
3425 
3426 //---------------------------------------------------------------------------
3427 
3428 void BView::removeCommArray(){
3429 	if( comm ){
3430 		delete comm->array;
3431 		delete comm;
3432 		comm	= NULL;
3433 	}
3434 }
3435 
3436 //---------------------------------------------------------------------------
3437 
3438 void BView::setOwner(BWindow *theOwner)
3439 {
3440 	if (!theOwner){
3441 		removeCommArray();
3442 	}
3443 
3444 	if (owner != theOwner && owner)
3445 	{
3446 		if (owner->fFocus == this)
3447 			MakeFocus( false );
3448 
3449 		if (owner->fLastMouseMovedView == this)
3450 			owner->fLastMouseMovedView = NULL;
3451 
3452 		owner->RemoveHandler(this);
3453 		if (fShelf)
3454 			owner->RemoveHandler(fShelf);
3455 	}
3456 
3457 	if (theOwner && theOwner != owner)
3458 	{
3459 		theOwner->AddHandler(this);
3460 		if (fShelf)
3461 			theOwner->AddHandler(fShelf);
3462 
3463 		if (top_level_view)
3464 			SetNextHandler(theOwner);
3465 		else
3466 			SetNextHandler(parent);
3467 	}
3468 
3469 	owner = theOwner;
3470 
3471 	for (BView *child = first_child; child != NULL; child = child->next_sibling)
3472 		child->setOwner(theOwner);
3473 }
3474 
3475 //---------------------------------------------------------------------------
3476 
3477 bool BView::removeSelf(){
3478 STRACE(("BView(%s)::removeSelf()...\n", this->Name() ));
3479 /* 		# check for dirty flags 						- by updateCachedState()
3480  * 		# check for dirty flags on 'child' children		- by updateCachedState()
3481  *		# handle if in middle of Begin/EndLineArray()	- by setOwner(NULL)
3482  * 		# remove trom the main tree						- by removeFromList()
3483  * 		# handle if child is the default button			- HERE
3484  * 		# handle if child is the focus view				- by setOwner(NULL)
3485  * 		# handle if child is the menu bar				- HERE
3486  * 		# handle if child token is = fLastViewToken		- by setOwner(NULL)
3487  * 		# contact app_server							- HERE
3488  * 		# set a new owner = NULL						- by setOwner(NULL)
3489  */
3490  	bool		returnValue = true;
3491 
3492 	if (!parent){
3493 		STRACE(("BView(%s)::removeSelf()... NO parent\n", this->Name()));
3494 		return false;
3495 	}
3496 
3497 	check_lock();
3498 
3499 	if (owner){
3500 
3501 		updateCachedState();
3502 
3503 		if (owner->fDefaultButton == this){
3504 			owner->SetDefaultButton( NULL );
3505 		}
3506 
3507 		if (owner->fKeyMenuBar == this){
3508 			owner->fKeyMenuBar = NULL;
3509 		}
3510 
3511 		if (owner->fLastViewToken == _get_object_token_(this)){
3512 			owner->fLastViewToken = B_NULL_TOKEN;
3513 		}
3514 
3515 		callDetachHooks( this );
3516 
3517 		BWindow			*ownerZ = owner;
3518 
3519 		setOwner( NULL );
3520 
3521 		ownerZ->session->WriteInt32( AS_LAYER_DELETE );
3522 	}
3523 
3524 	returnValue		= removeFromList();
3525 
3526 	parent			= NULL;
3527 	next_sibling	= NULL;
3528 	prev_sibling	= NULL;
3529 
3530 STRACE(("DONE: BView(%s)::removeSelf()\n", this->Name()));
3531 	return returnValue;
3532 }
3533 
3534 //---------------------------------------------------------------------------
3535 
3536 bool BView::callDetachHooks( BView *aView ){
3537 //	check_clock();
3538 
3539 		// call the hook function:
3540 	aView->DetachedFromWindow();
3541 
3542 		// we attach all its children
3543 	BView		*child;
3544 	child		= aView->first_child;
3545 
3546 	while( child ) {
3547 		aView->callDetachHooks(child);
3548 		child		= child->next_sibling;
3549 	}
3550 		// call the hook function:
3551 	aView->AllDetached();
3552 
3553 	return true;
3554 }
3555 
3556 //---------------------------------------------------------------------------
3557 
3558 bool BView::removeFromList(){
3559 
3560 	if (parent->first_child == this){
3561 		parent->first_child = next_sibling;
3562 
3563 		if (next_sibling)
3564 			next_sibling->prev_sibling	= NULL;
3565 	}
3566 	else{
3567 		prev_sibling->next_sibling	= next_sibling;
3568 
3569 		if (next_sibling)
3570 			next_sibling->prev_sibling	= prev_sibling;
3571 	}
3572 	return true;
3573 }
3574 
3575 //---------------------------------------------------------------------------
3576 
3577 bool BView::addToList(BView *aView, BView *before){
3578 	if ( !aView )
3579 		return false;
3580 
3581 	BView		*current 	= first_child;
3582 	BView		*last		= current;
3583 
3584 	while( current && current != before){
3585 		last		= current;
3586 		current		= current->next_sibling;
3587 	}
3588 
3589 	if( !current && before )
3590 		return false;
3591 
3592 		// we're at begining of the list, OR between two elements
3593 	if( current ){
3594 		if ( current == first_child ){
3595 			aView->next_sibling		= current;
3596 			current->prev_sibling	= aView;
3597 			first_child				= aView;
3598 		}
3599 		else{
3600 			aView->next_sibling		= current;
3601 			aView->prev_sibling		= current->prev_sibling;
3602 			current->prev_sibling->next_sibling		= aView;
3603 			current->prev_sibling	= aView;
3604 		}
3605 	}
3606 		// we have reached the end of the list
3607 	else{
3608 			// if last!=NULL then we add to the end.
3609 		if ( last ){
3610 			last->next_sibling		= aView;
3611 			aView->prev_sibling		= last;
3612 		}
3613 			// if last==NULL, then aView is the first child in the list
3614 		else{
3615 			first_child		= aView;
3616 		}
3617 	}
3618 
3619 	aView->parent		= this;
3620 
3621 	return true;
3622 }
3623 
3624 //---------------------------------------------------------------------------
3625 
3626 bool BView::attachView(BView *aView){
3627 // LEAVE the following line commented!!!
3628 //	check_lock();
3629 
3630 /* INFO:
3631  *	'check_lock()' checks for a lock on the window and then, modifies
3632  * 		BWindow::fLastViewToken with the one of the view witch called check_lock()
3633  * 		, and sends it to the app_server to be the view for witch current actions
3634  * 		are made.
3635  * 	This is a good solution for attaching a view to the server, but, this is done
3636  * 		many times, and because I suspect app_server holds ALL the 'Layer' pointers
3637  * 		in a hash list indexed by view tokens, a costly search action is made
3638  * 		for each view to be attached.
3639  * 	I think a better solution(also programming-wise), is to attach the number
3640  * 		of a view's children. Although this requires a list <iteration>, the
3641  * 		time to do it will be much smaller than searching a hash list.
3642  * 	On the server, only a recursive method is needed for building the tree...
3643  */
3644 
3645 	owner->session->WriteInt32( AS_LAYER_CREATE );
3646 	owner->session->WriteInt32( _get_object_token_( aView ) );
3647 	owner->session->WriteString( aView->Name() );
3648 	owner->session->WriteRect( aView->Frame() );
3649 	owner->session->WriteUInt32( aView->ResizingMode() );
3650 	owner->session->WriteUInt32( aView->Flags() );
3651 	owner->session->WriteBool( aView->IsHidden() );
3652 	owner->session->WriteInt32( aView->CountChildren() );
3653 
3654 	aView->setCachedState();
3655 
3656 		// call the hook function:
3657 	aView->AttachedToWindow();
3658 
3659 		// we attach all its children
3660 	BView		*child;
3661 	child		= aView->first_child;
3662 
3663 	while( child ) {
3664 		aView->attachView(child);
3665 		child		= child->next_sibling;
3666 	}
3667 		// call the hook function:
3668 	aView->AllAttached();
3669 
3670 	return true;
3671 }
3672 
3673 //---------------------------------------------------------------------------
3674 
3675 void BView::deleteView( BView* aView){
3676 
3677 	BView		*child;
3678 	child		= aView->first_child;
3679 
3680 	while( child ) {
3681 		deleteView(child);
3682 		child		= child->next_sibling;
3683 	}
3684 
3685 	delete aView;
3686 }
3687 
3688 //---------------------------------------------------------------------------
3689 
3690 BView* BView::findView(const BView* aView, const char* viewName) const{
3691 	if ( strcmp( viewName, aView->Name() ) == 0)
3692 		return const_cast<BView*>(aView);
3693 
3694 	BView			*child;
3695 	if ( (child = aView->first_child) ){
3696 		while ( child ) {
3697 			BView*		view = NULL;
3698 			if ( (view = findView( child, viewName )) )
3699 				return view;
3700 			child 		= child->next_sibling;
3701 		}
3702 	}
3703 
3704 	return NULL;
3705 }
3706 
3707 //---------------------------------------------------------------------------
3708 
3709 void BView::setCachedState(){
3710 	setFontState( &(fState->font), fState->fontFlags );
3711 
3712 	owner->session->WriteInt32( AS_LAYER_SET_STATE );
3713 	owner->session->WritePoint( fState->penPosition );
3714 	owner->session->WriteFloat( fState->penSize );
3715 	owner->session->WriteData( &(fState->highColor), sizeof(rgb_color) );
3716 	owner->session->WriteData( &(fState->lowColor), sizeof(rgb_color) );
3717 	owner->session->WriteData( &(fState->viewColor), sizeof(rgb_color) );
3718 	owner->session->WriteData( &(fState->patt), sizeof(pattern) );
3719 	owner->session->WriteInt8( (int8)fState->drawingMode );
3720 	owner->session->WritePoint( fState->coordSysOrigin );
3721 	owner->session->WriteInt8( (int8)fState->lineJoin );
3722 	owner->session->WriteInt8( (int8)fState->lineCap );
3723 	owner->session->WriteFloat( fState->miterLimit );
3724 	owner->session->WriteInt8( (int8)fState->alphaSrcMode );
3725 	owner->session->WriteInt8( (int8)fState->alphaFncMode );
3726 	owner->session->WriteFloat( fState->scale );
3727 	owner->session->WriteBool( fState->fontAliasing );
3728 		// we send the 'local' clipping region... if we have one...
3729 	int32		noOfRects	= fState->clippingRegion.CountRects();
3730 
3731 	owner->session->WriteInt32( noOfRects );
3732 	for (int32 i = 0; i < noOfRects; i++){
3733 		owner->session->WriteRect( fState->clippingRegion.RectAt(i) );
3734 	}
3735 
3736 		/* Although we might have a 'local' clipping region, when we call
3737 		 * 		BView::GetClippingRegion(...);
3738 		 *    we ask for the 'global' one; and that is kept on server, so we
3739 		 *    must invalidate B_VIEW_CLIP_REGION_BIT flag!
3740 		 */
3741 	fState->flags			= B_VIEW_CLIP_REGION_BIT;
3742 }
3743 
3744 //---------------------------------------------------------------------------
3745 
3746 void BView::setFontState(const BFont* font, uint16 mask){
3747 
3748 	owner->session->WriteInt32( AS_LAYER_SET_FONT_STATE );
3749 	owner->session->WriteUInt16( mask );
3750 
3751 		// always present.
3752 	if ( mask & B_FONT_FAMILY_AND_STYLE ){
3753 		uint32		fontID;
3754 		fontID		= font->FamilyAndStyle( );
3755 
3756 		owner->session->WriteUInt32( fontID );
3757 	}
3758 
3759 	if ( mask & B_FONT_SIZE ){
3760 		owner->session->WriteFloat( font->Size() );
3761 	}
3762 
3763 	if ( mask & B_FONT_SHEAR ){
3764 		owner->session->WriteFloat( font->Shear() );
3765 	}
3766 
3767 	if ( mask & B_FONT_ROTATION ){
3768 		owner->session->WriteFloat( font->Rotation() );
3769 	}
3770 
3771 	if ( mask & B_FONT_SPACING ){
3772 		owner->session->WriteUInt8( font->Spacing() );	// uint8
3773 	}
3774 
3775 	if ( mask & B_FONT_ENCODING ){
3776 		owner->session->WriteUInt8( font->Encoding() ); // uint8
3777 	}
3778 
3779 	if ( mask & B_FONT_FACE ){
3780 		owner->session->WriteUInt16( font->Face() );	// uint16
3781 	}
3782 
3783 	if ( mask & B_FONT_FLAGS ){
3784 		owner->session->WriteUInt32( font->Flags() ); // uint32
3785 	}
3786 }
3787 
3788 //---------------------------------------------------------------------------
3789 
3790 void BView::initCachedState(){
3791 	fState->font			= *be_plain_font;
3792 
3793 	fState->penPosition.Set( 0.0, 0.0 );
3794 	fState->penSize			= 1.0;
3795 
3796 	fState->highColor.red	= 0;
3797 	fState->highColor.blue	= 0;
3798 	fState->highColor.green	= 0;
3799 	fState->highColor.alpha	= 255;
3800 
3801 	fState->lowColor.red	= 255;
3802 	fState->lowColor.blue	= 255;
3803 	fState->lowColor.green	= 255;
3804 	fState->lowColor.alpha	= 255;
3805 
3806 	fState->viewColor.red	= 255;
3807 	fState->viewColor.blue	= 255;
3808 	fState->viewColor.green	= 255;
3809 	fState->viewColor.alpha	= 255;
3810 
3811 	fState->patt			= B_SOLID_HIGH;
3812 
3813 	fState->drawingMode		= B_OP_COPY;
3814 
3815 	// clippingRegion is empty by default
3816 
3817 	fState->coordSysOrigin.Set( 0.0, 0.0 );
3818 
3819 	fState->lineCap			= B_BUTT_CAP;
3820 	fState->lineJoin		= B_BEVEL_JOIN;
3821 	fState->miterLimit		= B_DEFAULT_MITER_LIMIT;
3822 
3823 	fState->alphaSrcMode	= B_PIXEL_ALPHA;
3824 	fState->alphaFncMode	= B_ALPHA_OVERLAY;
3825 
3826 	fState->scale			= 1.0;
3827 
3828 	fState->fontAliasing	= false;
3829 
3830 		/* INFO: We include(invalidate) only B_VIEW_CLIP_REGION_BIT flag,
3831 		 * because we should get the clipping region from app_server.
3832 		 * 		The other flags do not need to be included because the data they
3833 		 * represent is already in sync with app_server - app_server uses the
3834 		 * same init(default) values.
3835 		 */
3836 	fState->flags			= B_VIEW_CLIP_REGION_BIT;
3837 		// (default) flags used to determine witch fields to archive
3838 	fState->archivingFlags	= B_VIEW_COORD_BIT;
3839 }
3840 
3841 //---------------------------------------------------------------------------
3842 
3843 void BView::updateCachedState(){
3844 		// fail if we do not have an owner
3845 STRACE(("BView(%s)::updateCachedState()\n", Name() ));
3846  	do_owner_check();
3847 
3848  	owner->session->WriteInt32( AS_LAYER_GET_STATE );
3849  	owner->session->Sync();
3850 
3851 	uint32		fontID;
3852 	float		size;
3853 	float		shear;
3854 	float		rotation;
3855 	uint8		spacing;
3856 	uint8		encoding;
3857 	uint16		face;
3858 	uint32		flags;
3859 	int32		noOfRects;
3860 	BRect		rect;
3861 
3862 		// read and set the font state
3863 	owner->session->ReadInt32( (int32*)&fontID );
3864 	owner->session->ReadFloat( &size );
3865 	owner->session->ReadFloat( &shear );
3866 	owner->session->ReadFloat( &rotation );
3867 	owner->session->ReadInt8( (int8*)&spacing );
3868 	owner->session->ReadInt8( (int8*)&encoding );
3869 	owner->session->ReadInt16( (int16*)&face );
3870 	owner->session->ReadInt32( (int32*)&flags );
3871 
3872 	fState->fontFlags		= B_FONT_ALL;
3873 	fState->font.SetFamilyAndStyle( fontID );
3874 	fState->font.SetSize( size );
3875 	fState->font.SetShear( shear );
3876 	fState->font.SetRotation( rotation );
3877 	fState->font.SetSpacing( spacing );
3878 	fState->font.SetEncoding( encoding );
3879 	fState->font.SetFace( face );
3880 	fState->font.SetFlags( flags );
3881 
3882 		// read and set view's state
3883 	owner->session->ReadPoint( &(fState->penPosition) );
3884 	owner->session->ReadFloat( &(fState->penSize) );
3885 	owner->session->ReadData( &(fState->highColor), sizeof(rgb_color) );
3886 	owner->session->ReadData( &(fState->lowColor), sizeof(rgb_color) );
3887 	owner->session->ReadData( &(fState->viewColor), sizeof(rgb_color) );
3888 	owner->session->ReadData( &(fState->patt), sizeof(pattern) );
3889 	owner->session->ReadPoint( &(fState->coordSysOrigin) );
3890 	owner->session->ReadInt8( (int8*)&(fState->drawingMode) );
3891 	owner->session->ReadInt8( (int8*)&(fState->lineCap) );
3892 	owner->session->ReadInt8( (int8*)&(fState->lineJoin) );
3893 	owner->session->ReadFloat( &(fState->miterLimit) );
3894 	owner->session->ReadInt8( (int8*)&(fState->alphaSrcMode) );
3895 	owner->session->ReadInt8( (int8*)&(fState->alphaFncMode) );
3896 	owner->session->ReadFloat( &(fState->scale) );
3897 	owner->session->ReadBool( &(fState->fontAliasing) );
3898 
3899 	owner->session->ReadInt32( &noOfRects );
3900 
3901 	fState->clippingRegion.MakeEmpty();
3902 	for (int32 i = 0; i < noOfRects; i++){
3903 		owner->session->ReadRect( &rect );
3904 		fState->clippingRegion.Include( rect );
3905 	}
3906 	//------------------
3907 
3908 	owner->session->ReadFloat( &originX );
3909 	owner->session->ReadFloat( &originY );
3910 	owner->session->ReadRect( &fBounds );
3911 
3912 	fState->flags			= B_VIEW_CLIP_REGION_BIT;
3913 STRACE(("BView(%s)::updateCachedState() - DONE\n", Name() ));
3914 }
3915 
3916 //---------------------------------------------------------------------------
3917 
3918 status_t BView::setViewImage(const BBitmap *bitmap, BRect srcRect,
3919         BRect dstRect, uint32 followFlags, uint32 options)
3920 {
3921 	if (!do_owner_check())
3922 		return B_ERROR;
3923 
3924 	int32		serverToken = bitmap ? bitmap->get_server_token() : -1;
3925 	status_t	err;
3926 
3927 	owner->session->WriteInt32( AS_LAYER_SET_VIEW_IMAGE );
3928 	owner->session->WriteInt32( serverToken );
3929 	owner->session->WriteRect( srcRect );
3930 	owner->session->WriteRect( dstRect );
3931 	owner->session->WriteInt32( followFlags );
3932 	owner->session->WriteInt32( options );
3933 	owner->session->Sync();
3934 	owner->session->ReadData( &err, sizeof(status_t) );
3935 
3936 	return err;
3937 }
3938 
3939 //---------------------------------------------------------------------------
3940 
3941 void BView::SetPattern(pattern pat){
3942 	if (owner){
3943 		check_lock();
3944 
3945 		owner->session->WriteInt32( AS_LAYER_SET_PATTERN );
3946 		owner->session->WriteData( &pat, sizeof(pattern) );
3947 	}
3948 
3949 	fState->patt		= pat;
3950 }
3951 
3952 //---------------------------------------------------------------------------
3953 
3954 bool BView::do_owner_check() const{
3955 STRACE(("BView(%s)::do_owner_check()...", Name()));
3956 	int32			serverToken = _get_object_token_(this);
3957 
3958 	if (owner){
3959 		owner->AssertLocked();
3960 
3961 		if (owner->fLastViewToken != serverToken){
3962 			STRACE(("contacting app_server... sending token: %ld\n", serverToken));
3963 			owner->session->WriteInt32( AS_SET_CURRENT_LAYER );
3964 			owner->session->WriteInt32( serverToken );
3965 
3966 			owner->fLastViewToken = serverToken;
3967 		}
3968 		else{
3969 			STRACE(("this is the lastViewToken\n"));
3970 		}
3971 		return true;
3972 	}
3973 	else{
3974 		debugger("View method requires owner and doesn't have one.");
3975 		return false;
3976 	}
3977 }
3978 
3979 //---------------------------------------------------------------------------
3980 
3981 void BView::check_lock() const{
3982 STRACE(("BView(%s)::check_lock()...", Name()));
3983 	int32			serverToken = _get_object_token_(this);
3984 
3985 	if (owner){
3986 		owner->AssertLocked();
3987 
3988 		if (owner->fLastViewToken != serverToken){
3989 			STRACE(("contacting app_server... sending token: %ld\n", serverToken));
3990 			owner->session->WriteInt32( AS_SET_CURRENT_LAYER );
3991 			owner->session->WriteInt32( serverToken );
3992 
3993 			owner->fLastViewToken = serverToken;
3994 		}
3995 		else{
3996 			STRACE(("quiet2\n"));
3997 		}
3998 	}
3999 	else{
4000 		STRACE(("quiet1\n"));
4001 	}
4002 }
4003 
4004 //---------------------------------------------------------------------------
4005 
4006 void BView::check_lock_no_pick() const{
4007 	if (owner)
4008 		owner->AssertLocked();
4009 }
4010 
4011 //---------------------------------------------------------------------------
4012 
4013 bool BView::do_owner_check_no_pick() const{
4014 	if (owner){
4015 		owner->AssertLocked();
4016 		return true;
4017 	}
4018 	else{
4019 		debugger("View method requires owner and doesn't have one.");
4020 		return false;
4021 	}
4022 }
4023 
4024 //---------------------------------------------------------------------------
4025 
4026 void BView::_ReservedView2(){
4027 }
4028 void BView::_ReservedView3(){
4029 }
4030 void BView::_ReservedView4(){
4031 }
4032 void BView::_ReservedView5(){
4033 }
4034 void BView::_ReservedView6(){
4035 }
4036 void BView::_ReservedView7(){
4037 }
4038 void BView::_ReservedView8(){
4039 }
4040 #if !_PR3_COMPATIBLE_
4041 void BView::_ReservedView9(){
4042 }
4043 void BView::_ReservedView10(){
4044 }
4045 void BView::_ReservedView11(){
4046 }
4047 void BView::_ReservedView12(){
4048 }
4049 void BView::_ReservedView13(){
4050 }
4051 void BView::_ReservedView14(){
4052 }
4053 void BView::_ReservedView15(){
4054 }
4055 void BView::_ReservedView16(){
4056 }
4057 #endif
4058 
4059 
4060 //---------------------------------------------------------------------------
4061 
4062 inline rgb_color _get_rgb_color( uint32 color ){
4063 	rgb_color		c;
4064 	c.red			= (color & 0xFF000000) >> 24;
4065 	c.green			= (color & 0x00FF0000) >> 16;
4066 	c.blue			= (color & 0x0000FF00) >> 8;
4067 	c.alpha			= (color & 0x000000FF);
4068 
4069 	return c;
4070 }
4071 
4072 //---------------------------------------------------------------------------
4073 
4074 inline uint32 _get_uint32_color( rgb_color c ){
4075 	uint32			color;
4076 	color			= (c.red << 24) +
4077 					  (c.green << 16) +
4078 					  (c.blue << 8) +
4079 					  c.alpha;
4080 	return color;
4081 }
4082 
4083 //---------------------------------------------------------------------------
4084 
4085 inline rgb_color _set_static_rgb_color( uint8 r, uint8 g, uint8 b, uint8 a ){
4086 	rgb_color		color;
4087 	color.red		= r;
4088 	color.green		= g;
4089 	color.blue		= b;
4090 	color.alpha		= a;
4091 
4092 	return color;
4093 }
4094 
4095 //---------------------------------------------------------------------------
4096 
4097 inline void _set_ptr_rgb_color( rgb_color* c, uint8 r, uint8 g,
4098 								uint8 b, uint8 a )
4099 {
4100 	c->red			= r;
4101 	c->green		= g;
4102 	c->blue			= b;
4103 	c->alpha		= a;
4104 }
4105 
4106 //---------------------------------------------------------------------------
4107 
4108 inline bool _rgb_color_are_equal( rgb_color c1, rgb_color c2 ){
4109 	return _get_uint32_color( c1 ) == _get_uint32_color( c2 );
4110 }
4111 
4112 //---------------------------------------------------------------------------
4113 
4114 inline bool _is_new_pattern( const pattern& p1, const pattern& p2 ){
4115 	if ( memcmp( &p1, &p2, sizeof(pattern) ) == 0 )
4116 		return false;
4117 	else
4118 		return true;
4119 }
4120 
4121 //---------------------------------------------------------------------------
4122 
4123 void BView::PrintToStream(){
4124 	printf("BView::PrintToStream()\n");
4125 	printf("\tName: %s
4126 \tParent: %s
4127 \tFirstChild: %s
4128 \tNextSibling: %s
4129 \tPrevSibling: %s
4130 \tOwner(Window): %s
4131 \tToken: %ld
4132 \tFlags: %ld
4133 \tView origin: (%f,%f)
4134 \tView Bounds rectangle: (%f,%f,%f,%f)
4135 \tShow level: %d
4136 \tTopView?: %s
4137 \tBPicture: %s
4138 \tVertical Scrollbar %s
4139 \tHorizontal Scrollbar %s
4140 \tIs Printing?: %s
4141 \tShelf?: %s
4142 \tEventMask: %ld
4143 \tEventOptions: %ld\n",
4144 	Name(),
4145 	parent? parent->Name() : "NULL",
4146 	first_child? first_child->Name() : "NULL",
4147 	next_sibling? next_sibling->Name() : "NULL",
4148 	prev_sibling? prev_sibling->Name() : "NULL",
4149 	owner? owner->Name() : "NULL",
4150 	_get_object_token_(this),
4151 	fFlags,
4152 	originX, originY,
4153 	fBounds.left, fBounds.top, fBounds.right, fBounds.bottom,
4154 	fShowLevel,
4155 	top_level_view? "YES" : "NO",
4156 	cpicture? "YES" : "NULL",
4157 	fVerScroller? "YES" : "NULL",
4158 	fHorScroller? "YES" : "NULL",
4159 	f_is_printing? "YES" : "NO",
4160 	fShelf? "YES" : "NO",
4161 	fEventMask,
4162 	fEventOptions);
4163 
4164 	printf("\tState status:
4165 \t\tLocalCoordianteSystem: (%f,%f)
4166 \t\tPenLocation: (%f,%f)
4167 \t\tPenSize: %f
4168 \t\tHighColor: [%d,%d,%d,%d]
4169 \t\tLowColor: [%d,%d,%d,%d]
4170 \t\tViewColor: [%d,%d,%d,%d]
4171 \t\tPattern: %llx
4172 \t\tDrawingMode: %d
4173 \t\tLineJoinMode: %d
4174 \t\tLineCapMode: %d
4175 \t\tMiterLimit: %f
4176 \t\tAlphaSource: %d
4177 \t\tAlphaFuntion: %d
4178 \t\tScale: %f
4179 \t\t(Print)FontAliasing: %s
4180 \t\tFont Info:\n",
4181 	fState->coordSysOrigin.x, fState->coordSysOrigin.y,
4182 	fState->penPosition.x, fState->penPosition.y,
4183 	fState->penSize,
4184 	fState->highColor.red, fState->highColor.blue, fState->highColor.green, fState->highColor.alpha,
4185 	fState->lowColor.red, fState->lowColor.blue, fState->lowColor.green, fState->lowColor.alpha,
4186 	fState->viewColor.red, fState->viewColor.blue, fState->viewColor.green, fState->viewColor.alpha,
4187 	*((uint64*)&(fState->patt)),
4188 	fState->drawingMode,
4189 	fState->lineJoin,
4190 	fState->lineCap,
4191 	fState->miterLimit,
4192 	fState->alphaSrcMode,
4193 	fState->alphaFncMode,
4194 	fState->scale,
4195 	fState->fontAliasing? "YES" : "NO");
4196 
4197 	fState->font.PrintToStream();
4198 // TODO: also print the line array.
4199 }
4200 
4201 //---------------------------------------------------------------------------
4202 
4203 void BView::PrintTree(){
4204 
4205 	int32		spaces = 2;
4206 	BView		*c = first_child; //c = short for: current
4207 	printf( "'%s'\n", Name() );
4208 	if( c != NULL )
4209 		while( true ){
4210 			// action block
4211 			{
4212 				for( int i = 0; i < spaces; i++)
4213 					printf(" ");
4214 
4215 				printf( "'%s'\n", c->Name() );
4216 			}
4217 
4218 				// go deep
4219 			if(	c->first_child ){
4220 				c = c->first_child;
4221 				spaces += 2;
4222 			}
4223 				// go right or up
4224 			else
4225 					// go right
4226 				if( c->next_sibling ){
4227 					c = c->next_sibling;
4228 				}
4229 					// go up
4230 				else{
4231 					while( !c->parent->next_sibling && c->parent != this ){
4232 						c = c->parent;
4233 						spaces -= 2;
4234 					}
4235 						// that enough! We've reached this view.
4236 					if( c->parent == this )
4237 						break;
4238 
4239 					c = c->parent->next_sibling;
4240 					spaces -= 2;
4241 				}
4242 		}
4243 }
4244 
4245 ViewAttr::ViewAttr(void)
4246 {
4247 	font=*be_plain_font;
4248 	fontFlags=font.Flags();
4249 
4250 	penPosition.Set(0,0);
4251 	penSize=1.0;
4252 
4253 	// This probably needs to be set to bounds by the owning BView
4254 	clippingRegion.MakeEmpty();
4255 
4256 	SetRGBColor(&highColor,0,0,0);
4257 	SetRGBColor(&lowColor,255,255,255);
4258 	SetRGBColor(&viewColor,255,255,255);
4259 
4260 	patt=B_SOLID_HIGH;
4261 	drawingMode=B_OP_COPY;
4262 
4263 	coordSysOrigin.Set(0,0);
4264 
4265 	lineJoin=B_BUTT_JOIN;
4266 	lineCap=B_BUTT_CAP;
4267 	miterLimit=B_DEFAULT_MITER_LIMIT;
4268 
4269 	alphaSrcMode=B_CONSTANT_ALPHA;
4270 	alphaFncMode=B_ALPHA_OVERLAY;
4271 
4272 	scale=1.0;
4273 	fontAliasing=false;
4274 
4275 	// flags used for synchronization with app_server
4276 	// TODO: set this to the default value, whatever that is
4277 	flags=B_VIEW_CLIP_REGION_BIT;
4278 
4279 	// TODO: find out what value this should have.
4280 	archivingFlags=B_VIEW_COORD_BIT;
4281 }
4282 
4283 //---------------------------------------------------------------------------
4284 
4285 /* TODOs
4286  * 		-implement SetDiskMode() what's with this method? what does it do? test!
4287  * 			does it has something to do with DrawPictureAsync( filename* .. )?
4288  *		-implement DrawAfterChildren()
4289  */
4290 /*
4291  @log:
4292 
4293 	* some changes in ConvertXXXYYYY(...) methods.
4294 */
4295