/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QByteArray>
#include <QOpenGLContext>

#ifdef Q_OS_LINUX
#include <sys/ioctl.h>
#include <linux/fb.h>
#endif
#include <private/qmath_p.h>

#include "qeglconvenience_p.h"

#ifndef EGL_OPENGL_ES3_BIT_KHR
#define EGL_OPENGL_ES3_BIT_KHR 0x0040
#endif

QT_BEGIN_NAMESPACE

QVector<EGLint> q_createConfigAttributesFromFormat(const QSurfaceFormat &format)
{
    int redSize     = format.redBufferSize();
    int greenSize   = format.greenBufferSize();
    int blueSize    = format.blueBufferSize();
    int alphaSize   = format.alphaBufferSize();
    int depthSize   = format.depthBufferSize();
    int stencilSize = format.stencilBufferSize();
    int sampleCount = format.samples();

    QVector<EGLint> configAttributes;

    // Map default, unspecified values (-1) to 0. This is important due to sorting rule #3
    // in section 3.4.1 of the spec and allows picking a potentially faster 16-bit config
    // over 32-bit ones when there is no explicit request for the color channel sizes:
    //
    // The red/green/blue sizes have a sort priority of 3, so they are sorted by
    // first. (unless a caveat like SLOW or NON_CONFORMANT is present) The sort order is
    // Special and described as "by larger _total_ number of color bits.". So EGL will put
    // 32-bit configs in the list before the 16-bit configs. However, the spec also goes
    // on to say "If the requested number of bits in attrib_list for a particular
    // component is 0, then the number of bits for that component is not considered". This
    // part of the spec also seems to imply that setting the red/green/blue bits to zero
    // means none of the components are considered and EGL disregards the entire sorting
    // rule. It then looks to the next highest priority rule, which is
    // EGL_BUFFER_SIZE. Despite the selection criteria being "AtLeast" for
    // EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are put in the
    // list before 32-bit configs.
    //
    // This also means that explicitly specifying a size like 565 will still result in
    // having larger (888) configs first in the returned list. We need to handle this
    // ourselves later by manually filtering the list, instead of just blindly taking the
    // first config from it.

    configAttributes.append(EGL_RED_SIZE);
    configAttributes.append(redSize > 0 ? redSize : 0);

    configAttributes.append(EGL_GREEN_SIZE);
    configAttributes.append(greenSize > 0 ? greenSize : 0);

    configAttributes.append(EGL_BLUE_SIZE);
    configAttributes.append(blueSize > 0 ? blueSize : 0);

    configAttributes.append(EGL_ALPHA_SIZE);
    configAttributes.append(alphaSize > 0 ? alphaSize : 0);

    configAttributes.append(EGL_SAMPLES);
    configAttributes.append(sampleCount > 0 ? sampleCount : 0);

    configAttributes.append(EGL_SAMPLE_BUFFERS);
    configAttributes.append(sampleCount > 0);

    if (format.renderableType() != QSurfaceFormat::OpenVG) {
        configAttributes.append(EGL_DEPTH_SIZE);
        configAttributes.append(depthSize > 0 ? depthSize : 0);

        configAttributes.append(EGL_STENCIL_SIZE);
        configAttributes.append(stencilSize > 0 ? stencilSize : 0);
    } else {
        // OpenVG needs alpha mask for clipping
        configAttributes.append(EGL_ALPHA_MASK_SIZE);
        configAttributes.append(8);
    }

    return configAttributes;
}

bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes)
{
    int i = -1;
    // Reduce the complexity of a configuration request to ask for less
    // because the previous request did not result in success.  Returns
    // true if the complexity was reduced, or false if no further
    // reductions in complexity are possible.

    i = configAttributes->indexOf(EGL_SWAP_BEHAVIOR);
    if (i >= 0) {
        configAttributes->remove(i,2);
    }

#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
    // For OpenVG, we sometimes try to create a surface using a pre-multiplied format. If we can't
    // find a config which supports pre-multiplied formats, remove the flag on the surface type:

    i = configAttributes->indexOf(EGL_SURFACE_TYPE);
    if (i >= 0) {
        EGLint surfaceType = configAttributes->at(i +1);
        if (surfaceType & EGL_VG_ALPHA_FORMAT_PRE_BIT) {
            surfaceType ^= EGL_VG_ALPHA_FORMAT_PRE_BIT;
            configAttributes->replace(i+1,surfaceType);
            return true;
        }
    }
#endif

    // EGL chooses configs with the highest color depth over
    // those with smaller (but faster) lower color depths. One
    // way around this is to set EGL_BUFFER_SIZE to 16, which
    // trumps the others. Of course, there may not be a 16-bit
    // config available, so it's the first restraint we remove.
    i = configAttributes->indexOf(EGL_BUFFER_SIZE);
    if (i >= 0) {
        if (configAttributes->at(i+1) == 16) {
            configAttributes->remove(i,2);
            return true;
        }
    }

    i = configAttributes->indexOf(EGL_SAMPLES);
    if (i >= 0) {
        EGLint value = configAttributes->value(i+1, 0);
        if (value > 1)
            configAttributes->replace(i+1, qMin(EGLint(16), value / 2));
        else
            configAttributes->remove(i, 2);
        return true;
    }

    i = configAttributes->indexOf(EGL_SAMPLE_BUFFERS);
    if (i >= 0) {
        configAttributes->remove(i,2);
        return true;
    }

    i = configAttributes->indexOf(EGL_DEPTH_SIZE);
    if (i >= 0) {
        if (configAttributes->at(i + 1) >= 32)
            configAttributes->replace(i + 1, 24);
        else if (configAttributes->at(i + 1) > 1)
            configAttributes->replace(i + 1, 1);
        else
            configAttributes->remove(i, 2);
        return true;
    }

    i = configAttributes->indexOf(EGL_ALPHA_SIZE);
    if (i >= 0) {
        configAttributes->remove(i,2);
#if defined(EGL_BIND_TO_TEXTURE_RGBA) && defined(EGL_BIND_TO_TEXTURE_RGB)
        i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGBA);
        if (i >= 0) {
            configAttributes->replace(i,EGL_BIND_TO_TEXTURE_RGB);
            configAttributes->replace(i+1,true);

        }
#endif
        return true;
    }

    i = configAttributes->indexOf(EGL_STENCIL_SIZE);
    if (i >= 0) {
        if (configAttributes->at(i + 1) > 1)
            configAttributes->replace(i + 1, 1);
        else
            configAttributes->remove(i, 2);
        return true;
    }

#ifdef EGL_BIND_TO_TEXTURE_RGB
    i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGB);
    if (i >= 0) {
        configAttributes->remove(i,2);
        return true;
    }
#endif

    return false;
}

QEglConfigChooser::QEglConfigChooser(EGLDisplay display)
    : m_display(display)
    , m_surfaceType(EGL_WINDOW_BIT)
    , m_ignore(false)
    , m_confAttrRed(0)
    , m_confAttrGreen(0)
    , m_confAttrBlue(0)
    , m_confAttrAlpha(0)
{
}

QEglConfigChooser::~QEglConfigChooser()
{
}

