00001 using namespace std;
00002
00003 #import <CoreGraphics/CGBase.h>
00004 #import <CoreGraphics/CGDisplayConfiguration.h>
00005 #import <Carbon/Carbon.h>
00006 #import <IOKit/graphics/IOGraphicsLib.h>
00007
00008 #include "DisplayResOSX.h"
00009 #include "util-osx.h"
00010
00011 CGDirectDisplayID mythtv_display();
00012
00013
00014 DisplayResOSX::DisplayResOSX(void)
00015 {
00016 Initialize();
00017 }
00018
00019 DisplayResOSX::~DisplayResOSX(void)
00020 {
00021 }
00022
00023 bool DisplayResOSX::GetDisplaySize(int &width_mm, int &height_mm) const
00024 {
00025 CGDirectDisplayID d = mythtv_display();
00026
00027 io_connect_t port = CGDisplayIOServicePort(d);
00028 if (port == MACH_PORT_NULL )
00029 return false;
00030
00031 CFDictionaryRef dict = IODisplayCreateInfoDictionary(port, 0);
00032 if (!dict)
00033 return false;
00034
00035 width_mm = get_int_CF(dict, CFSTR(kDisplayHorizontalImageSize));
00036 height_mm = get_int_CF(dict, CFSTR(kDisplayVerticalImageSize));
00037
00038
00039 return true;
00040 }
00041
00042 CGDirectDisplayID mythtv_display()
00043 {
00044 CGDirectDisplayID d = NULL;
00045
00046
00047 Rect windowBounds;
00048 if (!GetWindowBounds(FrontNonFloatingWindow(),
00049 kWindowContentRgn,
00050 &windowBounds))
00051 {
00052 CGPoint pt;
00053 pt.x = windowBounds.left;
00054 pt.y = windowBounds.top;
00055
00056 CGDisplayCount ct;
00057 if (CGGetDisplaysWithPoint(pt, 1, &d, &ct))
00058 {
00059 d = NULL;
00060 }
00061 }
00062 if (!d)
00063 {
00064 d = CGMainDisplayID();
00065 }
00066 return d;
00067 }
00068
00069 bool DisplayResOSX::SwitchToVideoMode(int width, int height, short refreshrate)
00070 {
00071 CGDirectDisplayID d = mythtv_display();
00072 CFDictionaryRef dispMode = NULL;
00073 int match = 0;
00074
00075
00076 if (refreshrate)
00077 dispMode = CGDisplayBestModeForParametersAndRefreshRate(
00078 d, 32, width, height, (CGRefreshRate)(refreshrate), &match);
00079
00080 if (!match)
00081 dispMode =
00082 CGDisplayBestModeForParameters(d, 32, width, height, &match);
00083
00084 if (!match)
00085 dispMode =
00086 CGDisplayBestModeForParameters(d, 16, width, height, &match);
00087
00088 if (!match)
00089 return false;
00090
00091
00092 CGDisplayCapture(d);
00093 CGDisplayConfigRef cfg;
00094 CGBeginDisplayConfiguration(&cfg);
00095 CGConfigureDisplayFadeEffect(cfg, 0.3f, 0.5f, 0, 0, 0);
00096 CGConfigureDisplayMode(cfg, d, dispMode);
00097 CGError err = CGCompleteDisplayConfiguration(cfg, kCGConfigureForAppOnly);
00098 CGDisplayRelease(d);
00099 return (err == kCGErrorSuccess);
00100 }
00101
00102 const DisplayResVector& DisplayResOSX::GetVideoModes() const
00103 {
00104 if (m_video_modes.size())
00105 return m_video_modes;
00106
00107 CGDirectDisplayID d = mythtv_display();
00108 CFArrayRef displayModes = CGDisplayAvailableModes(d);
00109 if (NULL == displayModes)
00110 return m_video_modes;
00111
00112 DisplayResMap screen_map;
00113 for (int i=0; i<CFArrayGetCount(displayModes); ++i)
00114 {
00115 CFDictionaryRef displayMode = (CFDictionaryRef)
00116 CFArrayGetValueAtIndex(displayModes, i);
00117 int width = get_int_CF(displayMode, kCGDisplayWidth);
00118 int height = get_int_CF(displayMode, kCGDisplayHeight);
00119 int refresh = get_int_CF(displayMode, kCGDisplayRefreshRate);
00120
00121 uint key = DisplayResScreen::CalcKey(width, height, 0);
00122
00123 if (screen_map.find(key)==screen_map.end())
00124 screen_map[key] = DisplayResScreen(width, height,
00125 0, 0, -1.0, refresh);
00126 else
00127 screen_map[key].AddRefreshRate(refresh);
00128 }
00129
00130
00131 DisplayResMapCIt it = screen_map.begin();
00132 for (; screen_map.end() != it; ++it)
00133 m_video_modes.push_back(it->second);
00134
00135 return m_video_modes;
00136 }