01552a
From b96ff001587de11eaf98ace71b196cc5ab4cf007 Mon Sep 17 00:00:00 2001
01552a
From: Ray Strode <rstrode@redhat.com>
01552a
Date: Mon, 14 Jul 2014 08:04:54 -0400
01552a
Subject: [PATCH 1/5] seat: be a little more forgiving in the case there's no
01552a
 open terminal
01552a
01552a
We can end up in a situation where a seat object doesn't have a terminal
01552a
associated with it.  In that case we shouldn't crash, but continue on
01552a
with no input available for that seat.
01552a
01552a
https://bugs.freedesktop.org/show_bug.cgi?id=80553
01552a
---
01552a
 src/libply-splash-core/ply-seat.c | 23 +++++++++++++++++++----
01552a
 1 file changed, 19 insertions(+), 4 deletions(-)
01552a
01552a
diff --git a/src/libply-splash-core/ply-seat.c b/src/libply-splash-core/ply-seat.c
01552a
index 2ac8bf7..cd7e5bc 100644
01552a
--- a/src/libply-splash-core/ply-seat.c
01552a
+++ b/src/libply-splash-core/ply-seat.c
01552a
@@ -127,68 +127,83 @@ ply_seat_open (ply_seat_t          *seat,
01552a
   if (renderer_type != PLY_RENDERER_TYPE_NONE)
01552a
     {
01552a
       ply_renderer_t *renderer;
01552a
 
01552a
       renderer = ply_renderer_new (renderer_type, device, seat->terminal);
01552a
 
01552a
       if (!ply_renderer_open (renderer))
01552a
         {
01552a
           ply_trace ("could not open renderer for %s", device);
01552a
           ply_renderer_free (renderer);
01552a
 
01552a
           seat->renderer = NULL;
01552a
           seat->renderer_active = false;
01552a
 
01552a
           if (renderer_type != PLY_RENDERER_TYPE_AUTO)
01552a
             return false;
01552a
         }
01552a
       else
01552a
         {
01552a
           seat->renderer = renderer;
01552a
           seat->renderer_active = true;
01552a
         }
01552a
     }
01552a
 
01552a
   if (seat->renderer != NULL)
01552a
     {
01552a
       seat->keyboard = ply_keyboard_new_for_renderer (seat->renderer);
01552a
       add_pixel_displays (seat);
01552a
 
01552a
     }
01552a
-  else
01552a
+  else if (seat->terminal != NULL)
01552a
     {
01552a
       seat->keyboard = ply_keyboard_new_for_terminal (seat->terminal);
01552a
     }
01552a
-  add_text_displays (seat);
01552a
 
01552a
-  ply_keyboard_watch_for_input (seat->keyboard);
01552a
-  seat->keyboard_active = true;
01552a
+  if (seat->terminal != NULL)
01552a
+    {
01552a
+      add_text_displays (seat);
01552a
+    }
01552a
+  else
01552a
+    {
01552a
+      ply_trace ("not adding text display for seat, since seat has no associated terminal");
01552a
+    }
01552a
+
01552a
+  if (seat->keyboard != NULL)
01552a
+    {
01552a
+      ply_keyboard_watch_for_input (seat->keyboard);
01552a
+      seat->keyboard_active = true;
01552a
+    }
01552a
+  else
01552a
+    {
01552a
+      ply_trace ("not watching seat for input");
01552a
+    }
01552a
 
01552a
   return true;
01552a
 }
01552a
 
01552a
 bool
01552a
 ply_seat_is_open (ply_seat_t *seat)
01552a
 {
01552a
   return ply_list_get_length (seat->pixel_displays) > 0 ||
01552a
          ply_list_get_length (seat->text_displays) > 0;
01552a
 }
01552a
 
01552a
 void
01552a
 ply_seat_deactivate_keyboard (ply_seat_t *seat)
01552a
 {
01552a
   if (!seat->keyboard_active)
01552a
     return;
01552a
 
01552a
   seat->keyboard_active = false;
01552a
 
01552a
   if (seat->keyboard == NULL)
01552a
     return;
01552a
 
01552a
   ply_trace ("deactivating keybord");
01552a
   ply_keyboard_stop_watching_for_input (seat->keyboard);
01552a
 }
01552a
 
01552a
 void
01552a
 ply_seat_deactivate_renderer (ply_seat_t *seat)
