Blame SOURCES/fall-back-to-xorg-on-hybrid-gpus.patch

67f8b7
From 5bea406b353f39867eb86307b1c8b4093f22968e Mon Sep 17 00:00:00 2001
67f8b7
From: Ray Strode <rstrode@redhat.com>
67f8b7
Date: Tue, 18 Oct 2016 16:40:14 -0400
67f8b7
Subject: [PATCH 1/4] native: only match drm subsystem devices
67f8b7
67f8b7
Despite g_udev_client_new taking a list of subsystems, it doesn't
67f8b7
implicitly filter results to those subsystems.
67f8b7
67f8b7
This commit explicitly adds a subsystem match to make sure sound cards
67f8b7
don't end up in the resulting list of video cards.
67f8b7
67f8b7
https://bugzilla.gnome.org/show_bug.cgi?id=771442
67f8b7
---
67f8b7
 src/backends/native/meta-launcher.c | 5 +++++
67f8b7
 1 file changed, 5 insertions(+)
67f8b7
67f8b7
diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c
67f8b7
index ea28e5a..03a928a 100644
67f8b7
--- a/src/backends/native/meta-launcher.c
67f8b7
+++ b/src/backends/native/meta-launcher.c
67f8b7
@@ -268,60 +268,65 @@ sync_active (MetaLauncher *self)
67f8b7
   self->session_active = active;
67f8b7
 
67f8b7
   if (active)
67f8b7
     session_unpause ();
67f8b7
   else
67f8b7
     session_pause ();
67f8b7
 }
67f8b7
 
67f8b7
 static void
67f8b7
 on_active_changed (Login1Session *session,
67f8b7
                    GParamSpec    *pspec,
67f8b7
                    gpointer       user_data)
67f8b7
 {
67f8b7
   MetaLauncher *self = user_data;
67f8b7
   sync_active (self);
67f8b7
 }
67f8b7
 
67f8b7
 static gchar *
67f8b7
 get_primary_gpu_path (const gchar *seat_name)
67f8b7
 {
67f8b7
   const gchar *subsystems[] = {"drm", NULL};
67f8b7
   gchar *path = NULL;
67f8b7
   GList *devices, *tmp;
67f8b7
 
67f8b7
   g_autoptr (GUdevClient) gudev_client = g_udev_client_new (subsystems);
67f8b7
   g_autoptr (GUdevEnumerator) enumerator = g_udev_enumerator_new (gudev_client);
67f8b7
 
67f8b7
   g_udev_enumerator_add_match_name (enumerator, "card*");
67f8b7
   g_udev_enumerator_add_match_tag (enumerator, "seat");
67f8b7
 
67f8b7
+  /* We need to explicitly match the subsystem for now.
67f8b7
+   * https://bugzilla.gnome.org/show_bug.cgi?id=773224
67f8b7
+   */
67f8b7
+  g_udev_enumerator_add_match_subsystem (enumerator, "drm");
67f8b7
+
67f8b7
   devices = g_udev_enumerator_execute (enumerator);
67f8b7
   if (!devices)
67f8b7
     goto out;
67f8b7
 
67f8b7
   for (tmp = devices; tmp != NULL; tmp = tmp->next)
67f8b7
     {
67f8b7
       g_autoptr (GUdevDevice) platform_device = NULL;
67f8b7
       g_autoptr (GUdevDevice) pci_device = NULL;
67f8b7
       GUdevDevice *dev = tmp->data;
67f8b7
       gint boot_vga;
67f8b7
       const gchar *device_seat;
67f8b7
 
67f8b7
       /* filter out devices that are not character device, like card0-VGA-1 */
67f8b7
       if (g_udev_device_get_device_type (dev) != G_UDEV_DEVICE_TYPE_CHAR)
67f8b7
         continue;
67f8b7
 
67f8b7
       device_seat = g_udev_device_get_property (dev, "ID_SEAT");
67f8b7
       if (!device_seat)
67f8b7
         {
67f8b7
           /* when ID_SEAT is not set, it means seat0 */
67f8b7
           device_seat = "seat0";
67f8b7
         }
67f8b7
       else if (g_strcmp0 (device_seat, "seat0") != 0)
67f8b7
         {
67f8b7
           /* if the device has been explicitly assigned other seat
67f8b7
            * than seat0, it is probably the right device to use */
67f8b7
           path = g_strdup (g_udev_device_get_device_file (dev));
67f8b7
           break;
67f8b7
         }
67f8b7
 
67f8b7
-- 
67f8b7
2.10.1
67f8b7
67f8b7
67f8b7
From d9dc6ac094080a4190508297e8244a8905a8dcb4 Mon Sep 17 00:00:00 2001
67f8b7
From: Ray Strode <rstrode@redhat.com>
67f8b7
Date: Wed, 19 Oct 2016 10:41:14 -0400
67f8b7
Subject: [PATCH 2/4] native: shore up matching of card device
67f8b7
67f8b7
Right now we accept any character device that matches the glob card*.
67f8b7
67f8b7
That's fine, but we can be a little more specific by checking that
67f8b7
the devtype is what we expect.
67f8b7
67f8b7
This commit does that.
67f8b7
67f8b7
https://bugzilla.gnome.org/show_bug.cgi?id=771442
67f8b7
---
67f8b7
 src/backends/native/meta-launcher.c | 7 +++++++
67f8b7
 1 file changed, 7 insertions(+)
67f8b7
67f8b7
diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c
67f8b7
index 03a928a..765e5ef 100644
67f8b7
--- a/src/backends/native/meta-launcher.c
67f8b7
+++ b/src/backends/native/meta-launcher.c
67f8b7
@@ -20,60 +20,62 @@
67f8b7
 #include "config.h"
67f8b7
 
67f8b7
 #include "meta-launcher.h"
67f8b7
 
67f8b7
 #include <gio/gunixfdlist.h>
67f8b7
 
67f8b7
 #include <clutter/clutter.h>
67f8b7
 #include <clutter/egl/clutter-egl.h>
67f8b7
 #include <clutter/evdev/clutter-evdev.h>
67f8b7
 
67f8b7
 #include <sys/types.h>
67f8b7
 #include <sys/stat.h>
67f8b7
 #include <malloc.h>
67f8b7
 #include <fcntl.h>
67f8b7
 #include <errno.h>
67f8b7
 #include <stdlib.h>
67f8b7
 #include <string.h>
67f8b7
 #include <unistd.h>
67f8b7
 
67f8b7
 #include <systemd/sd-login.h>
67f8b7
 #include <gudev/gudev.h>
67f8b7
 
67f8b7
 #include "dbus-utils.h"
67f8b7
 #include "meta-dbus-login1.h"
67f8b7
 
67f8b7
 #include "backends/meta-backend-private.h"
67f8b7
 #include "meta-cursor-renderer-native.h"
67f8b7
 #include "meta-idle-monitor-native.h"
67f8b7
 #include "meta-renderer-native.h"
67f8b7
 
67f8b7
+#define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor"
67f8b7
+
67f8b7
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref)
67f8b7
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevClient, g_object_unref)
67f8b7
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevEnumerator, g_object_unref)
67f8b7
 
67f8b7
 struct _MetaLauncher
67f8b7
 {
67f8b7
   Login1Session *session_proxy;
67f8b7
   Login1Seat *seat_proxy;
67f8b7
 
67f8b7
   gboolean session_active;
67f8b7
 
67f8b7
   int kms_fd;
67f8b7
 };
67f8b7
 
67f8b7
 static Login1Session *
67f8b7
 get_session_proxy (GCancellable *cancellable,
67f8b7
                    GError      **error)
