--- /dev/null
+/* 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: */
--- /dev/null
+/* 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: */
--- /dev/null
+/* 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: */