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