EGLConfig QEglConfigChooser::chooseConfig()
{
    QVector<EGLint> configureAttributes = q_createConfigAttributesFromFormat(m_format);
    configureAttributes.append(EGL_SURFACE_TYPE);
    configureAttributes.append(surfaceType());

    configureAttributes.append(EGL_RENDERABLE_TYPE);
    bool needsES2Plus = false;
    switch (m_format.renderableType()) {
    case QSurfaceFormat::OpenVG:
        configureAttributes.append(EGL_OPENVG_BIT);
        break;
#ifdef EGL_VERSION_1_4
    case QSurfaceFormat::DefaultRenderableType:
#ifndef QT_NO_OPENGL
        if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL)
            configureAttributes.append(EGL_OPENGL_BIT);
        else
#endif // QT_NO_OPENGL
            needsES2Plus = true;
        break;
    case QSurfaceFormat::OpenGL:
         configureAttributes.append(EGL_OPENGL_BIT);
         break;
#endif
    case QSurfaceFormat::OpenGLES:
        if (m_format.majorVersion() == 1) {
            configureAttributes.append(EGL_OPENGL_ES_BIT);
            break;
        }
        Q_FALLTHROUGH();
    default:
        needsES2Plus = true;
        break;
    }
    if (needsES2Plus) {
        if (m_format.majorVersion() >= 3 && q_hasEglExtension(display(), "EGL_KHR_create_context"))
            configureAttributes.append(EGL_OPENGL_ES3_BIT_KHR);
        else
            configureAttributes.append(EGL_OPENGL_ES2_BIT);
    }
    configureAttributes.append(EGL_NONE);

    EGLConfig cfg = nullptr;
    do {
        // Get the number of matching configurations for this set of properties.
        EGLint matching = 0;
        if (!eglChooseConfig(display(), configureAttributes.constData(), nullptr, 0, &matching) || !matching)
            continue;

        // Fetch all of the matching configurations and find the
        // first that matches the pixel format we wanted.
        int i = configureAttributes.indexOf(EGL_RED_SIZE);
        m_confAttrRed = configureAttributes.at(i+1);
        i = configureAttributes.indexOf(EGL_GREEN_SIZE);
        m_confAttrGreen = configureAttributes.at(i+1);
        i = configureAttributes.indexOf(EGL_BLUE_SIZE);
        m_confAttrBlue = configureAttributes.at(i+1);
        i = configureAttributes.indexOf(EGL_ALPHA_SIZE);
        m_confAttrAlpha = i == -1 ? 0 : configureAttributes.at(i+1);

        QVector<EGLConfig> configs(matching);
        eglChooseConfig(display(), configureAttributes.constData(), configs.data(), configs.size(), &matching);
        if (!cfg && matching > 0)
            cfg = configs.first();

        // Filter the list. Due to the EGL sorting rules configs with higher depth are
        // placed first when the minimum color channel sizes have been specified (i.e. the
        // QSurfaceFormat contains color sizes > 0). To prevent returning a 888 config
        // when the QSurfaceFormat explicitly asked for 565, go through the returned
        // configs and look for one that exactly matches the requested sizes. When no
        // sizes have been given, take the first, which will be a config with the smaller
        // (e.g. 16-bit) depth.
        for (int i = 0; i < configs.size(); ++i) {
            if (filterConfig(configs[i]))
                return configs.at(i);
        }
    } while (q_reduceConfigAttributes(&configureAttributes));

    if (!cfg)
        qWarning("Cannot find EGLConfig, returning null config");
    return cfg;
}

bool QEglConfigChooser::filterConfig(EGLConfig config) const
{
    // If we are fine with the highest depth (e.g. RGB888 configs) even when something
    // smaller (565) was explicitly requested, do nothing.
    if (m_ignore)
        return true;

    EGLint red = 0;
    EGLint green = 0;
    EGLint blue = 0;
    EGLint alpha = 0;

    // Compare only if a size was given. Otherwise just accept.
    if (m_confAttrRed)
        eglGetConfigAttrib(display(), config, EGL_RED_SIZE, &red);
    if (m_confAttrGreen)
        eglGetConfigAttrib(display(), config, EGL_GREEN_SIZE, &green);
    if (m_confAttrBlue)
        eglGetConfigAttrib(display(), config, EGL_BLUE_SIZE, &blue);
    if (m_confAttrAlpha)
        eglGetConfigAttrib(display(), config, EGL_ALPHA_SIZE, &alpha);

    return red == m_confAttrRed && green == m_confAttrGreen
           && blue == m_confAttrBlue && alpha == m_confAttrAlpha;
}

EGLConfig q_configFromGLFormat(EGLDisplay display, const QSurfaceFormat &format, bool highestPixelFormat, int surfaceType)
{
    QEglConfigChooser chooser(display);
    chooser.setSurfaceFormat(format);
    chooser.setSurfaceType(surfaceType);
    chooser.setIgnoreColorChannels(highestPixelFormat);

    return chooser.chooseConfig();
}

QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config, const QSurfaceFormat &referenceFormat)
{
    QSurfaceFormat format;
    EGLint redSize     = 0;
    EGLint greenSize   = 0;
    EGLint blueSize    = 0;
    EGLint alphaSize   = 0;
    EGLint depthSize   = 0;
    EGLint stencilSize = 0;
    EGLint sampleCount = 0;
    EGLint renderableType = 0;

    eglGetConfigAttrib(display, config, EGL_RED_SIZE,     &redSize);
    eglGetConfigAttrib(display, config, EGL_GREEN_SIZE,   &greenSize);
    eglGetConfigAttrib(display, config, EGL_BLUE_SIZE,    &blueSize);
    eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE,   &alphaSize);
    eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE,   &depthSize);
    eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize);
    eglGetConfigAttrib(display, config, EGL_SAMPLES,      &sampleCount);
    eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType);

    if (referenceFormat.renderableType() == QSurfaceFormat::OpenVG && (renderableType & EGL_OPENVG_BIT))
        format.setRenderableType(QSurfaceFormat::OpenVG);
#ifdef EGL_VERSION_1_4
    else if (referenceFormat.renderableType() == QSurfaceFormat::OpenGL
             && (renderableType & EGL_OPENGL_BIT))
        format.setRenderableType(QSurfaceFormat::OpenGL);
    else if (referenceFormat.renderableType() == QSurfaceFormat::DefaultRenderableType
#ifndef QT_NO_OPENGL
             && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL
#endif
             && (renderableType & EGL_OPENGL_BIT))
        format.setRenderableType(QSurfaceFormat::OpenGL);
#endif
    else
        format.setRenderableType(QSurfaceFormat::OpenGLES);

    format.setRedBufferSize(redSize);
    format.setGreenBufferSize(greenSize);
    format.setBlueBufferSize(blueSize);
    format.setAlphaBufferSize(alphaSize);
    format.setDepthBufferSize(depthSize);
    format.setStencilBufferSize(stencilSize);
    format.setSamples(sampleCount);
    format.setStereo(false);         // EGL doesn't support stereo buffers
    format.setSwapInterval(referenceFormat.swapInterval());

    // Clear the EGL error state because some of the above may
    // have errored out because the attribute is not applicable
    // to the surface type.  Such errors don't matter.
    eglGetError();

    return format;
}

bool q_hasEglExtension(EGLDisplay display, const char* extensionName)
{
    QList<QByteArray> extensions =
        QByteArray(reinterpret_cast<const char *>
            (eglQueryString(display, EGL_EXTENSIONS))).split(' ');
    return extensions.contains(extensionName);
}

