]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
script: handle display hotplug
authorTimo Teräs <timo.teras@iki.fi>
Wed, 22 Mar 2023 11:54:39 +0000 (13:54 +0200)
committerRay Strode <halfline@gmail.com>
Wed, 22 Mar 2023 13:16:22 +0000 (13:16 +0000)
- Fix script plugin to handle monitor hotplug events

- Expose Plymouth.SetDisplayHotplugFunction to set script callback
  after display hotplug

fixes #186

src/plugins/splash/script/plugin.c
src/plugins/splash/script/script-lib-plymouth.c
src/plugins/splash/script/script-lib-plymouth.h
src/plugins/splash/script/script-lib-sprite.c
src/plugins/splash/script/script-lib-sprite.h

index 3395eb22ada7e384438ea5aa757aad24790c4d4e..6b04fd0026f58912466bd1c50b8e61a3c4b4c1de 100644 (file)
@@ -392,13 +392,22 @@ add_pixel_display (ply_boot_splash_plugin_t *plugin,
                    ply_pixel_display_t      *display)
 {
         ply_list_append_data (plugin->displays, display);
+
+        if (plugin->script_sprite_lib != NULL) {
+                script_lib_sprite_pixel_display_added (plugin->script_sprite_lib, display);
+                script_lib_plymouth_on_display_hotplug (plugin->script_state, plugin->script_plymouth_lib);
+        }
 }
 
 static void
 remove_pixel_display (ply_boot_splash_plugin_t *plugin,
                       ply_pixel_display_t      *display)
 {
-        script_lib_sprite_pixel_display_removed (plugin->script_sprite_lib, display);
+        if (plugin->script_sprite_lib != NULL) {
+                script_lib_sprite_pixel_display_removed (plugin->script_sprite_lib, display);
+                script_lib_plymouth_on_display_hotplug (plugin->script_state, plugin->script_plymouth_lib);
+        }
+
         ply_list_remove_data (plugin->displays, display);
 }
 
