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