| | 503 | |
|---|
| | 504 | /** helper method to get a value out of a CFDictionary */ |
|---|
| | 505 | static double getDictDouble (CFDictionaryRef refDict, CFStringRef key) |
|---|
| | 506 | { |
|---|
| | 507 | double double_value; |
|---|
| | 508 | CFNumberRef number_value = (CFNumberRef) CFDictionaryGetValue(refDict, key); |
|---|
| | 509 | if (!number_value) // if can't get a number for the dictionary |
|---|
| | 510 | return -1; // fail |
|---|
| | 511 | if (!CFNumberGetValue(number_value, kCFNumberDoubleType, &double_value)) // or if cant convert it |
|---|
| | 512 | return -1; // fail |
|---|
| | 513 | return double_value; // otherwise return the long value |
|---|
| | 514 | } |
|---|
| | 515 | |
|---|
| | 516 | |
|---|
| | 517 | /** implementation of setScreenResolution */ |
|---|
| | 518 | virtual bool setScreenResolution(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, unsigned int width, unsigned int height) |
|---|
| | 519 | { |
|---|
| | 520 | CGDirectDisplayID displayID = getDisplayID(screenIdentifier); |
|---|
| | 521 | |
|---|
| | 522 | // add next line and on following line replace hard coded depth and refresh rate |
|---|
| | 523 | CGRefreshRate refresh = getDictDouble (CGDisplayCurrentMode(displayID), kCGDisplayRefreshRate); |
|---|
| | 524 | CFDictionaryRef display_mode_values = |
|---|
| | 525 | CGDisplayBestModeForParametersAndRefreshRate( |
|---|
| | 526 | displayID, |
|---|
| | 527 | CGDisplayBitsPerPixel(displayID), |
|---|
| | 528 | width, height, |
|---|
| | 529 | refresh, |
|---|
| | 530 | NULL); |
|---|
| | 531 | |
|---|
| | 532 | |
|---|
| | 533 | CGDisplaySwitchToMode(displayID, display_mode_values); |
|---|
| | 534 | return true; |
|---|
| | 535 | } |
|---|
| | 536 | |
|---|
| | 537 | /** implementation of setScreenRefreshRate */ |
|---|
| | 538 | virtual bool setScreenRefreshRate(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, double refreshRate) { |
|---|
| | 539 | |
|---|
| | 540 | boolean_t success(false); |
|---|
| | 541 | unsigned width, height; |
|---|
| | 542 | getScreenResolution(screenIdentifier, width, height); |
|---|
| | 543 | |
|---|
| | 544 | CGDirectDisplayID displayID = getDisplayID(screenIdentifier); |
|---|
| | 545 | |
|---|
| | 546 | // add next line and on following line replace hard coded depth and refresh rate |
|---|
| | 547 | CFDictionaryRef display_mode_values = |
|---|
| | 548 | CGDisplayBestModeForParametersAndRefreshRate( |
|---|
| | 549 | displayID, |
|---|
| | 550 | CGDisplayBitsPerPixel(displayID), |
|---|
| | 551 | width, height, |
|---|
| | 552 | refreshRate, |
|---|
| | 553 | &success); |
|---|
| | 554 | |
|---|
| | 555 | |
|---|
| | 556 | if (success) |
|---|
| | 557 | CGDisplaySwitchToMode(displayID, display_mode_values); |
|---|
| | 558 | |
|---|
| | 559 | return (success != 0); |
|---|
| | 560 | } |
|---|
| | 561 | |
|---|
| 552 | | |
|---|
| 553 | | |
|---|
| 554 | | bool GraphicsWindowCarbon::realizeImplementation() |
|---|
| 555 | | { |
|---|
| 556 | | |
|---|
| 557 | | if (!_initialized) init(); |
|---|
| 558 | | if (!_initialized) return false; |
|---|
| 559 | | if (!_traits) return false; |
|---|
| 560 | | |
|---|
| 561 | | setWindowDecoration(_traits->windowDecoration); |
|---|
| 562 | | |
|---|
| 563 | | // move the window to the right screen |
|---|
| 564 | | |
|---|
| 565 | | OSXCarbonWindowingSystemInterface* wsi = dynamic_cast<OSXCarbonWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface()); |
|---|
| 566 | | int screenLeft(0), screenTop(0); |
|---|
| 567 | | if (wsi) { |
|---|
| 568 | | |
|---|
| 569 | | wsi->getScreenTopLeft((*_traits), screenLeft, screenTop); |
|---|
| 570 | | _traits->y += screenTop; |
|---|
| 571 | | _traits->x += screenLeft; |
|---|
| 572 | | } |
|---|
| 573 | | |
|---|
| 574 | | // create the window |
|---|
| 575 | | Rect bounds = {_traits->y, _traits->x, _traits->y + _traits->height, _traits->x + _traits->width}; |
|---|
| 576 | | OSStatus err = 0; |
|---|
| 577 | | WindowAttributes attr; |
|---|
| 578 | | |
|---|
| 579 | | if (_useWindowDecoration) |
|---|
| 580 | | { |
|---|
| 581 | | if (_traits->supportsResize) |
|---|
| | 609 | void GraphicsWindowCarbon::setWindowDecoration(bool flag) |
|---|
| | 610 | { |
|---|
| | 611 | _useWindowDecoration = flag; |
|---|
| | 612 | if (_realized) { |
|---|
| | 613 | OSErr err = noErr; |
|---|
| | 614 | Rect bounds; |
|---|
| | 615 | GetWindowBounds(getNativeWindowRef(), kWindowContentRgn, &bounds); |
|---|
| | 616 | |
|---|
| | 617 | if (_useWindowDecoration) { |
|---|
| | 618 | err = ChangeWindowAttributes(getNativeWindowRef(), kWindowStandardDocumentAttributes, kWindowNoTitleBarAttribute | kWindowNoShadowAttribute); |
|---|
| | 619 | SetWindowBounds(getNativeWindowRef(), kWindowContentRgn, &bounds); |
|---|
| | 620 | } else { |
|---|
| | 621 | err = ChangeWindowAttributes(getNativeWindowRef(), kWindowNoTitleBarAttribute | kWindowNoShadowAttribute, kWindowStandardDocumentAttributes); |
|---|
| | 622 | } |
|---|
| | 623 | |
|---|
| | 624 | if (err != noErr) { |
|---|
| | 625 | osg::notify(osg::WARN) << "GraphicsWindowCarbon::setWindowDecoration failed with " << err << std::endl; |
|---|
| | 626 | } |
|---|
| | 627 | } |
|---|
| | 628 | } |
|---|
| | 629 | |
|---|
| | 630 | WindowAttributes GraphicsWindowCarbon::computeWindowAttributes(bool useWindowDecoration, bool supportsResize) { |
|---|
| | 631 | WindowAttributes attr; |
|---|
| | 632 | |
|---|
| | 633 | if (useWindowDecoration) |
|---|
| | 634 | { |
|---|
| | 635 | if (supportsResize) |
|---|
| 592 | | |
|---|
| 593 | | err = CreateNewWindow(kDocumentWindowClass, attr, &bounds, &_window); |
|---|
| 594 | | |
|---|
| 595 | | if (err) { |
|---|
| 596 | | osg::notify(osg::WARN) << "GraphicsWindowCarbon::realizeImplementation() failed creating a window: " << err << std::endl; |
|---|
| 597 | | return false; |
|---|
| 598 | | } else { |
|---|
| 599 | | osg::notify(osg::INFO) << "GraphicsWindowCarbon::realizeImplementation() - window created with bounds(" << bounds.top << ", " << bounds.left << ", " << bounds.bottom << ", " << bounds.right << ")" << std::endl; |
|---|
| 600 | | } |
|---|
| 601 | | |
|---|
| 602 | | Rect titleRect; |
|---|
| 603 | | GetWindowBounds(_window, kWindowTitleBarRgn, &titleRect); |
|---|
| 604 | | _windowTitleHeight = abs(titleRect.top); |
|---|
| 605 | | |
|---|
| | 646 | return attr; |
|---|
| | 647 | } |
|---|
| | 648 | |
|---|
| | 649 | void GraphicsWindowCarbon::installEventHandler() { |
|---|
| | 650 | |
|---|
| | 672 | } |
|---|
| | 673 | |
|---|
| | 674 | |
|---|
| | 675 | bool GraphicsWindowCarbon::realizeImplementation() |
|---|
| | 676 | { |
|---|
| | 677 | |
|---|
| | 678 | if (!_initialized) init(); |
|---|
| | 679 | if (!_initialized) return false; |
|---|
| | 680 | if (!_traits) return false; |
|---|
| | 681 | |
|---|
| | 682 | setWindowDecoration(_traits->windowDecoration); |
|---|
| | 683 | |
|---|
| | 684 | // move the window to the right screen |
|---|
| | 685 | |
|---|
| | 686 | OSXCarbonWindowingSystemInterface* wsi = dynamic_cast<OSXCarbonWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface()); |
|---|
| | 687 | int screenLeft(0), screenTop(0); |
|---|
| | 688 | if (wsi) { |
|---|
| | 689 | |
|---|
| | 690 | wsi->getScreenTopLeft((*_traits), screenLeft, screenTop); |
|---|
| | 691 | _traits->y += screenTop; |
|---|
| | 692 | _traits->x += screenLeft; |
|---|
| | 693 | } |
|---|
| | 694 | |
|---|
| | 695 | WindowData *windowData = _traits.get() ? dynamic_cast<WindowData*>(_traits->inheritedWindowData.get()) : 0; |
|---|
| | 696 | _ownsWindow = (windowData) ? (windowData->getNativeWindowRef() == NULL) : true; |
|---|
| | 697 | |
|---|
| | 698 | if (_ownsWindow) { |
|---|
| | 699 | |
|---|
| | 700 | // create the window |
|---|
| | 701 | Rect bounds = {_traits->y, _traits->x, _traits->y + _traits->height, _traits->x + _traits->width}; |
|---|
| | 702 | OSStatus err = 0; |
|---|
| | 703 | WindowAttributes attr = computeWindowAttributes(_useWindowDecoration, _traits->supportsResize); |
|---|
| | 704 | |
|---|
| | 705 | err = CreateNewWindow(kDocumentWindowClass, attr, &bounds, &_window); |
|---|
| | 706 | |
|---|
| | 707 | if (err) { |
|---|
| | 708 | osg::notify(osg::WARN) << "GraphicsWindowCarbon::realizeImplementation() failed creating a window: " << err << std::endl; |
|---|
| | 709 | return false; |
|---|
| | 710 | } else { |
|---|
| | 711 | osg::notify(osg::INFO) << "GraphicsWindowCarbon::realizeImplementation() - window created with bounds(" << bounds.top << ", " << bounds.left << ", " << bounds.bottom << ", " << bounds.right << ")" << std::endl; |
|---|
| | 712 | } |
|---|
| | 713 | } |
|---|
| | 714 | else { |
|---|
| | 715 | _window = windowData->getNativeWindowRef(); |
|---|
| | 716 | } |
|---|
| | 717 | |
|---|
| | 718 | Rect titleRect; |
|---|
| | 719 | GetWindowBounds(_window, kWindowTitleBarRgn, &titleRect); |
|---|
| | 720 | _windowTitleHeight = abs(titleRect.top); |
|---|
| | 721 | |
|---|
| | 722 | if ((_ownsWindow) || (windowData && windowData->installEventHandler())) |
|---|
| | 723 | installEventHandler(); |
|---|