diff options
author | Thomas White <taw@physics.org> | 2018-01-19 21:54:53 +0100 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2018-01-19 22:30:31 +0100 |
commit | 3ded4e93cb9657c4cdb0a86bce6d18b98f00d087 (patch) | |
tree | 2e43517e2a0f73c95597626a49215761cc3b726f /src | |
parent | 62bc4fb111b38e8d3969451462d3c5e08b086c35 (diff) |
Inhibit screensaver using native GTK method
Diffstat (limited to 'src')
-rw-r--r-- | src/inhibit_screensaver.c | 254 | ||||
-rw-r--r-- | src/inhibit_screensaver.h | 36 | ||||
-rw-r--r-- | src/narrative_window.c | 6 | ||||
-rw-r--r-- | src/presentation.c | 1 | ||||
-rw-r--r-- | src/slideshow.c | 17 | ||||
-rw-r--r-- | src/slideshow.h | 5 | ||||
-rw-r--r-- | src/testcard.c | 7 |
7 files changed, 16 insertions, 310 deletions
diff --git a/src/inhibit_screensaver.c b/src/inhibit_screensaver.c deleted file mode 100644 index e982144..0000000 --- a/src/inhibit_screensaver.c +++ /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 index 0a62adc..0000000 --- a/src/inhibit_screensaver.h +++ /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 */ diff --git a/src/narrative_window.c b/src/narrative_window.c index fa58c08..6381755 100644 --- a/src/narrative_window.c +++ b/src/narrative_window.c @@ -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", diff --git a/src/presentation.c b/src/presentation.c index dab3e4e..0169f19 100644 --- a/src/presentation.c +++ b/src/presentation.c @@ -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" diff --git a/src/slideshow.c b/src/slideshow.c index e0d33bb..596b3ff 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -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; } diff --git a/src/slideshow.h b/src/slideshow.h index f52313e..be96303 100644 --- a/src/slideshow.h +++ b/src/slideshow.h @@ -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 */ diff --git a/src/testcard.c b/src/testcard.c index 74fa153..45fc348 100644 --- a/src/testcard.c +++ b/src/testcard.c @@ -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); } |