Blob Blame History Raw
From 76c34858d18c7ec2bdef6ceeee22b047a0a1bdcb Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 14 Jan 2019 11:11:01 -0500
Subject: [PATCH 2/9] backend: switch to using generated logind proxy

Right now we listen to prepare-for-sleep using
raw gdbus calls.

This commit switches it over to use a generated
proxy, which will become useful in a future commit,
for adding suspending inhibitors.
---
 src/backends/meta-backend.c    | 60 ++++++++++++++++++++++------------
 src/org.freedesktop.login1.xml | 14 ++++++++
 2 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 28f1cd92f..2f090e233 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -8,60 +8,61 @@
  * published by the Free Software Foundation; either version 2 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, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  * 02111-1307, USA.
  *
  * Written by:
  *     Jasper St. Pierre <jstpierre@mecheye.net>
  */
 
 #include "config.h"
 
 #include <stdlib.h>
 
 #include <clutter/clutter-mutter.h>
 #include <meta/meta-backend.h>
 #include <meta/main.h>
 #include <meta/util.h>
 #include "meta-backend-private.h"
 #include "meta-input-settings-private.h"
 #include "backends/x11/meta-backend-x11.h"
 #include "meta-cursor-tracker-private.h"
 #include "meta-stage-private.h"
+#include "meta-dbus-login1.h"
 
 #ifdef HAVE_REMOTE_DESKTOP
 #include "backends/meta-dbus-session-watcher.h"
 #include "backends/meta-screen-cast.h"
 #include "backends/meta-remote-access-controller-private.h"
 #include "backends/meta-remote-desktop.h"
 #endif
 
 #ifdef HAVE_NATIVE_BACKEND
 #include "backends/native/meta-backend-native.h"
 #endif
 
 #include "backends/meta-idle-monitor-private.h"
 #include "backends/meta-logical-monitor.h"
 #include "backends/meta-monitor-manager-dummy.h"
 #include "backends/meta-settings-private.h"
 
 #define META_IDLE_MONITOR_CORE_DEVICE 0
 
 enum
 {
   KEYMAP_CHANGED,
   KEYMAP_LAYOUT_GROUP_CHANGED,
   LAST_DEVICE_CHANGED,
 
   N_SIGNALS
 };
 
 static guint signals[N_SIGNALS];
 
@@ -87,93 +88,97 @@ struct _MetaBackendPrivate
   MetaMonitorManager *monitor_manager;
   MetaOrientationManager *orientation_manager;
   MetaCursorTracker *cursor_tracker;
   MetaCursorRenderer *cursor_renderer;
   MetaInputSettings *input_settings;
   MetaRenderer *renderer;
   MetaEgl *egl;
   MetaSettings *settings;
 #ifdef HAVE_REMOTE_DESKTOP
   MetaRemoteAccessController *remote_access_controller;
   MetaDbusSessionWatcher *dbus_session_watcher;
   MetaScreenCast *screen_cast;
   MetaRemoteDesktop *remote_desktop;
 #endif
 
   ClutterBackend *clutter_backend;
   ClutterActor *stage;
 
   gboolean is_pointer_position_initialized;
 
   guint device_update_idle_id;
 
   GHashTable *device_monitors;
 
   int current_device_id;
 
   MetaPointerConstraint *client_pointer_constraint;
   MetaDnd *dnd;
 
   UpClient *up_client;
-  guint sleep_signal_id;
   GCancellable *cancellable;
   GDBusConnection *system_bus;
+
+  Login1Manager *logind_proxy;
+  int            inhibit_sleep_fd;
 };
 typedef struct _MetaBackendPrivate MetaBackendPrivate;
 
 static void
 initable_iface_init (GInitableIface *initable_iface);
 
+
+static void prepare_for_sleep_cb (MetaBackend *backend,
+                                  gboolean     suspending);
+
 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaBackend, meta_backend, G_TYPE_OBJECT,
                                   G_ADD_PRIVATE (MetaBackend)
                                   G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
                                                          initable_iface_init));
 
 static void
 meta_backend_finalize (GObject *object)
 {
   MetaBackend *backend = META_BACKEND (object);
   MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 
   g_clear_object (&priv->monitor_manager);
   g_clear_object (&priv->orientation_manager);
   g_clear_object (&priv->input_settings);
 #ifdef HAVE_REMOTE_DESKTOP
   g_clear_object (&priv->remote_desktop);
   g_clear_object (&priv->screen_cast);
   g_clear_object (&priv->dbus_session_watcher);
   g_clear_object (&priv->remote_access_controller);
 #endif
 
   g_object_unref (priv->up_client);
-  if (priv->sleep_signal_id)
-    g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->sleep_signal_id);
   g_cancellable_cancel (priv->cancellable);
   g_clear_object (&priv->cancellable);
   g_clear_object (&priv->system_bus);
 
   if (priv->device_update_idle_id)
     g_source_remove (priv->device_update_idle_id);
 
   g_hash_table_destroy (priv->device_monitors);
 
   g_clear_object (&priv->settings);
 
   G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
 }
 
 static void
 meta_backend_sync_screen_size (MetaBackend *backend)
 {
   MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
   int width, height;
 
   meta_monitor_manager_get_screen_size (priv->monitor_manager, &width, &height);
 
   META_BACKEND_GET_CLASS (backend)->update_screen_size (backend, width, height);
 }
 
 static void
 reset_pointer_position (MetaBackend *backend)
 {
   MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
   MetaMonitorManager *monitor_manager = priv->monitor_manager;
@@ -553,101 +558,114 @@ meta_backend_class_init (MetaBackendClass *klass)
 static MetaMonitorManager *
 meta_backend_create_monitor_manager (MetaBackend *backend,
                                      GError     **error)
 {
   if (g_getenv ("META_DUMMY_MONITORS"))
     return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
 
   return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend,
                                                                    error);
 }
 
 static MetaRenderer *
 meta_backend_create_renderer (MetaBackend *backend,
                               GError     **error)
 {
   return META_BACKEND_GET_CLASS (backend)->create_renderer (backend, error);
 }
 
 static void
 lid_is_closed_changed_cb (UpClient   *client,
                           GParamSpec *pspec,
                           gpointer    user_data)
 {
   if (up_client_get_lid_is_closed (client))
     return;
 
   meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
 }
 
 static void
