diff options
-rw-r--r-- | src/client/ply-boot-client.c | 12 | ||||
-rw-r--r-- | src/client/ply-boot-client.h | 4 | ||||
-rw-r--r-- | src/client/plymouth.c | 16 | ||||
-rw-r--r-- | src/libplybootsplash/ply-renderer-plugin.h | 2 | ||||
-rw-r--r-- | src/libplybootsplash/ply-renderer.c | 16 | ||||
-rw-r--r-- | src/libplybootsplash/ply-renderer.h | 2 | ||||
-rw-r--r-- | src/main.c | 57 | ||||
-rw-r--r-- | src/plugins/renderers/drm/plugin.c | 47 | ||||
-rw-r--r-- | src/plugins/renderers/frame-buffer/plugin.c | 30 | ||||
-rw-r--r-- | src/plugins/renderers/x11/plugin.c | 19 | ||||
-rw-r--r-- | src/ply-boot-protocol.h | 1 | ||||
-rw-r--r-- | src/ply-boot-server.c | 39 | ||||
-rw-r--r-- | src/ply-boot-server.h | 4 |
13 files changed, 229 insertions, 20 deletions
diff --git a/src/client/ply-boot-client.c b/src/client/ply-boot-client.c index 5f7bb54f..917a6199 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 43684ac4..0e9122c4 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 80b0ec65..8669fd2a 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 6acb8928..e4f6b374 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 591af2c4..c34dfcfc 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 da03e8d8..c4bbdbe3 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); @@ -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 3081ac8f..1115b5cc 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 ce42eb3b..80b5973d 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 9e78c069..3777b6c2 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 419d4810..6be72186 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 9a1ed8e4..4cc579f6 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 ad145ca2..f2f815ae 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); |