index afa95b0e52df6881a2ae0132eddc14e2192938ca..528ed303881e8d629a01c8449a41d2b3b507a109 100644 (file)
@@ -108,6 +108,7 @@ script_lib_plymouth_data_t *script_lib_plymouth_setup (script_state_t        *st
         data->script_display_prompt_func = script_obj_new_null ();
         data->script_validate_input_func = script_obj_new_null ();
         data->script_display_message_func = script_obj_new_null ();
+        data->script_display_hotplug_func = script_obj_new_null ();
         data->script_hide_message_func = script_obj_new_null ();
         data->script_quit_func = script_obj_new_null ();
         data->script_system_update_func = script_obj_new_null ();
@@ -176,6 +177,12 @@ script_lib_plymouth_data_t *script_lib_plymouth_setup (script_state_t        *st
                                     &data->script_display_prompt_func,
                                     "function",
                                     NULL);
+        script_add_native_function (plymouth_hash,
+                                    "SetDisplayHotplugFunction",
+                                    plymouth_set_function,
+                                    &data->script_display_hotplug_func,
+                                    "function",
+                                    NULL);
         script_add_native_function (plymouth_hash,
                                     "SetValidateInputFunction",
                                     plymouth_set_function,
@@ -233,6 +240,7 @@ void script_lib_plymouth_destroy (script_lib_plymouth_data_t *data)
         script_obj_unref (data->script_display_password_func);
         script_obj_unref (data->script_display_question_func);
         script_obj_unref (data->script_display_prompt_func);
+        script_obj_unref (data->script_display_hotplug_func);
         script_obj_unref (data->script_validate_input_func);
         script_obj_unref (data->script_display_message_func);
         script_obj_unref (data->script_hide_message_func);
@@ -384,6 +392,16 @@ void script_lib_plymouth_on_display_prompt (script_state_t             *state,
         script_obj_unref (ret.object);
 }
 
+void script_lib_plymouth_on_display_hotplug (script_state_t             *state,
+                                             script_lib_plymouth_data_t *data)
+{
+        script_return_t ret = script_execute_object (state,
+                                                     data->script_display_hotplug_func,
+                                                     NULL,
+                                                     NULL);
+        script_obj_unref (ret.object);
+}
+
 bool script_lib_plymouth_on_validate_input (script_state_t             *state,
                                             script_lib_plymouth_data_t *data,
                                             const char                 *entry_text,
index 381680920814e3f97ba42b4b9f9602c1e51c1fdd..69ca1335e132ac7e5a848bdc333a4d671073168a 100644 (file)
@@ -37,6 +37,7 @@ typedef struct
         script_obj_t          *script_display_password_func;
         script_obj_t          *script_display_question_func;
         script_obj_t          *script_display_prompt_func;
+        script_obj_t          *script_display_hotplug_func;
         script_obj_t          *script_validate_input_func;
         script_obj_t          *script_display_message_func;
         script_obj_t          *script_hide_message_func;
@@ -80,6 +81,8 @@ void script_lib_plymouth_on_display_prompt (script_state_t             *state,
                                             const char                 *prompt,
                                             const char                 *entry_text,
                                             bool                        is_secret);
+void script_lib_plymouth_on_display_hotplug (script_state_t             *state,
+                                             script_lib_plymouth_data_t *data);
 bool script_lib_plymouth_on_validate_input (script_state_t             *state,
                                             script_lib_plymouth_data_t *data,
                                             const char                 *entry_text,
index 6397ea281a4a468f25e8ddf541473c5f40775425..c7e8317223483415b25d0b68332e07b2bfd3f3ae 100644 (file)
@@ -223,17 +223,7 @@ static script_return_t sprite_window_get_width (script_state_t *state,
                 return script_return_obj (script_obj_new_number (width));
         }
 
-        width = 0;
-        for (node = ply_list_get_first_node (data->displays);
-             node;
-             node = ply_list_get_next_node (data->displays, node)) {
-                display = ply_list_node_get_data (node);
-                if (width == 0)
-                        width = ply_pixel_display_get_width (display->pixel_display);
-                else
-                        width = MAX (width, ply_pixel_display_get_width (display->pixel_display));
-        }
-        return script_return_obj (script_obj_new_number (width));
+        return script_return_obj (script_obj_new_number (data->max_width));
 }
 
 static script_return_t sprite_window_get_height (script_state_t *state,
@@ -261,17 +251,7 @@ static script_return_t sprite_window_get_height (script_state_t *state,
                 return script_return_obj (script_obj_new_number (height));
         }
 
-        height = 0;
-        for (node = ply_list_get_first_node (data->displays);
-             node;
-             node = ply_list_get_next_node (data->displays, node)) {
-                display = ply_list_node_get_data (node);
-                if (height == 0)
-                        height = ply_pixel_display_get_height (display->pixel_display);
-                else
-                        height = MAX (height, ply_pixel_display_get_height (display->pixel_display));
-        }
-        return script_return_obj (script_obj_new_number (height));
+        return script_return_obj (script_obj_new_number (data->max_height));
 }
 
 static script_return_t sprite_window_get_x (script_state_t *state,
@@ -522,45 +502,65 @@ draw_area (script_lib_sprite_data_t *data,
         }
 }
 
+static void
+update_displays (script_lib_sprite_data_t *data)
+{
+        ply_list_node_t *node;
+        script_lib_display_t *script_display;
+
+        data->max_width = 0;
+        data->max_height = 0;
+        for (node = ply_list_get_first_node (data->displays);
+             node;
+             node = ply_list_get_next_node (data->displays, node)) {
+                script_display = ply_list_node_get_data (node);
+                data->max_width = MAX (data->max_width, ply_pixel_display_get_width (script_display->pixel_display));
+                data->max_height = MAX (data->max_height, ply_pixel_display_get_height (script_display->pixel_display));
+        }
+
+        for (node = ply_list_get_first_node (data->displays);
+             node;
+             node = ply_list_get_next_node (data->displays, node)) {
+                script_display = ply_list_node_get_data (node);
+                script_display->x = (data->max_width - ply_pixel_display_get_width (script_display->pixel_display)) / 2;
+                script_display->y = (data->max_height - ply_pixel_display_get_height (script_display->pixel_display)) / 2;
+        }
+
+        data->full_refresh = true;
+}
+
+static void
+add_display (script_lib_sprite_data_t *data,
+             ply_pixel_display_t      *pixel_display)
+{
+        script_lib_display_t *script_display = malloc (sizeof(script_lib_display_t));
+
+        script_display->pixel_display = pixel_display;
+        script_display->data = data;
+        ply_pixel_display_set_draw_handler (pixel_display,
+                                            (ply_pixel_display_draw_handler_t)
+                                            script_lib_sprite_draw_area, script_display);
+
+        ply_list_append_data (data->displays, script_display);
+}
+
 script_lib_sprite_data_t *script_lib_sprite_setup (script_state_t *state,
                                                    ply_list_t     *pixel_displays)
 {
         ply_list_node_t *node;
-        unsigned int max_width, max_height;
         script_lib_sprite_data_t *data = malloc (sizeof(script_lib_sprite_data_t));
 
         data->class = script_obj_native_class_new (sprite_free, "sprite", data);
         data->sprite_list = ply_list_new ();
         data->displays = ply_list_new ();
 
-        max_width = 0;
-        max_height = 0;
-
         for (node = ply_list_get_first_node (pixel_displays);
              node;
              node = ply_list_get_next_node (pixel_displays, node)) {
                 ply_pixel_display_t *pixel_display = ply_list_node_get_data (node);
-                max_width = MAX (max_width, ply_pixel_display_get_width (pixel_display));
-                max_height = MAX (max_height, ply_pixel_display_get_height (pixel_display));
-        }
-
-        for (node = ply_list_get_first_node (pixel_displays);
-             node;
-             node = ply_list_get_next_node (pixel_displays, node)) {
-                ply_pixel_display_t *pixel_display = ply_list_node_get_data (node);
-                script_lib_display_t *script_display = malloc (sizeof(script_lib_display_t));
-                script_display->pixel_display = pixel_display;
-
-                script_display->x = (max_width - ply_pixel_display_get_width (pixel_display)) / 2;
-                script_display->y = (max_height - ply_pixel_display_get_height (pixel_display)) / 2;
-
-                script_display->data = data;
-                ply_pixel_display_set_draw_handler (pixel_display,
-                                                    (ply_pixel_display_draw_handler_t)
-                                                    script_lib_sprite_draw_area, script_display);
-
-                ply_list_append_data (data->displays, script_display);
+                add_display (data, pixel_display);
         }
+        update_displays (data);
 
         script_obj_t *sprite_hash = script_obj_hash_get_element (state->global, "Sprite");
 
@@ -721,12 +721,20 @@ region_add_area (ply_region_t *region,
         ply_region_add_rectangle (region, &rectangle);
 }
 
+void script_lib_sprite_pixel_display_added (script_lib_sprite_data_t *data,
+                                            ply_pixel_display_t      *pixel_display)
+{
+        add_display (data, pixel_display);
+        update_displays (data);
+}
+
 void script_lib_sprite_pixel_display_removed (script_lib_sprite_data_t *data,
                                               ply_pixel_display_t      *pixel_display)
 {
         ply_list_node_t *node;
         ply_list_node_t *next_node;
         script_lib_display_t *display;
+        bool update = false;
 
         if (!data)
                 return;
@@ -738,9 +746,13 @@ void script_lib_sprite_pixel_display_removed (script_lib_sprite_data_t *data,
 
                 if (display->pixel_display == pixel_display) {
                         ply_list_remove_node (data->displays, node);
+                        update = true;
                 }
                 node = next_node;
         }
+
+        if (update)
+                update_displays (data);
 }
 
 void
index 78bfc548c87f02469beed960cfd24ab9899c8aca..6783d25d8539d31af0ad53eb2775f66eb6b42bbb 100644 (file)
@@ -35,6 +35,8 @@ typedef struct
         uint32_t                   background_color_start;
         uint32_t                   background_color_end;
         bool                       full_refresh;
+        unsigned int               max_width;
+        unsigned int               max_height;
 } script_lib_sprite_data_t;
 
 typedef struct
@@ -65,6 +67,8 @@ typedef struct
 
 script_lib_sprite_data_t *script_lib_sprite_setup (script_state_t *state,
                                                    ply_list_t     *displays);
+void script_lib_sprite_pixel_display_added (script_lib_sprite_data_t *data,
+                                            ply_pixel_display_t      *pixel_display);
 void script_lib_sprite_pixel_display_removed (script_lib_sprite_data_t *data,
                                               ply_pixel_display_t      *pixel_display);
 void script_lib_sprite_refresh (script_lib_sprite_data_t *data);