Related: tdf#142176 rearrange screensaver inhibiter to be more generic

and for not-x11 I see gtk just uses 0 for xid (which is called
window_system_id there now)

Change-Id: I9248bcceaa2d21d34133dea80697776df0aa8c6c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151560
Tested-by: Caolán McNamara <caolanm@redhat.com>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/vcl/inc/qt5/QtFrame.hxx b/vcl/inc/qt5/QtFrame.hxx
index 963572ca..b927d36 100644
--- a/vcl/inc/qt5/QtFrame.hxx
+++ b/vcl/inc/qt5/QtFrame.hxx
@@ -102,7 +102,7 @@ class VCLPLUG_QT_PUBLIC QtFrame : public QObject, public SalFrame
    QRect m_aRestoreGeometry;

#if CHECK_ANY_QT_USING_X11
    ScreenSaverInhibitor m_ScreenSaverInhibitor;
    SessionManagerInhibitor m_SessionManagerInhibitor;
    ModKeyFlags m_nKeyModifiers;
#endif

diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 00bbd26..1a83a7f 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -202,7 +202,7 @@ class GtkSalFrame final : public SalFrame
    bool                            m_bGraphics;
    ModKeyFlags                     m_nKeyModifiers;
    PointerStyle                    m_ePointerStyle;
    ScreenSaverInhibitor            m_ScreenSaverInhibitor;
    SessionManagerInhibitor         m_SessionManagerInhibitor;
    gulong                          m_nSetFocusSignalId;
    bool                            m_bFullscreen;
    bool                            m_bDefaultPos;
diff --git a/vcl/inc/unx/salframe.h b/vcl/inc/unx/salframe.h
index 3bbf972..d8a177d 100644
--- a/vcl/inc/unx/salframe.h
+++ b/vcl/inc/unx/salframe.h
@@ -105,7 +105,7 @@ class X11SalFrame final : public SalFrame
    int             m_nWorkArea;
    bool            m_bSetFocusOnMap;

    ScreenSaverInhibitor maScreenSaverInhibitor;
    SessionManagerInhibitor maSessionManagerInhibitor;
    tools::Rectangle       maPaintRegion;

    Timer           maAlwaysOnTopRaiseTimer;
diff --git a/vcl/inc/unx/screensaverinhibitor.hxx b/vcl/inc/unx/screensaverinhibitor.hxx
index 4ddbb53..6cfa3e2 100644
--- a/vcl/inc/unx/screensaverinhibitor.hxx
+++ b/vcl/inc/unx/screensaverinhibitor.hxx
@@ -19,17 +19,25 @@
#include <optional>
#include <string_view>

class VCL_PLUGIN_PUBLIC ScreenSaverInhibitor
enum ApplicationInhibitFlags
{
    APPLICATION_INHIBIT_LOGOUT = (1 << 0),
    APPLICATION_INHIBIT_SWITCH = (1 << 1),
    APPLICATION_INHIBIT_SUSPEND = (1 << 2),
    APPLICATION_INHIBIT_IDLE = (1 << 3) // Inhibit the session being marked as idle
};

