Blame SOURCES/0003-backend-add-signals-for-reporting-suspend-and-resume.patch

776610
From 4ac28995769b7820d802683bf86f1dc6c821a52b Mon Sep 17 00:00:00 2001
776610
From: Ray Strode <rstrode@redhat.com>
776610
Date: Thu, 10 Jan 2019 10:47:19 -0500
776610
Subject: [PATCH 3/9] backend: add signals for reporting suspend and resume
776610
776610
This commit adds "suspending" and "resuming" signals
776610
to MetaBackend.
776610
776610
It's preliminary work needed for tracking when to purge
776610
and recreate all textures (needed by nvidia).
776610
---
776610
 src/backends/meta-backend.c | 99 ++++++++++++++++++++++++++++++++-----
776610
 1 file changed, 87 insertions(+), 12 deletions(-)
776610
776610
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
776610
index 2f090e233..eb8790967 100644
776610
--- a/src/backends/meta-backend.c
776610
+++ b/src/backends/meta-backend.c
776610
@@ -1,93 +1,96 @@
776610
 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
776610
 
776610
 /*
776610
  * Copyright (C) 2014 Red Hat
776610
  *
776610
  * This program is free software; you can redistribute it and/or
776610
  * modify it under the terms of the GNU General Public License as
776610
  * published by the Free Software Foundation; either version 2 of the
776610
  * License, or (at your option) any later version.
776610
  *
776610
  * This program is distributed in the hope that it will be useful, but
776610
  * WITHOUT ANY WARRANTY; without even the implied warranty of
776610
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
776610
  * General Public License for more details.
776610
  *
776610
  * You should have received a copy of the GNU General Public License
776610
  * along with this program; if not, write to the Free Software
776610
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
776610
  * 02111-1307, USA.
776610
  *
776610
  * Written by:
776610
  *     Jasper St. Pierre <jstpierre@mecheye.net>
776610
  */
776610
 
776610
 #include "config.h"
776610
 
776610
 #include <stdlib.h>
776610
 
776610
+#include <gio/gunixfdlist.h>
776610
+
776610
 #include <clutter/clutter-mutter.h>
776610
 #include <meta/meta-backend.h>
776610
 #include <meta/main.h>
776610
 #include <meta/util.h>
776610
 #include "meta-backend-private.h"
776610
 #include "meta-input-settings-private.h"
776610
 #include "backends/x11/meta-backend-x11.h"
776610
 #include "meta-cursor-tracker-private.h"
776610
 #include "meta-stage-private.h"
776610
 #include "meta-dbus-login1.h"
776610
 
776610
 #ifdef HAVE_REMOTE_DESKTOP
776610
 #include "backends/meta-dbus-session-watcher.h"
776610
 #include "backends/meta-screen-cast.h"
776610
 #include "backends/meta-remote-access-controller-private.h"
776610
 #include "backends/meta-remote-desktop.h"
776610
 #endif
776610
 
776610
 #ifdef HAVE_NATIVE_BACKEND
776610
 #include "backends/native/meta-backend-native.h"
776610
 #endif
776610
 
776610
 #include "backends/meta-idle-monitor-private.h"
776610
 #include "backends/meta-logical-monitor.h"
776610
 #include "backends/meta-monitor-manager-dummy.h"
776610
 #include "backends/meta-settings-private.h"
776610
 
776610
 #define META_IDLE_MONITOR_CORE_DEVICE 0
776610
 
776610
 enum
776610
 {
776610
   KEYMAP_CHANGED,
776610
   KEYMAP_LAYOUT_GROUP_CHANGED,
776610
   LAST_DEVICE_CHANGED,
776610
-
776610
+  SUSPENDING,
776610
+  RESUMING,
776610
   N_SIGNALS
776610
 };
776610
 
776610
 static guint signals[N_SIGNALS];
776610
 
776610
 static MetaBackend *_backend;
776610
 
776610
 static gboolean stage_views_disabled = FALSE;
776610
 
776610
 /**
776610
  * meta_get_backend:
776610
  *
776610
  * Accessor for the singleton MetaBackend.
776610
  *
776610
  * Returns: (transfer none): The only #MetaBackend there is.
776610
  */
776610
 MetaBackend *
776610
 meta_get_backend (void)
776610
 {
776610
   return _backend;
776610
 }
776610
 
776610
 struct _MetaBackendPrivate
