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