class VCL_PLUGIN_PUBLIC SessionManagerInhibitor
{
public:
    void inhibit(bool bInhibit, std::u16string_view sReason, bool bIsX11,
                 const std::optional<unsigned int>& xid, std::optional<Display*> pDisplay);
    void inhibit(bool bInhibit, std::u16string_view sReason, ApplicationInhibitFlags eType,
                 unsigned int window_system_id, std::optional<Display*> pDisplay);

private:
    // These are all used as guint, however this header may be included
    // in kde/tde/etc backends, where we would ideally avoid having
    // any glib dependencies, hence the direct use of unsigned int.
    std::optional<unsigned int> mnFDOCookie; // FDO ScreenSaver Inhibit
    std::optional<unsigned int> mnFDOSSCookie; // FDO ScreenSaver Inhibit
    std::optional<unsigned int> mnFDOPMCookie; // FDO PowerManagement Inhibit
    std::optional<unsigned int> mnGSMCookie;
    std::optional<unsigned int> mnMSMCookie;
@@ -49,18 +57,20 @@ private:
    // all encompassing standard, hence we should just try all of them.
    //
    // The current APIs we have: (note: the list of supported environments is incomplete)
    // FDO: org.freedesktop.ScreenSaver::Inhibit - appears to be supported only by KDE?
    // FDSSO: org.freedesktop.ScreenSaver::Inhibit - appears to be supported only by KDE?
    // FDOPM: org.freedesktop.PowerManagement.Inhibit::Inhibit - XFCE, (KDE) ?
    //        (KDE: doesn't inhibit screensaver, but does inhibit PowerManagement)
    // GSM: org.gnome.SessionManager::Inhibit - gnome 3
    // MSM: org.mate.Sessionmanager::Inhibit - Mate <= 1.10, is identical to GSM
    //       (This is replaced by the GSM interface from Mate 1.12 onwards)
    //
    // Note: the Uninhibit call has different spelling in FDO (UnInhibit) vs GSM (Uninhibit)
    void inhibitFDO(bool bInhibit, const char* appname, const char* reason);
    // Note: the Uninhibit call has different spelling in FDOSS (UnInhibit) vs GSM (Uninhibit)
    void inhibitFDOSS(bool bInhibit, const char* appname, const char* reason);
    void inhibitFDOPM(bool bInhibit, const char* appname, const char* reason);
    void inhibitGSM(bool bInhibit, const char* appname, const char* reason, const unsigned int xid);
    void inhibitMSM(bool bInhibit, const char* appname, const char* reason, const unsigned int xid);
    void inhibitGSM(bool bInhibit, const char* appname, const char* reason,
                    ApplicationInhibitFlags eType, unsigned int window_system_id);
    void inhibitMSM(bool bInhibit, const char* appname, const char* reason,
                    ApplicationInhibitFlags eType, unsigned int window_system_id);

    void inhibitXScreenSaver(bool bInhibit, Display* pDisplay);
    static void inhibitXAutoLock(bool bInhibit, Display* pDisplay);
diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx
index 74dfc98..ed5c053 100644
--- a/vcl/qt5/QtFrame.cxx
+++ b/vcl/qt5/QtFrame.cxx
@@ -741,19 +741,19 @@ void QtFrame::StartPresentation(bool bStart)
    // meh - so there's no Qt platform independent solution
    // https://forum.qt.io/topic/38504/solved-qdialog-in-fullscreen-disable-os-screensaver
    assert(m_aSystemData.platform != SystemEnvData::Platform::Invalid);
    const bool bIsX11 = m_aSystemData.platform == SystemEnvData::Platform::Xcb;
    std::optional<unsigned int> aRootWindow;
    unsigned int nRootWindow(0);
    std::optional<Display*> aDisplay;

#if CHECK_QT5_USING_X11
    if (QX11Info::isPlatformX11())
    {
        aRootWindow = QX11Info::appRootWindow();
        nRootWindow = QX11Info::appRootWindow();
        aDisplay = QX11Info::display();
    }
#endif

