[libplybootsplash] Add renderer class

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.
This commit is contained in:
Ray Strode 2009-08-21 09:53:33 -04:00
parent 48d4f00052
commit 846d609e5f
5 changed files with 500 additions and 1 deletions

View 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

View file

@ -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: */

View file

@ -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: */

View file

@ -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: */

View file

@ -1,3 +1,3 @@
SUBDIRS = controls splash
SUBDIRS = controls splash renderers
MAINTAINERCLEANFILES = Makefile.in