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