]> git.ipfire.org Git - thirdparty/plymouth.git/blame - src/libply-splash-core/ply-boot-splash.c
ply-boot-splash: Set unbuffered input when creating a text display
[thirdparty/plymouth.git] / src / libply-splash-core / ply-boot-splash.c
CommitLineData
76a2e17c
RS
1/* ply-boot-splash.h - APIs for putting up a splash screen
2 *
3 * Copyright (C) 2007 Red Hat, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18 * 02111-1307, USA.
19 *
20 * Written by: Ray Strode <rstrode@redhat.com>
bbd9b2f5 21 * Soeren Sandmann <sandmann@redhat.com>
76a2e17c 22 */
76a2e17c
RS
23#include "ply-boot-splash.h"
24
25#include <assert.h>
26#include <errno.h>
27#include <stdint.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <sys/socket.h>
31#include <sys/types.h>
32#include <unistd.h>
fa8d0c2a 33#include <wchar.h>
76a2e17c
RS
34
35#include "ply-boot-splash-plugin.h"
b753e742 36#include "ply-terminal.h"
76a2e17c
RS
37#include "ply-event-loop.h"
38#include "ply-list.h"
39#include "ply-logger.h"
2bb73dcf 40#include "ply-trigger.h"
76a2e17c 41#include "ply-utils.h"
2d7f68e4 42#include "ply-progress.h"
6c6ecf5e 43#include "ply-keyboard.h"
6acf834f 44#include "ply-key-file.h"
76a2e17c 45
2f277ad6
RS
46#ifndef UPDATES_PER_SECOND
47#define UPDATES_PER_SECOND 30
48#endif
49
5e33469e
RS
50#ifndef FRAMES_PER_SECOND
51#define FRAMES_PER_SECOND 60
52#endif
53
76a2e17c
RS
54struct _ply_boot_splash
55{
85704145
RS
56 ply_event_loop_t *loop;
57 ply_module_handle_t *module_handle;
58 const ply_boot_splash_plugin_interface_t *plugin_interface;
59 ply_boot_splash_plugin_t *plugin;
60 ply_boot_splash_mode_t mode;
61 ply_buffer_t *boot_buffer;
62 ply_trigger_t *idle_trigger;
c0ee9474
RS
63
64 ply_keyboard_t *keyboard;
65 ply_list_t *pixel_displays;
66 ply_list_t *text_displays;
85704145
RS
67
68 char *theme_path;
69 char *plugin_dir;
70 char *status;
71
72 ply_progress_t *progress;
73 ply_boot_splash_on_idle_handler_t idle_handler;
74 void *idle_handler_user_data;
75
76 uint32_t is_loaded : 1;
5e33469e 77 uint32_t is_shown : 1;
85704145 78 uint32_t should_force_text_mode : 1;
76a2e17c
RS
79};
80
81typedef const ply_boot_splash_plugin_interface_t *
85704145 82(*get_plugin_interface_function_t) (void);
76a2e17c 83
3df0f126
RS
84static void ply_boot_splash_update_progress (ply_boot_splash_t *splash);
85static void ply_boot_splash_detach_from_event_loop (ply_boot_splash_t *splash);
86
76a2e17c 87ply_boot_splash_t *
85704145
RS
88ply_boot_splash_new (const char *theme_path,
89 const char *plugin_dir,
90 ply_buffer_t *boot_buffer)
76a2e17c 91{
85704145 92 ply_boot_splash_t *splash;
76a2e17c 93
85704145 94 assert (theme_path != NULL);
76a2e17c 95
85704145
RS
96 splash = calloc (1, sizeof(ply_boot_splash_t));
97 splash->loop = NULL;
98 splash->theme_path = strdup (theme_path);
99 splash->plugin_dir = strdup (plugin_dir);
100 splash->module_handle = NULL;
101 splash->mode = PLY_BOOT_SPLASH_MODE_INVALID;
76a2e17c 102
85704145 103 splash->boot_buffer = boot_buffer;
c0ee9474
RS
104 splash->pixel_displays = ply_list_new ();
105 splash->text_displays = ply_list_new ();
fa8d0c2a 106
85704145 107 return splash;
76a2e17c
RS
108}
109
c0ee9474
RS
110void
111ply_boot_splash_set_keyboard (ply_boot_splash_t *splash,
112 ply_keyboard_t *keyboard)
24a21ee0 113{
c0ee9474
RS
114 if (splash->plugin_interface->set_keyboard == NULL)
115 return;
24a21ee0 116
c0ee9474
RS
117 splash->plugin_interface->set_keyboard (splash->plugin, keyboard);
118 splash->keyboard = keyboard;
24a21ee0
RS
119}
120
c0ee9474
RS
121void
122ply_boot_splash_unset_keyboard (ply_boot_splash_t *splash)
24a21ee0 123{
c0ee9474
RS
124 if (splash->plugin_interface->unset_keyboard == NULL)
125 return;
24a21ee0 126
c0ee9474
RS
127 splash->plugin_interface->unset_keyboard (splash->plugin, splash->keyboard);
128}
24a21ee0 129
c0ee9474
RS
130void
131ply_boot_splash_add_pixel_display (ply_boot_splash_t *splash,
132 ply_pixel_display_t *display)
133{
134 unsigned long width, height;
24a21ee0 135
c0ee9474
RS
136 if (splash->plugin_interface->add_pixel_display == NULL)
137 return;
24a21ee0 138
c0ee9474
RS
139 width = ply_pixel_display_get_width (display);
140 height = ply_pixel_display_get_height (display);
24a21ee0 141
c0ee9474 142 ply_trace ("adding %lux%lu pixel display", width, height);
24a21ee0 143
5e33469e
RS
144 if (splash->is_shown) {
145 ply_trace ("Splash already shown, so pausing display until next frame update");
146 ply_pixel_display_pause_updates (display);
147 }
148
c0ee9474
RS
149 splash->plugin_interface->add_pixel_display (splash->plugin, display);
150 ply_list_append_data (splash->pixel_displays, display);
151}
24a21ee0 152
c0ee9474
RS
153void
154ply_boot_splash_remove_pixel_display (ply_boot_splash_t *splash,
155 ply_pixel_display_t *display)
156{
157 unsigned long width, height;
24a21ee0 158
c0ee9474
RS
159 if (splash->plugin_interface->remove_pixel_display == NULL)
160 return;
24a21ee0 161
c0ee9474
RS
162 width = ply_pixel_display_get_width (display);
163 height = ply_pixel_display_get_height (display);
24a21ee0 164
c0ee9474 165 ply_trace ("removing %lux%lu pixel display", width, height);
24a21ee0 166
c0ee9474
RS
167 splash->plugin_interface->remove_pixel_display (splash->plugin, display);
168 ply_list_remove_data (splash->pixel_displays, display);
24a21ee0
RS
169}
170
171void
c0ee9474
RS
172ply_boot_splash_add_text_display (ply_boot_splash_t *splash,
173 ply_text_display_t *display)
24a21ee0 174{
c0ee9474 175 int number_of_columns, number_of_rows;
10ac8d2d 176 ply_terminal_t *terminal;
24a21ee0 177
c0ee9474 178 if (splash->plugin_interface->add_text_display == NULL)
85704145 179 return;
24a21ee0 180
c0ee9474
RS
181 number_of_columns = ply_text_display_get_number_of_columns (display);
182 number_of_rows = ply_text_display_get_number_of_rows (display);
183
184 ply_trace ("adding %dx%d text display", number_of_columns, number_of_rows);
185
186 splash->plugin_interface->add_text_display (splash->plugin, display);
10ac8d2d 187
188 terminal = ply_text_display_get_terminal (display);
189 if (terminal)
190 ply_terminal_set_unbuffered_input (terminal);
191
c0ee9474 192 ply_list_append_data (splash->text_displays, display);
24a21ee0
RS
193}
194
195void
c0ee9474
RS
196ply_boot_splash_remove_text_display (ply_boot_splash_t *splash,
197 ply_text_display_t *display)
24a21ee0 198{
c0ee9474 199 int number_of_columns, number_of_rows;
24a21ee0 200
c0ee9474 201 if (splash->plugin_interface->remove_text_display == NULL)
85704145 202 return;
24a21ee0 203
c0ee9474
RS
204 number_of_columns = ply_text_display_get_number_of_columns (display);
205 number_of_rows = ply_text_display_get_number_of_rows (display);
206
207 ply_trace ("removing %dx%d text display", number_of_columns, number_of_rows);
208
209 splash->plugin_interface->remove_text_display (splash->plugin, display);
210 ply_list_remove_data (splash->text_displays, display);
24a21ee0
RS
211}
212
dfc91615
RS
213bool
214ply_boot_splash_load (ply_boot_splash_t *splash)
76a2e17c 215{
85704145
RS
216 ply_key_file_t *key_file;
217 char *module_name;
218 char *module_path;
6acf834f 219
85704145 220 assert (splash != NULL);
76a2e17c 221
85704145 222 get_plugin_interface_function_t get_boot_splash_plugin_interface;
76a2e17c 223
85704145 224 key_file = ply_key_file_new (splash->theme_path);
76a2e17c 225
310b63cd
RS
226 if (!ply_key_file_load (key_file)) {
227 ply_key_file_free (key_file);
85704145 228 return false;
310b63cd 229 }
76a2e17c 230
85704145 231 module_name = ply_key_file_get_value (key_file, "Plymouth Theme", "ModuleName");
6acf834f 232
85704145
RS
233 asprintf (&module_path, "%s%s.so",
234 splash->plugin_dir, module_name);
235 free (module_name);
6acf834f 236
85704145 237 splash->module_handle = ply_open_module (module_path);
6acf834f 238
85704145 239 free (module_path);
6acf834f 240
85704145
RS
241 if (splash->module_handle == NULL) {
242 ply_key_file_free (key_file);
243 return false;
244 }
76a2e17c 245
85704145
RS
246 get_boot_splash_plugin_interface = (get_plugin_interface_function_t)
247 ply_module_look_up_function (splash->module_handle,
248 "ply_boot_splash_plugin_get_interface");
249
250 if (get_boot_splash_plugin_interface == NULL) {
251 ply_save_errno ();
252 ply_close_module (splash->module_handle);
253 splash->module_handle = NULL;
254 ply_key_file_free (key_file);
255 ply_restore_errno ();
256 return false;
257 }
76a2e17c 258
85704145 259 splash->plugin_interface = get_boot_splash_plugin_interface ();
76a2e17c 260
85704145
RS
261 if (splash->plugin_interface == NULL) {
262 ply_save_errno ();
263 ply_close_module (splash->module_handle);
264 splash->module_handle = NULL;
265 ply_key_file_free (key_file);
266 ply_restore_errno ();
267 return false;
268 }
76a2e17c 269
85704145 270 splash->plugin = splash->plugin_interface->create_plugin (key_file);
6acf834f 271
85704145 272 ply_key_file_free (key_file);
76a2e17c 273
85704145 274 assert (splash->plugin != NULL);
76a2e17c 275
85704145 276 splash->is_loaded = true;
dfc91615 277
85704145 278 return true;
76a2e17c
RS
279}
280
57108e50
RS
281bool
282ply_boot_splash_load_built_in (ply_boot_splash_t *splash)
283{
85704145 284 get_plugin_interface_function_t get_boot_splash_plugin_interface;
57108e50 285
85704145 286 assert (splash != NULL);
57108e50 287
85704145 288 splash->module_handle = ply_open_built_in_module ();
57108e50 289
85704145
RS
290 if (splash->module_handle == NULL)
291 return false;
57108e50 292
85704145
RS
293 get_boot_splash_plugin_interface = (get_plugin_interface_function_t)
294 ply_module_look_up_function (splash->module_handle,
295 "ply_boot_splash_plugin_get_interface");
57108e50 296
85704145
RS
297 if (get_boot_splash_plugin_interface == NULL) {
298 ply_save_errno ();
299 ply_close_module (splash->module_handle);
300 splash->module_handle = NULL;
301 ply_restore_errno ();
302 return false;
303 }
57108e50 304
85704145 305 splash->plugin_interface = get_boot_splash_plugin_interface ();
57108e50 306
85704145
RS
307 if (splash->plugin_interface == NULL) {
308 ply_save_errno ();
309 ply_close_module (splash->module_handle);
310 splash->module_handle = NULL;
311 ply_restore_errno ();
312 return false;
313 }
57108e50 314
85704145 315 splash->plugin = splash->plugin_interface->create_plugin (NULL);
57108e50 316
85704145 317 assert (splash->plugin != NULL);
57108e50 318
85704145 319 splash->is_loaded = true;
57108e50 320
85704145 321 return true;
57108e50
RS
322}
323
dfc91615
RS
324void
325ply_boot_splash_unload (ply_boot_splash_t *splash)
76a2e17c 326{
85704145
RS
327 assert (splash != NULL);
328 assert (splash->plugin != NULL);
329 assert (splash->plugin_interface != NULL);
330 assert (splash->module_handle != NULL);
76a2e17c 331
85704145
RS
332 splash->plugin_interface->destroy_plugin (splash->plugin);
333 splash->plugin = NULL;
76a2e17c 334
85704145
RS
335 ply_close_module (splash->module_handle);
336 splash->plugin_interface = NULL;
337 splash->module_handle = NULL;
2f277ad6 338
85704145 339 splash->is_loaded = false;
76a2e17c
RS
340}
341
24a21ee0 342static void
c0ee9474
RS
343remove_pixel_displays (ply_boot_splash_t *splash)
344{
345 ply_list_node_t *node;
346
347 if (splash->plugin_interface->remove_pixel_display == NULL)
348 return;
349
350 ply_trace ("removing pixel displays");
351
352 node = ply_list_get_first_node (splash->pixel_displays);
353 while (node != NULL) {
354 ply_pixel_display_t *display;
355 ply_list_node_t *next_node;
356 unsigned long width, height;
357
358 display = ply_list_node_get_data (node);
359 next_node = ply_list_get_next_node (splash->pixel_displays, node);
360
361 width = ply_pixel_display_get_width (display);
362 height = ply_pixel_display_get_height (display);
363
364 ply_trace ("Removing %lux%lu pixel display", width, height);
365
366 splash->plugin_interface->remove_pixel_display (splash->plugin, display);
367
368 node = next_node;
369 }
370}
371
372static void
373remove_text_displays (ply_boot_splash_t *splash)
24a21ee0 374{
85704145 375 ply_list_node_t *node;
24a21ee0 376
c0ee9474
RS
377 if (splash->plugin_interface->remove_text_display == NULL)
378 return;
379
380 ply_trace ("removing text displays");
24a21ee0 381
c0ee9474 382 node = ply_list_get_first_node (splash->text_displays);
85704145 383 while (node != NULL) {
c0ee9474 384 ply_text_display_t *display;
85704145 385 ply_list_node_t *next_node;
c0ee9474 386 int number_of_columns, number_of_rows;
24a21ee0 387
c0ee9474
RS
388 display = ply_list_node_get_data (node);
389 next_node = ply_list_get_next_node (splash->text_displays, node);
24a21ee0 390
c0ee9474
RS
391 number_of_columns = ply_text_display_get_number_of_columns (display);
392 number_of_rows = ply_text_display_get_number_of_rows (display);
393
394 ply_trace ("Removing %dx%d text display", number_of_columns, number_of_rows);
24a21ee0 395
c0ee9474 396 splash->plugin_interface->remove_text_display (splash->plugin, display);
24a21ee0 397
85704145
RS
398 node = next_node;
399 }
24a21ee0
RS
400}
401
8a6d13f9
RS
402void
403ply_boot_splash_free (ply_boot_splash_t *splash)
404{
85704145
RS
405 ply_trace ("freeing splash");
406 if (splash == NULL)
407 return;
408
409 if (splash->loop != NULL) {
410 if (splash->plugin_interface->on_boot_progress != NULL) {
411 ply_event_loop_stop_watching_for_timeout (splash->loop,
412 (ply_event_loop_timeout_handler_t)
413 ply_boot_splash_update_progress, splash);
414 }
415
416 ply_event_loop_stop_watching_for_exit (splash->loop, (ply_event_loop_exit_handler_t)
417 ply_boot_splash_detach_from_event_loop,
418 splash);
3df0f126
RS
419 }
420
f8068438
RS
421 if (splash->module_handle != NULL) {
422 ply_boot_splash_unset_keyboard (splash);
c0ee9474 423
f8068438
RS
424 remove_pixel_displays (splash);
425 ply_list_free (splash->pixel_displays);
c0ee9474 426
f8068438
RS
427 remove_text_displays (splash);
428 ply_list_free (splash->text_displays);
24a21ee0 429
85704145 430 ply_boot_splash_unload (splash);
f8068438 431 }
8a6d13f9 432
85704145
RS
433 if (splash->idle_trigger != NULL)
434 ply_trigger_free (splash->idle_trigger);
3df0f126 435
85704145
RS
436 free (splash->theme_path);
437 free (splash->plugin_dir);
438 free (splash);
8a6d13f9
RS
439}
440
2f277ad6
RS
441static void
442ply_boot_splash_update_progress (ply_boot_splash_t *splash)
443{
85704145
RS
444 double percentage = 0.0;
445 double time = 0.0;
446
447 assert (splash != NULL);
448
449 if (splash->progress) {
450 percentage = ply_progress_get_percentage (splash->progress);
451 time = ply_progress_get_time (splash->progress);
452 }
453
454 if (splash->plugin_interface->on_boot_progress != NULL)
455 splash->plugin_interface->on_boot_progress (splash->plugin,
456 time,
457 percentage);
458
459 ply_event_loop_watch_for_timeout (splash->loop,
460 1.0 / UPDATES_PER_SECOND,
461 (ply_event_loop_timeout_handler_t)
462 ply_boot_splash_update_progress, splash);
2f277ad6
RS
463}
464
2d7f68e4
CB
465void
466ply_boot_splash_attach_progress (ply_boot_splash_t *splash,
85704145 467 ply_progress_t *progress)
2d7f68e4 468{
85704145
RS
469 assert (splash != NULL);
470 assert (progress != NULL);
471 assert (splash->progress == NULL);
472 splash->progress = progress;
2d7f68e4
CB
473}
474
5e33469e
RS
475static void
476ply_boot_splash_pause_pixel_displays (ply_boot_splash_t *splash)
477{
478 ply_list_node_t *node;
479
480 ply_list_foreach (splash->pixel_displays, node) {
481 ply_pixel_display_t *display = ply_list_node_get_data (node);
482 ply_pixel_display_pause_updates (display);
483 }
484}
485
486static void
487ply_boot_splash_unpause_pixel_displays (ply_boot_splash_t *splash)
488{
489 ply_list_node_t *node;
490
491 ply_list_foreach (splash->pixel_displays, node) {
492 ply_pixel_display_t *display = ply_list_node_get_data (node);
493 ply_pixel_display_unpause_updates (display);
494 }
495}
496
497static void
498ply_boot_splash_flush_displays (ply_boot_splash_t *splash)
499{
500 if (!splash->is_shown)
501 return;
502
503 ply_boot_splash_unpause_pixel_displays (splash);
504 ply_boot_splash_pause_pixel_displays (splash);
505}
506
507static void
508on_new_frame (ply_boot_splash_t *splash)
509{
510 if (!splash->is_shown)
511 return;
512
513 ply_boot_splash_flush_displays (splash);
514
515 ply_event_loop_watch_for_timeout (splash->loop,
516 1.0 / FRAMES_PER_SECOND,
517 (ply_event_loop_timeout_handler_t)
518 on_new_frame,
519 splash);
520}
2d7f68e4 521
76a2e17c 522bool
85704145 523ply_boot_splash_show (ply_boot_splash_t *splash,
8124531e 524 ply_boot_splash_mode_t mode)
76a2e17c 525{
85704145
RS
526 assert (splash != NULL);
527 assert (mode != PLY_BOOT_SPLASH_MODE_INVALID);
528 assert (splash->module_handle != NULL);
529 assert (splash->loop != NULL);
530 assert (splash->plugin_interface != NULL);
531 assert (splash->plugin != NULL);
532 assert (splash->plugin_interface->show_splash_screen != NULL);
533
534 if (splash->mode == mode) {
535 ply_trace ("already set same splash screen mode");
536 return true;
537 } else if (splash->mode != PLY_BOOT_SPLASH_MODE_INVALID) {
538 splash->plugin_interface->hide_splash_screen (splash->plugin,
539 splash->loop);
a1920e8a
HG
540 if (splash->plugin_interface->on_boot_progress != NULL) {
541 ply_event_loop_stop_watching_for_timeout (splash->loop,
542 (ply_event_loop_timeout_handler_t)
543 ply_boot_splash_update_progress, splash);
544 }
85704145
RS
545 }
546
547 ply_trace ("showing splash screen");
548 if (!splash->plugin_interface->show_splash_screen (splash->plugin,
549 splash->loop,
550 splash->boot_buffer,
551 mode)) {
552 ply_save_errno ();
553 ply_trace ("can't show splash: %m");
554 ply_restore_errno ();
555 return false;
556 }
557
5e33469e
RS
558 if (!splash->is_shown) {
559 size_t number_of_displays;
560 ply_trace ("(this is an initial showing)");
561 number_of_displays = ply_list_get_length (splash->pixel_displays);
562
563 if (number_of_displays > 0) {
564 ply_trace ("Pausing %ld already added displays",
565 number_of_displays);
566 ply_boot_splash_pause_pixel_displays (splash);
567 }
568
569 ply_event_loop_watch_for_timeout (splash->loop,
570 1.0 / FRAMES_PER_SECOND,
571 (ply_event_loop_timeout_handler_t)
572 on_new_frame,
573 splash);
574 splash->is_shown = true;
575 }
576
85704145
RS
577 if (splash->plugin_interface->on_boot_progress != NULL)
578 ply_boot_splash_update_progress (splash);
579
580 splash->mode = mode;
581 return true;
cef67c3f
RH
582}
583
584bool
585ply_boot_splash_system_update (ply_boot_splash_t *splash,
586 int progress)
587{
85704145
RS
588 assert (splash != NULL);
589 assert (splash->module_handle != NULL);
590 assert (splash->loop != NULL);
591 assert (splash->plugin_interface != NULL);
592 assert (splash->plugin != NULL);
593
594 if (splash->plugin_interface->system_update == NULL)
595 return false;
596
597 ply_trace ("updating system %i%%", progress);
598 splash->plugin_interface->system_update (splash->plugin,
599 progress);
600 return true;
76a2e17c
RS
601}
602
603void
604ply_boot_splash_update_status (ply_boot_splash_t *splash,
48138896 605 const char *status)
76a2e17c 606{
85704145
RS
607 assert (splash != NULL);
608 assert (status != NULL);
609 assert (splash->plugin_interface != NULL);
610 assert (splash->plugin != NULL);
611 assert (splash->plugin_interface->update_status != NULL);
612 assert (splash->mode != PLY_BOOT_SPLASH_MODE_INVALID);
613
614 splash->plugin_interface->update_status (splash->plugin, status);
76a2e17c
RS
615}
616
b8781ead
RS
617void
618ply_boot_splash_update_output (ply_boot_splash_t *splash,
619 const char *output,
620 size_t size)
621{
85704145
RS
622 assert (splash != NULL);
623 assert (output != NULL);
b8781ead 624
85704145
RS
625 if (splash->plugin_interface->on_boot_output != NULL)
626 splash->plugin_interface->on_boot_output (splash->plugin, output, size);
b8781ead
RS
627}
628
3822e357
RS
629void
630ply_boot_splash_root_mounted (ply_boot_splash_t *splash)
631{
85704145 632 assert (splash != NULL);
3822e357 633
85704145
RS
634 if (splash->plugin_interface->on_root_mounted != NULL)
635 splash->plugin_interface->on_root_mounted (splash->plugin);
2f277ad6
RS
636}
637
fe6a3b00
RS
638static void
639ply_boot_splash_detach_from_event_loop (ply_boot_splash_t *splash)
640{
85704145
RS
641 assert (splash != NULL);
642 splash->loop = NULL;
fe6a3b00
RS
643}
644
76a2e17c
RS
645void
646ply_boot_splash_hide (ply_boot_splash_t *splash)
647{
85704145
RS
648 assert (splash != NULL);
649 assert (splash->plugin_interface != NULL);
650 assert (splash->plugin != NULL);
651 assert (splash->plugin_interface->hide_splash_screen != NULL);
652
653 splash->plugin_interface->hide_splash_screen (splash->plugin,
654 splash->loop);
655
656 splash->mode = PLY_BOOT_SPLASH_MODE_INVALID;
657
658 if (splash->loop != NULL) {
5e33469e
RS
659 if (splash->is_shown) {
660 ply_boot_splash_unpause_pixel_displays (splash);
661
662 ply_event_loop_stop_watching_for_timeout (splash->loop,
663 (ply_event_loop_timeout_handler_t)
664 on_new_frame, splash);
665 splash->is_shown = false;
666 }
667
85704145
RS
668 if (splash->plugin_interface->on_boot_progress != NULL) {
669 ply_event_loop_stop_watching_for_timeout (splash->loop,
670 (ply_event_loop_timeout_handler_t)
671 ply_boot_splash_update_progress, splash);
672 }
673
674 ply_event_loop_stop_watching_for_exit (splash->loop, (ply_event_loop_exit_handler_t)
675 ply_boot_splash_detach_from_event_loop,
676 splash);
2f277ad6 677 }
76a2e17c
RS
678}
679
85704145
RS
680void ply_boot_splash_display_message (ply_boot_splash_t *splash,
681 const char *message)
b65d7dcf 682{
85704145
RS
683 assert (splash != NULL);
684 assert (splash->plugin_interface != NULL);
685 assert (splash->plugin != NULL);
0880f04e 686
85704145
RS
687 if (splash->plugin_interface->display_message != NULL)
688 splash->plugin_interface->display_message (splash->plugin, message);
b65d7dcf 689}
df5d6ded 690
85704145
RS
691void ply_boot_splash_hide_message (ply_boot_splash_t *splash,
692 const char *message)
eed3b65b 693{
85704145
RS
694 assert (splash != NULL);
695 assert (splash->plugin_interface != NULL);
696 assert (splash->plugin != NULL);
697 if (splash->plugin_interface->hide_message != NULL)
698 splash->plugin_interface->hide_message (splash->plugin, message);
eed3b65b
CB
699}
700
85704145 701void ply_boot_splash_display_normal (ply_boot_splash_t *splash)
268292ba 702{
85704145
RS
703 assert (splash != NULL);
704 assert (splash->plugin_interface != NULL);
705 assert (splash->plugin != NULL);
706 if (splash->plugin_interface->display_normal != NULL)
707 splash->plugin_interface->display_normal (splash->plugin);
268292ba 708}
df5d6ded 709
85704145
RS
710void ply_boot_splash_display_password (ply_boot_splash_t *splash,
711 const char *prompt,
712 int bullets)
b65d7dcf 713{
85704145
RS
714 assert (splash != NULL);
715 assert (splash->plugin_interface != NULL);
716 assert (splash->plugin != NULL);
717 if (splash->plugin_interface->display_password != NULL)
718 splash->plugin_interface->display_password (splash->plugin, prompt, bullets);
b65d7dcf 719}
df5d6ded 720
85704145
RS
721void ply_boot_splash_display_question (ply_boot_splash_t *splash,
722 const char *prompt,
723 const char *entry_text)
b65d7dcf 724{
85704145
RS
725 assert (splash != NULL);
726 assert (splash->plugin_interface != NULL);
727 assert (splash->plugin != NULL);
728 if (splash->plugin_interface->display_question != NULL)
729 splash->plugin_interface->display_question (splash->plugin, prompt, entry_text);
b65d7dcf
CB
730}
731
853ec9c2
MP
732void ply_boot_splash_display_prompt (ply_boot_splash_t *splash,
733 const char *prompt,
734 const char *entry_text,
735 bool is_secret)
736{
737 assert (splash != NULL);
738 assert (splash->plugin_interface != NULL);
739 assert (splash->plugin != NULL);
740 if (splash->plugin_interface->display_prompt != NULL)
741 splash->plugin_interface->display_prompt (splash->plugin, prompt, entry_text, is_secret);
742}
743
5d1b49c6
TT
744bool ply_boot_splash_validate_input (ply_boot_splash_t *splash,
745 const char *entry_text,
746 const char *add_text)
747{
748 bool input_valid = true;
e483f0c4 749
5d1b49c6
TT
750 assert (splash != NULL);
751 assert (splash->plugin_interface != NULL);
752 assert (splash->plugin != NULL);
753 if (splash->plugin_interface->validate_input != NULL)
754 input_valid = splash->plugin_interface->validate_input (splash->plugin, entry_text, add_text);
755 return input_valid;
756}
b65d7dcf
CB
757
758
76a2e17c
RS
759void
760ply_boot_splash_attach_to_event_loop (ply_boot_splash_t *splash,
761 ply_event_loop_t *loop)
762{
85704145
RS
763 assert (splash != NULL);
764 assert (loop != NULL);
765 assert (splash->loop == NULL);
76a2e17c 766
85704145 767 splash->loop = loop;
76a2e17c 768
85704145
RS
769 ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
770 ply_boot_splash_detach_from_event_loop,
771 splash);
76a2e17c
RS
772}
773
3df0f126
RS
774static void
775on_idle (ply_boot_splash_t *splash)
776{
85704145
RS
777 ply_trace ("splash now idle");
778 ply_event_loop_watch_for_timeout (splash->loop, 0.01,
779 (ply_event_loop_timeout_handler_t)
780 splash->idle_handler,
781 splash->idle_handler_user_data);
782 splash->idle_handler = NULL;
783 splash->idle_handler_user_data = NULL;
3df0f126
RS
784}
785
2bb73dcf 786void
85704145
RS
787ply_boot_splash_become_idle (ply_boot_splash_t *splash,
788 ply_boot_splash_on_idle_handler_t idle_handler,
789 void *user_data)
2bb73dcf 790{
85704145
RS
791 assert (splash->idle_trigger == NULL);
792
a1920e8a
HG
793 if (splash->plugin_interface->on_boot_progress != NULL &&
794 splash->progress != NULL) {
85704145 795 ply_progress_set_percentage (splash->progress, 1.0);
a1920e8a
HG
796 splash->plugin_interface->on_boot_progress (splash->plugin,
797 ply_progress_get_time (splash->progress),
798 1.0);
85704145
RS
799 }
800
801 ply_trace ("telling splash to become idle");
802 if (splash->plugin_interface->become_idle == NULL) {
803 ply_event_loop_watch_for_timeout (splash->loop, 0.01,
804 (ply_event_loop_timeout_handler_t)
805 idle_handler,
806 user_data);
807
808 return;
809 }
810
811 splash->idle_handler = idle_handler;
812 splash->idle_handler_user_data = user_data;
813
814 splash->idle_trigger = ply_trigger_new (&splash->idle_trigger);
815 ply_trigger_add_handler (splash->idle_trigger,
816 (ply_trigger_handler_t) on_idle,
817 splash);
818
819 splash->plugin_interface->become_idle (splash->plugin, splash->idle_trigger);
2bb73dcf
RS
820}
821
447c7830
HG
822bool
823ply_boot_splash_uses_pixel_displays (ply_boot_splash_t *splash)
824{
825 return splash->plugin_interface->add_pixel_display != NULL;
826}
827