VirtualBox

Changeset 89815 in vbox


Ignore:
Timestamp:
Jun 21, 2021 12:06:22 PM (3 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:3355. Dynamically introrespecting DBus screen saver interfaces.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r89717 r89815  
    15571557UICommon_QT_MODULES.linux   += X11Extras
    15581558UICommon_QT_MODULES.linux   += DBus
     1559UICommon_QT_MODULES.linux   += Xml
    15591560UICommon_QT_MODULES.solaris += X11Extras
    15601561UICommon_QT_MODULES.solaris += DBus
     1562UICommon_QT_MODULES.solaris += Xml
    15611563UICommon_QT_MODULES.freebsd += X11Extras
    15621564UICommon_QT_MODULES.freebsd += DBus
     1565UICommon_QT_MODULES.freebsd += Xml
    15631566UICommon_QT_MODULES.darwin  += MacExtras
    15641567UICommon_QT_MODULES.win     += WinExtras
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/x11/VBoxX11Helper.cpp

    r89767 r89815  
    1717
    1818/* Qt includes: */
    19 #include <QString>
    2019#include <QX11Info>
    2120#include <QtDBus/QDBusConnection>
     
    2322#include <QtDBus/QDBusInterface>
    2423#include <QtDBus/QDBusConnectionInterface>
     24#include <QtXml/QDomDocument>
     25#include <QtXml/QDomElement>
    2526
    2627/* GUI includes: */
     
    162163}
    163164
    164 QStringList X11ScrenSaverServices()
     165static QStringList X11FindDBusScreenSaverServices(const QDBusConnection &connection)
    165166{
    166167    QStringList serviceNames;
    167     QDBusConnection bus = QDBusConnection::sessionBus();
    168     QDBusReply<QStringList> replyr = bus.interface()->registeredServiceNames();
     168
     169    QDBusReply<QStringList> replyr = connection.interface()->registeredServiceNames();
    169170    if (!replyr.isValid())
     171    {
     172        const QDBusError replyError = replyr.error();
     173        LogRel(("QDBus error. Could not query registered service names %s %s",
     174                replyError.name().toUtf8().constData(), replyError.message().toUtf8().constData()));
    170175        return serviceNames;
     176    }
     177
    171178    for (int i = 0; i < replyr.value().size(); ++i)
    172179    {
     
    176183    }
    177184    if (serviceNames.isEmpty())
    178         LogRel(("No screen saver service found among registered DBus services."));
     185        LogRel(("QDBus error. No screen saver service found among registered DBus services."));
    179186
    180187    return serviceNames;
    181188}
    182189
    183 void X11InhibitScrenSaver(const QStringList &serviceNameList, QMap<QString, uint> &outCookies)
    184 {
    185     outCookies.clear();
    186     QDBusConnection bus = QDBusConnection::sessionBus();
    187 
    188     foreach(QString service, serviceNameList)
    189     {
    190         QDBusInterface screenSaverInterface(service, "/ScreenSaver",
    191                                             service, bus);
     190static void X11IntrorespectInterfaceNode(const QDomElement &interface,
     191                                         const QString &strServiceName, QVector<X11ScreenSaverInhibitMethod*> &methods)
     192{
     193    QDomElement child = interface.firstChildElement();
     194    while (!child.isNull()) {
     195
     196        if (child.tagName() == "method" && child.attribute("name") == "Inhibit")
     197        {
     198            X11ScreenSaverInhibitMethod *newMethod = new X11ScreenSaverInhibitMethod;
     199            newMethod->m_iCookie = 0;
     200            newMethod->m_strServiceName = strServiceName;
     201            newMethod->m_strInterface = interface.attribute("name");
     202            newMethod->m_strPath = "/";
     203            newMethod->m_strPath.append(interface.attribute("name"));
     204            newMethod->m_strPath.replace(".", "/");
     205            methods << newMethod;
     206        }
     207        child = child.nextSiblingElement();
     208    }
     209}
     210
     211static void X11IntrorespectServices(const QDBusConnection &connection,
     212                                    const QString &strService, const QString &path, QVector<X11ScreenSaverInhibitMethod*> &methods)
     213{
     214    QDBusMessage call = QDBusMessage::createMethodCall(strService, path.isEmpty() ? QLatin1String("/") : path,
     215                                                       QLatin1String("org.freedesktop.DBus.Introspectable"),
     216                                                       QLatin1String("Introspect"));
     217    QDBusReply<QString> xmlReply = connection.call(call);
     218
     219    if (!xmlReply.isValid())
     220        return;
     221
     222    QDomDocument doc;
     223    doc.setContent(xmlReply);
     224    QDomElement node = doc.documentElement();
     225    QDomElement child = node.firstChildElement();
     226    while (!child.isNull())
     227    {
     228        if (child.tagName() == QLatin1String("node"))
     229        {
     230            QString subPath = path + QLatin1Char('/') + child.attribute(QLatin1String("name"));
     231            X11IntrorespectServices(connection, strService, subPath, methods);
     232        }
     233        else if (child.tagName() == QLatin1String("interface"))
     234            X11IntrorespectInterfaceNode(child, strService, methods);
     235        child = child.nextSiblingElement();
     236    }
     237}
     238
     239static bool X11CheckDBusConnection(const QDBusConnection &connection)
     240{
     241    if (!connection.isConnected()) {
     242        const QDBusError lastError = connection.lastError();
     243        if (lastError.isValid())
     244        {
     245            LogRel(("QDBus error. Could not connect to D-Bus server: %s: %s\n",
     246                    lastError.name().toUtf8().constData(),
     247                    lastError.message().toUtf8().constData()));
     248        }
     249        else
     250            LogRel(("QDBus error. Could not connect to D-Bus server: Unable to load dbus libraries\n"));
     251        return false;
     252    }
     253    return true;
     254}
     255
     256QVector<X11ScreenSaverInhibitMethod*> X11FindDBusScrenSaverInhibitMethods()
     257{
     258    QVector<X11ScreenSaverInhibitMethod*> methods;
     259
     260    QDBusConnection connection = QDBusConnection::sessionBus();
     261    if (!X11CheckDBusConnection(connection))
     262        return methods;
     263
     264    foreach(const QString &strServiceName, X11FindDBusScreenSaverServices(connection))
     265        X11IntrorespectServices(connection, strServiceName, "", methods);
     266
     267    return methods;
     268}
     269
     270void X11InhibitUninhibitScrenSaver(bool fInhibit, QVector<X11ScreenSaverInhibitMethod*> &inOutIhibitMethods)
     271{
     272    QDBusConnection connection = QDBusConnection::sessionBus();
     273    if (!X11CheckDBusConnection(connection))
     274        return;
     275    for (int i = 0; i < inOutIhibitMethods.size(); ++i)
     276    {
     277        QDBusInterface screenSaverInterface(inOutIhibitMethods[i]->m_strServiceName, inOutIhibitMethods[i]->m_strPath,
     278                                            inOutIhibitMethods[i]->m_strInterface, connection);
    192279        if (!screenSaverInterface.isValid())
    193280        {
    194281            QDBusError error = screenSaverInterface.lastError();
    195             LogRel(("QDBus error for service %s: %s\n",
    196                     service.toUtf8().constData(), error.message().toUtf8().constData()));
     282            LogRel(("QDBus error for service %s: %s. %s\n",
     283                    inOutIhibitMethods[i]->m_strServiceName.toUtf8().constData(),
     284                    error.name().toUtf8().constData(),
     285                    error.message().toUtf8().constData()));
    197286            continue;
    198287        }
    199         QDBusReply<uint> reply = screenSaverInterface.call("Inhibit", "Oracle VirtualBox", "");
    200         if (reply.isValid())
    201             outCookies[service] = reply.value();
     288        QDBusReply<uint> reply;
     289        if (fInhibit)
     290        {
     291            reply = screenSaverInterface.call("Inhibit", "Oracle VirtualBox", "ScreenSaverInhibit");
     292            if (reply.isValid())
     293                inOutIhibitMethods[i]->m_iCookie = reply.value();
     294        }
    202295        else
    203296        {
    204             QDBusError error = screenSaverInterface.lastError();
    205             LogRel(("QDBus inhibition call error for service %s: %s\n",
    206                     service.toUtf8().constData(), error.message().toUtf8().constData()));
    207         }
    208     }
    209 }
    210 
    211 void X11UninhibitScrenSaver(const QMap<QString, uint> &cookies)
    212 {
    213 
    214     QDBusConnection bus = QDBusConnection::sessionBus();
    215 
    216     for (QMap<QString, uint>::const_iterator iterator = cookies.begin(); iterator != cookies.end(); ++iterator)
    217     {
    218 
    219         QDBusInterface screenSaverInterface(iterator.key(), "/ScreenSaver",
    220                                             iterator.key(), bus);
    221         if (!screenSaverInterface.isValid())
    222         {
    223             QDBusError error = screenSaverInterface.lastError();
    224             LogRel(("QDBus error for service %s: %s\n",
    225                     iterator.key().toUtf8().constData(), error.message().toUtf8().constData()));
    226             continue;
    227         }
    228         QDBusReply<uint> reply = screenSaverInterface.call("UnInhibit", iterator.value());
     297            reply = screenSaverInterface.call("UnInhibit", inOutIhibitMethods[i]->m_iCookie);
     298        }
    229299        if (!reply.isValid())
    230300        {
    231             QDBusError error = screenSaverInterface.lastError();
    232             LogRel(("QDBus uninhibition call error for service %s: %s\n",
    233                     iterator.key().toUtf8().constData(), error.message().toUtf8().constData()));
    234         }
    235     }
    236 }
    237 
     301            QDBusError error = reply.error();
     302            LogRel(("QDBus inhibition call error for service %s: %s. %s\n",
     303                    inOutIhibitMethods[i]->m_strServiceName.toUtf8().constData(),
     304                    error.name().toUtf8().constData(),
     305                    error.message().toUtf8().constData()));
     306        }
     307    }
     308}
    238309
    239310#ifdef VBOX_WS_X11
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/x11/VBoxX11Helper.h

    r89708 r89815  
    2222#endif
    2323
     24/* Qt includes: */
     25#include <QString>
     26
    2427/* GUI includes: */
    2528#include "UILibraryDefs.h"
     
    3841};
    3942
     43struct X11ScreenSaverInhibitMethod
     44{
     45    QString m_strServiceName;
     46    QString m_strInterface;
     47    QString m_strPath;
     48    uint    m_iCookie;
     49};
    4050
    4151/** X11: Determines and returns whether the compositing manager is running. */
     
    5464SHARED_LIBRARY_STUFF bool X11CheckExtension(const char *extensionName);
    5565
    56 /* Returns the list of DBus screensaver services.*/
    57 SHARED_LIBRARY_STUFF QStringList X11ScrenSaverServices();
     66/** Returns the list of Inhibit methods found by introrespecting DBus services. */
     67SHARED_LIBRARY_STUFF QVector<X11ScreenSaverInhibitMethod*> X11FindDBusScrenSaverInhibitMethods();
    5868
    59 /* Disables Screen Saver through QDBus. */
    60 SHARED_LIBRARY_STUFF  void X11InhibitScrenSaver(const QStringList &serviceNameList, QMap<QString, uint> &outCookies);
    61 
    62 /* Enables Screen Saver through QDBus. */
    63 SHARED_LIBRARY_STUFF  void X11UninhibitScrenSaver(const QMap<QString, uint> &cookies);
     69/** Disables/enables Screen Saver through QDBus. */
     70SHARED_LIBRARY_STUFF void X11InhibitUninhibitScrenSaver(bool fInhibit, QVector<X11ScreenSaverInhibitMethod*> &inOutIhibitMethods);
    6471
    6572#endif /* !FEQT_INCLUDED_SRC_platform_x11_VBoxX11Helper_h */
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp

    r89744 r89815  
    714714{
    715715#if defined(VBOX_WS_X11)
    716     QStringList services = X11ScrenSaverServices();
    717     if (services.isEmpty())
    718         return;
    719 
    720     if (fDisabled)
    721         X11InhibitScrenSaver(services, m_screenSaverInhibitionCookies);
    722     else
    723         X11UninhibitScrenSaver(m_screenSaverInhibitionCookies);
     716    if (m_methods.isEmpty())
     717        m_methods = X11FindDBusScrenSaverInhibitMethods();
     718    X11InhibitUninhibitScrenSaver(fDisabled, m_methods);
    724719#elif defined(VBOX_WS_WIN)
    725720    NativeWindowSubsystem::setScreenSaverActive(fDisabled);
     
    887882    , m_pVMInformationDialog(0)
    888883{
     884}
     885
     886UIMachineLogic::~UIMachineLogic()
     887{
     888    qDeleteAll(m_methods.begin(), m_methods.end());
     889    m_methods.clear();
    889890}
    890891
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h

    r89745 r89815  
    5353class CUSBDevice;
    5454class CVirtualBoxErrorInfo;
     55struct X11ScreenSaverInhibitMethod;
    5556
    5657#ifdef VBOX_WITH_DEBUGGER_GUI
     
    207208    /* Constructor: */
    208209    UIMachineLogic(QObject *pParent, UISession *pSession, UIVisualStateType visualStateType);
     210    /* Destructor: */
     211    ~UIMachineLogic();
    209212
    210213    /* Protected getters/setters: */
     
    463466    /* Holds the cookies returnd by QDBus inhibition calls. Map keys are service name. These are required during uninhibition.*/
    464467    QMap<QString, uint> m_screenSaverInhibitionCookies;
    465 
     468    QVector<X11ScreenSaverInhibitMethod*> m_methods;
    466469    /* Friend classes: */
    467470    friend class UIMachineWindow;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette