Inhibit screensaver using native GTK method
authorThomas White <taw@physics.org>
Fri, 19 Jan 2018 20:54:53 +0000 (21:54 +0100)
committerThomas White <taw@physics.org>
Fri, 19 Jan 2018 21:30:31 +0000 (22:30 +0100)
AUTHORS
Makefile.am
src/inhibit_screensaver.c [deleted file]
src/inhibit_screensaver.h [deleted file]
src/narrative_window.c
src/presentation.c
src/slideshow.c
src/slideshow.h
src/testcard.c

diff --git a/AUTHORS b/AUTHORS
index a78c19f..7174f0d 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,5 +1 @@
 Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
-
-Screensaver inhibition code, from VLC (src/inhibit_screensaver.c):
- Copyright © 2009-2012 Rémi Denis-Courmont
- Copyright © 2007-2012 Rafaël Carré
index 4e45359..446fb91 100644 (file)
@@ -14,7 +14,6 @@ src_colloquium_SOURCES = src/colloquium.c src/render.c \
                          src/frame.c src/sc_parse.c \
                          src/slideshow.c src/sc_interp.c \
                          src/imagestore.c src/pr_clock.c \
-                         src/inhibit_screensaver.c \
                          src/sc_editor.c src/narrative_window.c \
                          src/slide_window.c src/testcard.c src/print.c \
                          src/debugger.c
@@ -22,7 +21,7 @@ src_colloquium_SOURCES = src/colloquium.c src/render.c \
 EXTRA_DIST += src/presentation.h src/render.h \
               src/slideshow.h src/sc_parse.h src/sc_interp.h \
               src/imagestore.h src/pr_clock.h \
-              src/inhibit_screensaver.h src/print.h \
+              src/print.h \
               src/sc_editor.h src/slide_window.h src/narrative_window.h \
               src/print.h src/debugger.h
 
