New page wikitext, after the edit (new_wikitext) | '== Writing a script theme ==
Plymouth uses its own language implementation for scripts, it is a '''''C'''''-style language, it is recommended to read the [https://www.freedesktop.org/wiki/Software/Plymouth/Scripts/ plymouth documentation] on it's language which can help the user get a general understanding of how to write a script.
=== Specimen ===
To define a '''script''' theme, you use <code>script</code> as the module name in the <code>example.plymouth</code> file.
The script module has four options that can be defined:
* <code>ScriptFile</code>: An absolute path to the script file.
* <code>ImageDir</code>: An absolute path to a directory.
* <code>MonospaceFont</code>: The font to use in text sprites (the font needs to be available in the initramfs). (optional)
* <code>ConsoleLogTextColor</code>: The color to use for console logs (in hex: 0x''ffffff'') (optional)
{{CodeBox|title=example.plymouth|lang=toml|1=
[Plymouth-Theme]
Name=Example
Description=This will be an example plugin
ModuleName=script
[script]
ScriptFile=/usr/share/plymouth/themes/example/example.script
ImageDir=/usr/share/plymouth/themes/example/
}}
It is '''''recommended''''' to keep scripts and files in their respectives theme folders (so that they are populated in the initramfs).
=== Terminology ===
* Image: An image is a resource that has been loaded.
* Sprite: A sprite is an image that has been placed.
=== Hookable event callbacks ===
There are lots of different callbacks you can use in a script to track events/boot progress, each of these take a function as a parameter, which is called with the appropriate data when the relevant event is fired.
{{CodeBox|lang=C|1=
# The refresh function is called `x` amount of times per second, where `x` is the refresh rate set with `Plymouth.SetRefreshRate` or the default value (50).
fun on_refresh() {}
Plymouth.SetRefreshFunction(on_refresh);
}}
{{CodeBox|lang=C|1=
# The boot progress function is called whenever progress is made during the boot process.
fun on_boot_progress(duration, progress) {}
# duration and progress are both `numbers`
Plymouth.SetBootProgressFunction(on_boot_progress);
}}
{{CodeBox|lang=C|1=
# The root mounted function is called when the root partition is mounted (needs verification).
fun on_root_mounted() {}
Plymouth.SetRootMountedFunction(on_root_mounted);
}}
{{CodeBox|lang=C|1=
# The keyboard input function is called whenever input is made on a keyboard, this does not trigger on non-text characters such as return (needs verification).
fun on_keyboard_input(char) {}
# char is a string containing the character pressed.
Plymouth.SetKeyboardInputFunction(on_keyboard_input);
}}
{{CodeBox|lang=C|1=
# This is called whenever the status is changed.
fun on_status_update(new_status) {}
# new_status is a string containing the new status.
Plymouth.SetUpdateStatusFunction(on_status_update);
}}
{{CodeBox|lang=C|1=
# This is called whenever the display should return to normal.
fun on_mode_normal() {}
Plymouth.SetDisplayNormalFunction(on_mode_normal);
}}
{{CodeBox|lang=C|1=
# This is called whenever the display should show a password prompt.
fun on_mode_password(prompt, bullets) {}
# prompt is a string and bullets is a number indicating how many characters have been entered.
Plymouth.SetDisplayPasswordFunction(on_mode_password);
}}
{{CodeBox|lang=C|1=
# This is called whenever a question is asked.
fun on_mode_question(prompt, entry_text) {}
# prompt and entry_text are strings.
Plymouth.SetDisplayQuestionFunction(on_mode_question);
}}
{{CodeBox|lang=C|1=
# This is called whenever a prompt needs displaying.
fun on_mode_prompt(prompt, entry_text, is_secret) {}
# prompt and entry_text are strings and is_secret is a bool.
Plymouth.SetDisplayPromptFunction(on_mode_prompt);
}}
{{CodeBox|lang=C|1=
# This is called whenever a device is hotplugged into the machine.
fun on_hotplug() {}
Plymouth.SetDisplayHotplugFunction();
}}
{{CodeBox|lang=C|1=
# This is called whenever an input needs validation.
fun on_validate_input(entry_text, additional_text) { return some_bool; }
# entry_text and additional_text are both strings, the function expects a boolean return value.
Plymouth.SetValidateInputFunction(on_validate_input);
}}
{{CodeBox|lang=C|1=
# This is called when a new message needs to be displayed.
fun on_message(message) {}
# message is a string.
Plymouth.SetDisplayMessageFunction(on_message);
}}
{{CodeBox|lang=C|1=
# This is called to hide a previously shown message.
fun on_hide_message(message) {}
# message is a string.
Plymouth.SetHideMessageFunction(on_hide_message);
}}
{{CodeBox|lang=C|1=
# This is called when plymouth is quitting.
fun on_quit() {}
Plymouth.SetQuitFunction(on_quit);
}}
{{CodeBox|lang=C|1=
# This is called when there is a system update.
fun on_system_update(status) {}
# status is a string of the new status of the system.
Plymouth.SetSystemUpdateFunction();
}}
=== Other Builtin Functions ===
There are also other builtin functions which are listed below:
{{CodeBox|lang=C|1=
# returns a boolean depicting the current capslock state (true=on, false=off)
Plymouth.GetCapslockState(): returns bool
# returns the current mode that plymouth is in (normal, password, question, ...)
Plymouth.GetMode(): returns string;
# sets the amount of times the refresh function is called per second.
Plymouth.SetRefreshRate(number): returns null;
}}
In addition to this, there are also some mathematics functions under a different namespace:
{{CodeBox|lang=C|1=
# Returns absolute (positive) of a number.
Math.Abs(number);
# Returns the smallest number from two numbers.
Math.Min(number1, number2);
# Returns the largest number from two numbers.
Math.Max(number1, number2);
# Forces the value to be between min and max, otherwise either min or max are returned.
Math.Clamp(value, min, max);
# The value of Pi (3.14159...) to 21 d.p.
Math.Pi();
# Cosine function
Math.Cos(radians);
# Sine function
Math.Sin(radians);
# Tangent function
Math.Tan(radians);
# Arc tangent function taking 2 values (see "man atan2")
Math.ATan2(x, y);
# Square root of a number
Math.Sqrt(number);
# Returns the rounded down integer.
Math.Int(number);
# Returns a pseudo random number between 0 and 1.
Math.Random();
}}
Strings, images and sprites that each have their own associated functions:
{{CodeBox|lang=C|1=
# Create a string object
string_example = String("some string"); # or alternatively just "some string".
# Associated methods for strings:
# Returns the character at the given index
string_example.CharAt(number);
# Returns a substring starting at index `start` and ending at index `end`.
string_example.SubString(start, end);
# Returns the length of the string
string_example.Length();
# Creates an image object from the image at the given location.
image_example = Image(filename);
# Creates an image from text. All parameters apart from text are optional.
Image.Text = fun (text, red, green, blue, alpha, font, align)
# Associated methods for images:
# Rotates the image by the given angle
image_example.Rotate(angle);
# Crops the given image starting at x, y and ending at x+width, y+height.
image_example.Crop(x, y, width, height);
# Scales the given image to a given width and height.
image_example.Scale(width, height);
# Tiles the given image to a given width and height.
image_example.Tile(width, height);
# Creates a sprite, image is *optional*, if not provided then a sprite with no image is made, you can change the image later.
sprite_example = Sprite(image);
# Sprites also have methods associated with them:
# This sets the X coordinate of the sprite to number
sprite_example.SetX(number);
# This sets the Y coordinate of the sprite to number
sprite_example.SetY(number);
# This sets the Z coordinate of the sprite to number
sprite_example.SetZ(number);
# You can also get and set the sprite opacity:
sprite_example.SetOpacity(number);
sprite_example.GetOpacity();
# You can also get the width and height of the sprite:
sprite_example.GetWidth();
sprite_example.GetHeight();
# Finally you can also get and set the image of the sprite
sprite_example.SetImage(image);
sprite_example.GetImage();
# These can also all be set together using (WARNING: this is deprecated).
SetPosition(sprite_example, x,y,z)
}}
You can also get and set attributes for the window
{{CodeBox|lang=C|1=
# Get the display width and height
Window.GetWidth();
Window.GetHeight();
# Get and set the position of the background window sprite
Window.GetX(number);
Window.GetY(number);
Window.SetX(number);
Window.SetY(number);
# And you can also change the background sprite color:
Window.SetBackgroundTopColor(r, g, b);
Window.SetBackgroundBottomColor(r, g, b);
}}
=== Creating animations ===
One common way to create animations is to load all images for the animation and store them within a hashmap, then on each refresh we change the image that a sprite is displaying onto the next frame (and then loop to the start when the end of the animation is reached).
{{CodeBox|lang=C|1=
animation_first_frame = 0;
animation_last_frame = 250;
animation_current_frame = 0;
for (frame = animation_first_frame; frame <= animation_last_frame; frame++) {
animation_images[frame] = Image("animation/frame-" + frame + ".png");
}
# Create a sprite for the password box, we will assign a image later to it later.
animation_sprite = Sprite();
# Align the animation in the centre of the screen (optional)
animation_width = animation_images[animation_first_frame].GetWidth();
animation_height = animation_images[animation_first_frame].GetHeight();
animation_sprite.SetX((Window.GetWidth() / 2) - (animation_width / 2));
animation_sprite.SetY((Window.GetHeight() / 2) - (animation_height / 2));
animation_sprite.SetZ(-1);
# Now to animate we can change the image used in the sprite each frame,
fun on_refresh() {
animation_current_frame += 1;
if (animation_current_frame > animation_last_frame) {
# loop back to the start when the last frame is reached.
animation_current_frame = animation_first_frame;
}
animation_sprite.SetImage(animation_images[animation_current_frame]);
}
Plymouth.SetRefreshFunction(on_refresh);
}}
== Writing a two-step theme ==
{{Stub}}
== Writing a space-flares theme ==
=== Specimen ===
To define a '''space-flares''' theme, you use <code>space-flares</code> as the module name in the <code>example.plymouth</code> file.
The space-flares module has three options that can be defined:
* <code>ImageDir</code>: An absolute path to a directory that contains images.
* <code>MonospaceFont</code>: The font to use in text sprites (the font needs to be available in the initramfs). (optional)
* <code>ConsoleLogTextColor</code>: The color to use for console logs (in hex: 0x''ffffff'') (optional)
{{CodeBox|title=example.plymouth|lang=toml|1=
[Plymouth-Theme]
Name=Example
Description=This will be an example plugin
ModuleName=space-flares
[space-flares]
ImageDir=/usr/share/plymouth/themes/example/
}}
=== Customising
There are limited options for customising a solar-flares theme, you are limited to changing the following images (note: all of the images must be present):
* lock.png
* box.png
* star.png
* plant1.png (used if <code>SHOW_PLANETS</code> is defined in source)
* plant2.png (used if <code>SHOW_PLANETS</code> is defined in source)
* plant3.png (used if <code>SHOW_PLANETS</code> is defined in source)
* plant4.png (used if <code>SHOW_PLANETS</code> is defined in source)
* plant5.png (used if <code>SHOW_PLANETS</code> is defined in source)
* progress_bar.png (used if <code>SHOW_PROGRESS_BAR</code> is defined in source)
The amount of images actually displayed depends on how plymouth is compiled<ref>https://gitlab.freedesktop.org/plymouth/plymouth/-/blob/main/src/plugins/splash/space-flares/plugin.c#L69</ref>, however it defaults to showing a progress bar, with no planets, no comets, and, no logo halo.
You can also change more options by editing the source code at <code>/src/plugins/splash/space-flares/plugin.c</code> where you can define fps, blur, flare count, flare lines, and star Hz.
== Activating a theme ==
To set a theme you may refer to: https://wiki.gentoo.org/wiki/Plymouth#Themes
== Troubleshooting ==
To temporarily disable plymouth , you can add the following kernel parameters:
{{CodeBox|1=plymouth.enable=0 disablehooks=plymouth}}
To write debug output into /var/log/plymouth-debug.log, you can add the following kernel parameter:
{{CodeBox|1=plymouth.debug}}
If themes are not loading properly it may be a good idea to check the user's initramfs to ensure that it has been populated with the plymouth binaries and themes<ref>https://wiki.gentoo.org/wiki/Plymouth#Manual_initramfs_creation</ref>
== See also ==
* {{See also|Plymouth}}
== External resources ==
* [https://gitlab.freedesktop.org/plymouth/plymouth/-/tree/main/src/plugins/splash script module source code]
* [https://www.freedesktop.org/wiki/Software/Plymouth/Scripts/ Freedesktop Plymouth Script Wiki]
* [https://github.com/adi1090x/plymouth-themes Large theme repository]
* [https://wiki.archlinux.org/title/Plymouth Arch wiki on plymouth]
* [https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/desktop_migration_and_administration_guide/plymouth Redhat guide for plymouth theme creation] –
== References ==
{{reflist}}
[[Category:Software:Plymouth]]' |
Lines added in edit (added_lines) | [
0 => '== Writing a script theme ==',
1 => 'Plymouth uses its own language implementation for scripts, it is a '''''C'''''-style language, it is recommended to read the [https://www.freedesktop.org/wiki/Software/Plymouth/Scripts/ plymouth documentation] on it's language which can help the user get a general understanding of how to write a script.',
2 => '',
3 => '=== Specimen ===',
4 => 'To define a '''script''' theme, you use <code>script</code> as the module name in the <code>example.plymouth</code> file.',
5 => '',
6 => 'The script module has four options that can be defined:',
7 => '* <code>ScriptFile</code>: An absolute path to the script file.',
8 => '* <code>ImageDir</code>: An absolute path to a directory.',
9 => '* <code>MonospaceFont</code>: The font to use in text sprites (the font needs to be available in the initramfs). (optional)',
10 => '* <code>ConsoleLogTextColor</code>: The color to use for console logs (in hex: 0x''ffffff'') (optional)',
11 => '',
12 => '{{CodeBox|title=example.plymouth|lang=toml|1=',
13 => '[Plymouth-Theme]',
14 => 'Name=Example',
15 => 'Description=This will be an example plugin',
16 => 'ModuleName=script',
17 => '',
18 => '[script]',
19 => 'ScriptFile=/usr/share/plymouth/themes/example/example.script',
20 => 'ImageDir=/usr/share/plymouth/themes/example/',
21 => '}}',
22 => '',
23 => 'It is '''''recommended''''' to keep scripts and files in their respectives theme folders (so that they are populated in the initramfs).',
24 => '',
25 => '=== Terminology ===',
26 => '',
27 => '* Image: An image is a resource that has been loaded.',
28 => '* Sprite: A sprite is an image that has been placed.',
29 => '',
30 => '',
31 => '=== Hookable event callbacks ===',
32 => 'There are lots of different callbacks you can use in a script to track events/boot progress, each of these take a function as a parameter, which is called with the appropriate data when the relevant event is fired.',
33 => '',
34 => '{{CodeBox|lang=C|1=',
35 => '# The refresh function is called `x` amount of times per second, where `x` is the refresh rate set with `Plymouth.SetRefreshRate` or the default value (50).',
36 => 'fun on_refresh() {}',
37 => '',
38 => 'Plymouth.SetRefreshFunction(on_refresh);',
39 => '}}',
40 => '',
41 => '{{CodeBox|lang=C|1=',
42 => '# The boot progress function is called whenever progress is made during the boot process.',
43 => 'fun on_boot_progress(duration, progress) {}',
44 => '# duration and progress are both `numbers`',
45 => '',
46 => 'Plymouth.SetBootProgressFunction(on_boot_progress);',
47 => '}}',
48 => '',
49 => '{{CodeBox|lang=C|1=',
50 => '# The root mounted function is called when the root partition is mounted (needs verification).',
51 => 'fun on_root_mounted() {}',
52 => '',
53 => 'Plymouth.SetRootMountedFunction(on_root_mounted);',
54 => '}}',
55 => '',
56 => '{{CodeBox|lang=C|1=',
57 => '# The keyboard input function is called whenever input is made on a keyboard, this does not trigger on non-text characters such as return (needs verification).',
58 => 'fun on_keyboard_input(char) {}',
59 => '# char is a string containing the character pressed.',
60 => '',
61 => 'Plymouth.SetKeyboardInputFunction(on_keyboard_input);',
62 => '}}',
63 => '',
64 => '{{CodeBox|lang=C|1=',
65 => '# This is called whenever the status is changed.',
66 => 'fun on_status_update(new_status) {}',
67 => '# new_status is a string containing the new status.',
68 => '',
69 => 'Plymouth.SetUpdateStatusFunction(on_status_update);',
70 => '}}',
71 => '',
72 => '{{CodeBox|lang=C|1=',
73 => '# This is called whenever the display should return to normal.',
74 => 'fun on_mode_normal() {}',
75 => '',
76 => 'Plymouth.SetDisplayNormalFunction(on_mode_normal);',
77 => '}}',
78 => '',
79 => '{{CodeBox|lang=C|1=',
80 => '# This is called whenever the display should show a password prompt.',
81 => 'fun on_mode_password(prompt, bullets) {}',
82 => '# prompt is a string and bullets is a number indicating how many characters have been entered. ',
83 => '',
84 => 'Plymouth.SetDisplayPasswordFunction(on_mode_password);',
85 => '}}',
86 => '',
87 => '{{CodeBox|lang=C|1=',
88 => '# This is called whenever a question is asked.',
89 => 'fun on_mode_question(prompt, entry_text) {}',
90 => '# prompt and entry_text are strings.',
91 => '',
92 => 'Plymouth.SetDisplayQuestionFunction(on_mode_question);',
93 => '}}',
94 => '',
95 => '{{CodeBox|lang=C|1=',
96 => '# This is called whenever a prompt needs displaying.',
97 => 'fun on_mode_prompt(prompt, entry_text, is_secret) {}',
98 => '# prompt and entry_text are strings and is_secret is a bool.',
99 => '',
100 => 'Plymouth.SetDisplayPromptFunction(on_mode_prompt);',
101 => '}}',
102 => '',
103 => '{{CodeBox|lang=C|1=',
104 => '# This is called whenever a device is hotplugged into the machine.',
105 => 'fun on_hotplug() {}',
106 => '',
107 => 'Plymouth.SetDisplayHotplugFunction();',
108 => '}}',
109 => '',
110 => '{{CodeBox|lang=C|1=',
111 => '# This is called whenever an input needs validation.',
112 => 'fun on_validate_input(entry_text, additional_text) { return some_bool; }',
113 => '# entry_text and additional_text are both strings, the function expects a boolean return value.',
114 => '',
115 => 'Plymouth.SetValidateInputFunction(on_validate_input);',
116 => '}}',
117 => '',
118 => '{{CodeBox|lang=C|1=',
119 => '# This is called when a new message needs to be displayed.',
120 => 'fun on_message(message) {}',
121 => '# message is a string.',
122 => '',
123 => 'Plymouth.SetDisplayMessageFunction(on_message);',
124 => '}}',
125 => '',
126 => '{{CodeBox|lang=C|1=',
127 => '# This is called to hide a previously shown message.',
128 => 'fun on_hide_message(message) {}',
129 => '# message is a string.',
130 => '',
131 => 'Plymouth.SetHideMessageFunction(on_hide_message);',
132 => '}}',
133 => '',
134 => '{{CodeBox|lang=C|1=',
135 => '# This is called when plymouth is quitting.',
136 => 'fun on_quit() {}',
137 => '',
138 => 'Plymouth.SetQuitFunction(on_quit);',
139 => '}}',
140 => '',
141 => '{{CodeBox|lang=C|1=',
142 => '# This is called when there is a system update.',
143 => 'fun on_system_update(status) {}',
144 => '# status is a string of the new status of the system.',
145 => '',
146 => 'Plymouth.SetSystemUpdateFunction();',
147 => '}}',
148 => '',
149 => '=== Other Builtin Functions ===',
150 => 'There are also other builtin functions which are listed below:',
151 => '{{CodeBox|lang=C|1=',
152 => '# returns a boolean depicting the current capslock state (true=on, false=off)',
153 => 'Plymouth.GetCapslockState(): returns bool',
154 => '',
155 => '# returns the current mode that plymouth is in (normal, password, question, ...)',
156 => 'Plymouth.GetMode(): returns string;',
157 => '',
158 => '# sets the amount of times the refresh function is called per second.',
159 => 'Plymouth.SetRefreshRate(number): returns null;',
160 => '}}',
161 => '',
162 => 'In addition to this, there are also some mathematics functions under a different namespace:',
163 => '{{CodeBox|lang=C|1=',
164 => '# Returns absolute (positive) of a number.',
165 => 'Math.Abs(number);',
166 => '',
167 => '# Returns the smallest number from two numbers.',
168 => 'Math.Min(number1, number2);',
169 => '',
170 => '# Returns the largest number from two numbers.',
171 => 'Math.Max(number1, number2);',
172 => '',
173 => '# Forces the value to be between min and max, otherwise either min or max are returned.',
174 => 'Math.Clamp(value, min, max);',
175 => '',
176 => '# The value of Pi (3.14159...) to 21 d.p.',
177 => 'Math.Pi();',
178 => '',
179 => '# Cosine function',
180 => 'Math.Cos(radians);',
181 => '',
182 => '# Sine function',
183 => 'Math.Sin(radians);',
184 => '',
185 => '# Tangent function',
186 => 'Math.Tan(radians);',
187 => '',
188 => '# Arc tangent function taking 2 values (see "man atan2")',
189 => 'Math.ATan2(x, y);',
190 => '',
191 => '# Square root of a number',
192 => 'Math.Sqrt(number);',
193 => '',
194 => '# Returns the rounded down integer.',
195 => 'Math.Int(number);',
196 => '',
197 => '# Returns a pseudo random number between 0 and 1. ',
198 => 'Math.Random();',
199 => '}}',
200 => '',
201 => 'Strings, images and sprites that each have their own associated functions:',
202 => '{{CodeBox|lang=C|1=',
203 => '',
204 => '# Create a string object',
205 => 'string_example = String("some string"); # or alternatively just "some string".',
206 => '',
207 => '# Associated methods for strings:',
208 => '# Returns the character at the given index',
209 => 'string_example.CharAt(number);',
210 => '# Returns a substring starting at index `start` and ending at index `end`.',
211 => 'string_example.SubString(start, end);',
212 => '# Returns the length of the string',
213 => 'string_example.Length();',
214 => '',
215 => '',
216 => '# Creates an image object from the image at the given location.',
217 => 'image_example = Image(filename);',
218 => '# Creates an image from text. All parameters apart from text are optional.',
219 => 'Image.Text = fun (text, red, green, blue, alpha, font, align)',
220 => '',
221 => '# Associated methods for images:',
222 => '# Rotates the image by the given angle',
223 => 'image_example.Rotate(angle);',
224 => '# Crops the given image starting at x, y and ending at x+width, y+height.',
225 => 'image_example.Crop(x, y, width, height);',
226 => '# Scales the given image to a given width and height.',
227 => 'image_example.Scale(width, height);',
228 => '# Tiles the given image to a given width and height.',
229 => 'image_example.Tile(width, height);',
230 => '',
231 => '',
232 => '# Creates a sprite, image is *optional*, if not provided then a sprite with no image is made, you can change the image later.',
233 => 'sprite_example = Sprite(image);',
234 => '',
235 => '# Sprites also have methods associated with them:',
236 => '# This sets the X coordinate of the sprite to number',
237 => 'sprite_example.SetX(number);',
238 => '# This sets the Y coordinate of the sprite to number',
239 => 'sprite_example.SetY(number);',
240 => '# This sets the Z coordinate of the sprite to number',
241 => 'sprite_example.SetZ(number);',
242 => '# You can also get and set the sprite opacity:',
243 => 'sprite_example.SetOpacity(number);',
244 => 'sprite_example.GetOpacity();',
245 => '# You can also get the width and height of the sprite:',
246 => 'sprite_example.GetWidth();',
247 => 'sprite_example.GetHeight();',
248 => '# Finally you can also get and set the image of the sprite',
249 => 'sprite_example.SetImage(image);',
250 => 'sprite_example.GetImage();',
251 => '',
252 => '# These can also all be set together using (WARNING: this is deprecated).',
253 => 'SetPosition(sprite_example, x,y,z)',
254 => '}}',
255 => '',
256 => 'You can also get and set attributes for the window',
257 => '{{CodeBox|lang=C|1=',
258 => '# Get the display width and height',
259 => 'Window.GetWidth();',
260 => 'Window.GetHeight();',
261 => '',
262 => '# Get and set the position of the background window sprite',
263 => 'Window.GetX(number);',
264 => 'Window.GetY(number);',
265 => '',
266 => 'Window.SetX(number);',
267 => 'Window.SetY(number);',
268 => '',
269 => '# And you can also change the background sprite color:',
270 => 'Window.SetBackgroundTopColor(r, g, b);',
271 => 'Window.SetBackgroundBottomColor(r, g, b);',
272 => '}}',
273 => '',
274 => '',
275 => '',
276 => '=== Creating animations ===',
277 => 'One common way to create animations is to load all images for the animation and store them within a hashmap, then on each refresh we change the image that a sprite is displaying onto the next frame (and then loop to the start when the end of the animation is reached).',
278 => '{{CodeBox|lang=C|1=',
279 => '',
280 => ' animation_first_frame = 0;',
281 => 'animation_last_frame = 250;',
282 => 'animation_current_frame = 0;',
283 => '',
284 => 'for (frame = animation_first_frame; frame <= animation_last_frame; frame++) {',
285 => ' animation_images[frame] = Image("animation/frame-" + frame + ".png");',
286 => '}',
287 => '',
288 => '# Create a sprite for the password box, we will assign a image later to it later.',
289 => 'animation_sprite = Sprite();',
290 => '# Align the animation in the centre of the screen (optional)',
291 => 'animation_width = animation_images[animation_first_frame].GetWidth();',
292 => 'animation_height = animation_images[animation_first_frame].GetHeight();',
293 => 'animation_sprite.SetX((Window.GetWidth() / 2) - (animation_width / 2));',
294 => 'animation_sprite.SetY((Window.GetHeight() / 2) - (animation_height / 2));',
295 => 'animation_sprite.SetZ(-1);',
296 => '',
297 => '# Now to animate we can change the image used in the sprite each frame,',
298 => 'fun on_refresh() {',
299 => ' animation_current_frame += 1;',
300 => ' if (animation_current_frame > animation_last_frame) {',
301 => ' # loop back to the start when the last frame is reached.',
302 => ' animation_current_frame = animation_first_frame;',
303 => ' }',
304 => ' animation_sprite.SetImage(animation_images[animation_current_frame]);',
305 => '}',
306 => 'Plymouth.SetRefreshFunction(on_refresh);',
307 => '}}',
308 => '',
309 => '== Writing a two-step theme ==',
310 => '{{Stub}}',
311 => '',
312 => '== Writing a space-flares theme ==',
313 => '=== Specimen ===',
314 => 'To define a '''space-flares''' theme, you use <code>space-flares</code> as the module name in the <code>example.plymouth</code> file.',
315 => '',
316 => 'The space-flares module has three options that can be defined:',
317 => '* <code>ImageDir</code>: An absolute path to a directory that contains images.',
318 => '* <code>MonospaceFont</code>: The font to use in text sprites (the font needs to be available in the initramfs). (optional)',
319 => '* <code>ConsoleLogTextColor</code>: The color to use for console logs (in hex: 0x''ffffff'') (optional)',
320 => '',
321 => '{{CodeBox|title=example.plymouth|lang=toml|1=',
322 => '[Plymouth-Theme]',
323 => 'Name=Example',
324 => 'Description=This will be an example plugin',
325 => 'ModuleName=space-flares',
326 => '',
327 => '[space-flares]',
328 => 'ImageDir=/usr/share/plymouth/themes/example/',
329 => '}}',
330 => '',
331 => '=== Customising',
332 => 'There are limited options for customising a solar-flares theme, you are limited to changing the following images (note: all of the images must be present):',
333 => '* lock.png',
334 => '* box.png',
335 => '* star.png',
336 => '* plant1.png (used if <code>SHOW_PLANETS</code> is defined in source)',
337 => '* plant2.png (used if <code>SHOW_PLANETS</code> is defined in source)',
338 => '* plant3.png (used if <code>SHOW_PLANETS</code> is defined in source)',
339 => '* plant4.png (used if <code>SHOW_PLANETS</code> is defined in source)',
340 => '* plant5.png (used if <code>SHOW_PLANETS</code> is defined in source)',
341 => '* progress_bar.png (used if <code>SHOW_PROGRESS_BAR</code> is defined in source)',
342 => '',
343 => '',
344 => 'The amount of images actually displayed depends on how plymouth is compiled<ref>https://gitlab.freedesktop.org/plymouth/plymouth/-/blob/main/src/plugins/splash/space-flares/plugin.c#L69</ref>, however it defaults to showing a progress bar, with no planets, no comets, and, no logo halo.',
345 => 'You can also change more options by editing the source code at <code>/src/plugins/splash/space-flares/plugin.c</code> where you can define fps, blur, flare count, flare lines, and star Hz.',
346 => '',
347 => '== Activating a theme ==',
348 => 'To set a theme you may refer to: https://wiki.gentoo.org/wiki/Plymouth#Themes',
349 => '',
350 => '== Troubleshooting ==',
351 => '',
352 => 'To temporarily disable plymouth , you can add the following kernel parameters:',
353 => '{{CodeBox|1=plymouth.enable=0 disablehooks=plymouth}}',
354 => '',
355 => 'To write debug output into /var/log/plymouth-debug.log, you can add the following kernel parameter:',
356 => '{{CodeBox|1=plymouth.debug}}',
357 => '',
358 => 'If themes are not loading properly it may be a good idea to check the user's initramfs to ensure that it has been populated with the plymouth binaries and themes<ref>https://wiki.gentoo.org/wiki/Plymouth#Manual_initramfs_creation</ref>',
359 => '',
360 => '',
361 => '== See also ==',
362 => '',
363 => '* {{See also|Plymouth}}',
364 => '',
365 => '== External resources ==',
366 => '',
367 => '* [https://gitlab.freedesktop.org/plymouth/plymouth/-/tree/main/src/plugins/splash script module source code]',
368 => '* [https://www.freedesktop.org/wiki/Software/Plymouth/Scripts/ Freedesktop Plymouth Script Wiki]',
369 => '* [https://github.com/adi1090x/plymouth-themes Large theme repository]',
370 => '* [https://wiki.archlinux.org/title/Plymouth Arch wiki on plymouth]',
371 => '* [https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/desktop_migration_and_administration_guide/plymouth Redhat guide for plymouth theme creation] – ',
372 => '',
373 => '== References ==',
374 => '',
375 => '{{reflist}}',
376 => '',
377 => '[[Category:Software:Plymouth]]'
] |
New page text, stripped of any markup (new_text) | 'Contents
1 Writing a script theme
1.1 Specimen
1.2 Terminology
1.3 Hookable event callbacks
1.4 Other Builtin Functions
1.5 Creating animations
2 Writing a two-step theme
3 Writing a space-flares theme
3.1 Specimen
4 Activating a theme
5 Troubleshooting
6 See also
7 External resources
8 References
Writing a script theme[edit | edit source]
Plymouth uses its own language implementation for scripts, it is a C-style language, it is recommended to read the plymouth documentation on it's language which can help the user get a general understanding of how to write a script.
Specimen[edit | edit source]
To define a script theme, you use script as the module name in the example.plymouth file.
The script module has four options that can be defined:
ScriptFile: An absolute path to the script file.
ImageDir: An absolute path to a directory.
MonospaceFont: The font to use in text sprites (the font needs to be available in the initramfs). (optional)
ConsoleLogTextColor: The color to use for console logs (in hex: 0xffffff) (optional)
CODE example.plymouth [Plymouth-Theme]
Name=Example
Description=This will be an example plugin
ModuleName=script
[script]
ScriptFile=/usr/share/plymouth/themes/example/example.script
ImageDir=/usr/share/plymouth/themes/example/
It is recommended to keep scripts and files in their respectives theme folders (so that they are populated in the initramfs).
Terminology[edit | edit source]
Image: An image is a resource that has been loaded.
Sprite: A sprite is an image that has been placed.
Hookable event callbacks[edit | edit source]
There are lots of different callbacks you can use in a script to track events/boot progress, each of these take a function as a parameter, which is called with the appropriate data when the relevant event is fired.
CODE # The refresh function is called `x` amount of times per second, where `x` is the refresh rate set with `Plymouth.SetRefreshRate` or the default value (50).
fun on_refresh() {}
Plymouth.SetRefreshFunction(on_refresh);
CODE # The boot progress function is called whenever progress is made during the boot process.
fun on_boot_progress(duration, progress) {}
# duration and progress are both `numbers`
Plymouth.SetBootProgressFunction(on_boot_progress);
CODE # The root mounted function is called when the root partition is mounted (needs verification).
fun on_root_mounted() {}
Plymouth.SetRootMountedFunction(on_root_mounted);
CODE # The keyboard input function is called whenever input is made on a keyboard, this does not trigger on non-text characters such as return (needs verification).
fun on_keyboard_input(char) {}
# char is a string containing the character pressed.
Plymouth.SetKeyboardInputFunction(on_keyboard_input);
CODE # This is called whenever the status is changed.
fun on_status_update(new_status) {}
# new_status is a string containing the new status.
Plymouth.SetUpdateStatusFunction(on_status_update);
CODE # This is called whenever the display should return to normal.
fun on_mode_normal() {}
Plymouth.SetDisplayNormalFunction(on_mode_normal);
CODE # This is called whenever the display should show a password prompt.
fun on_mode_password(prompt, bullets) {}
# prompt is a string and bullets is a number indicating how many characters have been entered.
Plymouth.SetDisplayPasswordFunction(on_mode_password);
CODE # This is called whenever a question is asked.
fun on_mode_question(prompt, entry_text) {}
# prompt and entry_text are strings.
Plymouth.SetDisplayQuestionFunction(on_mode_question);
CODE # This is called whenever a prompt needs displaying.
fun on_mode_prompt(prompt, entry_text, is_secret) {}
# prompt and entry_text are strings and is_secret is a bool.
Plymouth.SetDisplayPromptFunction(on_mode_prompt);
CODE # This is called whenever a device is hotplugged into the machine.
fun on_hotplug() {}
Plymouth.SetDisplayHotplugFunction();
CODE # This is called whenever an input needs validation.
fun on_validate_input(entry_text, additional_text) { return some_bool; }
# entry_text and additional_text are both strings, the function expects a boolean return value.
Plymouth.SetValidateInputFunction(on_validate_input);
CODE # This is called when a new message needs to be displayed.
fun on_message(message) {}
# message is a string.
Plymouth.SetDisplayMessageFunction(on_message);
CODE # This is called to hide a previously shown message.
fun on_hide_message(message) {}
# message is a string.
Plymouth.SetHideMessageFunction(on_hide_message);
CODE # This is called when plymouth is quitting.
fun on_quit() {}
Plymouth.SetQuitFunction(on_quit);
CODE # This is called when there is a system update.
fun on_system_update(status) {}
# status is a string of the new status of the system.
Plymouth.SetSystemUpdateFunction();
Other Builtin Functions[edit | edit source]
There are also other builtin functions which are listed below:
CODE # returns a boolean depicting the current capslock state (true=on, false=off)
Plymouth.GetCapslockState(): returns bool
# returns the current mode that plymouth is in (normal, password, question, ...)
Plymouth.GetMode(): returns string;
# sets the amount of times the refresh function is called per second.
Plymouth.SetRefreshRate(number): returns null;
In addition to this, there are also some mathematics functions under a different namespace:
CODE # Returns absolute (positive) of a number.
Math.Abs(number);
# Returns the smallest number from two numbers.
Math.Min(number1, number2);
# Returns the largest number from two numbers.
Math.Max(number1, number2);
# Forces the value to be between min and max, otherwise either min or max are returned.
Math.Clamp(value, min, max);
# The value of Pi (3.14159...) to 21 d.p.
Math.Pi();
# Cosine function
Math.Cos(radians);
# Sine function
Math.Sin(radians);
# Tangent function
Math.Tan(radians);
# Arc tangent function taking 2 values (see "man atan2")
Math.ATan2(x, y);
# Square root of a number
Math.Sqrt(number);
# Returns the rounded down integer.
Math.Int(number);
# Returns a pseudo random number between 0 and 1.
Math.Random();
Strings, images and sprites that each have their own associated functions:
CODE # Create a string object
string_example = String("some string"); # or alternatively just "some string".
# Associated methods for strings:
# Returns the character at the given index
string_example.CharAt(number);
# Returns a substring starting at index `start` and ending at index `end`.
string_example.SubString(start, end);
# Returns the length of the string
string_example.Length();
# Creates an image object from the image at the given location.
image_example = Image(filename);
# Creates an image from text. All parameters apart from text are optional.
Image.Text = fun (text, red, green, blue, alpha, font, align)
# Associated methods for images:
# Rotates the image by the given angle
image_example.Rotate(angle);
# Crops the given image starting at x, y and ending at x+width, y+height.
image_example.Crop(x, y, width, height);
# Scales the given image to a given width and height.
image_example.Scale(width, height);
# Tiles the given image to a given width and height.
image_example.Tile(width, height);
# Creates a sprite, image is *optional*, if not provided then a sprite with no image is made, you can change the image later.
sprite_example = Sprite(image);
# Sprites also have methods associated with them:
# This sets the X coordinate of the sprite to number
sprite_example.SetX(number);
# This sets the Y coordinate of the sprite to number
sprite_example.SetY(number);
# This sets the Z coordinate of the sprite to number
sprite_example.SetZ(number);
# You can also get and set the sprite opacity:
sprite_example.SetOpacity(number);
sprite_example.GetOpacity();
# You can also get the width and height of the sprite:
sprite_example.GetWidth();
sprite_example.GetHeight();
# Finally you can also get and set the image of the sprite
sprite_example.SetImage(image);
sprite_example.GetImage();
# These can also all be set together using (WARNING: this is deprecated).
SetPosition(sprite_example, x,y,z)
You can also get and set attributes for the window
CODE # Get the display width and height
Window.GetWidth();
Window.GetHeight();
# Get and set the position of the background window sprite
Window.GetX(number);
Window.GetY(number);
Window.SetX(number);
Window.SetY(number);
# And you can also change the background sprite color:
Window.SetBackgroundTopColor(r, g, b);
Window.SetBackgroundBottomColor(r, g, b);
Creating animations[edit | edit source]
One common way to create animations is to load all images for the animation and store them within a hashmap, then on each refresh we change the image that a sprite is displaying onto the next frame (and then loop to the start when the end of the animation is reached).
CODE animation_first_frame = 0;
animation_last_frame = 250;
animation_current_frame = 0;
for (frame = animation_first_frame; frame <= animation_last_frame; frame++) {
animation_images[frame] = Image("animation/frame-" + frame + ".png");
}
# Create a sprite for the password box, we will assign a image later to it later.
animation_sprite = Sprite();
# Align the animation in the centre of the screen (optional)
animation_width = animation_images[animation_first_frame].GetWidth();
animation_height = animation_images[animation_first_frame].GetHeight();
animation_sprite.SetX((Window.GetWidth() / 2) - (animation_width / 2));
animation_sprite.SetY((Window.GetHeight() / 2) - (animation_height / 2));
animation_sprite.SetZ(-1);
# Now to animate we can change the image used in the sprite each frame,
fun on_refresh() {
animation_current_frame += 1;
if (animation_current_frame > animation_last_frame) {
# loop back to the start when the last frame is reached.
animation_current_frame = animation_first_frame;
}
animation_sprite.SetImage(animation_images[animation_current_frame]);
}
Plymouth.SetRefreshFunction(on_refresh);
Writing a two-step theme[edit | edit source]
This article is a stub. Please help out by expanding it - how to get started.
Writing a space-flares theme[edit | edit source]
Specimen[edit | edit source]
To define a space-flares theme, you use space-flares as the module name in the example.plymouth file.
The space-flares module has three options that can be defined:
ImageDir: An absolute path to a directory that contains images.
MonospaceFont: The font to use in text sprites (the font needs to be available in the initramfs). (optional)
ConsoleLogTextColor: The color to use for console logs (in hex: 0xffffff) (optional)
CODE example.plymouth [Plymouth-Theme]
Name=Example
Description=This will be an example plugin
ModuleName=space-flares
[space-flares]
ImageDir=/usr/share/plymouth/themes/example/
=== Customising
There are limited options for customising a solar-flares theme, you are limited to changing the following images (note: all of the images must be present):
lock.png
box.png
star.png
plant1.png (used if SHOW_PLANETS is defined in source)
plant2.png (used if SHOW_PLANETS is defined in source)
plant3.png (used if SHOW_PLANETS is defined in source)
plant4.png (used if SHOW_PLANETS is defined in source)
plant5.png (used if SHOW_PLANETS is defined in source)
progress_bar.png (used if SHOW_PROGRESS_BAR is defined in source)
The amount of images actually displayed depends on how plymouth is compiled[1], however it defaults to showing a progress bar, with no planets, no comets, and, no logo halo.
You can also change more options by editing the source code at /src/plugins/splash/space-flares/plugin.c where you can define fps, blur, flare count, flare lines, and star Hz.
Activating a theme[edit | edit source]
To set a theme you may refer to: https://wiki.gentoo.org/wiki/Plymouth#Themes
Troubleshooting[edit | edit source]
To temporarily disable plymouth , you can add the following kernel parameters:
CODE plymouth.enable=0 disablehooks=plymouth
To write debug output into /var/log/plymouth-debug.log, you can add the following kernel parameter:
CODE plymouth.debug
If themes are not loading properly it may be a good idea to check the user's initramfs to ensure that it has been populated with the plymouth binaries and themes[2]
See also[edit | edit source]
Plymouth — a bootsplash used to show splash screens during system boot and shutdown.
External resources[edit | edit source]
script module source code
Freedesktop Plymouth Script Wiki
Large theme repository
Arch wiki on plymouth
Redhat guide for plymouth theme creation –
References[edit | edit source]
↑ https://gitlab.freedesktop.org/plymouth/plymouth/-/blob/main/src/plugins/splash/space-flares/plugin.c#L69
↑ https://wiki.gentoo.org/wiki/Plymouth#Manual_initramfs_creation' |