01552a
 {
01552a
   if (!seat->renderer_active)
01552a
-- 
01552a
2.3.7
01552a
01552a
01552a
From b5ed92bc2efd0b52e901a67ea8e5afa809ca3598 Mon Sep 17 00:00:00 2001
01552a
From: Ray Strode <rstrode@redhat.com>
01552a
Date: Fri, 3 Jul 2015 09:29:39 -0400
01552a
Subject: [PATCH 2/5] main: show cursor on crash
01552a
01552a
---
01552a
 src/main.c | 3 +++
01552a
 1 file changed, 3 insertions(+)
01552a
01552a
diff --git a/src/main.c b/src/main.c
01552a
index 77fa96f..db5c281 100644
01552a
--- a/src/main.c
01552a
+++ b/src/main.c
01552a
@@ -2051,66 +2051,69 @@ on_error_message (ply_buffer_t *debug_buffer,
01552a
 {
01552a
   ply_buffer_append_bytes (debug_buffer, bytes, number_of_bytes);
01552a
 }
01552a
 
01552a
 static void
01552a
 dump_debug_buffer_to_file (void)
01552a
 {
01552a
   int fd;
01552a
   const char *bytes;
01552a
   size_t size;
01552a
 
01552a
   fd = open (debug_buffer_path,
01552a
              O_WRONLY | O_CREAT | O_TRUNC, 0600);
01552a
 
01552a
   if (fd < 0)
01552a
     return;
01552a
 
01552a
   size = ply_buffer_get_size (debug_buffer);
01552a
   bytes = ply_buffer_get_bytes (debug_buffer);
01552a
   ply_write (fd, bytes, size);
01552a
   close (fd);
01552a
 }
01552a
 
01552a
  #include <termios.h>
01552a
  #include <unistd.h>
01552a
 static void
01552a
 on_crash (int signum)
01552a
 {
01552a
     struct termios term_attributes;
01552a
     int fd;
01552a
+    static const char *show_cursor_sequence = "\033[?25h";
01552a
 
01552a
     fd = open ("/dev/tty1", O_RDWR | O_NOCTTY);
01552a
     if (fd < 0) fd = open ("/dev/hvc0", O_RDWR | O_NOCTTY);
01552a
 
01552a
     ioctl (fd, KDSETMODE, KD_TEXT);
01552a
 
01552a
+    write (fd, show_cursor_sequence, sizeof (show_cursor_sequence) - 1);
01552a
+
01552a
     tcgetattr (fd, &term_attributes);
01552a
 
01552a
     term_attributes.c_iflag |= BRKINT | IGNPAR | ICRNL | IXON;
01552a
     term_attributes.c_oflag |= OPOST;
01552a
     term_attributes.c_lflag |= ECHO | ICANON | ISIG | IEXTEN;
01552a
 
01552a
     tcsetattr (fd, TCSAFLUSH, &term_attributes);
01552a
 
01552a
     close (fd);
01552a
 
01552a
     if (debug_buffer != NULL)
01552a
       {
01552a
         dump_debug_buffer_to_file ();
01552a
         sleep (30);
01552a
       }
01552a
 
01552a
     if (pid_file != NULL)
01552a
       {
01552a
         unlink (pid_file);
01552a
         free (pid_file);
01552a
         pid_file = NULL;
01552a
       }
01552a
 
01552a
     signal (signum, SIG_DFL);
01552a
     raise(signum);
01552a
 }
01552a
 
01552a
 static void
01552a
 write_pid_file (const char *filename)
01552a
 {
01552a
-- 
01552a
2.3.7
01552a
01552a
01552a
From 4278596f4f5a6856aff50e97b7c0ff05aed67372 Mon Sep 17 00:00:00 2001
01552a
From: Frederic Crozat <fcrozat@suse.com>
01552a
Date: Thu, 12 Jun 2014 15:01:37 +0200
01552a
Subject: [PATCH 3/5] device-manager: only call ply_terminal_free
01552a
01552a
ply_terminal_free will call ply_terminal_close anyway and is guarded
01552a
against NULL terminal (ply_terminal_close is not).
01552a
---
01552a
 src/libply-splash-core/ply-device-manager.c | 1 -
01552a
 1 file changed, 1 deletion(-)
01552a
01552a
diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
01552a
index 8f5360c..17607f4 100644
01552a
--- a/src/libply-splash-core/ply-device-manager.c
01552a
+++ b/src/libply-splash-core/ply-device-manager.c
01552a
@@ -415,61 +415,60 @@ free_seats (ply_device_manager_t *manager)
01552a
 {
01552a
   ply_list_node_t *node;
01552a
 
01552a
   ply_trace ("removing seats");
01552a
   node = ply_list_get_first_node (manager->seats);
01552a
   while (node != NULL)
01552a
     {
01552a
       ply_seat_t *seat;
01552a
       ply_list_node_t *next_node;
01552a
 
01552a
       seat = ply_list_node_get_data (node);
01552a
       next_node = ply_list_get_next_node (manager->seats, node);
01552a
 
01552a
       if (manager->seat_removed_handler != NULL)
01552a
         manager->seat_removed_handler (manager->seat_event_handler_data, seat);
01552a
 
01552a
       ply_seat_free (seat);
01552a
       ply_list_remove_node (manager->seats, node);
01552a
 
01552a
       node = next_node;
01552a
     }
01552a
 }
01552a
 
01552a
 static void
01552a
 free_terminal (char                 *device,
01552a
                ply_terminal_t       *terminal,
01552a
                ply_device_manager_t *manager)
01552a
 {
01552a
   ply_hashtable_remove (manager->terminals, device);
01552a
 
01552a
-  ply_terminal_close (terminal);
01552a
   ply_terminal_free (terminal);
01552a
 }
01552a
 
01552a
 static void
01552a
 free_terminals (ply_device_manager_t *manager)
01552a
 {
01552a
   ply_hashtable_foreach (manager->terminals,
01552a
                          (ply_hashtable_foreach_func_t *)
01552a
                          free_terminal,
01552a
                          manager);
01552a
 }
01552a
 
01552a
 static ply_terminal_t *
01552a
 get_terminal (ply_device_manager_t *manager,
01552a
               const char           *device_name)
01552a
 {
01552a
   char *full_name = NULL;
01552a
   ply_terminal_t *terminal;
01552a
 
01552a
   if (strncmp (device_name, "/dev/", strlen ("/dev/")) == 0)
01552a
     full_name = strdup (device_name);
01552a
   else
01552a
     asprintf (&full_name, "/dev/%s", device_name);
01552a
 
01552a
   if (strcmp (full_name, "/dev/tty0") == 0 ||
01552a
       strcmp (full_name, "/dev/tty") == 0 ||
01552a
       strcmp (full_name, ply_terminal_get_name (manager->local_console_terminal)) == 0)
01552a
     {
01552a
       terminal = manager->local_console_terminal;
01552a
 
01552a
-- 
01552a
2.3.7
01552a
01552a
01552a
From e7048fdd1a40ed683fc706a40816cc490a693ba9 Mon Sep 17 00:00:00 2001
01552a
From: Ray Strode <rstrode@redhat.com>
01552a
Date: Wed, 7 Jan 2015 16:24:57 -0500
01552a
Subject: [PATCH 4/5] device-manager: try fb device if drm device failed
01552a
01552a
If the drm device failed to work, then fall back to the fb device.
01552a
01552a
Right now, we ignore fb devices that have associated drm devices.
01552a
01552a
This may fix vmwgfx.
01552a
---
01552a
 src/libply-splash-core/ply-device-manager.c | 39 ++++++++++++++++++++++++++++-
01552a
 1 file changed, 38 insertions(+), 1 deletion(-)
01552a
01552a
diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
01552a
index 17607f4..cc153e2 100644
01552a
--- a/src/libply-splash-core/ply-device-manager.c
01552a
+++ b/src/libply-splash-core/ply-device-manager.c
01552a
@@ -88,95 +88,132 @@ attach_to_event_loop (ply_device_manager_t *manager,
01552a
 }
01552a
 
01552a
 static bool
01552a
 device_is_for_local_console (ply_device_manager_t *manager,
01552a
                              struct udev_device   *device)
01552a
 {
01552a
   const char *device_path;
01552a
   struct udev_device *bus_device;
01552a
   char *bus_device_path;
01552a
   const char *boot_vga;
01552a
   bool for_local_console;
01552a
 
01552a
   /* Look at the associated bus device to see if this card is the
01552a
    * card the kernel is using for its console. */
01552a
   device_path = udev_device_get_syspath (device);
01552a
   asprintf (&bus_device_path, "%s/device", device_path);
01552a
   bus_device = udev_device_new_from_syspath (manager->udev_context, bus_device_path);
01552a
 
01552a
   boot_vga = udev_device_get_sysattr_value (bus_device, "boot_vga");
01552a
   free (bus_device_path);
01552a
 
01552a
   if (boot_vga != NULL && strcmp (boot_vga, "1") == 0)
01552a
     for_local_console = true;
01552a
   else
01552a
     for_local_console = false;
01552a
 
01552a
   return for_local_console;
01552a
 }
01552a
 
01552a
 static bool
01552a
+drm_device_in_use (ply_device_manager_t *manager,
01552a
+                   const char           *device_path)
01552a
+{
01552a
+  ply_list_node_t *node;
01552a
+
01552a
+  node = ply_list_get_first_node (manager->seats);
01552a
+  while (node != NULL)
01552a
+    {
01552a
+      ply_seat_t *seat;
01552a
+      ply_renderer_t *renderer;
01552a
+      ply_list_node_t *next_node;
01552a
+      const char *renderer_device_path;
01552a
+
01552a
+      seat = ply_list_node_get_data (node);
01552a
+      next_node = ply_list_get_next_node (manager->seats, node);
01552a
+      renderer = ply_seat_get_renderer (seat);
01552a
+
01552a
+      if (renderer != NULL)
01552a
+        {
01552a
+          renderer_device_path = ply_renderer_get_device_name (renderer);
01552a
+
01552a
+          if (renderer_device_path != NULL)
01552a
+            {
01552a
+              if (strcmp (device_path, renderer_device_path) == 0)
01552a
+                {
01552a
+                  return true;
01552a
+                }
01552a
+            }
01552a
+        }
01552a
+
01552a
+      node = next_node;
01552a
+    }
01552a
+
01552a
+  return false;
01552a
+}
01552a
+
01552a
+static bool
01552a
 fb_device_has_drm_device (ply_device_manager_t *manager,
01552a
                           struct udev_device   *fb_device)
01552a
 {
01552a
   struct udev_enumerate *card_matches;
01552a
   struct udev_list_entry *card_entry;
01552a
   const char *id_path;
01552a
   bool has_drm_device = false;
01552a
 
01552a
   /* We want to see if the framebuffer is associated with a DRM-capable
01552a
    * graphics card, if it is, we'll use the DRM device */
01552a
   card_matches = udev_enumerate_new (manager->udev_context);
01552a
   udev_enumerate_add_match_is_initialized(card_matches);
01552a
   udev_enumerate_add_match_parent (card_matches, udev_device_get_parent (fb_device));
01552a
   udev_enumerate_add_match_subsystem (card_matches, "drm");
01552a
   id_path = udev_device_get_property_value (fb_device, "ID_PATH");
01552a
   udev_enumerate_add_match_property (card_matches, "ID_PATH", id_path);
01552a
 
01552a
   ply_trace ("trying to find associated drm node for fb device (path: %s)", id_path);
01552a
 
01552a
   udev_enumerate_scan_devices (card_matches);
01552a
 
01552a
   /* there should only ever be at most one match so we don't iterate through
01552a
    * the list, but just look at the first entry */
01552a
   card_entry = udev_enumerate_get_list_entry (card_matches);
01552a
 
01552a
   if (card_entry != NULL)
01552a
     {
01552a
       struct udev_device *card_device = NULL;
01552a
       const char *card_node;
01552a
       const char *card_path;
01552a
 
01552a
       card_path = udev_list_entry_get_name (card_entry);
01552a
       card_device = udev_device_new_from_syspath (manager->udev_context, card_path);
01552a
       card_node = udev_device_get_devnode (card_device);
01552a
-      if (card_node != NULL)
01552a
+      if (card_node != NULL && drm_device_in_use (manager, card_node))
01552a
         has_drm_device = true;
01552a
       else
01552a
         ply_trace ("no card node!");
01552a
 
01552a
       udev_device_unref (card_device);
01552a
     }
01552a
   else
01552a
     {
01552a
       ply_trace ("no card entry!");
01552a
     }
01552a
 
01552a
   udev_enumerate_unref (card_matches);
01552a
   return has_drm_device;
01552a
 }
01552a
 
01552a
 static void
01552a
 create_seat_for_udev_device (ply_device_manager_t *manager,
01552a
                              struct udev_device   *device)
01552a
 {
01552a
   bool for_local_console;
01552a
   const char *device_path;
01552a
   ply_terminal_t *terminal = NULL;
01552a
 
01552a
   for_local_console = device_is_for_local_console (manager, device);
01552a
 
01552a
   ply_trace ("device is for local console: %s", for_local_console? "yes" : "no");
01552a
 
01552a
   if (for_local_console)
01552a
     terminal = manager->local_console_terminal;
01552a
 
01552a
-- 
01552a
2.3.7
01552a
01552a
01552a
From b9989b912fb394c00d3d4740eb72a25f80a8bc71 Mon Sep 17 00:00:00 2001
01552a
From: Ray Strode <rstrode@redhat.com>
01552a
Date: Fri, 3 Jul 2015 10:38:47 -0400
01552a
Subject: [PATCH 5/5] device-manager: don't try to load graphical splash after
01552a
 using text splash
01552a
01552a
We only support loading one splash at a time at the moment, so this
01552a
commit makes sure we don't load a graphical splash after already loading
01552a
a text splash
01552a
---
01552a
 src/libply-splash-core/ply-device-manager.c | 10 +++++++++-
01552a
 1 file changed, 9 insertions(+), 1 deletion(-)
01552a
01552a
diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
01552a
index cc153e2..a7890d0 100644
01552a
--- a/src/libply-splash-core/ply-device-manager.c
01552a
+++ b/src/libply-splash-core/ply-device-manager.c
01552a
@@ -379,61 +379,69 @@ create_seats_for_subsystem (ply_device_manager_t *manager,
01552a
   return found_device;
01552a
 }
01552a
 
01552a
 static void
01552a
 on_udev_event (ply_device_manager_t *manager)
01552a
 {
01552a
   struct udev_device *device;
01552a
   const char *action;
01552a
 
01552a
   device = udev_monitor_receive_device (manager->udev_monitor);
01552a
   if (device == NULL)
01552a
     return;
01552a
 
01552a
   action = udev_device_get_action (device);
01552a
 
01552a
   ply_trace ("got %s event for device %s", action, udev_device_get_sysname (device));
01552a
 
01552a
   if (action == NULL)
01552a
     return;
01552a
 
01552a
   if (strcmp (action, "add") == 0)
01552a
     {
01552a
       const char *subsystem;
01552a
       bool coldplug_complete = manager->udev_queue_fd_watch == NULL;
01552a
 
01552a
       subsystem = udev_device_get_subsystem (device);
01552a
 
01552a
       if (strcmp (subsystem, SUBSYSTEM_DRM) == 0 ||
01552a
           coldplug_complete)
01552a
         {
01552a
-          create_seat_for_udev_device (manager, device);
01552a
+          ply_list_t *local_pixel_displays = NULL;
01552a
+
01552a
+          if (manager->local_console_seat != NULL)
01552a
+            local_pixel_displays = ply_seat_get_pixel_displays (manager->local_console_seat);
01552a
+
01552a
+          if (coldplug_complete && manager->local_console_seat != NULL && local_pixel_displays == NULL)
01552a
+            ply_trace ("ignoring since we're already using text splash for local console");
01552a
+          else
01552a
+            create_seat_for_udev_device (manager, device);
01552a
         }
01552a
       else
01552a
         {
01552a
           ply_trace ("ignoring since we only handle subsystem %s devices after coldplug completes", subsystem);
01552a
         }
01552a
     }
01552a
   else if (strcmp (action, "remove") == 0)
01552a
     {
01552a
       free_seat_for_udev_device (manager, device);
01552a
     }
01552a
 
01552a
   udev_device_unref (device);
01552a
 }
01552a
 
01552a
 static void
01552a
 watch_for_udev_events (ply_device_manager_t *manager)
01552a
 {
01552a
   int fd;
01552a
   assert (manager != NULL);
01552a
   assert (manager->udev_monitor == NULL);
01552a
 
01552a
   ply_trace ("watching for udev graphics device add and remove events");
01552a
 
01552a
   manager->udev_monitor = udev_monitor_new_from_netlink (manager->udev_context, "udev");
01552a
 
01552a
   udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_DRM, NULL);
01552a
   udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_FRAME_BUFFER, NULL);
01552a
   udev_monitor_filter_add_match_tag (manager->udev_monitor, "seat");
01552a
   udev_monitor_enable_receiving (manager->udev_monitor);
01552a
 
01552a
-- 
01552a
2.3.7
01552a