nss: upgrade to release 3.73
[LibreOffice.git] / vcl / unx / generic / window / screensaverinhibitor.cxx
blob0b499e638ecb70fdc1c1d55d3f1b6ca527384a77
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <sal/config.h>
12 #include <functional>
14 #include <unx/gensys.h>
15 #include <unx/screensaverinhibitor.hxx>
17 #include <X11/Xlib.h>
18 #include <X11/Xatom.h>
20 #if !defined(__sun) && !defined(AIX)
21 #include <X11/extensions/dpms.h>
22 #endif
24 #include <config_gio.h>
26 #if ENABLE_GIO
27 #include <gio/gio.h>
29 #define FDO_DBUS_SERVICE "org.freedesktop.ScreenSaver"
30 #define FDO_DBUS_PATH "/org/freedesktop/ScreenSaver"
31 #define FDO_DBUS_INTERFACE "org.freedesktop.ScreenSaver"
33 #define FDOPM_DBUS_SERVICE "org.freedesktop.PowerManagement.Inhibit"
34 #define FDOPM_DBUS_PATH "/org/freedesktop/PowerManagement/Inhibit"
35 #define FDOPM_DBUS_INTERFACE "org.freedesktop.PowerManagement.Inhibit"
37 #define GSM_DBUS_SERVICE "org.gnome.SessionManager"
38 #define GSM_DBUS_PATH "/org/gnome/SessionManager"
39 #define GSM_DBUS_INTERFACE "org.gnome.SessionManager"
41 // Mate <= 1.10 uses org.mate.SessionManager, > 1.10 will use org.gnome.SessionManager
42 #define MSM_DBUS_SERVICE "org.mate.SessionManager"
43 #define MSM_DBUS_PATH "/org/mate/SessionManager"
44 #define MSM_DBUS_INTERFACE "org.mate.SessionManager"
45 #endif
47 #include <sal/log.hxx>
49 void ScreenSaverInhibitor::inhibit( bool bInhibit, const OUString& sReason,
50 bool bIsX11, const std::optional<unsigned int>& xid, std::optional<Display*> pDisplay )
52 const char* appname = SalGenericSystem::getFrameClassName();
53 const OString aReason = OUStringToOString( sReason, RTL_TEXTENCODING_UTF8 );
55 inhibitFDO( bInhibit, appname, aReason.getStr() );
56 inhibitFDOPM( bInhibit, appname, aReason.getStr() );
58 if ( !bIsX11 )
59 return;
61 if (pDisplay)
63 inhibitXScreenSaver( bInhibit, *pDisplay );
64 inhibitXAutoLock( bInhibit, *pDisplay );
65 inhibitDPMS( bInhibit, *pDisplay );
68 if (xid)
70 inhibitGSM( bInhibit, appname, aReason.getStr(), *xid );
71 inhibitMSM( bInhibit, appname, aReason.getStr(), *xid );
75 #if ENABLE_GIO
76 static void dbusInhibit( bool bInhibit,
77 const gchar* service, const gchar* path, const gchar* interface,
78 const std::function<GVariant*( GDBusProxy*, GError*& )>& fInhibit,
79 const std::function<GVariant*( GDBusProxy*, const guint, GError*& )>& fUnInhibit,
80 std::optional<guint>& rCookie )
82 if ( ( !bInhibit && !rCookie ) ||
83 ( bInhibit && rCookie ) )
85 return;
88 GError *error = nullptr;
89 GDBusConnection *session_connection = g_bus_get_sync( G_BUS_TYPE_SESSION, nullptr, &error );
90 if (session_connection == nullptr) {
91 SAL_WARN( "vcl.screensaverinhibitor", "failed to connect to dbus session bus" );
93 if (error != nullptr) {
94 SAL_WARN( "vcl.screensaverinhibitor", "Error: " << error->message );
95 g_error_free( error );
98 return;
101 GDBusProxy *proxy = g_dbus_proxy_new_sync( session_connection,
102 G_DBUS_PROXY_FLAGS_NONE,
103 nullptr,
104 service,
105 path,
106 interface,
107 nullptr,
108 nullptr );
110 g_object_unref( G_OBJECT( session_connection ) );
112 if (proxy == nullptr) {
113 SAL_INFO( "vcl.screensaverinhibitor", "could not get dbus proxy: " << service );
114 return;
117 GVariant *res = nullptr;
119 if ( bInhibit )
121 res = fInhibit( proxy, error );
123 if (res != nullptr)
125 guint nCookie;
127 g_variant_get(res, "(u)", &nCookie);
128 g_variant_unref(res);
130 rCookie = nCookie;
132 else
134 SAL_INFO( "vcl.screensaverinhibitor", service << ".Inhibit failed");
137 else
139 res = fUnInhibit( proxy, *rCookie, error );
140 rCookie.reset();
142 if (res != nullptr)
144 g_variant_unref(res);
146 else
148 SAL_INFO( "vcl.screensaverinhibitor", service << ".UnInhibit failed" );
152 if (error != nullptr)
154 SAL_INFO( "vcl.screensaverinhibitor", "Error: " << error->message );
155 g_error_free( error );
158 g_object_unref( G_OBJECT( proxy ) );
160 #endif // ENABLE_GIO
162 void ScreenSaverInhibitor::inhibitFDO( bool bInhibit, const char* appname, const char* reason )
164 #if ENABLE_GIO
165 dbusInhibit( bInhibit,
166 FDO_DBUS_SERVICE, FDO_DBUS_PATH, FDO_DBUS_INTERFACE,
167 [appname, reason] ( GDBusProxy *proxy, GError*& error ) -> GVariant* {
168 return g_dbus_proxy_call_sync( proxy, "Inhibit",
169 g_variant_new("(ss)", appname, reason),
170 G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error );
172 [] ( GDBusProxy *proxy, const guint nCookie, GError*& error ) -> GVariant* {
173 return g_dbus_proxy_call_sync( proxy, "UnInhibit",
174 g_variant_new("(u)", nCookie),
175 G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error );
177 mnFDOCookie );
178 #else
179 (void) this;
180 (void) bInhibit;
181 (void) appname;
182 (void) reason;
183 #endif // ENABLE_GIO
186 void ScreenSaverInhibitor::inhibitFDOPM( bool bInhibit, const char* appname, const char* reason )
188 #if ENABLE_GIO
189 dbusInhibit( bInhibit,
190 FDOPM_DBUS_SERVICE, FDOPM_DBUS_PATH, FDOPM_DBUS_INTERFACE,
191 [appname, reason] ( GDBusProxy *proxy, GError*& error ) -> GVariant* {
192 return g_dbus_proxy_call_sync( proxy, "Inhibit",
193 g_variant_new("(ss)", appname, reason),
194 G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error );
196 [] ( GDBusProxy *proxy, const guint nCookie, GError*& error ) -> GVariant* {
197 return g_dbus_proxy_call_sync( proxy, "UnInhibit",
198 g_variant_new("(u)", nCookie),
199 G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error );
201 mnFDOPMCookie );
202 #else
203 (void) this;
204 (void) bInhibit;
205 (void) appname;
206 (void) reason;
207 #endif // ENABLE_GIO
210 void ScreenSaverInhibitor::inhibitGSM( bool bInhibit, const char* appname, const char* reason, const unsigned int xid )
212 #if ENABLE_GIO
213 dbusInhibit( bInhibit,
214 GSM_DBUS_SERVICE, GSM_DBUS_PATH, GSM_DBUS_INTERFACE,
215 [appname, reason, xid] ( GDBusProxy *proxy, GError*& error ) -> GVariant* {
216 return g_dbus_proxy_call_sync( proxy, "Inhibit",
217 g_variant_new("(susu)",
218 appname,
219 xid,
220 reason,
221 8 //Inhibit the session being marked as idle
223 G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error );
225 [] ( GDBusProxy *proxy, const guint nCookie, GError*& error ) -> GVariant* {
226 return g_dbus_proxy_call_sync( proxy, "Uninhibit",
227 g_variant_new("(u)", nCookie),
228 G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error );
230 mnGSMCookie );
231 #else
232 (void) this;
233 (void) bInhibit;
234 (void) appname;
235 (void) reason;
236 (void) xid;
237 #endif // ENABLE_GIO
240 void ScreenSaverInhibitor::inhibitMSM( bool bInhibit, const char* appname, const char* reason, const unsigned int xid )
242 #if ENABLE_GIO
243 dbusInhibit( bInhibit,
244 MSM_DBUS_SERVICE, MSM_DBUS_PATH, MSM_DBUS_INTERFACE,
245 [appname, reason, xid] ( GDBusProxy *proxy, GError*& error ) -> GVariant* {
246 return g_dbus_proxy_call_sync( proxy, "Inhibit",
247 g_variant_new("(susu)",
248 appname,
249 xid,
250 reason,
251 8 //Inhibit the session being marked as idle
253 G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error );
255 [] ( GDBusProxy *proxy, const guint nCookie, GError*& error ) -> GVariant* {
256 return g_dbus_proxy_call_sync( proxy, "Uninhibit",
257 g_variant_new("(u)", nCookie),
258 G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error );
260 mnMSMCookie );
261 #else
262 (void) this;
263 (void) bInhibit;
264 (void) appname;
265 (void) reason;
266 (void) xid;
267 #endif // ENABLE_GIO
271 * Disable screensavers using the XSetScreenSaver/XGetScreenSaver API.
273 * Worth noting: xscreensaver explicitly ignores this and does its own
274 * timeout handling.
276 void ScreenSaverInhibitor::inhibitXScreenSaver( bool bInhibit, Display* pDisplay )
278 int nTimeout, nInterval, bPreferBlanking, bAllowExposures;
279 XGetScreenSaver( pDisplay, &nTimeout, &nInterval,
280 &bPreferBlanking, &bAllowExposures );
282 // To disable/reenable we simply fiddle the timeout, whilst
283 // retaining all other properties.
284 if ( bInhibit && nTimeout)
286 mnXScreenSaverTimeout = nTimeout;
287 XResetScreenSaver( pDisplay );
288 XSetScreenSaver( pDisplay, 0, nInterval,
289 bPreferBlanking, bAllowExposures );
291 else if ( !bInhibit && mnXScreenSaverTimeout )
293 XSetScreenSaver( pDisplay, *mnXScreenSaverTimeout,
294 nInterval, bPreferBlanking,
295 bAllowExposures );
296 mnXScreenSaverTimeout.reset();
301 /* definitions from xautolock.c (pl15) */
302 #define XAUTOLOCK_DISABLE 1
303 #define XAUTOLOCK_ENABLE 2
305 void ScreenSaverInhibitor::inhibitXAutoLock( bool bInhibit, Display* pDisplay )
307 ::Window aRootWindow = RootWindowOfScreen( ScreenOfDisplay( pDisplay, 0 ) );
309 Atom nAtom = XInternAtom( pDisplay,
310 "XAUTOLOCK_MESSAGE",
311 False );
313 if ( nAtom == None )
315 return;
318 int nMessage = bInhibit ? XAUTOLOCK_DISABLE : XAUTOLOCK_ENABLE;
320 XChangeProperty( pDisplay,
321 aRootWindow,
322 nAtom,
323 XA_INTEGER,
324 8, // format -- 8 bit quantity
325 PropModeReplace,
326 reinterpret_cast<unsigned char*>( &nMessage ),
327 sizeof( nMessage ) );
330 void ScreenSaverInhibitor::inhibitDPMS( bool bInhibit, Display* pDisplay )
332 #if !defined(__sun) && !defined(AIX)
333 int dummy;
334 // This won't change while X11 is running, hence
335 // we can evaluate only once and store as static
336 static bool bDPMSExtensionAvailable = ( DPMSQueryExtension( pDisplay, &dummy, &dummy) != 0 );
338 if ( !bDPMSExtensionAvailable )
340 return;
343 if ( bInhibit )
345 CARD16 state; // unused by us
346 DPMSInfo( pDisplay, &state, &mbDPMSWasEnabled );
348 if ( mbDPMSWasEnabled )
350 DPMSGetTimeouts( pDisplay,
351 &mnDPMSStandbyTimeout,
352 &mnDPMSSuspendTimeout,
353 &mnDPMSOffTimeout );
354 DPMSSetTimeouts( pDisplay,
357 0 );
360 else if ( !bInhibit && mbDPMSWasEnabled )
362 DPMSSetTimeouts( pDisplay,
363 mnDPMSStandbyTimeout,
364 mnDPMSSuspendTimeout,
365 mnDPMSOffTimeout );
367 #endif // !defined(__sun) && !defined(AIX)
370 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */