00001 #include "DisplayResX.h"
00002 #include <iostream>
00003 #include <cstdio>
00004 #include <cstring>
00005 #include <cstdlib>
00006
00007 #include "util-x11.h"
00008
00009 #include <X11/extensions/Xrandr.h>
00010
00011 static XRRScreenConfiguration *GetScreenConfig(Display*& display);
00012
00013 DisplayResX::DisplayResX(void)
00014 {
00015 Initialize();
00016 }
00017
00018 DisplayResX::~DisplayResX(void)
00019 {
00020 }
00021
00022 bool DisplayResX::GetDisplaySize(int &width_mm, int &height_mm) const
00023 {
00024 QSize dim = MythXGetDisplayDimensions();
00025 if ((dim.width() > 0) && (dim.height() > 0))
00026 {
00027 width_mm = dim.width();
00028 height_mm = dim.height();
00029 return true;
00030 }
00031
00032 return false;
00033 }
00034
00035 bool DisplayResX::SwitchToVideoMode(int width, int height, short desired_rate)
00036 {
00037 short rate;
00038 DisplayResScreen desired_screen(width, height, 0, 0, -1.0, desired_rate);
00039 int idx = DisplayResScreen::FindBestMatch(m_video_modes_unsorted,
00040 desired_screen, rate);
00041 if (idx >= 0)
00042 {
00043 Display *display = NULL;
00044 XRRScreenConfiguration *cfg = GetScreenConfig(display);
00045 if (!cfg)
00046 return false;
00047
00048 X11L;
00049 Rotation rot;
00050 XRRConfigCurrentConfiguration(cfg, &rot);
00051
00052 Window root = DefaultRootWindow(display);
00053 Status status = XRRSetScreenConfigAndRate(display, cfg, root, idx,
00054 rot, rate, CurrentTime);
00055
00056 XRRFreeScreenConfigInfo(cfg);
00057 XCloseDisplay(display);
00058 X11U;
00059
00060 if (RRSetConfigSuccess != status)
00061 cerr<<"DisplaResX: XRRSetScreenConfigAndRate() call failed."<<endl;
00062 return RRSetConfigSuccess == status;
00063 }
00064 cerr<<"DisplaResX: Desired Resolution and FrameRate not found."<<endl;
00065 return false;
00066 }
00067
00068 const DisplayResVector& DisplayResX::GetVideoModes(void) const
00069 {
00070 if (m_video_modes.size())
00071 return m_video_modes;
00072
00073 Display *display = NULL;
00074 XRRScreenConfiguration *cfg = GetScreenConfig(display);
00075 if (!cfg)
00076 return m_video_modes;
00077
00078 int num_sizes, num_rates;
00079 XRRScreenSize *sizes = NULL;
00080 X11S(sizes = XRRConfigSizes(cfg, &num_sizes));
00081 for (int i = 0; i < num_sizes; ++i)
00082 {
00083 short *rates = NULL;
00084 X11S(rates = XRRRates(display, DefaultScreen(display), i, &num_rates));
00085 DisplayResScreen scr(sizes[i].width, sizes[i].height,
00086 sizes[i].mwidth, sizes[i].mheight,
00087 rates, num_rates);
00088 m_video_modes.push_back(scr);
00089 }
00090 m_video_modes_unsorted = m_video_modes;
00091 sort(m_video_modes.begin(), m_video_modes.end());
00092
00093 X11L;
00094 XRRFreeScreenConfigInfo(cfg);
00095 XCloseDisplay(display);
00096 X11U;
00097
00098 return m_video_modes;
00099 }
00100
00101 static XRRScreenConfiguration *GetScreenConfig(Display*& display)
00102 {
00103 display = MythXOpenDisplay();
00104 if (!display)
00105 {
00106 cerr<<"DisplaResX: MythXOpenDisplay call failed"<<endl;
00107 return NULL;
00108 }
00109
00110 X11L;
00111
00112 Window root = RootWindow(display, DefaultScreen(display));
00113
00114 XRRScreenConfiguration *cfg = NULL;
00115 int event_basep = 0, error_basep = 0;
00116 if (XRRQueryExtension(display, &event_basep, &error_basep))
00117 cfg = XRRGetScreenInfo(display, root);
00118
00119 if (!cfg)
00120 {
00121 if (display)
00122 {
00123 XCloseDisplay(display);
00124 display = NULL;
00125 }
00126 cerr<<"DisplaResX: Unable to XRRgetScreenInfo"<<endl;
00127 }
00128
00129 X11U;
00130
00131 return cfg;
00132 }