776610
 {
776610
   MetaMonitorManager *monitor_manager;
776610
   MetaOrientationManager *orientation_manager;
776610
   MetaCursorTracker *cursor_tracker;
776610
   MetaCursorRenderer *cursor_renderer;
776610
   MetaInputSettings *input_settings;
776610
   MetaRenderer *renderer;
776610
@@ -523,149 +526,221 @@ meta_backend_class_init (MetaBackendClass *klass)
776610
   object_class->finalize = meta_backend_finalize;
776610
 
776610
   klass->post_init = meta_backend_real_post_init;
776610
   klass->create_cursor_renderer = meta_backend_real_create_cursor_renderer;
776610
   klass->grab_device = meta_backend_real_grab_device;
776610
   klass->ungrab_device = meta_backend_real_ungrab_device;
776610
   klass->select_stage_events = meta_backend_real_select_stage_events;
776610
   klass->get_relative_motion_deltas = meta_backend_real_get_relative_motion_deltas;
776610
 
776610
   signals[KEYMAP_CHANGED] =
776610
     g_signal_new ("keymap-changed",
776610
                   G_TYPE_FROM_CLASS (object_class),
776610
                   G_SIGNAL_RUN_LAST,
776610
                   0,
776610
                   NULL, NULL, NULL,
776610
                   G_TYPE_NONE, 0);
776610
   signals[KEYMAP_LAYOUT_GROUP_CHANGED] =
776610
     g_signal_new ("keymap-layout-group-changed",
776610
                   G_TYPE_FROM_CLASS (object_class),
776610
                   G_SIGNAL_RUN_LAST,
776610
                   0,
776610
                   NULL, NULL, NULL,
776610
                   G_TYPE_NONE, 1, G_TYPE_UINT);
776610
   signals[LAST_DEVICE_CHANGED] =
776610
     g_signal_new ("last-device-changed",
776610
                   G_TYPE_FROM_CLASS (object_class),
776610
                   G_SIGNAL_RUN_LAST,
776610
                   0,
776610
                   NULL, NULL, NULL,
776610
                   G_TYPE_NONE, 1, G_TYPE_INT);
776610
+  signals[SUSPENDING] =
776610
+    g_signal_new ("suspending",
776610
+                  G_TYPE_FROM_CLASS (object_class),
776610
+                  G_SIGNAL_RUN_LAST,
776610
+                  0,
776610
+                  NULL, NULL, NULL,
776610
+                  G_TYPE_NONE, 0);
776610
+  signals[RESUMING] =
776610
+    g_signal_new ("resuming",
776610
+                  G_TYPE_FROM_CLASS (object_class),
776610
+                  G_SIGNAL_RUN_LAST,
776610
+                  0,
776610
+                  NULL, NULL, NULL,
776610
+                  G_TYPE_NONE, 0);
776610
 
776610
   mutter_stage_views = g_getenv ("MUTTER_STAGE_VIEWS");
776610
   stage_views_disabled = g_strcmp0 (mutter_stage_views, "0") == 0;
776610
 }
776610
 
776610
 static MetaMonitorManager *
776610
 meta_backend_create_monitor_manager (MetaBackend *backend,
776610
                                      GError     **error)
776610
 {
776610
   if (g_getenv ("META_DUMMY_MONITORS"))
776610
     return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
776610
 
776610
   return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend,
776610
                                                                    error);
776610
 }
776610
 
776610
 static MetaRenderer *
776610
 meta_backend_create_renderer (MetaBackend *backend,
776610
                               GError     **error)
776610
 {
776610
   return META_BACKEND_GET_CLASS (backend)->create_renderer (backend, error);
776610
 }
776610
 
776610
 static void
776610
 lid_is_closed_changed_cb (UpClient   *client,
776610
                           GParamSpec *pspec,
776610
                           gpointer    user_data)
776610
 {
776610
   if (up_client_get_lid_is_closed (client))
776610
     return;
776610
 
776610
   meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
776610
 }
776610
 
776610
+static void
776610
+inhibit_sleep (MetaBackend *backend)
776610
+{
776610
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
776610
+  g_autoptr (GVariant) fd_variant = NULL;
776610
+  g_autoptr (GUnixFDList) fd_list = NULL;
776610
+  g_autoptr (GError) error = NULL;
776610
+  int handle, fd;
776610
+
776610
+  if (priv->inhibit_sleep_fd >= 0)
776610
+    return;
776610
+
776610
+  if (!login1_manager_call_inhibit_sync (priv->logind_proxy,
776610
+                                         "sleep",
776610
+                                         "Display Server",
776610
+                                         "Prepare for suspend",
776610
+                                         "delay",
776610
+                                         NULL,
776610
+                                         &fd_variant,
776610
+                                         &fd_list,
776610
+                                         priv->cancellable,
776610
+                                         &error))
776610
+    {
776610
+      g_warning ("Failed to inhibit sleep: %s", error->message);
776610
+      return;
776610
+    }
776610
+
776610
+  handle = g_variant_get_handle (fd_variant);
776610
+  fd = g_unix_fd_list_get (fd_list, handle, &error);
776610
+
776610
+  if (fd < 0)
776610
+    {
776610
+      g_warning ("Failed to fetch sleep inhibitor fd: %s", error->message);
776610
+      return;
776610
+    }
776610
+
776610
+  priv->inhibit_sleep_fd = fd;
776610
+}
776610
+
776610
+static void
776610
+uninhibit_sleep (MetaBackend *backend)
776610
+{
776610
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
776610
+
776610
+  close (priv->inhibit_sleep_fd);
776610
+  priv->inhibit_sleep_fd = -1;
776610
+}
776610
+
776610
 static void
