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