    m_ScreenSaverInhibitor.inhibit(bStart, u"presentation", bIsX11, aRootWindow, aDisplay);
    m_SessionManagerInhibitor.inhibit(bStart, u"presentation", APPLICATION_INHIBIT_IDLE,
                                      nRootWindow, aDisplay);
#else
    Q_UNUSED(bStart)
#endif
diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx
index 528bb91..f96c99b 100644
--- a/vcl/unx/generic/window/salframe.cxx
+++ b/vcl/unx/generic/window/salframe.cxx
@@ -1972,9 +1972,9 @@ void X11SalFrame::ShowFullScreen( bool bFullScreen, sal_Int32 nScreen )

void X11SalFrame::StartPresentation( bool bStart )
{
    maScreenSaverInhibitor.inhibit( bStart,
    maSessionManagerInhibitor.inhibit( bStart,
                                    u"presentation",
                                    true, // isX11
                                    APPLICATION_INHIBIT_IDLE,
                                    mhWindow,
                                    GetXDisplay() );

diff --git a/vcl/unx/generic/window/screensaverinhibitor.cxx b/vcl/unx/generic/window/screensaverinhibitor.cxx
index a227402..b1cfcb3 100644
--- a/vcl/unx/generic/window/screensaverinhibitor.cxx
+++ b/vcl/unx/generic/window/screensaverinhibitor.cxx
@@ -26,9 +26,9 @@
#if ENABLE_GIO
#include <gio/gio.h>

#define FDO_DBUS_SERVICE        "org.freedesktop.ScreenSaver"
#define FDO_DBUS_PATH           "/org/freedesktop/ScreenSaver"
#define FDO_DBUS_INTERFACE      "org.freedesktop.ScreenSaver"
#define FDOSS_DBUS_SERVICE        "org.freedesktop.ScreenSaver"
#define FDOSS_DBUS_PATH           "/org/freedesktop/ScreenSaver"
#define FDOSS_DBUS_INTERFACE      "org.freedesktop.ScreenSaver"

#define FDOPM_DBUS_SERVICE      "org.freedesktop.PowerManagement.Inhibit"
#define FDOPM_DBUS_PATH         "/org/freedesktop/PowerManagement/Inhibit"
@@ -46,30 +46,27 @@

#include <sal/log.hxx>

void ScreenSaverInhibitor::inhibit( bool bInhibit, std::u16string_view sReason,
                                    bool bIsX11, const std::optional<unsigned int>& xid, std::optional<Display*> pDisplay )
void SessionManagerInhibitor::inhibit(bool bInhibit, std::u16string_view sReason, ApplicationInhibitFlags eType,
                                      unsigned int window_system_id, std::optional<Display*> pDisplay)
{
    const char* appname = SalGenericSystem::getFrameClassName();
    const OString aReason = OUStringToOString( sReason, RTL_TEXTENCODING_UTF8 );

    inhibitFDO( bInhibit, appname, aReason.getStr() );
    inhibitFDOPM( bInhibit, appname, aReason.getStr() );
    if (eType == APPLICATION_INHIBIT_IDLE)
    {
        inhibitFDOSS( bInhibit, appname, aReason.getStr() );
        inhibitFDOPM( bInhibit, appname, aReason.getStr() );
    }

    if ( !bIsX11 )
        return;

    if (pDisplay)
    if (eType == APPLICATION_INHIBIT_IDLE && pDisplay)
    {
        inhibitXScreenSaver( bInhibit, *pDisplay );
        inhibitXAutoLock( bInhibit, *pDisplay );
        inhibitDPMS( bInhibit, *pDisplay );
    }

    if (xid)
    {
        inhibitGSM( bInhibit, appname, aReason.getStr(), *xid );
        inhibitMSM( bInhibit, appname, aReason.getStr(), *xid );
    }
    inhibitGSM(bInhibit, appname, aReason.getStr(), eType, window_system_id);
    inhibitMSM(bInhibit, appname, aReason.getStr(), eType, window_system_id);
}

#if ENABLE_GIO
@@ -159,11 +156,11 @@ static void dbusInhibit( bool bInhibit,
}
#endif // ENABLE_GIO

void ScreenSaverInhibitor::inhibitFDO( bool bInhibit, const char* appname, const char* reason )
void SessionManagerInhibitor::inhibitFDOSS( bool bInhibit, const char* appname, const char* reason )
{
#if ENABLE_GIO
    dbusInhibit( bInhibit,
                 FDO_DBUS_SERVICE, FDO_DBUS_PATH, FDO_DBUS_INTERFACE,
                 FDOSS_DBUS_SERVICE, FDOSS_DBUS_PATH, FDOSS_DBUS_INTERFACE,
                 [appname, reason] ( GDBusProxy *proxy, GError*& error ) -> GVariant* {
                     return g_dbus_proxy_call_sync( proxy, "Inhibit",
                                                    g_variant_new("(ss)", appname, reason),
@@ -174,7 +171,7 @@ void ScreenSaverInhibitor::inhibitFDO( bool bInhibit, const char* appname, const
                                                    g_variant_new("(u)", nCookie),
                                                    G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error );
                 },
                 mnFDOCookie );
                 mnFDOSSCookie );
#else
    (void) this;
    (void) bInhibit;
@@ -183,7 +180,7 @@ void ScreenSaverInhibitor::inhibitFDO( bool bInhibit, const char* appname, const
#endif // ENABLE_GIO
}

void ScreenSaverInhibitor::inhibitFDOPM( bool bInhibit, const char* appname, const char* reason )
void SessionManagerInhibitor::inhibitFDOPM( bool bInhibit, const char* appname, const char* reason )
{
#if ENABLE_GIO
    dbusInhibit( bInhibit,
@@ -207,28 +204,18 @@ void ScreenSaverInhibitor::inhibitFDOPM( bool bInhibit, const char* appname, con
#endif // ENABLE_GIO
}

#if ENABLE_GIO
enum ApplicationInhibitFlags
{
    APPLICATION_INHIBIT_LOGOUT  = (1 << 0),
    APPLICATION_INHIBIT_SWITCH  = (1 << 1),
    APPLICATION_INHIBIT_SUSPEND = (1 << 2),
    APPLICATION_INHIBIT_IDLE    = (1 << 3) // Inhibit the session being marked as idle
};
#endif

void ScreenSaverInhibitor::inhibitGSM( bool bInhibit, const char* appname, const char* reason, const unsigned int xid )
void SessionManagerInhibitor::inhibitGSM( bool bInhibit, const char* appname, const char* reason, ApplicationInhibitFlags eType, unsigned int window_system_id )
{
#if ENABLE_GIO
    dbusInhibit( bInhibit,
                 GSM_DBUS_SERVICE, GSM_DBUS_PATH, GSM_DBUS_INTERFACE,
                 [appname, reason, xid] ( GDBusProxy *proxy, GError*& error ) -> GVariant* {
                 [appname, reason, eType, window_system_id] ( GDBusProxy *proxy, GError*& error ) -> GVariant* {
                     return g_dbus_proxy_call_sync( proxy, "Inhibit",
                                                    g_variant_new("(susu)",
                                                                  appname,
                                                                  xid,
                                                                  window_system_id,
                                                                  reason,
                                                                  APPLICATION_INHIBIT_IDLE
                                                                  eType
                                                                 ),
                                                    G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error );
                 },
@@ -243,22 +230,23 @@ void ScreenSaverInhibitor::inhibitGSM( bool bInhibit, const char* appname, const
    (void) bInhibit;
    (void) appname;
    (void) reason;
    (void) xid;
    (void) eType;
    (void) window_system_id;
#endif // ENABLE_GIO
}

void ScreenSaverInhibitor::inhibitMSM( bool bInhibit, const char* appname, const char* reason, const unsigned int xid )
void SessionManagerInhibitor::inhibitMSM( bool bInhibit, const char* appname, const char* reason, ApplicationInhibitFlags eType, unsigned int window_system_id )
{
#if ENABLE_GIO
    dbusInhibit( bInhibit,
                 MSM_DBUS_SERVICE, MSM_DBUS_PATH, MSM_DBUS_INTERFACE,
                 [appname, reason, xid] ( GDBusProxy *proxy, GError*& error ) -> GVariant* {
                 [appname, reason, eType, window_system_id] ( GDBusProxy *proxy, GError*& error ) -> GVariant* {
                     return g_dbus_proxy_call_sync( proxy, "Inhibit",
                                                    g_variant_new("(susu)",
                                                                  appname,
                                                                  xid,
                                                                  window_system_id,
                                                                  reason,
                                                                  8 //Inhibit the session being marked as idle
                                                                  eType
                                                                 ),
                                                    G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error );
                 },
@@ -273,7 +261,8 @@ void ScreenSaverInhibitor::inhibitMSM( bool bInhibit, const char* appname, const
    (void) bInhibit;
    (void) appname;
    (void) reason;
    (void) xid;
    (void) eType;
    (void) window_system_id;
#endif // ENABLE_GIO
}

@@ -283,7 +272,7 @@ void ScreenSaverInhibitor::inhibitMSM( bool bInhibit, const char* appname, const
 * Worth noting: xscreensaver explicitly ignores this and does its own
 * timeout handling.
 */
void ScreenSaverInhibitor::inhibitXScreenSaver( bool bInhibit, Display* pDisplay )
void SessionManagerInhibitor::inhibitXScreenSaver( bool bInhibit, Display* pDisplay )
{
    int nTimeout, nInterval, bPreferBlanking, bAllowExposures;
    XGetScreenSaver( pDisplay, &nTimeout, &nInterval,
@@ -312,7 +301,7 @@ void ScreenSaverInhibitor::inhibitXScreenSaver( bool bInhibit, Display* pDisplay
#define XAUTOLOCK_DISABLE 1
#define XAUTOLOCK_ENABLE  2

void ScreenSaverInhibitor::inhibitXAutoLock( bool bInhibit, Display* pDisplay )
void SessionManagerInhibitor::inhibitXAutoLock( bool bInhibit, Display* pDisplay )
{
    ::Window aRootWindow = RootWindowOfScreen( ScreenOfDisplay( pDisplay, 0 ) );

@@ -337,7 +326,7 @@ void ScreenSaverInhibitor::inhibitXAutoLock( bool bInhibit, Display* pDisplay )
                     sizeof( nMessage ) );
}

void ScreenSaverInhibitor::inhibitDPMS( bool bInhibit, Display* pDisplay )
void SessionManagerInhibitor::inhibitDPMS( bool bInhibit, Display* pDisplay )
{
#if !defined(__sun)
    int dummy;
diff --git a/vcl/unx/gtk3/gtkframe.cxx b/vcl/unx/gtk3/gtkframe.cxx
index 4f8a7d4..b6b4cd5 100644
--- a/vcl/unx/gtk3/gtkframe.cxx
+++ b/vcl/unx/gtk3/gtkframe.cxx
@@ -2472,21 +2472,18 @@ void GtkSalFrame::ShowFullScreen( bool bFullScreen, sal_Int32 nScreen )

void GtkSalFrame::StartPresentation( bool bStart )
{
    std::optional<guint> aWindow;
    guint nWindow(0);
    std::optional<Display*> aDisplay;

    bool bX11 = DLSYM_GDK_IS_X11_DISPLAY(getGdkDisplay());
    if (bX11)
    if (DLSYM_GDK_IS_X11_DISPLAY(getGdkDisplay()))
    {
        aWindow = GtkSalFrame::GetNativeWindowHandle(m_pWindow);
        nWindow = GtkSalFrame::GetNativeWindowHandle(m_pWindow);
        aDisplay = gdk_x11_display_get_xdisplay(getGdkDisplay());
    }

    m_ScreenSaverInhibitor.inhibit( bStart,
                                    u"presentation",
                                    bX11,
                                    aWindow,
                                    aDisplay );
    m_SessionManagerInhibitor.inhibit(bStart, u"presentation",
                                      APPLICATION_INHIBIT_IDLE,
                                      nWindow, aDisplay);
}

void GtkSalFrame::SetAlwaysOnTop( bool bOnTop )