]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
[libplybootsplash] Add renderer class
authorRay Strode <rstrode@redhat.com>
Fri, 21 Aug 2009 13:53:33 +0000 (09:53 -0400)
committerRay Strode <rstrode@redhat.com>
Mon, 28 Sep 2009 15:23:36 +0000 (11:23 -0400)
In order to support multiple rendering backends, and multi-head
monitor layouts, I'm moving the actually rendering to render
plugins.

Examples of plugins could be frame-buffer, drm fb, and x11
(for debugging).

The renderer class is responsible for loading the appropriate rendering
backend, and providing an interface for the rendering backend to
advertise multiple displays.

Right now we only check for a frame-buffer plugin, although, it isn't
implemented yet.

src/libplybootsplash/Makefile.am
src/libplybootsplash/ply-renderer-plugin.h [new file with mode: 0644]
src/libplybootsplash/ply-renderer.c [new file with mode: 0644]
src/libplybootsplash/ply-renderer.h [new file with mode: 0644]
src/plugins/Makefile.am

index adf75f1c13ad4f7c59d0aa5d3c7572e5089adcb5..1172cf1dac5d02e76be185316457c2a7019a4625 100644 (file)
@@ -10,6 +10,7 @@ libplybootsplash_HEADERS = \
                    ply-animation.h                                           \
                    ply-boot-splash.h                                         \
                    ply-boot-splash-plugin.h                                  \
+                   ply-console.h                                             \
                    ply-entry.h                                               \
                    ply-image.h                                               \
                    ply-keyboard.h                                            \
@@ -18,6 +19,8 @@ libplybootsplash_HEADERS = \
                    ply-pixel-buffer.h                                        \
                    ply-progress-animation.h                                  \
                    ply-progress-bar.h                                        \
+                   ply-renderer.h                                            \
+                   ply-renderer-plugin.h                                     \
                    ply-terminal.h                                            \
                    ply-text-progress-bar.h                                   \
                    ply-throbber.h                                            \
@@ -35,6 +38,7 @@ libplybootsplash_la_LDFLAGS = -export-symbols-regex '^[^_].*' \
                    -no-undefined
 libplybootsplash_la_SOURCES = \
                    $(libplybootsplash_HEADERS)                              \
+                   ply-console.c                                            \
                    ply-entry.c                                              \
                    ply-image.c                                              \
                    ply-keyboard.c                                           \
@@ -46,6 +50,7 @@ libplybootsplash_la_SOURCES = \
                    ply-text-progress-bar.c                                  \
                    ply-terminal.c                                           \
                    ply-pixel-buffer.c                                       \
+                   ply-renderer.c                                           \
                    ply-window.c                                             \
                    ply-boot-splash.c
 