diff --git a/src/inhibit_screensaver.c b/src/inhibit_screensaver.c
deleted file mode 100644 (file)
index e982144..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * inhibit_screensaver.c
- *
- * Copyright © 2013 Thomas White <taw@bitwiz.org.uk>
- * Copyright © 2009-2012 Rémi Denis-Courmont
- * Copyright © 2007-2012 Rafaël Carré
- *
- * This file is part of Colloquium.
- *
- * Colloquium is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * >>> This file is based on dbus.c from VLC. The original licence is below. <<<
- *
- */
-
-/*****************************************************************************
- * dbus.c: power management inhibition using D-Bus
- *****************************************************************************
- * Copyright © 2009-2012 Rémi Denis-Courmont
- * Copyright © 2007-2012 Rafaël Carré
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-/*
- * Based on freedesktop Power Management Specification version 0.2
- * http://people.freedesktop.org/~hughsient/temp/power-management-spec-0.2.html
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <dbus/dbus.h>
-
-
-enum inhibit_api
-{
-       FDO_SS, /**< KDE >= 4 and GNOME >= 3.6 */
-       FDO_PM, /**< KDE and GNOME <= 2.26 */
-       MATE,   /**< >= 1.0 */
-       GNOME,  /**< GNOME 2.26..3.4 */
-};
-
-#define MAX_API (GNOME+1)
-
-
-/* Currently, all services have identical service and interface names. */
-static const char dbus_service[][40] =
-{
-       [FDO_SS] = "org.freedesktop.ScreenSaver",
-       [FDO_PM] = "org.freedesktop.PowerManagement.Inhibit",
-       [MATE]   = "org.mate.SessionManager",
-       [GNOME]  = "org.gnome.SessionManager",
-};
-
-
-static const char dbus_path[][33] =
-{
-       [FDO_SS] = "/ScreenSaver",
-       [FDO_PM] = "/org/freedesktop/PowerManagement",
-       [MATE]   = "/org/mate/SessionManager",
-       [GNOME]  = "/org/gnome/SessionManager",
-};
-
-
-static const char dbus_method_uninhibit[][10] =
-{
-       [FDO_SS] = "UnInhibit",
-       [FDO_PM] = "UnInhibit",
-       [MATE]   = "Uninhibit",
-       [GNOME]  = "Uninhibit",
-};
-
-
-struct inhibit_sys
-{
-       DBusConnection *conn;
-       DBusPendingCall *pending;
-       dbus_uint32_t cookie;
-       enum inhibit_api api;
-};
-
-
-void do_inhibit(struct inhibit_sys *sys, int flags)
-{
-       enum inhibit_api type = sys->api;
-
-       /* Receive reply from previous request, possibly hours later ;-) */
-       if ( sys->pending != NULL ) {
-
-               DBusMessage *reply;
-
-               /* NOTE: Unfortunately, the pending reply cannot simply be
-                * cancelled.   Otherwise, the cookie would be lost and
-                * inhibition would remain on (until complete disconnection from
-                * the bus). */
-               dbus_pending_call_block(sys->pending);
-               reply = dbus_pending_call_steal_reply(sys->pending);
-               dbus_pending_call_unref(sys->pending);
-               sys->pending = NULL;
-
-               if ( reply != NULL ) {
-                       if ( !dbus_message_get_args(reply, NULL,
-                                                   DBUS_TYPE_UINT32,
-                                                   &sys->cookie,
-                                                   DBUS_TYPE_INVALID))
-                       {
-                               sys->cookie = 0;
-                       }
-                       dbus_message_unref(reply);
-               }
-
-       }
-
-       /* FIXME: This check is incorrect if flags change from one non-zero value
-        * to another one. But the D-Bus API cannot currently inhibit suspend
-        * independently from the screensaver. */
-       if ( !sys->cookie == !flags ) return; /* nothing to do */
-
-       /* Send request */
-       const char *method = flags ? "Inhibit" : dbus_method_uninhibit[type];
-       dbus_bool_t ret;
-
-       DBusMessage *msg = dbus_message_new_method_call(dbus_service[type],
-                                                       dbus_path[type],
-                                                       dbus_service[type],
-                                                       method);
-       if ( msg == NULL ) return;
-
-    if (flags)
-    {
-        const char *app = PACKAGE;
-        const char *reason = "Presentation in progress";
-
-        assert(sys->cookie == 0);
-
-        switch (type)
-        {
-            case MATE:
-            case GNOME:
-            {
-                dbus_uint32_t xid = 0; // FIXME ?
-                dbus_uint32_t gflags = 0xC;
-
-                ret = dbus_message_append_args(msg, DBUS_TYPE_STRING, &app,
-                                                    DBUS_TYPE_UINT32, &xid,
-                                                    DBUS_TYPE_STRING, &reason,
-                                                    DBUS_TYPE_UINT32, &gflags,
-                                                    DBUS_TYPE_INVALID);
-                break;
-            }
-            default:
-                ret = dbus_message_append_args(msg, DBUS_TYPE_STRING, &app,
-                                                    DBUS_TYPE_STRING, &reason,
-                                                    DBUS_TYPE_INVALID);
-                break;
-        }
-
-        if (!ret
-        || !dbus_connection_send_with_reply(sys->conn, msg, &sys->pending, -1))
-            sys->pending = NULL;
-    }
-    else
-    {
-        assert(sys->cookie != 0);
-        if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &sys->cookie,
-                                           DBUS_TYPE_INVALID)
-         || !dbus_connection_send (sys->conn, msg, NULL))
-            sys->cookie = 0;
-    }
-    dbus_connection_flush(sys->conn);
-    dbus_message_unref(msg);
-}
-
-
-void inhibit_cleanup(struct inhibit_sys *sys)
-{
-       if ( sys->pending != NULL ) {
-               dbus_pending_call_cancel(sys->pending);
-               dbus_pending_call_unref(sys->pending);
-       }
-
-       dbus_connection_close(sys->conn);
-       dbus_connection_unref(sys->conn);
-       free(sys);
-}
-
-
-struct inhibit_sys *inhibit_prepare()
-{
-       struct inhibit_sys *sys;
-       DBusError err;
-       int i;
-
-       sys = malloc(sizeof(struct inhibit_sys));
-       if ( sys == NULL ) {
-               fprintf(stderr, "Failed to allocate inhibit.\n");
-               return NULL;
-       }
-
-       dbus_error_init(&err);
-
-       sys->conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
-       if ( sys->conn == NULL ) {
-               fprintf(stderr, "cannot connect to session bus: %s\n",
-                       err.message);
-               dbus_error_free(&err);
-               free(sys);
-               return NULL;
-       }
-
-       sys->pending = NULL;
-       sys->cookie = 0;
-
-       for ( i=0; i<MAX_API; i++ ) {
-               if ( dbus_bus_name_has_owner(sys->conn, dbus_service[i], NULL) )
-               {
-                       sys->api = i;
-                       return sys;
-               }
-
-               fprintf(stderr, "cannot find service %s\n", dbus_service[i]);
-       }
-
-       inhibit_cleanup(sys);
-       return NULL;
-}
diff --git a/src/inhibit_screensaver.h b/src/inhibit_screensaver.h
deleted file mode 100644 (file)
index 0a62adc..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * inhibit_screensaver.h
- *
- * Copyright © 2013 Thomas White <taw@bitwiz.org.uk>
- *
- * This file is part of Colloquium.
- *
- * Colloquium is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef INHIBIT_SCREENSAVER_H
-#define INHIBIT_SCREENSAVER_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-struct inhibit_sys;
-
-extern void do_inhibit(struct inhibit_sys *sys, int flags);
-extern void inhibit_cleanup(struct inhibit_sys *sys);
-extern struct inhibit_sys *inhibit_prepare(void);
-
-#endif /* INHIBIT_SCREENSAVER_H */
index fa58c08..6381755 100644 (file)
@@ -592,7 +592,7 @@ static void start_slideshow_here_sig(GSimpleAction *action, GVariant *parameter,
        bvp = sc_editor_get_cursor_bvp(nw->sceditor);
        if ( bvp == NULL ) return;
 
-       nw->show = sc_slideshow_new(nw->p);
+       nw->show = sc_slideshow_new(nw->p, GTK_APPLICATION(nw->app));
        if ( nw->show == NULL ) return;
 
        g_signal_connect(G_OBJECT(nw->show), "key-press-event",
@@ -613,7 +613,7 @@ static void start_slideshow_noslides_sig(GSimpleAction *action, GVariant *parame
 
        if ( num_slides(nw->p) == 0 ) return;
 
-       nw->show = sc_slideshow_new(nw->p);
+       nw->show = sc_slideshow_new(nw->p, GTK_APPLICATION(nw->app));
        if ( nw->show == NULL ) return;
 
        g_signal_connect(G_OBJECT(nw->show), "key-press-event",
@@ -634,7 +634,7 @@ static void start_slideshow_sig(GSimpleAction *action, GVariant *parameter,
 
        if ( num_slides(nw->p) == 0 ) return;
 
-       nw->show = sc_slideshow_new(nw->p);
+       nw->show = sc_slideshow_new(nw->p, GTK_APPLICATION(nw->app));
        if ( nw->show == NULL ) return;
 
        g_signal_connect(G_OBJECT(nw->show), "key-press-event",
index dab3e4e..0169f19 100644 (file)
@@ -34,7 +34,6 @@
 #include "slide_window.h"
 #include "frame.h"
 #include "imagestore.h"
-#include "inhibit_screensaver.h"
 #include "render.h"
 #include "sc_interp.h"
 
index e0d33bb..596b3ff 100644 (file)
@@ -34,7 +34,6 @@
 #include "presentation.h"
 #include "render.h"
 #include "pr_clock.h"
-#include "inhibit_screensaver.h"
 #include "frame.h"
 
 G_DEFINE_TYPE_WITH_CODE(SCSlideshow, sc_slideshow, GTK_TYPE_WINDOW, NULL)
@@ -87,6 +86,9 @@ static gint ss_destroy_sig(GtkWidget *widget, SCSlideshow *ss)
        if ( ss->surface != NULL ) {
                cairo_surface_destroy(ss->surface);
        }
+       if ( ss->app != NULL ) {
+               gtk_application_uninhibit(ss->app, ss->inhibit_cookie);
+       }
        return FALSE;
 }
 
@@ -167,7 +169,7 @@ void sc_slideshow_set_slide(SCSlideshow *ss, SCBlock *ns)
 }
 
 
-SCSlideshow *sc_slideshow_new(struct presentation *p)
+SCSlideshow *sc_slideshow_new(struct presentation *p, GtkApplication *app)
 {
        GdkDisplay *display;
        int n_monitors;
@@ -182,10 +184,6 @@ SCSlideshow *sc_slideshow_new(struct presentation *p)
        ss->blank_cursor = NULL;
        ss->surface = NULL;
 
-       if ( ss->inhibit == NULL ) {
-               ss->inhibit = inhibit_prepare();
-       }
-
        ss->drawingarea = gtk_drawing_area_new();
        gtk_container_add(GTK_CONTAINER(ss), ss->drawingarea);
 
@@ -227,7 +225,12 @@ SCSlideshow *sc_slideshow_new(struct presentation *p)
 
        ss->linked = 1;
 
-       if ( ss->inhibit != NULL ) do_inhibit(ss->inhibit, 1);
+       if ( app != NULL ) {
+               ss->inhibit_cookie = gtk_application_inhibit(app, GTK_WINDOW(ss),
+                                                            GTK_APPLICATION_INHIBIT_IDLE,
+                                                            "Presentation slide show is running");
+               ss->app = app;
+       }
 
        return ss;
 }
index f52313e..be96303 100644 (file)
@@ -58,11 +58,12 @@ struct _scslideshow
        int                  slide_height;
        int                  xoff;
        int                  yoff;
-       struct inhibit_sys  *inhibit;
        int                  linked;
        cairo_surface_t     *surface;
        struct frame        *top;
        int                  single_monitor;
+       uint                 inhibit_cookie;
+       GtkApplication      *app;
 };
 
 
@@ -74,7 +75,7 @@ struct _scslideshowclass
 typedef struct _scslideshow SCSlideshow;
 typedef struct _scslideshowclass SCSlideshowClass;
 
-extern SCSlideshow *sc_slideshow_new(struct presentation *p);
+extern SCSlideshow *sc_slideshow_new(struct presentation *p, GtkApplication *app);
 extern void sc_slideshow_set_slide(SCSlideshow *ss, SCBlock *ns);
 
 #endif /* SLIDESHOW_H */
index 74fa153..45fc348 100644 (file)
@@ -31,7 +31,6 @@
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
 
-#include "inhibit_screensaver.h"
 #include "presentation.h"
 
 
@@ -42,7 +41,6 @@ struct testcard
        int slide_width;
        int slide_height;
        GtkWidget *drawingarea;
-       struct inhibit_sys *inhibit;
        struct presentation *p;
 };
 
@@ -245,10 +243,6 @@ void show_testcard(struct presentation *p)
 
        tc->p = p;
 
-       if ( tc->inhibit == NULL ) {
-               tc->inhibit = inhibit_prepare();
-       }
-
        tc->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
        tc->drawingarea = gtk_drawing_area_new();
@@ -288,6 +282,5 @@ void show_testcard(struct presentation *p)
 
        gtk_widget_show_all(GTK_WIDGET(tc->window));
 
-       if ( tc->inhibit != NULL ) do_inhibit(tc->inhibit, 1);
 }