Beispiel #1
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #7
0
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];
        }
Beispiel #8
0
    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;
    }
Beispiel #9
0
    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.");
        }
    }
Beispiel #10
0
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;
}