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 32using 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 44static fill_rectangle sFillRectHook; 45static screen_to_screen_blit sBlitRectHook; 46static screen_to_screen_transparent_blit sTransparentBlitHook; 47static screen_to_screen_scaled_filtered_blit sScaledFilteredBlitHook; 48static wait_engine_idle sWaitIdleHook; 49static acquire_engine sAcquireEngineHook; 50static release_engine sReleaseEngineHook; 51 52static engine_token *sEngineToken; 53 54 55// Helper methods which translates the pre r5 graphics methods to r5 ones 56static int32 57card_sync() 58{ 59 sWaitIdleHook(); 60 return 0; 61} 62 63 64static int32 65blit(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 85static int32 86transparent_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 105static int32 106scaled_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 126static int32 127draw_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 142static int32 143draw_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 158static int32 159draw_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 177void 178set_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 191BWindowScreen::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 210BWindowScreen::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 225BWindowScreen::~BWindowScreen() 226{ 227 CALLED(); 228 _DisposeData(); 229} 230 231 232void 233BWindowScreen::Quit(void) 234{ 235 CALLED(); 236 Disconnect(); 237 BWindow::Quit(); 238} 239 240 241void 242BWindowScreen::ScreenConnected(bool active) 243{ 244 // Implemented in subclasses 245} 246 247 248void 249BWindowScreen::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 262void 263BWindowScreen::WindowActivated(bool active) 264{ 265 CALLED(); 266 fWindowState = active; 267 if (active && fLockState == 0 && fWorkState) 268 _Activate(); 269} 270 271 272void 273BWindowScreen::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 291void 292BWindowScreen::ScreenChanged(BRect screenFrame, color_space depth) 293{ 294 // Implemented in subclasses 295} 296 297 298void 299BWindowScreen::Hide() 300{ 301 CALLED(); 302 303 Disconnect(); 304 BWindow::Hide(); 305} 306 307 308void 309BWindowScreen::Show() 310{ 311 CALLED(); 312 313 BWindow::Show(); 314} 315 316 317void 318BWindowScreen::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 366status_t 367BWindowScreen::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 380bool 381BWindowScreen::CanControlFrameBuffer() 382{ 383 return (fCardInfo.flags & B_FRAME_BUFFER_CONTROL) != 0; 384} 385 386 387status_t 388BWindowScreen::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 409status_t 410BWindowScreen::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 427void * 428BWindowScreen::IOBase() 429{ 430 // Not supported 431 return NULL; 432} 433#endif 434 435 436rgb_color * 437BWindowScreen::ColorList() 438{ 439 CALLED(); 440 return fPalette; 441} 442 443 444frame_buffer_info * 445BWindowScreen::FrameBufferInfo() 446{ 447 CALLED(); 448 return &fFrameBufferInfo; 449} 450 451 452graphics_card_hook 453BWindowScreen::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 494graphics_card_info * 495BWindowScreen::CardInfo() 496{ 497 CALLED(); 498 return &fCardInfo; 499} 500 501 502void 503BWindowScreen::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 526void 527BWindowScreen::SuspensionHook(bool active) 528{ 529 // Implemented in subclasses 530} 531 532 533void 534BWindowScreen::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 555status_t 556BWindowScreen::Perform(perform_code d, void* arg) 557{ 558 return inherited::Perform(d, arg); 559} 560 561 562// Reserved for future binary compatibility 563void BWindowScreen::_ReservedWindowScreen1() {} 564void BWindowScreen::_ReservedWindowScreen2() {} 565void BWindowScreen::_ReservedWindowScreen3() {} 566void BWindowScreen::_ReservedWindowScreen4() {} 567 568 569status_t 570BWindowScreen::_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 641void 642BWindowScreen::_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 669status_t 670BWindowScreen::_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 689status_t 690BWindowScreen::_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 722status_t 723BWindowScreen::_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 751status_t 752BWindowScreen::_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 788void 789BWindowScreen::_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 810status_t 811BWindowScreen::_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 875void 876BWindowScreen::_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 903void 904BWindowScreen::_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 924status_t 925BWindowScreen::_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 947status_t 948BWindowScreen::_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 1013status_t 1014BWindowScreen::_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