static XRRScreenConfiguration *GetScreenConfig(MythXDisplay*& display) { display = OpenMythXDisplay(); if (!display) { LOG(VB_GENERAL, LOG_ERR, "DisplaResX: MythXOpenDisplay call failed"); return NULL; } Window root = RootWindow(display->GetDisplay(), display->GetScreen()); XRRScreenConfiguration *cfg = NULL; int event_basep = 0, error_basep = 0; if (XRRQueryExtension(display->GetDisplay(), &event_basep, &error_basep)) cfg = XRRGetScreenInfo(display->GetDisplay(), root); if (!cfg) { delete display; display = NULL; LOG(VB_GENERAL, LOG_ERR, "DisplaResX: Unable to XRRgetScreenInfo"); } return cfg; }
QSize MythXGetDisplayDimensions(void) { QSize ret(-1,-1); MythXDisplay *d = OpenMythXDisplay(); if (d) { ret = d->GetDisplayDimensions(); delete d; } return ret; }
float MythXGetRefreshRate(void) { float ret = -1; MythXDisplay *d = OpenMythXDisplay(); if (d) { ret = d->GetRefreshRate(); delete d; } return ret; }
int CheckNVOpenGLSyncToVBlank(void) { MythXDisplay *d = OpenMythXDisplay(); if (!d) return -1; Display *dpy = d->GetDisplay(); int screen = d->GetScreen(); if (!XNVCTRLIsNvScreen(dpy, screen)) { delete d; return -1; } int major, minor; if (!XNVCTRLQueryVersion(dpy, &major, &minor)) return -1; int sync = NV_CTRL_SYNC_TO_VBLANK_OFF; if (!XNVCTRLQueryAttribute(dpy, screen, 0, NV_CTRL_SYNC_TO_VBLANK, &sync)) { delete d; return -1; } if (!sync) { LOG(VB_GENERAL, LOG_WARNING, LOC + "OpenGL Sync to VBlank is disabled."); LOG(VB_GENERAL, LOG_WARNING, LOC + "For best results enable this in NVidia settings or try running:"); LOG(VB_GENERAL, LOG_WARNING, LOC + "nvidia-settings -a \"SyncToVBlank=1\""); } if (!sync && getenv("__GL_SYNC_TO_VBLANK")) { LOG(VB_GENERAL, LOG_INFO, LOC + "OpenGL Sync to VBlank enabled via __GL_SYNC_TO_VBLANK."); sync = 1; } else if (!sync) { LOG(VB_GENERAL, LOG_WARNING, LOC + "Alternatively try setting the '__GL_SYNC_TO_VBLANK' environment variable."); } return sync; }
int MythDisplay::GetNumberXineramaScreens(void) { int nr_xinerama_screens = 0; #if USING_X11 // TODO Qt is Xinerama aware so this should be unnecessary MythXDisplay *d = OpenMythXDisplay(); if (d) { nr_xinerama_screens = d->GetNumberXineramaScreens(); delete d; } #else // Mac OS X when not using X11 server supports Xinerama. if (QApplication::desktop()) nr_xinerama_screens = QApplication::desktop()->numScreens(); #endif return nr_xinerama_screens; }
/** \fn GetNumberXineramaScreens(void) * \brief Returns number of Xinerama screens if Xinerama * is available, or 0 if it is not available. */ int GetNumberXineramaScreens(void) { int nr_xinerama_screens = 0; #ifdef USING_X11 MythXDisplay *d = OpenMythXDisplay(); if (d) { nr_xinerama_screens = d->GetNumberXineramaScreens(); delete d; } #else // if !USING_X11 #if CONFIG_DARWIN // Mac OS X when not using X11 server supports Xinerama. if (QApplication::desktop()) nr_xinerama_screens = QApplication::desktop()->numScreens(); #endif // CONFIG_DARWIN #endif // !USING_X11 return nr_xinerama_screens; }
int GetNvidiaRates(t_screenrate& screenmap) { #ifdef USING_XRANDR MythXDisplay *d = OpenMythXDisplay(); if (!d) { return -1; } Display *dpy; bool ret; int screen, display_devices, mask, major, minor, len, j; char *str, *start; int nDisplayDevice; char *pMetaModes, *pModeLines[8], *tmp, *modeString; char *modeLine, *modeName; int MetaModeLen, ModeLineLen[8]; int thisMask; int id; int twinview = 0; map<int, map<int,bool> > maprate; memset(pModeLines, 0, sizeof(pModeLines)); memset(ModeLineLen, 0, sizeof(ModeLineLen)); /* * Open a display connection, and make sure the NV-CONTROL X * extension is present on the screen we want to use. */ dpy = d->GetDisplay(); screen = d->GetScreen(); if (!XNVCTRLIsNvScreen(dpy, screen)) { LOG(VB_PLAYBACK, LOG_INFO, QString("The NV-CONTROL X extension is not available on screen %1 " "of '%2'.") .arg(screen) .arg(XDisplayName(NULL))); delete d; return -1; } ret = XNVCTRLQueryVersion(dpy, &major, &minor); if (ret != True) { LOG(VB_PLAYBACK, LOG_INFO, QString("The NV-CONTROL X extension does not exist on '%1'.") .arg(XDisplayName(NULL))); delete d; return -1; } ret = XNVCTRLQueryAttribute(dpy, screen, 0, NV_CTRL_DYNAMIC_TWINVIEW, &twinview); if (!ret) { LOG(VB_PLAYBACK, LOG_ERR, "Failed to query if Dynamic Twinview is enabled"); XCloseDisplay(dpy); return -1; } if (!twinview) { LOG(VB_PLAYBACK, LOG_ERR, "Dynamic Twinview not enabled, ignoring"); delete d; return 0; } /* * query the connected display devices on this X screen and print * basic information about each X screen */ ret = XNVCTRLQueryAttribute(dpy, screen, 0, NV_CTRL_CONNECTED_DISPLAYS, &display_devices); if (!ret) { LOG(VB_PLAYBACK, LOG_ERR, "Failed to query the enabled Display Devices."); delete d; return -1; } /* first, we query the MetaModes on this X screen */ ret = XNVCTRLQueryBinaryData(dpy, screen, 0, // n/a NV_CTRL_BINARY_DATA_METAMODES, (unsigned char **)&pMetaModes, &MetaModeLen); if (!ret) { LOG(VB_PLAYBACK, LOG_ERR, "Failed to query the metamode on selected display device."); delete d; return -1; } /* * then, we query the ModeLines for each display device on * this X screen; we'll need these later */ nDisplayDevice = 0; for (mask = 1; mask < (1 << 24); mask <<= 1) { if (!(display_devices & mask)) continue; ret = XNVCTRLQueryBinaryData(dpy, screen, mask, NV_CTRL_BINARY_DATA_MODELINES, (unsigned char **)&str, &len); if (!ret) { LOG(VB_PLAYBACK, LOG_ERR, "Unknown error. Failed to query the enabled Display Devices."); // Free Memory currently allocated for (j=0; j < nDisplayDevice; ++j) { free(pModeLines[j]); } delete d; return -1; } pModeLines[nDisplayDevice] = str; ModeLineLen[nDisplayDevice] = len; nDisplayDevice++; } /* now, parse each MetaMode */ str = start = pMetaModes; for (j = 0; j < MetaModeLen - 1; ++j) { /* * if we found the end of a line, treat the string from * start to str[j] as a MetaMode */ if ((str[j] == '\0') && (str[j+1] != '\0')) { id = extract_id_string(start); /* * the MetaMode may be preceded with "token=value" * pairs, separated by the main MetaMode with "::"; if * "::" exists in the string, skip past it */ tmp = strstr(start, "::"); if (tmp) { tmp += 2; } else { tmp = start; } /* split the MetaMode string by comma */ char *strtok_state = NULL; for (modeString = strtok_r(tmp, ",", &strtok_state); modeString; modeString = strtok_r(NULL, ",", &strtok_state)) { /* * retrieve the modeName and display device mask * for this segment of the Metamode */ parse_mode_string(modeString, &modeName, &thisMask); /* lookup the modeline that matches */ nDisplayDevice = 0; if (thisMask) { for (mask = 1; mask < (1 << 24); mask <<= 1) { if (!(display_devices & mask)) continue; if (thisMask & mask) break; nDisplayDevice++; } } modeLine = find_modeline(modeName, pModeLines[nDisplayDevice], ModeLineLen[nDisplayDevice]); if (modeLine && !modeline_is_interlaced(modeLine)) { int w, h, vfl, hfl, i, irate; double dcl, r; char *buf[256]; uint64_t key, key2; // skip name tmp = strchr(modeLine, '"'); tmp = strchr(tmp+1, '"') +1 ; while (*tmp == ' ') tmp++; i = 0; for (modeString = strtok_r(tmp, " ", &strtok_state); modeString; modeString = strtok_r(NULL, " ", &strtok_state)) { buf[i++] = modeString; } w = strtol(buf[1], NULL, 10); h = strtol(buf[5], NULL, 10); vfl = strtol(buf[8], NULL, 10); hfl = strtol(buf[4], NULL, 10); h = strtol(buf[5], NULL, 10); istringstream istr(buf[0]); istr.imbue(locale("C")); istr >> dcl; r = (dcl * 1000000.0) / (vfl * hfl); irate = (int) round(r * 1000.0); key = DisplayResScreen::CalcKey(w, h, (double) id); key2 = DisplayResScreen::CalcKey(w, h, 0.0); // We need to eliminate duplicates, giving priority to the first entries found if (maprate.find(key2) == maprate.end()) { // First time we see this resolution, create a map for it maprate[key2] = map<int, bool>(); } if ((maprate[key2].find(irate) == maprate[key2].end()) && (screenmap.find(key) == screenmap.end())) { screenmap[key] = r; maprate[key2][irate] = true; } } free(modeName); } /* move to the next MetaMode */ start = &str[j+1]; }
bool Create(void) { m_x_disp = OpenMythXDisplay(); if (!m_x_disp) return false; MythXLocker locker(m_x_disp); if (m_va_disp_type == kVADisplayGLX) { MythMainWindow *mw = GetMythMainWindow(); if (!mw) return false; MythRenderOpenGL *gl = static_cast<MythRenderOpenGL*>(mw->GetRenderDevice()); if (!gl) { LOG(VB_PLAYBACK, LOG_ERR, LOC + QString("Failed to get OpenGL context - you must use the " "OpenGL UI painter for VAAPI GLX support.")); return false; } gl->makeCurrent(); Display *display = glXGetCurrentDisplay(); gl->doneCurrent(); m_va_disp = vaGetDisplayGLX(display); } else { m_va_disp = vaGetDisplay(m_x_disp->GetDisplay()); } if (!m_va_disp) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create VADisplay"); return false; } int major_ver, minor_ver; INIT_ST; va_status = vaInitialize(m_va_disp, &major_ver, &minor_ver); CHECK_ST; if (ok) m_driver = vaQueryVendorString(m_va_disp); static bool debugged = false; if (ok && !debugged) { debugged = true; LOG(VB_GENERAL, LOG_INFO, LOC + QString("Version: %1.%2") .arg(major_ver).arg(minor_ver)); LOG(VB_GENERAL, LOG_INFO, LOC + QString("Driver : %1").arg(m_driver)); } if (ok) { LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Created VAAPI %1 display") .arg(m_va_disp_type == kVADisplayGLX ? "GLX" : "X11")); } return ok; }
ScreenSaverX11Private(ScreenSaverX11 *outer) : m_dpmsaware(false), m_dpmsdeactivated(false), m_xscreensaverRunning(false), m_gscreensaverRunning(false), m_dpmsenabled(false), m_timeoutInterval(-1), m_resetTimer(NULL), m_display(NULL) { const uint flags = kMSDontBlockInputDevs | kMSDontDisableDrawing | kMSProcessEvents; m_xscreensaverRunning = myth_system("xscreensaver-command -version >&- 2>&-", flags) == 0; m_gscreensaverRunning = myth_system("gnome-screensaver-command --help >&- 2>&-", flags) == 0; if (IsScreenSaverRunning()) { m_resetTimer = new QTimer(outer); m_resetTimer->setSingleShot(false); QObject::connect(m_resetTimer, SIGNAL(timeout()), outer, SLOT(resetSlot())); if (m_xscreensaverRunning) LOG(VB_GENERAL, LOG_INFO, LOC + "XScreenSaver support enabled"); if (m_gscreensaverRunning) LOG(VB_GENERAL, LOG_INFO, LOC + "Gnome screen saver support enabled"); } m_display = OpenMythXDisplay(); if (m_display) { int dummy0, dummy1; m_dpmsaware = DPMSQueryExtension(m_display->GetDisplay(), &dummy0, &dummy1); } else { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to open connection to X11 server"); } if (m_dpmsaware) { CARD16 power_level; /* If someone runs into X server weirdness that goes away when * they externally disable DPMS, then the 'dpmsenabled' test should * be short circuited by a call to 'DPMSCapable()'. Be sure to * manually initialize dpmsenabled to false. */ DPMSInfo(m_display->GetDisplay(), &power_level, &m_dpmsenabled); if (m_dpmsenabled) LOG(VB_GENERAL, LOG_INFO, LOC + "DPMS is active."); else LOG(VB_GENERAL, LOG_INFO, LOC + "DPMS is disabled."); } else { LOG(VB_GENERAL, LOG_INFO, LOC + "DPMS is not supported."); } }
DisplayInfo MythDisplay::GetDisplayInfo(int video_rate) { DisplayInfo ret; #if defined(Q_WS_MAC) CGDirectDisplayID disp = GetOSXDisplay(GetWindowID()); if (!disp) return ret; CFDictionaryRef ref = CGDisplayCurrentMode(disp); float rate = 0.0f; if (ref) rate = get_float_CF(ref, kCGDisplayRefreshRate); if (VALID_RATE(rate)) ret.rate = 1000000.0f / rate; else ret.rate = fix_rate(video_rate); CGSize size_in_mm = CGDisplayScreenSize(disp); ret.size = QSize((uint) size_in_mm.width, (uint) size_in_mm.height); uint width = (uint)CGDisplayPixelsWide(disp); uint height = (uint)CGDisplayPixelsHigh(disp); ret.res = QSize(width, height); #elif defined(Q_WS_WIN) HDC hdc = GetDC(GetWindowID()); int rate = 0; if (hdc) { rate = GetDeviceCaps(hdc, VREFRESH); int width = GetDeviceCaps(hdc, HORZSIZE); int height = GetDeviceCaps(hdc, VERTSIZE); ret.size = QSize((uint)width, (uint)height); width = GetDeviceCaps(hdc, HORZRES); height = GetDeviceCaps(hdc, VERTRES); ret.res = QSize((uint)width, (uint)height); } if (VALID_RATE(rate)) { // see http://support.microsoft.com/kb/2006076 switch (rate) { case 23: ret.rate = 41708; break; // 23.976Hz case 29: ret.rate = 33367; break; // 29.970Hz case 47: ret.rate = 20854; break; // 47.952Hz case 59: ret.rate = 16683; break; // 59.940Hz case 71: ret.rate = 13903; break; // 71.928Hz case 119: ret.rate = 8342; break; // 119.880Hz default: ret.rate = 1000000.0f / (float)rate; } } else ret.rate = fix_rate(video_rate); #elif USING_X11 MythXDisplay *disp = OpenMythXDisplay(); if (!disp) return ret; float rate = disp->GetRefreshRate(); if (VALID_RATE(rate)) ret.rate = 1000000.0f / rate; else ret.rate = fix_rate(video_rate); ret.res = disp->GetDisplaySize(); ret.size = disp->GetDisplayDimensions(); delete disp; #endif return ret; }