summaryrefslogtreecommitdiff
authorRay Strode <rstrode@redhat.com>2009-11-28 04:44:21 (GMT)
committer Ray Strode <rstrode@redhat.com>2009-11-28 05:33:06 (GMT)
commit5ab755153356b3f685afe87c5926969389665bb2 (patch) (side-by-side diff)
treeec63f3c34c45a4345ec48641059528437ed6bb26
parent3ab7b2c54ec811f8b802f6133bf0089b97366db4 (diff)
parentd52b4efba18c4295618302fea9674e54c36e1b7e (diff)
downloadplymouth-5ab755153356b3f685afe87c5926969389665bb2.zip
plymouth-5ab755153356b3f685afe87c5926969389665bb2.tar.gz
[branch-merge] Improve plymouth -> X hand off
This merges the "no-fbcon" branch to master. Previously, the way to get a transition between plymouth and X was for plymouth to quit, leaving the tty in KD_GRAPHICS mode, and hope X starts and picks up the peices. In this limbo state where plymouth isn't running but X isn't started yet the user is unable to switch VTs or really do anything at all. If X doesn't start then the user is hosed; they have to reboot. Now, instead of quitting plymouth before starting X we "deactivate" it. This gets plymouth into a state where X can take over the display, but plymouth stays running. Once X has fully started up or failed to start the display manager can tell plymouth to quit (with --retain-splash if X started successfully and without if X started unsucessfully)
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--src/client/ply-boot-client.c12
-rw-r--r--src/client/ply-boot-client.h4
-rw-r--r--src/client/plymouth.c16
-rw-r--r--src/libplybootsplash/ply-renderer-plugin.h2
-rw-r--r--src/libplybootsplash/ply-renderer.c16
-rw-r--r--src/libplybootsplash/ply-renderer.h2
-rw-r--r--src/main.c57
-rw-r--r--src/plugins/renderers/drm/plugin.c47
-rw-r--r--src/plugins/renderers/frame-buffer/plugin.c30
-rw-r--r--src/plugins/renderers/x11/plugin.c19
-rw-r--r--src/ply-boot-protocol.h1
-rw-r--r--src/ply-boot-server.c39
-rw-r--r--src/ply-boot-server.h4
13 files changed, 229 insertions, 20 deletions
diff --git a/src/client/ply-boot-client.c b/src/client/ply-boot-client.c
index 5f7bb54..917a619 100644
--- a/src/client/ply-boot-client.c
+++ b/src/client/ply-boot-client.c
@@ -653,6 +653,18 @@ ply_boot_client_tell_daemon_to_hide_splash (ply_boot_client_t *
}
void
+ply_boot_client_tell_daemon_to_deactivate (ply_boot_client_t *client,
+ ply_boot_client_response_handler_t handler,
+ ply_boot_client_response_handler_t failed_handler,
+ void *user_data)
+{
+ assert (client != NULL);
+
+ ply_boot_client_queue_request (client, PLY_BOOT_PROTOCOL_REQUEST_TYPE_DEACTIVATE,
+ NULL, handler, failed_handler, user_data);
+}
+
+void
ply_boot_client_tell_daemon_to_quit (ply_boot_client_t *client,
bool retain_splash,
ply_boot_client_response_handler_t handler,
diff --git a/src/client/ply-boot-client.h b/src/client/ply-boot-client.h
index 43684ac..0e9122c 100644
--- a/src/client/ply-boot-client.h
+++ b/src/client/ply-boot-client.h
@@ -104,6 +104,10 @@ void ply_boot_client_tell_daemon_to_hide_splash (ply_boot_client_t
ply_boot_client_response_handler_t handler,
ply_boot_client_response_handler_t failed_handler,
void *user_data);
+void ply_boot_client_tell_daemon_to_deactivate (ply_boot_client_t *client,
+ ply_boot_client_response_handler_t handler,
+ ply_boot_client_response_handler_t failed_handler,
+ void *user_data);
void ply_boot_client_tell_daemon_to_quit (ply_boot_client_t *client,
bool retain_splash,
ply_boot_client_response_handler_t handler,
diff --git a/src/client/plymouth.c b/src/client/plymouth.c
index 80b0ec6..8669fd2 100644
--- a/src/client/plymouth.c
+++ b/src/client/plymouth.c
@@ -594,6 +594,17 @@ on_report_error_request (state_t *state,
}
static void
+on_deactivate_request (state_t *state,
+ const char *command)
+{
+ ply_boot_client_tell_daemon_to_deactivate (state->client,
+ (ply_boot_client_response_handler_t)
+ on_success,
+ (ply_boot_client_response_handler_t)
+ on_failure, state);
+}
+
+static void
on_quit_request (state_t *state,
const char *command)
{
@@ -710,6 +721,11 @@ main (int argc,
NULL);
ply_command_parser_add_command (state.command_parser,
+ "deactivate", "Tell boot daemon to deactivate",
+ (ply_command_handler_t)
+ on_deactivate_request, &state, NULL);
+
+ ply_command_parser_add_command (state.command_parser,
"quit", "Tell boot daemon to quit",
(ply_command_handler_t)
on_quit_request, &state,
diff --git a/src/libplybootsplash/ply-renderer-plugin.h b/src/libplybootsplash/ply-renderer-plugin.h
index 6acb892..e4f6b37 100644
--- a/src/libplybootsplash/ply-renderer-plugin.h
+++ b/src/libplybootsplash/ply-renderer-plugin.h
@@ -46,6 +46,8 @@ typedef struct
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 (* activate) (ply_renderer_backend_t *backend);
+ void (* deactivate) (ply_renderer_backend_t *backend);
void (* flush_head) (ply_renderer_backend_t *backend,
ply_renderer_head_t *head);
diff --git a/src/libplybootsplash/ply-renderer.c b/src/libplybootsplash/ply-renderer.c
index 591af2c..c34dfcf 100644
--- a/src/libplybootsplash/ply-renderer.c
+++ b/src/libplybootsplash/ply-renderer.c
@@ -278,6 +278,22 @@ ply_renderer_close (ply_renderer_t *renderer)
ply_renderer_close_device (renderer);
}
+void
+ply_renderer_activate (ply_renderer_t *renderer)
+{
+ assert (renderer->plugin_interface != NULL);
+
+ return renderer->plugin_interface->activate (renderer->backend);
+}
+
+void
+ply_renderer_deactivate (ply_renderer_t *renderer)
+{
+ assert (renderer->plugin_interface != NULL);
+
+ return renderer->plugin_interface->deactivate (renderer->backend);
+}
+
ply_list_t *
ply_renderer_get_heads (ply_renderer_t *renderer)
{
diff --git a/src/libplybootsplash/ply-renderer.h b/src/libplybootsplash/ply-renderer.h
index da03e8d..c4bbdbe 100644
--- a/src/libplybootsplash/ply-renderer.h
+++ b/src/libplybootsplash/ply-renderer.h
@@ -47,6 +47,8 @@ ply_renderer_t *ply_renderer_new (const char *device_name,
void ply_renderer_free (ply_renderer_t *renderer);
bool ply_renderer_open (ply_renderer_t *renderer);
void ply_renderer_close (ply_renderer_t *renderer);
+void ply_renderer_activate (ply_renderer_t *renderer);
+void ply_renderer_deactivate (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);
diff --git a/src/main.c b/src/main.c
index 3b27edf..95dc9fe 100644
--- a/src/main.c
+++ b/src/main.c
@@ -96,6 +96,7 @@ typedef struct
ply_renderer_t *renderer;
ply_terminal_t *terminal;
+ ply_trigger_t *deactivate_trigger;
ply_trigger_t *quit_trigger;
char kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE];
@@ -106,6 +107,7 @@ typedef struct
uint32_t is_attached : 1;
uint32_t should_be_attached : 1;
uint32_t should_retain_splash : 1;
+ uint32_t is_inactive : 1;
char *kernel_console_tty;
char *override_splash_path;
@@ -553,9 +555,12 @@ remove_displays_and_keyboard (state_t *state)
node = next_node;
}
- ply_keyboard_stop_watching_for_input (state->keyboard);
- ply_keyboard_free (state->keyboard);
- state->keyboard = NULL;
+ if (state->keyboard != NULL)
+ {
+ ply_keyboard_stop_watching_for_input (state->keyboard);
+ ply_keyboard_free (state->keyboard);
+ state->keyboard = NULL;
+ }
}
static void
@@ -690,7 +695,24 @@ quit_program (state_t *state)
static void
on_boot_splash_idle (state_t *state)
{
+
ply_trace ("boot splash idle");
+
+ if (state->deactivate_trigger != NULL)
+ {
+ ply_trace ("deactivating renderer");
+ ply_renderer_deactivate (state->renderer);
+
+ ply_trace ("quitting splash");
+ quit_splash (state);
+
+ ply_trigger_pull (state->deactivate_trigger, NULL);
+ state->deactivate_trigger = NULL;
+ state->is_inactive = true;
+
+ return;
+ }
+
if (!state->should_retain_splash)
{
ply_trace ("hiding splash");
@@ -704,6 +726,27 @@ on_boot_splash_idle (state_t *state)
quit_program (state);
}
+
+static void
+on_deactivate (state_t *state,
+ ply_trigger_t *deactivate_trigger)
+{
+ ply_trace ("deactivating");
+ if (state->boot_splash != NULL)
+ {
+ state->deactivate_trigger = deactivate_trigger;
+ ply_boot_splash_become_idle (state->boot_splash,
+ (ply_boot_splash_on_idle_handler_t)
+ on_boot_splash_idle,
+ state);
+ }
+ else
+ {
+ ply_trigger_pull (state->deactivate_trigger, NULL);
+ state->deactivate_trigger = NULL;
+ }
+}
+
static void
on_quit (state_t *state,
bool retain_splash,
@@ -725,6 +768,10 @@ on_quit (state_t *state,
on_boot_splash_idle,
state);
}
+ else if (state->is_inactive && !retain_splash)
+ /* We've been deactivated and X failed to start
+ */
+ dump_details_and_quit_splash (state);
else
quit_program (state);
}
@@ -747,6 +794,7 @@ start_boot_server (state_t *state)
(ply_boot_server_newroot_handler_t) on_newroot,
(ply_boot_server_system_initialized_handler_t) on_system_initialized,
(ply_boot_server_error_handler_t) on_error,
+ (ply_boot_server_deactivate_handler_t) on_deactivate,
(ply_boot_server_quit_handler_t) on_quit,
state);
@@ -1041,7 +1089,8 @@ add_displays_and_keyboard_to_boot_splash (state_t *state,
ply_list_node_t *node;
ply_trace ("setting keyboard on boot splash");
- ply_boot_splash_set_keyboard (splash, state->keyboard);
+ if (state->keyboard != NULL)
+ ply_boot_splash_set_keyboard (splash, state->keyboard);
node = ply_list_get_first_node (state->pixel_displays);
while (node != NULL)
diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c
index 3081ac8..1115b5c 100644
--- a/src/plugins/renderers/drm/plugin.c
+++ b/src/plugins/renderers/drm/plugin.c
@@ -110,6 +110,8 @@ struct _ply_renderer_backend
int32_t dither_red;
int32_t dither_green;
int32_t dither_blue;
+
+ uint32_t is_inactive : 1;
};
ply_renderer_plugin_interface_t *ply_renderer_backend_get_interface (void);
@@ -367,16 +369,11 @@ find_driver_for_device (const char *device_name)
}
static void
-on_active_vt_changed (ply_renderer_backend_t *backend)
+activate (ply_renderer_backend_t *backend)
{
ply_list_node_t *node;
- if (ply_console_get_active_vt (backend->console) !=
- ply_terminal_get_vt_number (backend->terminal))
- {
- drmDropMaster (backend->device_fd);
- return;
- }
+ backend->is_inactive = false;
drmSetMaster (backend->device_fd);
node = ply_list_get_first_node (backend->heads);
@@ -396,6 +393,29 @@ on_active_vt_changed (ply_renderer_backend_t *backend)
}
}
+static void
+deactivate (ply_renderer_backend_t *backend)
+{
+ ply_trace ("dropping master");
+ drmDropMaster (backend->device_fd);
+ backend->is_inactive = true;
+}
+
+static void
+on_active_vt_changed (ply_renderer_backend_t *backend)
+{
+ if (ply_console_get_active_vt (backend->console) !=
+ ply_terminal_get_vt_number (backend->terminal))
+ {
+ ply_trace ("deactivating on vt change");
+ deactivate (backend);
+ return;
+ }
+
+ ply_trace ("activating on vt change");
+ activate (backend);
+}
+
static bool
load_driver (ply_renderer_backend_t *backend)
{
@@ -889,8 +909,12 @@ unmap_from_device (ply_renderer_backend_t *backend)
head = (ply_renderer_head_t *) ply_list_node_get_data (node);
next_node = ply_list_get_next_node (backend->heads, node);
- ply_renderer_head_set_scan_out_buffer_to_console (backend, head,
- should_set_to_black);
+ if (!backend->is_inactive)
+ {
+ ply_trace ("scanning out directly to console");
+ ply_renderer_head_set_scan_out_buffer_to_console (backend, head,
+ should_set_to_black);
+ }
ply_renderer_head_unmap (backend, head);
@@ -935,8 +959,7 @@ flush_head (ply_renderer_backend_t *backend,
assert (backend != NULL);
- if (ply_console_get_active_vt (backend->console) !=
- ply_terminal_get_vt_number (backend->terminal))
+ if (backend->is_inactive)
return;
ply_console_set_mode (backend->console, PLY_CONSOLE_MODE_GRAPHICS);
@@ -1079,6 +1102,8 @@ ply_renderer_backend_get_interface (void)
.query_device = query_device,
.map_to_device = map_to_device,
.unmap_from_device = unmap_from_device,
+ .activate = activate,
+ .deactivate = deactivate,
.flush_head = flush_head,
.get_heads = get_heads,
.get_buffer_for_head = get_buffer_for_head,
diff --git a/src/plugins/renderers/frame-buffer/plugin.c b/src/plugins/renderers/frame-buffer/plugin.c
index ce42eb3..80b5973 100644
--- a/src/plugins/renderers/frame-buffer/plugin.c
+++ b/src/plugins/renderers/frame-buffer/plugin.c
@@ -108,6 +108,8 @@ struct _ply_renderer_backend
unsigned int bytes_per_pixel;
unsigned int row_stride;
+ uint32_t is_inactive : 1;
+
void (* flush_area) (ply_renderer_backend_t *backend,
ply_renderer_head_t *head,
ply_rectangle_t *area_to_flush);
@@ -301,14 +303,31 @@ destroy_backend (ply_renderer_backend_t *backend)
}
static void
+activate (ply_renderer_backend_t *backend)
+{
+ backend->is_inactive = false;
+
+ if (backend->head.map_address != MAP_FAILED)
+ ply_renderer_head_redraw (backend, &backend->head);
+}
+
+static void
+deactivate (ply_renderer_backend_t *backend)
+{
+ backend->is_inactive = true;
+}
+
+static void
on_active_vt_changed (ply_renderer_backend_t *backend)
{
if (ply_console_get_active_vt (backend->console) !=
ply_terminal_get_vt_number (backend->terminal))
- return;
+ {
+ deactivate (backend);
+ return;
+ }
- if (backend->head.map_address != MAP_FAILED)
- ply_renderer_head_redraw (backend, &backend->head);
+ activate (backend);
}
static bool
@@ -525,8 +544,7 @@ flush_head (ply_renderer_backend_t *backend,
assert (backend != NULL);
assert (&backend->head == head);
- if (ply_console_get_active_vt (backend->console) !=
- ply_terminal_get_vt_number (backend->terminal))
+ if (backend->is_inactive)
return;
ply_console_set_mode (backend->console, PLY_CONSOLE_MODE_GRAPHICS);
@@ -661,6 +679,8 @@ ply_renderer_backend_get_interface (void)
.query_device = query_device,
.map_to_device = map_to_device,
.unmap_from_device = unmap_from_device,
+ .activate = activate,
+ .deactivate = deactivate,
.flush_head = flush_head,
.get_heads = get_heads,
.get_buffer_for_head = get_buffer_for_head,
diff --git a/src/plugins/renderers/x11/plugin.c b/src/plugins/renderers/x11/plugin.c
index 9e78c06..3777b6c 100644
--- a/src/plugins/renderers/x11/plugin.c
+++ b/src/plugins/renderers/x11/plugin.c
@@ -86,6 +86,8 @@ struct _ply_renderer_backend
ply_console_t *console;
ply_fd_watch_t *display_watch;
+
+ uint32_t is_inactive : 1;
};
ply_renderer_plugin_interface_t *ply_renderer_backend_get_interface (void);
@@ -308,6 +310,18 @@ unmap_from_device (ply_renderer_backend_t *backend)
}
static void
+activate (ply_renderer_backend_t *backend)
+{
+ backend->is_inactive = false;
+}
+
+static void
+deactivate (ply_renderer_backend_t *backend)
+{
+ backend->is_inactive = true;
+}
+
+static void
flush_area_to_device (ply_renderer_backend_t *backend,
ply_renderer_head_t *head,
ply_rectangle_t *area_to_flush,
@@ -338,6 +352,9 @@ flush_head (ply_renderer_backend_t *backend,
assert (backend != NULL);
+ if (backend->is_inactive)
+ return;
+
pixel_buffer = head->pixel_buffer;
updated_region = ply_pixel_buffer_get_updated_areas (pixel_buffer);
areas_to_flush = ply_region_get_rectangle_list (updated_region);
@@ -516,6 +533,8 @@ ply_renderer_backend_get_interface (void)
.query_device = query_device,
.map_to_device = map_to_device,
.unmap_from_device = unmap_from_device,
+ .activate = activate,
+ .deactivate = deactivate,
.flush_head = flush_head,
.get_heads = get_heads,
.get_buffer_for_head = get_buffer_for_head,
diff --git a/src/ply-boot-protocol.h b/src/ply-boot-protocol.h
index 419d481..6be7218 100644
--- a/src/ply-boot-protocol.h
+++ b/src/ply-boot-protocol.h
@@ -26,6 +26,7 @@
#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_PING "P"
#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_UPDATE "U"
#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_SYSTEM_INITIALIZED "S"
+#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_DEACTIVATE "D"
#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUIT "Q"
#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD "*"
#define PLY_BOOT_PROTOCOL_REQUEST_TYPE_CACHED_PASSWORD "c"
diff --git a/src/ply-boot-server.c b/src/ply-boot-server.c
index 9a1ed8e..4cc579f 100644
--- a/src/ply-boot-server.c
+++ b/src/ply-boot-server.c
@@ -65,6 +65,7 @@ struct _ply_boot_server
ply_boot_server_ignore_keystroke_handler_t ignore_keystroke_handler;
ply_boot_server_progress_pause_handler_t progress_pause_handler;
ply_boot_server_progress_unpause_handler_t progress_unpause_handler;
+ ply_boot_server_deactivate_handler_t deactivate_handler;
ply_boot_server_quit_handler_t quit_handler;
void *user_data;
@@ -85,6 +86,7 @@ ply_boot_server_new (ply_boot_server_update_handler_t update_handler,
ply_boot_server_newroot_handler_t newroot_handler,
ply_boot_server_system_initialized_handler_t initialized_handler,
ply_boot_server_error_handler_t error_handler,
+ ply_boot_server_deactivate_handler_t deactivate_handler,
ply_boot_server_quit_handler_t quit_handler,
void *user_data)
{
@@ -108,6 +110,7 @@ ply_boot_server_new (ply_boot_server_update_handler_t update_handler,
server->system_initialized_handler = initialized_handler;
server->show_splash_handler = show_splash_handler;
server->hide_splash_handler = hide_splash_handler;
+ server->deactivate_handler = deactivate_handler;
server->quit_handler = quit_handler;
server->user_data = user_data;
@@ -272,6 +275,17 @@ ply_boot_connection_on_password_answer (ply_boot_connection_t *connection,
}
static void
+ply_boot_connection_on_deactivated (ply_boot_connection_t *connection)
+{
+ if (!ply_write (connection->fd,
+ PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK,
+ strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK)))
+ {
+ ply_error ("could not write bytes: %m");
+ }
+}
+
+static void
ply_boot_connection_on_quit_complete (ply_boot_connection_t *connection)
{
if (!ply_write (connection->fd,
@@ -353,6 +367,24 @@ ply_boot_connection_on_request (ply_boot_connection_t *connection)
if (server->hide_splash_handler != NULL)
server->hide_splash_handler (server->user_data, server);
}
+ else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_DEACTIVATE) == 0)
+ {
+ ply_trigger_t *deactivate_trigger;
+
+ deactivate_trigger = ply_trigger_new (NULL);
+
+ ply_trigger_add_handler (deactivate_trigger,
+ (ply_trigger_handler_t)
+ ply_boot_connection_on_deactivated,
+ connection);
+
+ if (server->deactivate_handler != NULL)
+ server->deactivate_handler (server->user_data, deactivate_trigger, server);
+
+ free (argument);
+ free (command);
+ return;
+ }
else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUIT) == 0)
{
bool retain_splash;
@@ -663,6 +695,12 @@ on_hide_splash (ply_event_loop_t *loop)
}
static void
+on_deactivate (ply_event_loop_t *loop)
+{
+ printf ("got deactivate request\n");
+}
+
+static void
on_quit (ply_event_loop_t *loop)
{
printf ("got quit request, quiting...\n");
@@ -754,6 +792,7 @@ main (int argc,
(ply_boot_server_newroot_handler_t) on_newroot,
(ply_boot_server_system_initialized_handler_t) on_system_initialized,
(ply_boot_server_error_handler_t) on_error,
+ (ply_boot_server_deactivate_handler_t) on_deactivate,
(ply_boot_server_quit_handler_t) on_quit,
loop);
diff --git a/src/ply-boot-server.h b/src/ply-boot-server.h
index ad145ca..f2f815a 100644
--- a/src/ply-boot-server.h
+++ b/src/ply-boot-server.h
@@ -80,6 +80,9 @@ typedef void (* ply_boot_server_system_initialized_handler_t) (void
typedef void (* ply_boot_server_error_handler_t) (void *user_data,
ply_boot_server_t *server);
+typedef void (* ply_boot_server_deactivate_handler_t) (void *user_data,
+ ply_trigger_t *deactivate_trigger,
+ ply_boot_server_t *server);
typedef void (* ply_boot_server_quit_handler_t) (void *user_data,
bool retain_splash,
ply_trigger_t *quit_trigger,
@@ -99,6 +102,7 @@ ply_boot_server_t *ply_boot_server_new (ply_boot_server_update_handler_t update_
ply_boot_server_newroot_handler_t newroot_handler,
ply_boot_server_system_initialized_handler_t initialized_handler,
ply_boot_server_error_handler_t error_handler,
+ ply_boot_server_deactivate_handler_t deactivate_handler,
ply_boot_server_quit_handler_t quit_handler,
void *user_data);