-prepare_for_sleep_cb (GDBusConnection *connection,
-                      const gchar     *sender_name,
-                      const gchar     *object_path,
-                      const gchar     *interface_name,
-                      const gchar     *signal_name,
-                      GVariant        *parameters,
-                      gpointer         user_data)
+prepare_for_sleep_cb (MetaBackend *backend,
+                      gboolean     suspending)
 {
   gboolean suspending;
 
   g_variant_get (parameters, "(b)", &suspending);
   if (suspending)
     return;
   meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
 }
 
+static Login1Manager *
+get_logind_proxy (GCancellable *cancellable,
+                  GError      **error)
+{
+  Login1Manager *proxy;
+
+  proxy =
+    login1_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                           G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+                                           "org.freedesktop.login1",
+                                           "/org/freedesktop/login1",
+                                           cancellable, error);
+  if (!proxy)
+    g_prefix_error (error, "Could not get logind proxy: ");
+
+  return proxy;
+}
+
 static void
 system_bus_gotten_cb (GObject      *object,
                       GAsyncResult *res,
                       gpointer      user_data)
 {
   MetaBackendPrivate *priv;
+  g_autoptr (GError) error = NULL;
   GDBusConnection *bus;
 
   bus = g_bus_get_finish (res, NULL);
   if (!bus)
     return;
 
   priv = meta_backend_get_instance_private (user_data);
   priv->system_bus = bus;
-  priv->sleep_signal_id =
-    g_dbus_connection_signal_subscribe (priv->system_bus,
-                                        "org.freedesktop.login1",
-                                        "org.freedesktop.login1.Manager",
-                                        "PrepareForSleep",
-                                        "/org/freedesktop/login1",
-                                        NULL,
-                                        G_DBUS_SIGNAL_FLAGS_NONE,
-                                        prepare_for_sleep_cb,
-                                        NULL,
-                                        NULL);
+  priv->logind_proxy = get_logind_proxy (priv->cancellable, &error);
+
+  if (!priv->logind_proxy)
+    g_warning ("Failed to get logind proxy: %s", error->message);
+
+  g_signal_connect_object (priv->logind_proxy,
+                           "prepare-for-sleep",
+                           G_CALLBACK (prepare_for_sleep_cb),
+                           user_data,
+                           G_CONNECT_SWAPPED);
 }
 
 static gboolean
 meta_backend_initable_init (GInitable     *initable,
                             GCancellable  *cancellable,
                             GError       **error)
 {
   MetaBackend *backend = META_BACKEND (initable);
   MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 
   priv->settings = meta_settings_new (backend);
 
   priv->egl = g_object_new (META_TYPE_EGL, NULL);
 
   priv->orientation_manager = g_object_new (META_TYPE_ORIENTATION_MANAGER, NULL);
 
   priv->monitor_manager = meta_backend_create_monitor_manager (backend, error);
   if (!priv->monitor_manager)
     return FALSE;
 
   priv->renderer = meta_backend_create_renderer (backend, error);
   if (!priv->renderer)
     return FALSE;
 
   priv->cursor_tracker = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
 
   priv->dnd = g_object_new (META_TYPE_DND, NULL);
 
   priv->up_client = up_client_new ();
   g_signal_connect (priv->up_client, "notify::lid-is-closed",
diff --git a/src/org.freedesktop.login1.xml b/src/org.freedesktop.login1.xml
index 765475132..7db8f373c 100644
--- a/src/org.freedesktop.login1.xml
+++ b/src/org.freedesktop.login1.xml
@@ -16,31 +16,45 @@
       <arg name="major" type="u" direction="in"/>
       <arg name="minor" type="u" direction="in"/>
       <arg name="fd" type="h" direction="out"/>
       <arg name="paused" type="b" direction="out"/>
     </method>
     <method name="ReleaseDevice">
       <arg name="major" type="u"/>
       <arg name="minor" type="u"/>
     </method>
     <method name="PauseDeviceComplete">
       <arg name="major" type="u"/>
       <arg name="minor" type="u"/>
     </method>
     <signal name="PauseDevice">
       <arg name="major" type="u"/>
       <arg name="minor" type="u"/>
       <arg name="type" type="s"/>
     </signal>
     <signal name="ResumeDevice">
       <arg name="major" type="u"/>
       <arg name="minor" type="u"/>
       <arg name="fd" type="h"/>
     </signal>
   </interface>
 
   <interface name="org.freedesktop.login1.Seat">
     <method name="SwitchTo">
       <arg name="vt" type="u"/>
     </method>
   </interface>
+
+  <interface name="org.freedesktop.login1.Manager">
+    <method name="Inhibit">
+      <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
+      <arg name="what" type="s" direction="in"/>
+      <arg name="who" type="s" direction="in"/>
+      <arg name="why" type="s" direction="in"/>
+      <arg name="mode" type="s" direction="in"/>
+      <arg name="fd" type="h" direction="out"/>
+    </method>
+    <signal name="PrepareForSleep">
+      <arg name="active" type="b"/>
+    </signal>
+  </interface>
 </node>
-- 
2.18.1