776610
 prepare_for_sleep_cb (MetaBackend *backend,
776610
                       gboolean     suspending)
776610
 {
776610
-  gboolean suspending;
776610
-
776610
-  g_variant_get (parameters, "(b)", &suspending);
776610
-  if (suspending)
776610
+  if (suspending) {
776610
+    g_signal_emit (backend, signals[SUSPENDING], 0);
776610
+    uninhibit_sleep (backend);
776610
     return;
776610
+  }
776610
+
776610
+  inhibit_sleep (backend);
776610
+  g_signal_emit (backend, signals[RESUMING], 0);
776610
   meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
776610
 }
776610
 
776610
 static Login1Manager *
776610
 get_logind_proxy (GCancellable *cancellable,
776610
                   GError      **error)
776610
 {
776610
   Login1Manager *proxy;
776610
 
776610
   proxy =
776610
     login1_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
776610
                                            G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
776610
                                            "org.freedesktop.login1",
776610
                                            "/org/freedesktop/login1",
776610
                                            cancellable, error);
776610
   if (!proxy)
776610
     g_prefix_error (error, "Could not get logind proxy: ");
776610
 
776610
   return proxy;
776610
 }
776610
 
776610
 static void
776610
 system_bus_gotten_cb (GObject      *object,
776610
                       GAsyncResult *res,
776610
                       gpointer      user_data)
776610
 {
776610
+  MetaBackend *backend = META_BACKEND (user_data);
776610
   MetaBackendPrivate *priv;
776610
   g_autoptr (GError) error = NULL;
776610
   GDBusConnection *bus;
776610
 
776610
   bus = g_bus_get_finish (res, NULL);
776610
   if (!bus)
776610
     return;
776610
 
776610
   priv = meta_backend_get_instance_private (user_data);
776610
   priv->system_bus = bus;
776610
   priv->logind_proxy = get_logind_proxy (priv->cancellable, &error);
776610
+  priv->inhibit_sleep_fd = -1;
776610
 
776610
   if (!priv->logind_proxy)
776610
-    g_warning ("Failed to get logind proxy: %s", error->message);
776610
-
776610
-  g_signal_connect_object (priv->logind_proxy,
776610
-                           "prepare-for-sleep",
776610
-                           G_CALLBACK (prepare_for_sleep_cb),
776610
-                           user_data,
776610
-                           G_CONNECT_SWAPPED);
776610
+    {
776610
+      g_warning ("Failed to get logind proxy: %s", error->message);
776610
+    }
776610
+  else
776610
+    {
776610
+      inhibit_sleep (backend);
776610
+      g_signal_connect_object (priv->logind_proxy,
776610
+                               "prepare-for-sleep",
776610
+                               G_CALLBACK (prepare_for_sleep_cb),
776610
+                               user_data,
776610
+                               G_CONNECT_SWAPPED);
776610
+    }
776610
 }
776610
 
776610
 static gboolean
776610
 meta_backend_initable_init (GInitable     *initable,
776610
                             GCancellable  *cancellable,
776610
                             GError       **error)
776610
 {
776610
   MetaBackend *backend = META_BACKEND (initable);
776610
   MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
776610
 
776610
   priv->settings = meta_settings_new (backend);
776610
 
776610
   priv->egl = g_object_new (META_TYPE_EGL, NULL);
776610
 
776610
   priv->orientation_manager = g_object_new (META_TYPE_ORIENTATION_MANAGER, NULL);
776610
 
776610
   priv->monitor_manager = meta_backend_create_monitor_manager (backend, error);
776610
   if (!priv->monitor_manager)
776610
     return FALSE;
776610
 
776610
   priv->renderer = meta_backend_create_renderer (backend, error);
776610
   if (!priv->renderer)
776610
     return FALSE;
776610
 
776610
   priv->cursor_tracker = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
776610
 
776610
   priv->dnd = g_object_new (META_TYPE_DND, NULL);
776610
 
776610
   priv->up_client = up_client_new ();
776610
   g_signal_connect (priv->up_client, "notify::lid-is-closed",
776610
-- 
776610
2.18.1
776610