67f8b7
 {
67f8b7
   g_autofree char *proxy_path = NULL;
67f8b7
   g_autofree char *session_id = NULL;
67f8b7
   Login1Session *session_proxy;
67f8b7
 
67f8b7
   if (sd_pid_get_session (getpid (), &session_id) < 0)
67f8b7
     {
67f8b7
       g_set_error (error,
67f8b7
                    G_IO_ERROR,
67f8b7
                    G_IO_ERROR_NOT_FOUND,
67f8b7
                    "Could not get session ID: %m");
67f8b7
       return NULL;
67f8b7
     }
67f8b7
@@ -283,66 +285,71 @@ on_active_changed (Login1Session *session,
67f8b7
 }
67f8b7
 
67f8b7
 static gchar *
67f8b7
 get_primary_gpu_path (const gchar *seat_name)
67f8b7
 {
67f8b7
   const gchar *subsystems[] = {"drm", NULL};
67f8b7
   gchar *path = NULL;
67f8b7
   GList *devices, *tmp;
67f8b7
 
67f8b7
   g_autoptr (GUdevClient) gudev_client = g_udev_client_new (subsystems);
67f8b7
   g_autoptr (GUdevEnumerator) enumerator = g_udev_enumerator_new (gudev_client);
67f8b7
 
67f8b7
   g_udev_enumerator_add_match_name (enumerator, "card*");
67f8b7
   g_udev_enumerator_add_match_tag (enumerator, "seat");
67f8b7
 
67f8b7
   /* We need to explicitly match the subsystem for now.
67f8b7
    * https://bugzilla.gnome.org/show_bug.cgi?id=773224
67f8b7
    */
67f8b7
   g_udev_enumerator_add_match_subsystem (enumerator, "drm");
67f8b7
 
67f8b7
   devices = g_udev_enumerator_execute (enumerator);
67f8b7
   if (!devices)
67f8b7
     goto out;
67f8b7
 
67f8b7
   for (tmp = devices; tmp != NULL; tmp = tmp->next)
67f8b7
     {
67f8b7
       g_autoptr (GUdevDevice) platform_device = NULL;
67f8b7
       g_autoptr (GUdevDevice) pci_device = NULL;
67f8b7
       GUdevDevice *dev = tmp->data;
67f8b7
       gint boot_vga;
67f8b7
+      const gchar *device_type;
67f8b7
       const gchar *device_seat;
67f8b7
 
67f8b7
       /* filter out devices that are not character device, like card0-VGA-1 */
67f8b7
       if (g_udev_device_get_device_type (dev) != G_UDEV_DEVICE_TYPE_CHAR)
67f8b7
         continue;
67f8b7
 
67f8b7
+      device_type = g_udev_device_get_property (dev, "DEVTYPE");
67f8b7
+      if (g_strcmp0 (device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
67f8b7
+        continue;
67f8b7
+
67f8b7
       device_seat = g_udev_device_get_property (dev, "ID_SEAT");
67f8b7
       if (!device_seat)
67f8b7
         {
67f8b7
           /* when ID_SEAT is not set, it means seat0 */
67f8b7
           device_seat = "seat0";
67f8b7
         }
67f8b7
       else if (g_strcmp0 (device_seat, "seat0") != 0)
67f8b7
         {
67f8b7
           /* if the device has been explicitly assigned other seat
67f8b7
            * than seat0, it is probably the right device to use */
67f8b7
           path = g_strdup (g_udev_device_get_device_file (dev));
67f8b7
           break;
67f8b7
         }
67f8b7
 
67f8b7
       /* skip devices that do not belong to our seat */
67f8b7
       if (g_strcmp0 (seat_name, device_seat))
67f8b7
         continue;
67f8b7
 
67f8b7
       platform_device = g_udev_device_get_parent_with_subsystem (dev, "platform", NULL);
67f8b7
       if (platform_device != NULL)
67f8b7
         {
67f8b7
           path = g_strdup (g_udev_device_get_device_file (dev));
67f8b7
           break;
67f8b7
         }
67f8b7
 
67f8b7
       pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL);
67f8b7
       if (pci_device != NULL)
67f8b7
         {
67f8b7
           /* get value of boot_vga attribute or 0 if the device has no boot_vga */
67f8b7
           boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga");
67f8b7
-- 
67f8b7
2.10.1
67f8b7
67f8b7
67f8b7
From 54ceafff8c8b0b02cd9124eae56a05da4f117033 Mon Sep 17 00:00:00 2001
67f8b7
From: Ray Strode <rstrode@redhat.com>
67f8b7
Date: Tue, 18 Oct 2016 16:43:04 -0400
67f8b7
Subject: [PATCH 3/4] native: fail on systems with connectors spread across
67f8b7
 multiple gpus
67f8b7
67f8b7
We don't support using more than one GPU for output yet, so we should fail
67f8b7
if we encounter that situation, so GDM will fall back to X.
67f8b7
67f8b7
https://bugzilla.gnome.org/show_bug.cgi?id=771442
67f8b7
---
67f8b7
 src/backends/native/meta-launcher.c | 63 ++++++++++++++++++++++++++++++++++++-
67f8b7
 1 file changed, 62 insertions(+), 1 deletion(-)
67f8b7
67f8b7
diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c
67f8b7
index 765e5ef..a2885a1 100644
67f8b7
--- a/src/backends/native/meta-launcher.c
67f8b7
+++ b/src/backends/native/meta-launcher.c
67f8b7
@@ -257,141 +257,202 @@ on_evdev_device_close (int      fd,
67f8b7
 
67f8b7
 out:
67f8b7
   close (fd);
67f8b7
 }
67f8b7
 
67f8b7
 static void
67f8b7
 sync_active (MetaLauncher *self)
67f8b7
 {
67f8b7
   gboolean active = login1_session_get_active (LOGIN1_SESSION (self->session_proxy));
67f8b7
 
67f8b7
   if (active == self->session_active)
67f8b7
     return;
67f8b7
 
67f8b7
   self->session_active = active;
67f8b7
 
67f8b7
   if (active)
67f8b7
     session_unpause ();
67f8b7
   else
67f8b7
     session_pause ();
67f8b7
 }
67f8b7
 
67f8b7
 static void
67f8b7
 on_active_changed (Login1Session *session,
67f8b7
                    GParamSpec    *pspec,
67f8b7
                    gpointer       user_data)
67f8b7
 {
67f8b7
   MetaLauncher *self = user_data;
67f8b7
   sync_active (self);
67f8b7
 }
67f8b7
 
67f8b7
+static guint
67f8b7
+count_devices_with_connectors (const gchar *seat_name,
67f8b7
+                               GList       *devices)
67f8b7
+{
67f8b7
+  g_autoptr (GHashTable) cards = NULL;
67f8b7
+  GList *tmp;
67f8b7
+
67f8b7
+  cards = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
67f8b7
+  for (tmp = devices; tmp != NULL; tmp = tmp->next)
67f8b7
+    {
67f8b7
+      GUdevDevice *device = tmp->data;
67f8b7
+      g_autoptr (GUdevDevice) parent_device = NULL;
67f8b7
+      const gchar *parent_device_type = NULL;
67f8b7
+      const gchar *card_seat;
67f8b7
+
67f8b7
+      /* filter out the real card devices, we only care about the connectors */
67f8b7
+      if (g_udev_device_get_device_type (device) != G_UDEV_DEVICE_TYPE_NONE)
67f8b7
+        continue;
67f8b7
+
67f8b7
+      /* only connectors have a modes attribute */
67f8b7
+      if (!g_udev_device_has_sysfs_attr (device, "modes"))
67f8b7
+        continue;
67f8b7
+
67f8b7
+      parent_device = g_udev_device_get_parent (device);
67f8b7
+
67f8b7
+      if (g_udev_device_get_device_type (parent_device) == G_UDEV_DEVICE_TYPE_CHAR)
67f8b7
+        parent_device_type = g_udev_device_get_property (parent_device, "DEVTYPE");
67f8b7
+
67f8b7
+      if (g_strcmp0 (parent_device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
67f8b7
+        continue;
67f8b7
+
67f8b7
+      card_seat = g_udev_device_get_property (parent_device, "ID_SEAT");
67f8b7
+
67f8b7
+      if (!card_seat)
67f8b7
+        card_seat = "seat0";
67f8b7
+
67f8b7
+      if (g_strcmp0 (seat_name, card_seat) != 0)
67f8b7
+        continue;
67f8b7
+
67f8b7
+      g_hash_table_insert (cards,
67f8b7
+                           (gpointer) g_udev_device_get_name (parent_device),
67f8b7
+                           g_steal_pointer (&parent_device));
67f8b7
+    }
67f8b7
+
67f8b7
+  return g_hash_table_size (cards);
67f8b7
+}
67f8b7
+
67f8b7
 static gchar *
67f8b7
 get_primary_gpu_path (const gchar *seat_name)
67f8b7
 {
67f8b7
   const gchar *subsystems[] = {"drm", NULL};
67f8b7
   gchar *path = NULL;
67f8b7
   GList *devices, *tmp;
67f8b7
 
67f8b7
   g_autoptr (GUdevClient) gudev_client = g_udev_client_new (subsystems);
67f8b7
   g_autoptr (GUdevEnumerator) enumerator = g_udev_enumerator_new (gudev_client);
67f8b7
 
67f8b7
   g_udev_enumerator_add_match_name (enumerator, "card*");
67f8b7
   g_udev_enumerator_add_match_tag (enumerator, "seat");
67f8b7
 
67f8b7
   /* We need to explicitly match the subsystem for now.
67f8b7
    * https://bugzilla.gnome.org/show_bug.cgi?id=773224
67f8b7
    */
67f8b7
   g_udev_enumerator_add_match_subsystem (enumerator, "drm");
67f8b7
 
67f8b7
   devices = g_udev_enumerator_execute (enumerator);
67f8b7
   if (!devices)
67f8b7
     goto out;
67f8b7
 
67f8b7
+  /* For now, fail on systems where some of the connectors
67f8b7
+   * are connected to secondary gpus.
67f8b7
+   *
67f8b7
+   * https://bugzilla.gnome.org/show_bug.cgi?id=771442
67f8b7
+   */
67f8b7
+  if (g_getenv ("MUTTER_ALLOW_HYBRID_GPUS") == NULL)
67f8b7
+    {
67f8b7
+      guint num_devices;
67f8b7
+
67f8b7
+      num_devices = count_devices_with_connectors (seat_name, devices);
67f8b7
+      if (num_devices != 1)
67f8b7
+        goto out;
67f8b7
+    }
67f8b7
+
67f8b7
   for (tmp = devices; tmp != NULL; tmp = tmp->next)
67f8b7
     {
67f8b7
       g_autoptr (GUdevDevice) platform_device = NULL;
67f8b7
       g_autoptr (GUdevDevice) pci_device = NULL;
67f8b7
       GUdevDevice *dev = tmp->data;
67f8b7
       gint boot_vga;
67f8b7
       const gchar *device_type;
67f8b7
       const gchar *device_seat;
67f8b7
 
67f8b7
       /* filter out devices that are not character device, like card0-VGA-1 */
67f8b7
       if (g_udev_device_get_device_type (dev) != G_UDEV_DEVICE_TYPE_CHAR)
67f8b7
         continue;
67f8b7
 
67f8b7
       device_type = g_udev_device_get_property (dev, "DEVTYPE");
67f8b7
       if (g_strcmp0 (device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
67f8b7
         continue;
67f8b7
 
67f8b7
       device_seat = g_udev_device_get_property (dev, "ID_SEAT");
67f8b7
       if (!device_seat)
67f8b7
         {
67f8b7
           /* when ID_SEAT is not set, it means seat0 */
67f8b7
           device_seat = "seat0";
67f8b7
         }
67f8b7
       else if (g_strcmp0 (device_seat, "seat0") != 0)
67f8b7
         {
67f8b7
           /* if the device has been explicitly assigned other seat
67f8b7
            * than seat0, it is probably the right device to use */
67f8b7
           path = g_strdup (g_udev_device_get_device_file (dev));
67f8b7
           break;
67f8b7
         }
67f8b7
 
67f8b7
       /* skip devices that do not belong to our seat */
67f8b7
       if (g_strcmp0 (seat_name, device_seat))
67f8b7
         continue;
67f8b7
 
67f8b7
       platform_device = g_udev_device_get_parent_with_subsystem (dev, "platform", NULL);
67f8b7
       if (platform_device != NULL)
67f8b7
         {
67f8b7
           path = g_strdup (g_udev_device_get_device_file (dev));
67f8b7
           break;
67f8b7
         }
67f8b7
 
67f8b7
       pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL);
67f8b7
       if (pci_device != NULL)
67f8b7
         {
67f8b7
           /* get value of boot_vga attribute or 0 if the device has no boot_vga */
67f8b7
           boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga");
67f8b7
           if (boot_vga == 1)
67f8b7
             {
67f8b7
               /* found the boot_vga device */
67f8b7
               path = g_strdup (g_udev_device_get_device_file (dev));
67f8b7
               break;
67f8b7
             }
67f8b7
         }
67f8b7
     }
67f8b7
 
67f8b7
+out:
67f8b7
   g_list_free_full (devices, g_object_unref);
67f8b7
 
67f8b7
-out:
67f8b7
   return path;
67f8b7
 }
67f8b7
 
67f8b7
 static gboolean
67f8b7
 get_kms_fd (Login1Session *session_proxy,
67f8b7
             const gchar   *seat_id,
67f8b7
             int           *fd_out,
67f8b7
             GError       **error)
67f8b7
 {
67f8b7
   int major, minor;
67f8b7
   int fd;
67f8b7
 
67f8b7
   g_autofree gchar *path = get_primary_gpu_path (seat_id);
67f8b7
   if (!path)
67f8b7
     {
67f8b7
       g_set_error (error,
67f8b7
                    G_IO_ERROR,
67f8b7
                    G_IO_ERROR_NOT_FOUND,
67f8b7
                    "could not find drm kms device");
67f8b7
       return FALSE;
67f8b7
     }
67f8b7
 
67f8b7
   if (!get_device_info_from_path (path, &major, &minor))
67f8b7
     {
67f8b7
       g_set_error (error,
67f8b7
                    G_IO_ERROR,
67f8b7
                    G_IO_ERROR_NOT_FOUND,
67f8b7
                    "Could not get device info for path %s: %m", path);
67f8b7
       return FALSE;
67f8b7
     }
67f8b7
-- 
67f8b7
2.10.1
67f8b7
67f8b7
67f8b7
From 0d87baa029329c409646e04bcf40bea5da67b5f7 Mon Sep 17 00:00:00 2001
67f8b7
From: Ray Strode <rstrode@redhat.com>
67f8b7
Date: Wed, 19 Oct 2016 14:27:24 -0400
67f8b7
Subject: [PATCH 4/4] native: don't call steal_pointer prematurely
67f8b7
67f8b7
commit e2bfaf07514ed633f8721b5f521577685b6cccc0 does this:
67f8b7
67f8b7
g_hash_table_insert (cards,
67f8b7
                     g_udev_device_get_name (parent_device),
67f8b7
                     g_steal_pointer (&parent_device));
67f8b7
67f8b7
The problem is the g_steal_pointer call may happen before the
67f8b7
g_udev_device_get_name call leading to a crash.
67f8b7
67f8b7
This commit does the get_name call on an earlier line
67f8b7
67f8b7
https://bugzilla.gnome.org/show_bug.cgi?id=771442
67f8b7
---
67f8b7
 src/backends/native/meta-launcher.c | 4 +++-
67f8b7
 1 file changed, 3 insertions(+), 1 deletion(-)
67f8b7
67f8b7
diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c
67f8b7
index a2885a1..ddb7080 100644
67f8b7
--- a/src/backends/native/meta-launcher.c
67f8b7
+++ b/src/backends/native/meta-launcher.c
67f8b7
@@ -270,88 +270,90 @@ sync_active (MetaLauncher *self)
67f8b7
   self->session_active = active;
67f8b7
 
67f8b7
   if (active)
67f8b7
     session_unpause ();
67f8b7
   else
67f8b7
     session_pause ();
67f8b7
 }
67f8b7
 
67f8b7
 static void
67f8b7
 on_active_changed (Login1Session *session,
67f8b7
                    GParamSpec    *pspec,
67f8b7
                    gpointer       user_data)
67f8b7
 {
67f8b7
   MetaLauncher *self = user_data;
67f8b7
   sync_active (self);
67f8b7
 }
67f8b7
 
67f8b7
 static guint
67f8b7
 count_devices_with_connectors (const gchar *seat_name,
67f8b7
                                GList       *devices)
67f8b7
 {
67f8b7
   g_autoptr (GHashTable) cards = NULL;
67f8b7
   GList *tmp;
67f8b7
 
67f8b7
   cards = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
67f8b7
   for (tmp = devices; tmp != NULL; tmp = tmp->next)
67f8b7
     {
67f8b7
       GUdevDevice *device = tmp->data;
67f8b7
       g_autoptr (GUdevDevice) parent_device = NULL;
67f8b7
       const gchar *parent_device_type = NULL;
67f8b7
+      const gchar *parent_device_name = NULL;
67f8b7
       const gchar *card_seat;
67f8b7
 
67f8b7
       /* filter out the real card devices, we only care about the connectors */
67f8b7
       if (g_udev_device_get_device_type (device) != G_UDEV_DEVICE_TYPE_NONE)
67f8b7
         continue;
67f8b7
 
67f8b7
       /* only connectors have a modes attribute */
67f8b7
       if (!g_udev_device_has_sysfs_attr (device, "modes"))
67f8b7
         continue;
67f8b7
 
67f8b7
       parent_device = g_udev_device_get_parent (device);
67f8b7
 
67f8b7
       if (g_udev_device_get_device_type (parent_device) == G_UDEV_DEVICE_TYPE_CHAR)
67f8b7
         parent_device_type = g_udev_device_get_property (parent_device, "DEVTYPE");
67f8b7
 
67f8b7
       if (g_strcmp0 (parent_device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
67f8b7
         continue;
67f8b7
 
67f8b7
       card_seat = g_udev_device_get_property (parent_device, "ID_SEAT");
67f8b7
 
67f8b7
       if (!card_seat)
67f8b7
         card_seat = "seat0";
67f8b7
 
67f8b7
       if (g_strcmp0 (seat_name, card_seat) != 0)
67f8b7
         continue;
67f8b7
 
67f8b7
+      parent_device_name = g_udev_device_get_name (parent_device);
67f8b7
       g_hash_table_insert (cards,
67f8b7
-                           (gpointer) g_udev_device_get_name (parent_device),
67f8b7
+                           (gpointer) parent_device_name ,
67f8b7
                            g_steal_pointer (&parent_device));
67f8b7
     }
67f8b7
 
67f8b7
   return g_hash_table_size (cards);
67f8b7
 }
67f8b7
 
67f8b7
 static gchar *
67f8b7
 get_primary_gpu_path (const gchar *seat_name)
67f8b7
 {
67f8b7
   const gchar *subsystems[] = {"drm", NULL};
67f8b7
   gchar *path = NULL;
67f8b7
   GList *devices, *tmp;
67f8b7
 
67f8b7
   g_autoptr (GUdevClient) gudev_client = g_udev_client_new (subsystems);
67f8b7
   g_autoptr (GUdevEnumerator) enumerator = g_udev_enumerator_new (gudev_client);
67f8b7
 
67f8b7
   g_udev_enumerator_add_match_name (enumerator, "card*");
67f8b7
   g_udev_enumerator_add_match_tag (enumerator, "seat");
67f8b7
 
67f8b7
   /* We need to explicitly match the subsystem for now.
67f8b7
    * https://bugzilla.gnome.org/show_bug.cgi?id=773224
67f8b7
    */
67f8b7
   g_udev_enumerator_add_match_subsystem (enumerator, "drm");
67f8b7
 
67f8b7
   devices = g_udev_enumerator_execute (enumerator);
67f8b7
   if (!devices)
67f8b7
     goto out;
67f8b7
 
67f8b7
   /* For now, fail on systems where some of the connectors
67f8b7
    * are connected to secondary gpus.
67f8b7
-- 
67f8b7
2.10.1
67f8b7