diff --git a/src/libplybootsplash/ply-renderer-plugin.h b/src/libplybootsplash/ply-renderer-plugin.h
new file mode 100644 (file)
index 0000000..6acb892
--- /dev/null
@@ -0,0 +1,71 @@
+/* ply-renderer-plugin.h - plugin interface for ply_renderer_t
+ *
+ * Copyright (C) 2009 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.
+ *
+ * Written By: Ray Strode <rstrode@redhat.com>
+ */
+#ifndef PLY_RENDERER_PLUGIN_H
+#define PLY_RENDERER_PLUGIN_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "ply-console.h"
+#include "ply-event-loop.h"
+#include "ply-list.h"
+#include "ply-region.h"
+#include "ply-renderer.h"
+
+typedef struct _ply_renderer_plugin ply_renderer_plugin_t;
+typedef struct _ply_renderer_backend ply_renderer_backend_t;
+
+typedef struct
+{
+  ply_renderer_backend_t * (* create_backend) (const char *device_name,
+                                               ply_terminal_t *terminal,
+                                               ply_console_t *console);
+  void (* destroy_backend) (ply_renderer_backend_t *backend);
+  bool (* open_device) (ply_renderer_backend_t *backend);
+  void (* close_device) (ply_renderer_backend_t *backend);
+  bool (* query_device) (ply_renderer_backend_t *backend);
+  bool (* map_to_device) (ply_renderer_backend_t *backend);
+  void (* unmap_from_device) (ply_renderer_backend_t *backend);
+  void (* flush_head) (ply_renderer_backend_t *backend,
+                       ply_renderer_head_t    *head);
+
+  ply_list_t * (* get_heads) (ply_renderer_backend_t *backend);
+
+  ply_pixel_buffer_t * (* get_buffer_for_head) (ply_renderer_backend_t *backend,
+                                                ply_renderer_head_t    *head);
+
+  ply_renderer_input_source_t * (* get_input_source) (ply_renderer_backend_t *backend);
+  bool                 (* open_input_source) (ply_renderer_backend_t *backend,
+                                              ply_renderer_input_source_t *input_source);
+
+  void                 (* set_handler_for_input_source) (ply_renderer_backend_t    *backend,
+                                                         ply_renderer_input_source_t *input_source,
+                                                         ply_renderer_input_source_handler_t handler,
+                                                         void                      *user_data);
+
+  void                 (* close_input_source) (ply_renderer_backend_t *backend,
+                                               ply_renderer_input_source_t *input_source);
+} ply_renderer_plugin_interface_t;
+
+#endif /* PLY_RENDERER_PLUGIN_H */
+/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
diff --git a/src/libplybootsplash/ply-renderer.c b/src/libplybootsplash/ply-renderer.c
new file mode 100644 (file)
index 0000000..510479d
--- /dev/null
@@ -0,0 +1,353 @@
+/* ply-renderer.c - renderer abstraction
+ *
+ * Copyright (C) 2006, 2007, 2008, 2009 Red Hat, Inc.
+ *               2008 Charlie Brej <cbrej@cs.man.ac.uk>
+ *
+ * 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.
+ *
+ * Written by: Charlie Brej <cbrej@cs.man.ac.uk>
+ *             Kristian Høgsberg <krh@redhat.com>
+ *             Ray Strode <rstrode@redhat.com>
+ */
+#include "config.h"
+#include "ply-renderer.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "ply-renderer-plugin.h"
+#include "ply-buffer.h"
+#include "ply-console.h"
+#include "ply-event-loop.h"
+#include "ply-list.h"
+#include "ply-logger.h"
+#include "ply-utils.h"
+
+struct _ply_renderer
+{
+  ply_event_loop_t *loop;
+  ply_module_handle_t *module_handle;
+  const ply_renderer_plugin_interface_t *plugin_interface;
+  ply_renderer_backend_t *backend;
+
+  char *device_name;
+  ply_console_t *console;
+};
+
+typedef const ply_renderer_plugin_interface_t *
+        (* get_backend_interface_function_t) (void);
+
+static void ply_renderer_unload_plugin (ply_renderer_t *renderer);
+
+ply_renderer_t *
+ply_renderer_new (const char    *device_name,
+                  ply_terminal_t *terminal,
+                  ply_console_t *console)
+{
+  ply_renderer_t *renderer;
+
+  renderer = calloc (1, sizeof (struct _ply_renderer));
+
+  if (device_name != NULL)
+    renderer->device_name = strdup (device_name);
+
+  renderer->terminal = terminal;
+  renderer->console = console;
+
+  return renderer;
+}
+
+void
+ply_renderer_free (ply_renderer_t *renderer)
+{
+  if (renderer == NULL)
+    return;
+
+  if (renderer->plugin_interface != NULL)
+    {
+      ply_trace ("Unloading renderer backend plugin");
+      ply_renderer_unload_plugin (renderer);
+    }
+
+  free (renderer->device_name);
+  free (renderer);
+}
+
+static bool
+ply_renderer_load_plugin (ply_renderer_t *renderer,
+                          const char     *module_path)
+{
+  assert (renderer != NULL);
+
+  get_backend_interface_function_t get_renderer_backend_interface;
+
+  renderer->module_handle = ply_open_module (module_path);
+
+  if (renderer->module_handle == NULL)
+    return false;
+
+  get_renderer_backend_interface = (get_backend_interface_function_t)
+      ply_module_look_up_function (renderer->module_handle,
+                                   "ply_renderer_backend_get_interface");
+
+  if (get_renderer_backend_interface == NULL)
+    {
+      ply_save_errno ();
+      ply_trace ("module '%s' is not a renderer plugin",
+                 module_path);
+      ply_close_module (renderer->module_handle);
+      renderer->module_handle = NULL;
+      ply_restore_errno ();
+      return false;
+    }
+
+  renderer->plugin_interface = get_renderer_backend_interface ();
+
+  if (renderer->plugin_interface == NULL)
+    {
+      ply_trace ("module '%s' is not a valid renderer plugin",
+                 module_path);
+      ply_save_errno ();
+      ply_close_module (renderer->module_handle);
+      renderer->module_handle = NULL;
+      ply_restore_errno ();
+      return false;
+    }
+
+  renderer->backend = renderer->plugin_interface->create_backend (renderer->device_name,
+                                                                  renderer->terminal,
+                                                                  renderer->console);
+
+  if (renderer->backend == NULL)
+    {
+      ply_save_errno ();
+      ply_trace ("module '%s' renderer backend could not be created",
+                 module_path);
+      ply_close_module (renderer->module_handle);
+      renderer->module_handle = NULL;
+      ply_restore_errno ();
+      return false;
+    }
+
+  return true;
+}
+
+static void
+ply_renderer_unload_plugin (ply_renderer_t *renderer)
+{
+  assert (renderer != NULL);
+  assert (renderer->plugin_interface != NULL);
+  assert (renderer->module_handle != NULL);
+
+  ply_close_module (renderer->module_handle);
+  renderer->plugin_interface = NULL;
+  renderer->module_handle = NULL;
+}
+
+static bool
+ply_renderer_open_device (ply_renderer_t *renderer)
+{
+  assert (renderer != NULL);
+  assert (renderer->plugin_interface != NULL);
+
+  return renderer->plugin_interface->open_device (renderer->backend);
+}
+
+static void
+ply_renderer_close_device (ply_renderer_t *renderer)
+{
+  assert (renderer != NULL);
+  assert (renderer->plugin_interface != NULL);
+
+  renderer->plugin_interface->close_device (renderer->backend);
+}
+
+static bool
+ply_renderer_query_device (ply_renderer_t *renderer)
+{
+  assert (renderer != NULL);
+  assert (renderer->plugin_interface != NULL);
+
+  return renderer->plugin_interface->query_device (renderer->backend);
+}
+
+static bool
+ply_renderer_map_to_device (ply_renderer_t *renderer)
+{
+  assert (renderer != NULL);
+  assert (renderer->plugin_interface != NULL);
+
+  return renderer->plugin_interface->map_to_device (renderer->backend);
+}
+
+static void
+ply_renderer_unmap_from_device (ply_renderer_t *renderer)
+{
+  assert (renderer != NULL);
+  assert (renderer->plugin_interface != NULL);
+
+  renderer->plugin_interface->unmap_from_device (renderer->backend);
+}
+
+bool
+ply_renderer_open (ply_renderer_t *renderer)
+{
+  int i;
+
+  /* FIXME: at some point we may want to make this
+   * part more dynamic (so you don't have to edit this
+   * list to add a new renderer)
+   */
+  const char *known_plugins[] =
+    {
+      PLYMOUTH_PLUGIN_PATH "renderers/frame-buffer.so",
+      NULL
+    };
+
+  for (i = 0; known_plugins[i] != NULL; i++)
+    {
+      const char *plugin_path;
+
+      plugin_path = known_plugins[i];
+
+      if (!ply_renderer_load_plugin (renderer, plugin_path))
+        continue;
+
+      if (!ply_renderer_open_device (renderer))
+        {
+          ply_trace ("could not open rendering device for plugin %s",
+                     plugin_path);
+          ply_renderer_unload_plugin (renderer);
+          continue;
+        }
+
+      if (!ply_renderer_query_device (renderer))
+        {
+          ply_trace ("could not query rendering device for plugin %s",
+                     plugin_path);
+          ply_renderer_unload_plugin (renderer);
+          continue;
+        }
+
+      if (!ply_renderer_map_to_device (renderer))
+        {
+          ply_trace ("could not map renderer to device for plugin %s",
+                     plugin_path);
+          ply_renderer_unload_plugin (renderer);
+          continue;
+        }
+      return true;
+  }
+
+  ply_trace ("could not find suitable rendering plugin");
+  return false;
+}
+
+void
+ply_renderer_close (ply_renderer_t *renderer)
+{
+  ply_renderer_unmap_from_device (renderer);
+  ply_renderer_close_device (renderer);
+}
+
+ply_list_t *
+ply_renderer_get_heads (ply_renderer_t *renderer)
+{
+  assert (renderer->plugin_interface != NULL);
+
+  return renderer->plugin_interface->get_heads (renderer->backend);
+}
+
+ply_pixel_buffer_t *
+ply_renderer_get_buffer_for_head (ply_renderer_t      *renderer,
+                                  ply_renderer_head_t *head)
+{
+  assert (renderer != NULL);
+  assert (renderer->plugin_interface != NULL);
+  assert (head != NULL);
+
+  return renderer->plugin_interface->get_buffer_for_head (renderer->backend,
+                                                          head);
+}
+
+void
+ply_renderer_flush_head (ply_renderer_t      *renderer,
+                         ply_renderer_head_t *head)
+{
+  assert (renderer != NULL);
+  assert (renderer->plugin_interface != NULL);
+  assert (head != NULL);
+
+  if (ply_console_get_active_vt (renderer->console) !=
+      ply_terminal_get_vt_number (renderer->terminal))
+    return;
+
+  renderer->plugin_interface->flush_head (renderer->backend, head);
+}
+
+ply_renderer_input_source_t *
+ply_renderer_get_input_source (ply_renderer_t *renderer)
+{
+  assert (renderer != NULL);
+  assert (renderer->plugin_interface != NULL);
+
+  return renderer->plugin_interface->get_input_source (renderer->backend);
+}
+
+bool
+ply_renderer_open_input_source (ply_renderer_t              *renderer,
+                                ply_renderer_input_source_t *input_source)
+{
+  assert (renderer != NULL);
+  assert (input_source != NULL);
+
+  return renderer->plugin_interface->open_input_source (renderer->backend,
+                                                        input_source);
+}
+
+void
+ply_renderer_set_handler_for_input_source (ply_renderer_t                      *renderer,
+                                           ply_renderer_input_source_t         *input_source,
+                                           ply_renderer_input_source_handler_t  handler,
+                                           void                                *user_data)
+{
+  assert (renderer != NULL);
+  assert (input_source != NULL);
+
+  renderer->plugin_interface->set_handler_for_input_source (renderer->backend,
+                                                            input_source,
+                                                            handler,
+                                                            user_data);
+}
+
+void
+ply_renderer_close_input_source (ply_renderer_t              *renderer,
+                                 ply_renderer_input_source_t *input_source)
+{
+  assert (renderer != NULL);
+  assert (input_source != NULL);
+
+  renderer->plugin_interface->close_input_source (renderer->backend,
+                                                  input_source);
+}
+
+/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
diff --git a/src/libplybootsplash/ply-renderer.h b/src/libplybootsplash/ply-renderer.h
new file mode 100644 (file)
index 0000000..da03e8d
--- /dev/null
@@ -0,0 +1,70 @@
+/* ply-renderer.h - rendering abstraction
+ *
+ * Copyright (C) 2009 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.
+ *
+ * Written By: Ray Strode <rstrode@redhat.com>
+ */
+#ifndef PLY_RENDERER_H
+#define PLY_RENDERER_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "ply-buffer.h"
+#include "ply-console.h"
+#include "ply-list.h"
+#include "ply-pixel-buffer.h"
+#include "ply-terminal.h"
+#include "ply-utils.h"
+
+typedef struct _ply_renderer ply_renderer_t;
+typedef struct _ply_renderer_head ply_renderer_head_t;
+typedef struct _ply_renderer_input_source ply_renderer_input_source_t;
+
+typedef void (* ply_renderer_input_source_handler_t) (void                        *user_data,
+                                                      ply_buffer_t                *key_buffer,
+                                                      ply_renderer_input_source_t *input_source);
+
+#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
+ply_renderer_t *ply_renderer_new (const char    *device_name,
+                                  ply_terminal_t *terminal,
+                                  ply_console_t *console);
+void ply_renderer_free (ply_renderer_t *renderer);
+bool ply_renderer_open (ply_renderer_t *renderer);
+void ply_renderer_close (ply_renderer_t *renderer);
+ply_list_t *ply_renderer_get_heads (ply_renderer_t *renderer);
+ply_pixel_buffer_t *ply_renderer_get_buffer_for_head (ply_renderer_t      *renderer,
+                                                      ply_renderer_head_t *head);
+
+void ply_renderer_flush_head (ply_renderer_t      *renderer,
+                              ply_renderer_head_t *head);
+
+ply_renderer_input_source_t *ply_renderer_get_input_source (ply_renderer_t *renderer);
+bool ply_renderer_open_input_source (ply_renderer_t              *renderer,
+                                     ply_renderer_input_source_t *input_source);
+void ply_renderer_set_handler_for_input_source (ply_renderer_t                      *renderer,
+                                                ply_renderer_input_source_t         *input_source,
+                                                ply_renderer_input_source_handler_t  handler,
+                                                void                                *user_data);
+
+void ply_renderer_close_input_source (ply_renderer_t              *renderer,
+                                      ply_renderer_input_source_t *input_source);
+#endif
+
+#endif /* PLY_RENDERER_H */
+/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
index b4fd30b91258fad9a54edac4aaa25b39d03b7192..12531fbd2e69f37b6b3ac31787c274874e9d207d 100644 (file)
@@ -1,3 +1,3 @@
-SUBDIRS = controls splash
+SUBDIRS = controls splash renderers
 
 MAINTAINERCLEANFILES = Makefile.in