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