1 /* 2 * Copyright 2002-2005, 3 * Marcus Overhagen, 4 * Stefano Ceccherini (burton666@libero.it), 5 * Carwyn Jones (turok2@currantbun.com) 6 * All rights reserved. 7 * Distributed under the terms of the MIT License. 8 */ 9 10 11 #include <Application.h> 12 #include <Screen.h> 13 #include <String.h> 14 #include <WindowScreen.h> 15 16 #include <stdlib.h> 17 #include <stdio.h> 18 #include <string.h> 19 20 #include <input_globals.h> 21 #include <InputServerTypes.h> // For IS_SET_MOUSE_POSITION 22 #include <WindowPrivate.h> 23 24 #include <AppServerLink.h> 25 #include <ServerProtocol.h> 26 27 using BPrivate::AppServerLink; 28 29 30 #define TRACE_WINDOWSCREEN 1 31 #if TRACE_WINDOWSCREEN 32 #define CALLED() printf("%s\n", __PRETTY_FUNCTION__); 33 #else 34 #define CALLED() ; 35 #endif 36 37 38 // Acceleration hooks pointers 39 static fill_rectangle sFillRectHook; 40 static screen_to_screen_blit sBlitRectHook; 41 static screen_to_screen_transparent_blit sTransparentBlitHook; 42 static screen_to_screen_scaled_filtered_blit sScaledFilteredBlitHook; 43 static wait_engine_idle sWaitIdleHook; 44 static acquire_engine sAcquireEngineHook; 45 static release_engine sReleaseEngineHook; 46 47 static engine_token *sEngineToken; 48 49 50 // Helper methods which translates the pre r5 graphics methods to r5 ones 51 static int32 52 card_sync() 53 { 54 sWaitIdleHook(); 55 return 0; 56 } 57 58 59 static int32 60 blit(int32 sx, int32 sy, int32 dx, int32 dy, int32 width, int32 height) 61 { 62 blit_params param; 63 param.src_left = sx; 64 param.src_top = sy; 65 param.dest_left = dx; 66 param.dest_top = dy; 67 param.width = width; 68 param.height = height; 69 70 sAcquireEngineHook(B_2D_ACCELERATION, 0xff, NULL, &sEngineToken); 71 sBlitRectHook(sEngineToken, ¶m, 1); 72 sReleaseEngineHook(sEngineToken, NULL); 73 return 0; 74 } 75 76 // TODO: This function seems not to be exported through CardHookAt(). 77 // At least, nothing I've tried uses it. 78 /* 79 static int32 80 transparent_blit(int32 sx, int32 sy, int32 dx, int32 dy, 81 int32 width, int32 height, uint32 transparent_color) 82 { 83 blit_params param; 84 param.src_left = sx; 85 param.src_top = sy; 86 param.dest_left = dx; 87 param.dest_top = dy; 88 param.width = width; 89 param.height = height; 90 91 sAcquireEngineHook(B_2D_ACCELERATION, 0xff, 0, &sEngineToken); 92 sTransparentBlitHook(sEngineToken, transparent_color, ¶m, 1); 93 sReleaseEngineHook(sEngineToken, 0); 94 return 0; 95 } 96 */ 97 98 static int32 99 scaled_filtered_blit(int32 sx, int32 sy, int32 sw, int32 sh, int32 dx, int32 dy, int32 dw, int32 dh) 100 { 101 scaled_blit_params param; 102 param.src_left = sx; 103 param.src_top = sy; 104 param.src_width = sw; 105 param.src_height = sh; 106 param.dest_left = dx; 107 param.dest_top = dy; 108 param.dest_width = dw; 109 param.dest_height = dh; 110 111 sAcquireEngineHook(B_2D_ACCELERATION, 0xff, NULL, &sEngineToken); 112 sScaledFilteredBlitHook(sEngineToken, ¶m, 1); 113 sReleaseEngineHook(sEngineToken, NULL); 114 return 0; 115 } 116 117 118 static int32 119 draw_rect_8(int32 sx, int32 sy, int32 sw, int32 sh, uint8 color_index) 120 { 121 fill_rect_params param; 122 param.left = sx; 123 param.top = sy; 124 param.right = sw; 125 param.bottom = sh; 126 127 sAcquireEngineHook(B_2D_ACCELERATION, 0xff, NULL, &sEngineToken); 128 sFillRectHook(sEngineToken, color_index, ¶m, 1); 129 sReleaseEngineHook(sEngineToken, NULL); 130 return 0; 131 } 132 133 134 static int32 135 draw_rect_16(int32 sx, int32 sy, int32 sw, int32 sh, uint16 color) 136 { 137 fill_rect_params param; 138 param.left = sx; 139 param.top = sy; 140 param.right = sw; 141 param.bottom = sh; 142 143 sAcquireEngineHook(B_2D_ACCELERATION, 0xff, NULL, &sEngineToken); 144 sFillRectHook(sEngineToken, color, ¶m, 1); 145 sReleaseEngineHook(sEngineToken, NULL); 146 return 0; 147 } 148 149 150 static int32 151 draw_rect_32(int32 sx, int32 sy, int32 sw, int32 sh, uint32 color) 152 { 153 fill_rect_params param; 154 param.left = sx; 155 param.top = sy; 156 param.right = sw; 157 param.bottom = sh; 158 159 sAcquireEngineHook(B_2D_ACCELERATION, 0xff, NULL, &sEngineToken); 160 sFillRectHook(sEngineToken, color, ¶m, 1); 161 sReleaseEngineHook(sEngineToken, NULL); 162 return 0; 163 } 164 165 166 static void 167 mode2parms(uint32 space, uint32 *out_space, int32 *width, int32 *height) 168 { 169 switch (space) { 170 case B_8_BIT_640x480: 171 *out_space = B_CMAP8; 172 *width = 640; *height = 480; 173 break; 174 case B_8_BIT_800x600: 175 *out_space = B_CMAP8; 176 *width = 800; *height = 600; 177 break; 178 case B_8_BIT_1024x768: 179 *out_space = B_CMAP8; 180 *width = 1024; *height = 768; 181 break; 182 case B_8_BIT_1280x1024: 183 *out_space = B_CMAP8; 184 *width = 1280; *height = 1024; 185 break; 186 case B_8_BIT_1600x1200: 187 *out_space = B_CMAP8; 188 *width = 1600; *height = 1200; 189 break; 190 case B_16_BIT_640x480: 191 *out_space = B_RGB16; 192 *width = 640; *height = 480; 193 break; 194 case B_16_BIT_800x600: 195 *out_space = B_RGB16; 196 *width = 800; *height = 600; 197 break; 198 case B_16_BIT_1024x768: 199 *out_space = B_RGB16; 200 *width = 1024; *height = 768; 201 break; 202 case B_16_BIT_1280x1024: 203 *out_space = B_RGB16; 204 *width = 1280; *height = 1024; 205 break; 206 case B_16_BIT_1600x1200: 207 *out_space = B_RGB16; 208 *width = 1600; *height = 1200; 209 break; 210 case B_32_BIT_640x480: 211 *out_space = B_RGB32; 212 *width = 640; *height = 480; 213 break; 214 case B_32_BIT_800x600: 215 *out_space = B_RGB32; 216 *width = 800; *height = 600; 217 break; 218 case B_32_BIT_1024x768: 219 *out_space = B_RGB32; 220 *width = 1024; *height = 768; 221 break; 222 case B_32_BIT_1280x1024: 223 *out_space = B_RGB32; 224 *width = 1280; *height = 1024; 225 break; 226 case B_32_BIT_1600x1200: 227 *out_space = B_RGB32; 228 *width = 1600; *height = 1200; 229 break; 230 case B_8_BIT_1152x900: 231 *out_space = B_CMAP8; 232 *width = 1152; *height = 900; 233 break; 234 case B_16_BIT_1152x900: 235 *out_space = B_RGB16; 236 *width = 1152; *height = 900; 237 break; 238 case B_32_BIT_1152x900: 239 *out_space = B_RGB32; 240 *width = 1152; *height = 900; 241 break; 242 case B_15_BIT_640x480: 243 *out_space = B_RGB15; 244 *width = 640; *height = 480; 245 break; 246 case B_15_BIT_800x600: 247 *out_space = B_RGB15; 248 *width = 800; *height = 600; 249 break; 250 case B_15_BIT_1024x768: 251 *out_space = B_RGB15; 252 *width = 1024; *height = 768; 253 break; 254 case B_15_BIT_1280x1024: 255 *out_space = B_RGB15; 256 *width = 1280; *height = 1024; 257 break; 258 case B_15_BIT_1600x1200: 259 *out_space = B_RGB15; 260 *width = 1600; *height = 1200; 261 break; 262 case B_15_BIT_1152x900: 263 *out_space = B_RGB15; 264 *width = 1152; *height = 900; 265 break; 266 } 267 } 268 269 270 // #pragma mark - public API calls 271 272 273 void 274 set_mouse_position(int32 x, int32 y) 275 { 276 BMessage command(IS_SET_MOUSE_POSITION); 277 BMessage reply; 278 279 command.AddPoint("where", BPoint(x, y)); 280 _control_input_server_(&command, &reply); 281 } 282 283 284 // #pragma mark - 285 286 287 BWindowScreen::BWindowScreen(const char *title, uint32 space, 288 status_t *error, bool debug_enable) 289 : BWindow(BScreen().Frame().InsetByCopy(200, 200), title, B_TITLED_WINDOW, 290 kWindowScreenFlag | B_NOT_MINIMIZABLE | B_NOT_CLOSABLE 291 | B_NOT_ZOOMABLE | B_NOT_MOVABLE | B_NOT_RESIZABLE, B_CURRENT_WORKSPACE) 292 { 293 CALLED(); 294 uint32 attributes = 0; 295 if (debug_enable) 296 attributes |= B_ENABLE_DEBUGGER; 297 298 status_t status = InitData(space, attributes); 299 if (error) 300 *error = status; 301 } 302 303 304 BWindowScreen::BWindowScreen(const char *title, uint32 space, 305 uint32 attributes, status_t *error) 306 : BWindow(BScreen().Frame().InsetByCopy(200, 200), title, B_TITLED_WINDOW, 307 kWindowScreenFlag | B_NOT_MINIMIZABLE | B_NOT_CLOSABLE 308 | B_NOT_ZOOMABLE | B_NOT_MOVABLE | B_NOT_RESIZABLE, B_CURRENT_WORKSPACE) 309 { 310 CALLED(); 311 status_t status = InitData(space, attributes); 312 if (error) 313 *error = status; 314 } 315 316 317 BWindowScreen::~BWindowScreen() 318 { 319 CALLED(); 320 Disconnect(); 321 if (fAddonImage >= 0) 322 unload_add_on(fAddonImage); 323 324 delete_sem(fActivateSem); 325 delete_sem(fDebugSem); 326 327 if (fDebugState) 328 activate_workspace(fDebugWorkspace); 329 330 free(fDisplayMode); 331 free(fOldDisplayMode); 332 free(fModeList); 333 } 334 335 336 void 337 BWindowScreen::Quit(void) 338 { 339 CALLED(); 340 Disconnect(); 341 BWindow::Quit(); 342 } 343 344 345 void 346 BWindowScreen::ScreenConnected(bool active) 347 { 348 // Implemented in subclasses 349 } 350 351 352 void 353 BWindowScreen::Disconnect() 354 { 355 CALLED(); 356 if (fLockState == 1) { 357 if (fDebugState) 358 fDebugFirst = true; 359 SetActiveState(0); 360 } 361 } 362 363 364 void 365 BWindowScreen::WindowActivated(bool active) 366 { 367 CALLED(); 368 fWindowState = active; 369 if(active && fLockState == 0 && fWorkState) 370 SetActiveState(1); 371 } 372 373 374 void 375 BWindowScreen::WorkspaceActivated(int32 ws, bool state) 376 { 377 CALLED(); 378 fWorkState = state; 379 if (state) { 380 if (fLockState == 0 && fWindowState) { 381 SetActiveState(1); 382 if (!IsHidden()) { 383 Activate(true); 384 WindowActivated(true); 385 } 386 } 387 } else if (fLockState) 388 SetActiveState(0); 389 } 390 391 392 void 393 BWindowScreen::ScreenChanged(BRect screen_size, color_space depth) 394 { 395 // Implemented in subclasses 396 } 397 398 399 void 400 BWindowScreen::Hide() 401 { 402 CALLED(); 403 Disconnect(); 404 BWindow::Hide(); 405 } 406 407 408 void 409 BWindowScreen::Show() 410 { 411 CALLED(); 412 BWindow::Show(); 413 if (!fActivateState) { 414 release_sem(fActivateSem); 415 fActivateState = true; 416 } 417 } 418 419 420 void 421 BWindowScreen::SetColorList(rgb_color *list, int32 first_index, int32 last_index) 422 { 423 CALLED(); 424 if (first_index < 0 || last_index > 255 || first_index > last_index) 425 return; 426 427 if (Lock()) { 428 if (!fActivateState) { 429 //If we aren't active, we just change our local palette 430 for (int32 x = first_index; x <= last_index; x++) 431 fColorList[x] = list[x]; 432 } else { 433 uint32 colorCount = last_index - first_index + 1; 434 if (fAddonImage >= 0) { 435 set_indexed_colors sic = (set_indexed_colors)fGetAccelerantHook(B_SET_INDEXED_COLORS, NULL); 436 if (sic != NULL) 437 sic(colorCount, first_index, (uint8 *)fColorList, 0); 438 } 439 440 BScreen screen(this); 441 screen.WaitForRetrace(); 442 // Update our local palette too. We're doing this between two 443 // WaitForRetrace() calls so nobody will notice. 444 for (int32 x = first_index; x <= last_index; x++) 445 fColorList[x] = list[x]; 446 447 // TODO: Tell the app_server about our changes 448 449 screen.WaitForRetrace(); 450 } 451 452 Unlock(); 453 } 454 } 455 456 457 status_t 458 BWindowScreen::SetSpace(uint32 space) 459 { 460 CALLED(); 461 display_mode mode; 462 status_t status = GetModeFromSpace(space, &mode); 463 if (status == B_OK) 464 status = AssertDisplayMode(&mode); 465 return status; 466 } 467 468 469 bool 470 BWindowScreen::CanControlFrameBuffer() 471 { 472 return (fAddonImage >= 0 && (fCardInfo.flags & B_FRAME_BUFFER_CONTROL)); 473 } 474 475 476 status_t 477 BWindowScreen::SetFrameBuffer(int32 width, int32 height) 478 { 479 CALLED(); 480 display_mode highMode = *fDisplayMode; 481 highMode.flags |= B_SCROLL; 482 483 highMode.virtual_height = (int16)height; 484 highMode.virtual_width = (int16)width; 485 486 display_mode lowMode = highMode; 487 display_mode mode = highMode; 488 489 BScreen screen(this); 490 status_t status = screen.ProposeMode(&mode, &lowMode, &highMode); 491 if (status == B_OK) 492 status = AssertDisplayMode(&mode); 493 494 return status; 495 } 496 497 498 status_t 499 BWindowScreen::MoveDisplayArea(int32 x, int32 y) 500 { 501 CALLED(); 502 move_display_area moveDisplayArea = (move_display_area)fGetAccelerantHook(B_MOVE_DISPLAY, NULL); 503 if (moveDisplayArea && moveDisplayArea((int16)x, (int16)y) == B_OK) { 504 fFrameBufferInfo.display_x = x; 505 fFrameBufferInfo.display_y = y; 506 fDisplayMode->h_display_start = x; 507 fDisplayMode->v_display_start = y; 508 return B_OK; 509 } 510 return B_ERROR; 511 } 512 513 514 void * 515 BWindowScreen::IOBase() 516 { 517 // Not supported 518 return NULL; 519 } 520 521 522 rgb_color * 523 BWindowScreen::ColorList() 524 { 525 CALLED(); 526 return fColorList; 527 } 528 529 530 frame_buffer_info * 531 BWindowScreen::FrameBufferInfo() 532 { 533 CALLED(); 534 return &fFrameBufferInfo; 535 } 536 537 538 graphics_card_hook 539 BWindowScreen::CardHookAt(int32 index) 540 { 541 CALLED(); 542 if (fAddonImage < 0) 543 return NULL; 544 545 graphics_card_hook hook = NULL; 546 547 switch (index) { 548 case 5: // 8 bit fill rect 549 hook = (graphics_card_hook)draw_rect_8; 550 break; 551 case 6: // 32 bit fill rect 552 hook = (graphics_card_hook)draw_rect_32; 553 break; 554 case 7: // screen to screen blit 555 hook = (graphics_card_hook)blit; 556 break; 557 case 8: // screen to screen scaled filtered blit 558 hook = (graphics_card_hook)scaled_filtered_blit; 559 break; 560 case 10: // sync aka wait for graphics card idle 561 hook = (graphics_card_hook)card_sync; 562 break; 563 case 13: // 16 bit fill rect 564 hook = (graphics_card_hook)draw_rect_16; 565 break; 566 default: 567 break; 568 } 569 570 return hook; 571 } 572 573 574 graphics_card_info * 575 BWindowScreen::CardInfo() 576 { 577 CALLED(); 578 return &fCardInfo; 579 } 580 581 582 void 583 BWindowScreen::RegisterThread(thread_id id) 584 { 585 CALLED(); 586 while (acquire_sem(fDebugSem) == B_INTERRUPTED) 587 ; 588 void *newDebugList = realloc(fDebugList, (fDebugListCount + 1) * sizeof(thread_id)); 589 if (newDebugList != NULL) { 590 fDebugList = (thread_id *)newDebugList; 591 fDebugList[fDebugListCount] = id; 592 fDebugListCount++; 593 } 594 release_sem(fDebugSem); 595 } 596 597 598 void 599 BWindowScreen::SuspensionHook(bool active) 600 { 601 // Implemented in subclasses 602 } 603 604 605 void 606 BWindowScreen::Suspend(char *label) 607 { 608 CALLED(); 609 if (fDebugState) { 610 fprintf(stderr, "## Debugger(\"%s\").", label); 611 fprintf(stderr, " Press Alt-F%ld or Cmd-F%ld to resume.\n", space0 + 1, space0 + 1); 612 613 if (IsLocked()) 614 Unlock(); 615 616 activate_workspace(fDebugWorkspace); 617 618 // Suspend ourself 619 suspend_thread(find_thread(NULL)); 620 621 Lock(); 622 } 623 } 624 625 626 status_t 627 BWindowScreen::Perform(perform_code d, void *arg) 628 { 629 return inherited::Perform(d, arg); 630 } 631 632 633 // Reserved for future binary compatibility 634 void BWindowScreen::_ReservedWindowScreen1() {} 635 void BWindowScreen::_ReservedWindowScreen2() {} 636 void BWindowScreen::_ReservedWindowScreen3() {} 637 void BWindowScreen::_ReservedWindowScreen4() {} 638 639 640 /* unimplemented for protection of the user: 641 * 642 * BWindowScreen::BWindowScreen() 643 * BWindowScreen::BWindowScreen(BWindowScreen &) 644 * BWindowScreen &BWindowScreen::operator=(BWindowScreen &) 645 */ 646 647 648 BRect 649 BWindowScreen::CalcFrame(int32 index, int32 space, display_mode *dmode) 650 { 651 CALLED(); 652 BScreen screen; 653 if (dmode) 654 screen.GetMode(dmode); 655 656 return screen.Frame(); 657 } 658 659 660 status_t 661 BWindowScreen::InitData(uint32 space, uint32 attributes) 662 { 663 CALLED(); 664 665 fDebugState = attributes & B_ENABLE_DEBUGGER; 666 fDebugListCount = 0; 667 fDebugList = NULL; 668 fDebugFirst = true; 669 670 fAttributes = attributes; 671 fScreenIndex = fDebugWorkspace = current_workspace(); 672 fLockState = 0; 673 fAddonImage = -1; 674 fWindowState = 0; 675 676 BScreen screen(this); 677 status_t status = screen.GetModeList(&fModeList, &fModeCount); 678 if (status < B_OK) 679 return status; 680 681 display_mode newMode; 682 status = GetModeFromSpace(space, &newMode); 683 if (status < B_OK) 684 return status; 685 686 space_mode = 1; 687 space0 = 0; 688 689 memcpy(fColorList, screen.ColorMap()->color_list, 256); 690 691 status = GetCardInfo(); 692 if (status < B_OK) 693 return status; 694 695 fActivateSem = create_sem(0, "WindowScreen start lock"); 696 fActivateState = 0; 697 698 fDebugSem = create_sem(1, "WindowScreen debug sem"); 699 fOldDisplayMode = (display_mode *)calloc(1, sizeof(display_mode)); 700 fDisplayMode = (display_mode *)calloc(1, sizeof(display_mode)); 701 memcpy(fDisplayMode, &newMode, sizeof(display_mode)); 702 703 fWorkState = 1; 704 705 return B_OK; 706 } 707 708 709 status_t 710 BWindowScreen::SetActiveState(int32 state) 711 { 712 CALLED(); 713 status_t status = B_ERROR; 714 if (state == 1) { 715 //be_app->HideCursor(); 716 status = AssertDisplayMode(fDisplayMode); 717 if (status == B_OK && (status = SetupAccelerantHooks(true)) == B_OK) { 718 if (!fActivateState) { 719 while (acquire_sem(fActivateSem) == B_INTERRUPTED) 720 ; 721 } 722 723 SetColorList(fColorList); 724 if (fDebugState && !fDebugFirst) { 725 SuspensionHook(true); 726 Resume(); 727 } else { 728 fDebugFirst = true; 729 ScreenConnected(true); 730 } 731 732 if (status == B_OK) 733 return status; 734 735 } else 736 SetupAccelerantHooks(false); 737 738 be_app->ShowCursor(); 739 } else { 740 AssertDisplayMode(fOldDisplayMode); 741 if (fDebugState && !fDebugFirst) { 742 Suspend(); 743 SuspensionHook(false); 744 } else 745 ScreenConnected(false); 746 747 status = SetupAccelerantHooks(false); 748 if (status == B_OK) { 749 be_app->ShowCursor(); 750 if (fActivateState) { 751 // TODO: Set palette 752 } 753 } 754 } 755 756 return status; 757 } 758 759 760 status_t 761 BWindowScreen::SetupAccelerantHooks(bool enable) 762 { 763 CALLED(); 764 if (fAddonImage >= 0) { 765 m_wei(); 766 sFillRectHook = NULL; 767 sBlitRectHook = NULL; 768 sTransparentBlitHook = NULL; 769 sScaledFilteredBlitHook = NULL; 770 sWaitIdleHook = NULL; 771 sEngineToken = NULL; 772 sAcquireEngineHook = NULL; 773 sReleaseEngineHook = NULL; 774 } 775 776 if (enable) 777 fLockState = 1; 778 else 779 fLockState = 0; 780 781 status_t status = B_OK; 782 if (enable) { 783 if (fAddonImage < 0) { 784 status = InitClone(); 785 if (status == B_OK) { 786 m_wei = (wait_engine_idle)fGetAccelerantHook(B_WAIT_ENGINE_IDLE, NULL); 787 m_re = (release_engine)fGetAccelerantHook(B_RELEASE_ENGINE, NULL); 788 m_ae = (acquire_engine)fGetAccelerantHook(B_ACQUIRE_ENGINE, NULL); 789 fill_rect = (fill_rectangle)fGetAccelerantHook(B_FILL_RECTANGLE, NULL); 790 blit_rect = (screen_to_screen_blit)fGetAccelerantHook(B_SCREEN_TO_SCREEN_BLIT, NULL); 791 trans_blit_rect = (screen_to_screen_transparent_blit)fGetAccelerantHook(B_SCREEN_TO_SCREEN_TRANSPARENT_BLIT, NULL); 792 scaled_filtered_blit_rect = (screen_to_screen_scaled_filtered_blit)fGetAccelerantHook(B_SCREEN_TO_SCREEN_SCALED_FILTERED_BLIT, NULL); 793 } 794 } 795 796 if (status == B_OK) { 797 sFillRectHook = fill_rect; 798 sBlitRectHook = blit_rect; 799 sTransparentBlitHook = trans_blit_rect; 800 sScaledFilteredBlitHook = scaled_filtered_blit_rect; 801 sWaitIdleHook = m_wei; 802 sAcquireEngineHook = m_ae; 803 sReleaseEngineHook = m_re; 804 m_wei(); 805 } 806 } 807 808 return status; 809 } 810 811 812 status_t 813 BWindowScreen::GetCardInfo() 814 { 815 CALLED(); 816 817 BScreen screen(this); 818 display_mode mode; 819 status_t status = screen.GetMode(&mode); 820 if (status < B_OK) 821 return status; 822 823 uint32 bitsPerPixel; 824 switch(mode.space & 0x0fff) { 825 case B_CMAP8: 826 bitsPerPixel = 8; 827 break; 828 case B_RGB16: 829 bitsPerPixel = 16; 830 break; 831 case B_RGB32: 832 bitsPerPixel = 32; 833 break; 834 default: 835 bitsPerPixel = 0; 836 break; 837 } 838 839 fCardInfo.version = 2; 840 fCardInfo.id = screen.ID().id; 841 fCardInfo.bits_per_pixel = bitsPerPixel; 842 fCardInfo.width = mode.virtual_width; 843 fCardInfo.height = mode.virtual_height; 844 845 if (mode.space & 0x10) 846 strncpy(fCardInfo.rgba_order, "rgba", 4); 847 else 848 strncpy(fCardInfo.rgba_order, "bgra", 4); 849 850 fCardInfo.flags = 0; 851 if (mode.flags & B_SCROLL) 852 fCardInfo.flags |= B_FRAME_BUFFER_CONTROL; 853 if (mode.flags & B_PARALLEL_ACCESS) 854 fCardInfo.flags |= B_PARALLEL_BUFFER_ACCESS; 855 856 AppServerLink link; 857 link.StartMessage(AS_GET_FRAME_BUFFER_CONFIG); 858 link.Attach<screen_id>(screen.ID()); 859 860 status_t result = B_ERROR; 861 if (link.FlushWithReply(result) < B_OK || result < B_OK) 862 return result; 863 864 frame_buffer_config config; 865 link.Read<frame_buffer_config>(&config); 866 867 fCardInfo.frame_buffer = config.frame_buffer; 868 fCardInfo.bytes_per_row = config.bytes_per_row; 869 870 return B_OK; 871 } 872 873 874 void 875 BWindowScreen::Suspend() 876 { 877 CALLED(); 878 879 while (acquire_sem(fDebugSem) == B_INTERRUPTED) 880 ; 881 882 // Suspend all the registered threads 883 for (int32 i = 0; i < fDebugListCount; i++) { 884 snooze(10000); 885 suspend_thread(fDebugList[i]); 886 } 887 888 graphics_card_info *info = CardInfo(); 889 size_t fbSize = info->bytes_per_row * info->height; 890 891 // Save the content of the frame buffer into the local buffer 892 fDebugBuffer = (char *)malloc(fbSize); 893 memcpy(fDebugBuffer, info->frame_buffer, fbSize); 894 } 895 896 897 void 898 BWindowScreen::Resume() 899 { 900 CALLED(); 901 graphics_card_info *info = CardInfo(); 902 903 // Copy the content of the debug_buffer back into the frame buffer. 904 memcpy(info->frame_buffer, fDebugBuffer, info->bytes_per_row * info->height); 905 free(fDebugBuffer); 906 907 // Resume all the registered threads 908 for (int32 i = 0; i < fDebugListCount; i++) 909 resume_thread(fDebugList[i]); 910 911 release_sem(fDebugSem); 912 } 913 914 915 status_t 916 BWindowScreen::GetModeFromSpace(uint32 space, display_mode *dmode) 917 { 918 CALLED(); 919 920 uint32 destSpace; 921 int32 width, height; 922 status_t status = B_ERROR; 923 924 mode2parms(space, &destSpace, &width, &height); 925 // mode2parms converts the space to actual width, height and color_space, e.g B_8_BIT_640x480 926 927 for (uint32 i = 0; i < fModeCount; i++) { 928 if (fModeList[i].space == destSpace && fModeList[i].virtual_width == width 929 && fModeList[i].virtual_height == height) { 930 931 memcpy(dmode, &fModeList[i], sizeof(display_mode)); 932 status = B_OK; 933 break; 934 } 935 } 936 937 return status; 938 } 939 940 941 status_t 942 BWindowScreen::InitClone() 943 { 944 CALLED(); 945 946 if (fAddonImage >= 0) 947 return B_OK; 948 949 AppServerLink link; 950 link.StartMessage(AS_GET_ACCELERANT_PATH); 951 link.Attach<int32>(fScreenIndex); 952 953 status_t status = B_ERROR; 954 if (link.FlushWithReply(status) < B_OK || status < B_OK) 955 return status; 956 957 BString accelerantPath; 958 link.ReadString(accelerantPath); 959 fAddonImage = load_add_on(accelerantPath.String()); 960 if (fAddonImage < B_OK) { 961 printf("InitClone: cannot load accelerant image\n"); 962 return fAddonImage; 963 } 964 965 status = get_image_symbol(fAddonImage, B_ACCELERANT_ENTRY_POINT, 966 B_SYMBOL_TYPE_TEXT, (void **)&fGetAccelerantHook); 967 if (status < B_OK) { 968 printf("InitClone: cannot get accelerant entry point\n"); 969 unload_add_on(fAddonImage); 970 fAddonImage = -1; 971 return status; 972 } 973 974 status = B_ERROR; 975 clone_accelerant clone = (clone_accelerant)fGetAccelerantHook(B_CLONE_ACCELERANT, 0); 976 if (clone == NULL) { 977 printf("InitClone: cannot get clone hook\n"); 978 unload_add_on(fAddonImage); 979 fAddonImage = -1; 980 return status; 981 } 982 983 link.StartMessage(AS_GET_DRIVER_PATH); 984 link.Attach<int32>(fScreenIndex); 985 if (link.FlushWithReply(status) == B_OK && status == B_OK) { 986 BString driverPath; 987 link.ReadString(driverPath); 988 status = clone((void *)driverPath.String()); 989 } 990 991 if (status < B_OK) { 992 printf("InitClone: cannot clone accelerant\n"); 993 unload_add_on(fAddonImage); 994 fAddonImage = -1; 995 } 996 997 return status; 998 } 999 1000 1001 status_t 1002 BWindowScreen::AssertDisplayMode(display_mode *dmode) 1003 { 1004 CALLED(); 1005 1006 status_t status = B_ERROR; 1007 BScreen screen(this); 1008 display_mode mode; 1009 status = screen.GetMode(&mode); 1010 if (status < B_OK) 1011 return status; 1012 if (mode.virtual_height != dmode->virtual_height || mode.virtual_width != dmode->virtual_width 1013 || mode.space != dmode->space || mode.flags != dmode->flags) { 1014 status = screen.SetMode(dmode); 1015 if (status < B_OK) { 1016 printf("AssertDisplayMode: Setting mode failed: %s\n", strerror(status)); 1017 return status; 1018 } 1019 memcpy(fDisplayMode, dmode, sizeof(display_mode)); 1020 space_mode = 1; 1021 } 1022 1023 status = GetCardInfo(); 1024 if (status < B_OK) 1025 return status; 1026 1027 fFrameBufferInfo.bits_per_pixel = fCardInfo.bits_per_pixel; 1028 fFrameBufferInfo.bytes_per_row = fCardInfo.bytes_per_row; 1029 fFrameBufferInfo.width = fCardInfo.width; 1030 fFrameBufferInfo.height = fCardInfo.height; 1031 fFrameBufferInfo.display_width = fCardInfo.width; 1032 fFrameBufferInfo.display_height = fCardInfo.height; 1033 fFrameBufferInfo.display_x = 0; 1034 fFrameBufferInfo.display_y = 0; 1035 1036 return status; 1037 } 1038