struct AttrInfo { EGLint attr; const char *name; };
static struct AttrInfo attrs[] = {
    {EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE"},
    {EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE"},
    {EGL_BLUE_SIZE, "EGL_BLUE_SIZE"},
    {EGL_GREEN_SIZE, "EGL_GREEN_SIZE"},
    {EGL_RED_SIZE, "EGL_RED_SIZE"},
    {EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE"},
    {EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE"},
    {EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT"},
    {EGL_CONFIG_ID, "EGL_CONFIG_ID"},
    {EGL_LEVEL, "EGL_LEVEL"},
    {EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT"},
    {EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS"},
    {EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH"},
    {EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE"},
    {EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID"},
    {EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE"},
    {EGL_SAMPLES, "EGL_SAMPLES"},
    {EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS"},
    {EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE"},
    {EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE"},
    {EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE"},
    {EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE"},
    {EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE"},
    {EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB"},
    {EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA"},
    {EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL"},
    {EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL"},
    {-1, nullptr}};

void q_printEglConfig(EGLDisplay display, EGLConfig config)
{
    EGLint index;
    for (index = 0; attrs[index].attr != -1; ++index) {
        EGLint value;
        if (eglGetConfigAttrib(display, config, attrs[index].attr, &value)) {
            qDebug("\t%s: %d", attrs[index].name, (int)value);
        }
    }
}

#ifdef Q_OS_UNIX

QSizeF q_physicalScreenSizeFromFb(int framebufferDevice, const QSize &screenSize)
{
#ifndef Q_OS_LINUX
    Q_UNUSED(framebufferDevice)
#endif
    const int defaultPhysicalDpi = 100;
    static QSizeF size;

    if (size.isEmpty()) {
        // Note: in millimeters
        int width = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_WIDTH");
        int height = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_HEIGHT");

        if (width && height) {
            size.setWidth(width);
            size.setHeight(height);
            return size;
        }

        int w = -1;
        int h = -1;
        QSize screenResolution;
#ifdef Q_OS_LINUX
        struct fb_var_screeninfo vinfo;

        if (framebufferDevice != -1) {
            if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1) {
                qWarning("eglconvenience: Could not query screen info");
            } else {
                w = vinfo.width;
                h = vinfo.height;
                screenResolution = QSize(vinfo.xres, vinfo.yres);
            }
        } else
#endif
        {
            // Use the provided screen size, when available, since some platforms may have their own
            // specific way to query it. Otherwise try querying it from the framebuffer.
            screenResolution = screenSize.isEmpty() ? q_screenSizeFromFb(framebufferDevice) : screenSize;
        }

        size.setWidth(w <= 0 ? screenResolution.width() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(w));
        size.setHeight(h <= 0 ? screenResolution.height() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(h));

        if (w <= 0 || h <= 0)
            qWarning("Unable to query physical screen size, defaulting to %d dpi.\n"
                     "To override, set QT_QPA_EGLFS_PHYSICAL_WIDTH "
                     "and QT_QPA_EGLFS_PHYSICAL_HEIGHT (in millimeters).", defaultPhysicalDpi);
    }

    return size;
}

QSize q_screenSizeFromFb(int framebufferDevice)
{
#ifndef Q_OS_LINUX
    Q_UNUSED(framebufferDevice)
#endif
    const int defaultWidth = 800;
    const int defaultHeight = 600;
    static QSize size;

    if (size.isEmpty()) {
        int width = qEnvironmentVariableIntValue("QT_QPA_EGLFS_WIDTH");
        int height = qEnvironmentVariableIntValue("QT_QPA_EGLFS_HEIGHT");

        if (width && height) {
            size.setWidth(width);
            size.setHeight(height);
            return size;
        }

#ifdef Q_OS_LINUX
        struct fb_var_screeninfo vinfo;
        int xres = -1;
        int yres = -1;

        if (framebufferDevice != -1) {
            if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1) {
                qWarning("eglconvenience: Could not read screen info");
            } else {
                xres = vinfo.xres;
                yres = vinfo.yres;
            }
        }

        size.setWidth(xres <= 0 ? defaultWidth : xres);
        size.setHeight(yres <= 0 ? defaultHeight : yres);
#else
        size.setWidth(defaultWidth);
        size.setHeight(defaultHeight);
#endif
    }

    return size;
}

int q_screenDepthFromFb(int framebufferDevice)
{
#ifndef Q_OS_LINUX
    Q_UNUSED(framebufferDevice)
#endif
    const int defaultDepth = 32;
    static int depth = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DEPTH");

    if (depth == 0) {
#ifdef Q_OS_LINUX
        struct fb_var_screeninfo vinfo;

        if (framebufferDevice != -1) {
            if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1)
                qWarning("eglconvenience: Could not query screen info");
            else
                depth = vinfo.bits_per_pixel;
        }

        if (depth <= 0)
            depth = defaultDepth;
#else
        depth = defaultDepth;
#endif
    }

    return depth;
}

qreal q_refreshRateFromFb(int framebufferDevice)
{
#ifndef Q_OS_LINUX
    Q_UNUSED(framebufferDevice)
#endif

    static qreal rate = 0;

#ifdef Q_OS_LINUX
    if (rate == 0) {
        if (framebufferDevice != -1) {
            struct fb_var_screeninfo vinfo;
            if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) != -1) {
                const quint64 quot = quint64(vinfo.left_margin + vinfo.right_margin + vinfo.xres + vinfo.hsync_len)
                    * quint64(vinfo.upper_margin + vinfo.lower_margin + vinfo.yres + vinfo.vsync_len)
                    * vinfo.pixclock;
                if (quot)
                    rate = 1000000000000LLU / quot;
            } else {
                qWarning("eglconvenience: Could not query screen info");
            }
        }
    }
#endif

    if (rate == 0)
        rate = 60;

    return rate;
}

#endif // Q_OS_UNIX

QT_END_NAMESPACE
