diff options
-rw-r--r-- | doc/man/Makefile.am | 20 | ||||
-rw-r--r-- | doc/man/mate-session-inhibit.xml | 92 | ||||
-rw-r--r-- | po/POTFILES.in | 1 | ||||
-rw-r--r-- | tools/Makefile.am | 14 | ||||
-rw-r--r-- | tools/mate-session-inhibit.c | 242 |
5 files changed, 366 insertions, 3 deletions
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 0e88e3d..1a5a919 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -1,10 +1,26 @@ +XSLTPROC_FLAGS = \ + --nonet \ + --stringparam man.output.quietly 1 \ + --stringparam funcsynopsis.style ansi \ + --stringparam man.th.extra1.suppress 1 \ + --stringparam man.authors.section.enabled 0 \ + --stringparam man.copyright.section.enabled 0 + +.xml.1: + $(AM_V_GEN) $(XSLTPROC) $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< + man_MANS = \ mate-session.1 \ mate-session-properties.1 \ mate-session-save.1 \ - mate-wm.1 + mate-wm.1 \ + mate-session-inhibit.1 -EXTRA_DIST = \ +EXTRA_DIST = \ + mate-session-inhibit.xml \ $(man_MANS) +CLEANFILES = \ + mate-session-inhibit.1 + -include $(top_srcdir)/git.mk diff --git a/doc/man/mate-session-inhibit.xml b/doc/man/mate-session-inhibit.xml new file mode 100644 index 0000000..10ed92c --- /dev/null +++ b/doc/man/mate-session-inhibit.xml @@ -0,0 +1,92 @@ +<refentry id="mate-session-inhibit" lang="en"> + +<refentryinfo> +<title>mate-session-inhibit</title> +<productname>mate-session</productname> +</refentryinfo> + +<refmeta> +<refentrytitle>mate-session-inhibit</refentrytitle> +<manvolnum>1</manvolnum> +<refmiscinfo class="manual">User Commands</refmiscinfo> +</refmeta> + +<refnamediv> +<refname>mate-session-inhibit</refname> +<refpurpose>inhibit mate-session functionality</refpurpose> +</refnamediv> + +<refsynopsisdiv> +<cmdsynopsis> +<command>mate-session-inhibit</command> +<arg choice="opt" rep="repeat">OPTION</arg> +<arg choice="req">COMMAND</arg> +</cmdsynopsis> +</refsynopsisdiv> + +<refsect1><title>Description</title> +<para><command>mate-session-inhibit</command> can inhibit certain +mate-session functionality while executing the given COMMAND. To +achieve this, it calls the Inhibit() method of the mate-session +D-Bus API and creates an inhibitor. The inhibitor is automatically +removed when mate-session-inhibit exits. +</para> +<para> +A typical use case is to prevent the session from going idle (and +thus locking the screen) while a movie player is running. +</para> + +</refsect1> + +<refsect1><title>Options</title> +<variablelist> + +<varlistentry> +<term><option>-h</option>, <option>--help</option></term> +<listitem><para> +print help and exit +</para></listitem> +</varlistentry> + +<varlistentry> +<term><option>--version</option></term> +<listitem><para> +print version information and exit +</para></listitem> +</varlistentry> + +<varlistentry> +<term><option>--app-id</option> ID</term> +<listitem><para> +The application id to use when calling the mate-session Inhibit() method. +If this option is not specified, "unknown" is used. +</para></listitem> +</varlistentry> + +<varlistentry> +<term><option>--reason</option> REASON</term> +<listitem><para> +A human-readable reason to pass along when calling the mate-session +Inhibit() method. If this option is not specified, "not specified" is used. +</para></listitem> +</varlistentry> + +<varlistentry> +<term><option>--inhibit</option> ARG</term> +<listitem><para> +ARG specifies the things to inhibit, as a colon-separated list. The +possible values are logout, switch-user, suspend, idle, automount. +If this option is used more than once, the values are combined. +If this option is not specified, "idle" is assumed. +</para></listitem> +</varlistentry> + +</variablelist> +</refsect1> + +<refsect1><title>See also</title> +<para> +<citerefentry><refentrytitle>systemd-inhibit</refentrytitle><manvolnum>1</manvolnum></citerefentry> +</para> +</refsect1> +</refentry> diff --git a/po/POTFILES.in b/po/POTFILES.in index 928b5e1..e59589e 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -20,3 +20,4 @@ mate-session/gsm-xsmp-server.c mate-session/gsm-util.c mate-session/main.c tools/mate-session-save.c +tools/mate-session-inhibit.c diff --git a/tools/Makefile.am b/tools/Makefile.am index 4e3ba0f..a7c42c0 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,4 +1,4 @@ -bin_PROGRAMS = mate-session-save +bin_PROGRAMS = mate-session-save mate-session-inhibit AM_CPPFLAGS = \ $(MATE_SESSION_CFLAGS) \ @@ -19,4 +19,16 @@ mate_session_save_LDADD = \ $(DBUS_GLIB_LIBS) \ $(MATECONF_LIBS) +mate_session_inhibit_SOURCES = \ + mate-session-inhibit.c + +mate_session_inhibit_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + $(MATE_SESSION_CFLAGS) \ + -DLOCALE_DIR=\""$(datadir)/locale"\" \ + $(DISABLE_DEPRECATED_CFLAGS) + +mate_session_inhibit_LDADD = \ + $(MATE_SESSION_LIBS) + -include $(top_srcdir)/git.mk diff --git a/tools/mate-session-inhibit.c b/tools/mate-session-inhibit.c new file mode 100644 index 0000000..cd6c182 --- /dev/null +++ b/tools/mate-session-inhibit.c @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2012 Red Hat, Inc. + * + * This program 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 2, 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gio/gio.h> + +typedef enum { + GSM_INHIBITOR_FLAG_LOGOUT = 1 << 0, + GSM_INHIBITOR_FLAG_SWITCH_USER = 1 << 1, + GSM_INHIBITOR_FLAG_SUSPEND = 1 << 2, + GSM_INHIBITOR_FLAG_IDLE = 1 << 3, + GSM_INHIBITOR_FLAG_AUTOMOUNT = 1 << 4 +} GsmInhibitorFlags; + +static GsmInhibitorFlags parse_flags (const gchar *arg) +{ + GsmInhibitorFlags flags; + gchar **args; + gint i; + + flags = 0; + + args = g_strsplit (arg, ":", 0); + for (i = 0; args[i]; i++) + { + if (strcmp (args[i], "logout") == 0) + flags |= GSM_INHIBITOR_FLAG_LOGOUT; + else if (strcmp (args[i], "switch-user") == 0) + flags |= GSM_INHIBITOR_FLAG_SWITCH_USER; + else if (strcmp (args[i], "suspend") == 0) + flags |= GSM_INHIBITOR_FLAG_SUSPEND; + else if (strcmp (args[i], "idle") == 0) + flags |= GSM_INHIBITOR_FLAG_IDLE; + else if (strcmp (args[i], "automount") == 0) + flags |= GSM_INHIBITOR_FLAG_AUTOMOUNT; + else + g_print ("Ignoring inhibit argument: %s\n", args[i]); + } + + g_strfreev (args); + + return flags; +} + +static gboolean inhibit (const gchar *app_id, + const gchar *reason, + GsmInhibitorFlags flags) +{ + GDBusConnection *bus; + GVariant *ret; + GError *error = NULL; + + bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + + if (bus == NULL) + { + g_warning ("Failed to connect to session bus: %s", error->message); + g_error_free (error); + return FALSE; + } + + ret = g_dbus_connection_call_sync (bus, + "org.mate.SessionManager", + "/org/mate/SessionManager", + "org.mate.SessionManager", + "Inhibit", + g_variant_new ("(susu)", + app_id, 0, reason, flags), + G_VARIANT_TYPE ("(u)"), + 0, + G_MAXINT, + NULL, + &error); + + if (ret == NULL) + { + g_warning ("Failed to call Inhibit: %s\n", error->message); + g_error_free (error); + return FALSE; + } + + g_variant_unref (ret); + + return TRUE; +} + +static void usage (void) +{ + g_print (_("%s [OPTION...] COMMAND\n" + "\n" + "Execute COMMAND while inhibiting some session functionality.\n" + "\n" + " -h, --help Show this help\n" + " --version Show program version\n" + " --app-id ID The application id to use\n" + " when inhibiting (optional)\n" + " --reason REASON The reason for inhibiting (optional)\n" + " --inhibit ARG Things to inhibit, colon-separated list of:\n" + " logout, switch-user, suspend, idle, automount\n" + "\n" + "If no --inhibit option is specified, idle is assumed.\n"), + g_get_prgname ()); +} + +static void version (void) +{ + g_print ("%s %s\n", g_get_prgname (), PACKAGE_VERSION); +} + +int main (int argc, char *argv[]) +{ + gchar *prgname; + GsmInhibitorFlags inhibit_flags = 0; + gboolean show_help = FALSE; + gboolean show_version = FALSE; + gint i; + pid_t pid; + int status; + const gchar *app_id = "unknown"; + const gchar *reason = "not specified"; + + prgname = g_path_get_basename (argv[0]); + g_set_prgname (prgname); + g_free (prgname); + + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + for (i = 1; i < argc; i++) + { + if (strcmp (argv[i], "--help") == 0 || + strcmp (argv[i], "-h") == 0) + show_help = TRUE; + else if (strcmp (argv[i], "--version") == 0) + show_version = TRUE; + else if (strcmp (argv[i], "--app-id") == 0) + { + i++; + if (i == argc) + { + g_print (_("%s requires an argument\n"), argv[i]); + exit (1); + } + app_id = argv[i]; + } + else if (strcmp (argv[i], "--reason") == 0) + { + i++; + if (i == argc) + { + g_print (_("%s requires an argument\n"), argv[i]); + exit (1); + } + reason = argv[i]; + } + else if (strcmp (argv[i], "--inhibit") == 0) + { + i++; + if (i == argc) + { + g_print (_("%s requires an argument\n"), argv[i]); + exit (1); + } + inhibit_flags |= parse_flags (argv[i]); + } + else + break; + } + + if (show_version) + { + version (); + return 0; + } + + if (show_help || i == argc) + { + usage (); + return 0; + } + + if (inhibit_flags == 0) + inhibit_flags = GSM_INHIBITOR_FLAG_IDLE; + + inhibit (app_id, reason, inhibit_flags); + + pid = fork (); + if (pid < 0) + { + g_print ("fork failed\n"); + exit (1); + } + + if (pid == 0) + { + execvp (argv[i], argv + i); + g_print (_("Failed to execute %s\n"), argv[i]); + exit (1); + } + + do + { + if (waitpid (pid, &status, 0) == -1) + { + g_print ("waitpid failed\n"); + exit (1); + } + + if (WIFEXITED (status)) + exit (WEXITSTATUS (status)); + + } while (!WIFEXITED (status) && ! WIFSIGNALED(status)); + + return 0; +} |