This is a brief introduction to the Plymouth scripting language. The language has many points in common with Javascript and C, so if you know those languages, little should be of surprise. # Basics There are three types of supported comments: [[!format txt """ # script style line comments // C++ style line comments /* and C style block comments /* which may be nested */ */ """]] There are some basic objects: numbers, strings, hashes, functions and null. Simple expression operations such as must be terminated with a semicolon, e.g. [[!format txt """ a = b; """]] Multiple operations can be grouped using curly “{ }” brackets, e.g. [[!format txt """ { a = b; c = a + 8; } """]] Numbers can be operated with +, -, *, / and %. Amend assignments (+=, /= etc.) are allowed, as are pre/post inc/decrement, e.g. [[!format txt """ a *= ++b; """]] Strings can be appended using + (even to numbers), e.g. [[!format txt """ a = “A” + 7 + “B”; # gives a string “A7B” """]] Applying operations on incomparable operands gives a NULL, e.g. [[!format txt """ a = “eight” / 2; # gives a NULL """]] Comparisons return a number 1, for true, or 0, for false, e.g. [[!format txt """ a = (7 >= 6); # sets a to 1 b = ("Cat" == "Dog"); # sets b to 0 """]] Conditional execution operations, “if/else”, “while” and “for” are supported, e.g. [[!format txt """ if (a > 0) { a--; b = 0; } else a = 0 """]] Conditions evaluate NULL, 0 and “” (empty string) to false, everything else is true, e.g. [[!format txt """ while (a--) b *= a; """]] Or operations are lazily evaluated and return the first value that evaluates to true (And returns the first false value), e.g. [[!format txt """ value = cached || (cached = do_lookup (index)); # if cached is already set then it is used, otherwise a lookup is executed if (value > 0 && value < 10) valid == 1; """]] Hashes can be created by simply accessing their contents using a dot or [] brackets, e.g. [[!format txt """ a.size = 1; b = a[“size”]; # b equals 1 """]] All hash indexing is done using strings even when using a number, e.g. [[!format txt """ a[1] = 1; a[“1”] = 2; # a[1] now equals 2 """]] An auto incrementing hash can be constructed by defining a set between [] brackets, wth the indexing starting at zero, e.g. [[!format txt """ a = [1, "c", [3, 2]]; # a[0] equals 1, a[1] equals "C", a[2][0] equals 3, a[2][1] equals 2 """]] To define a function use the “fun” keyword, e.g. [[!format txt """ fun functionname (index, par1, par2) { if (index == 1) return par1; else return par2; } """]] Functions have local variables but if a global one exists, that is used instead. You can force the use of a local even though a global already exists (and vice versa) by using the "local" and "global" hashes, e.g. [[!format txt """ val = 1; #global val = 1 fun functionname () { val = 2; #global val = 2 (global exists, so is used) local.val = 3; #local val = 3 (explicitly uses the local) val = 4; #local val = 4 (local exists, so is used) mval = 5; #local mval = 5 (neither global nor local exist, so a local is created) } """]] # Plymouth Interaction There are two basic Plymouth objects: Image and Sprite. ## Plymouth Images To create a new image you need to supply the filename of the image within the theme image directory to Image, e.g. [[!format txt """ box_image = Image ("box.png"); logo_image = Image ("special://logo"); # "special://logo" is a special keyword which finds the logo image """]] You can also create images from text. These are useful to show text messages, e.g. [[!format txt """ warning_image = Image.Text ("System running FSCK. This may take some time"); """]] The default is white text color, but you can supply additional parameters of: red, green, blue, alpha, fontname and alignment. Default font is "Sans 12" and default alignment is "left". Alignement is only useful for multi-line text, and its possible values are "left", "center", or "right". [[!format txt """ warning_image = Image.Text ("I feel faded", 0.8, 0.8, 0.8, 0.8, "Fixed"); """]] The width and height of an image can be attained using GetWidth and GetHeight, e.g. [[!format txt """ logo_area = logo_image.GetWidth() * logo_image.GetHeight(); """]] An image can be rotated or scaled using Rotate and Scale, e.g. [[!format txt """ upside_down_logo_image = logo_image.Rotate (3.1415); # the second paramiter is the angle in radians fat_logo_image = logo_image.Scale (logo_image.GetWidth() * 2 , logo_image.GetHeight ()) # make the image twice the width """]] ## Plymouth Sprites To place an image on the screen, we use sprites. To create a new sprite call Sprite, then set the image using SetImage, e.g. [[!format txt """ my_sprite = Sprite (); my_sprite.SetImage (fat_logo_image); """]] You can also set the image while creating the sprite by supplying it to the constructor e.g. [[!format txt """ my_sprite = Sprite (fat_logo_image); """]] The default placement of a new sprite is at the top left corner of the screen (at 0,0). To change the position call SetX and SetY, e.g. [[!format txt """ my_sprite.SetX (100); my_sprite.SetY (200); """]] If there are multiple sprites it us useful to decide which sprite should be shown above other. This is controlled using the Z component, the sprite with higher the Z is drawn on top. [[!format txt """ background_sprite.SetZ (-10); foreground_sprite.SetZ (10); """]] To set X, Y and Z in one call you can use SetPosition [[!format txt """ logo_sprite.Setposition(100, 100, 0); # place at X=100, Y=100, Z=0 """]] SetOpacity can make sprites transparent (the default opacity is solid 1) or even invisible when set to 0 , e.g. [[!format txt """ faded_sprite.SetOpacity (0.5); invisible_sprite.SetOpacity (0); """]] It is also possible to get the X/Y/Z/Opcaity/Image properties of a sprite. [[!format txt """ sprite.SetOpacity(sprite.GetOpacity()/2); sprite.SetPosition(sprite.GetX()+1, sprite.Gety()+1, sprite.GetZ()); sprite.SetImage(sprite.GetImage().Rotate(0.1)); """]] Knowing the size of the window can be useful to position sprites. This can be reached using Window.GetWidth and Window.GetHeight, e.g. [[!format txt """ centred_sprite.SetX (Window.GetWidth () / 2 - centred_sprite.GetImage().GetWidth() / 2); centred_sprite.SetY (Window.GetHeight () / 2 - centred_sprite.GetImage().GetHeight() / 2); """]] If the sprites do not fully cover the whole window, some of the sprite background will be exposed. To set the background colours use Window.SetBackground{Top,Bottom}Color. These take Red, Green and Blue values between 0 and 1, e.g. [[!format txt """ Window.SetBackgroundTopColor (0, 0, 1); # Nice blue on top of the screen fading to Window.SetBackgroundBottomColor (0.8, 0.2, 0.1); # an equally nice brown on the bottom """]] ## Plymouth Callbacks Calling Plymouth.SetRefreshFunction with a function will set that function to be called up to 50 times every second, e.g. [[!format txt """ fun refresh_callback () { time++; } Plymouth.SetRefreshFunction (refresh_callback); """]] Other callbacks which can be hooked onto are: * Plymouth.SetBootProgressFunction: the callback function is called with two numbers, time spent booting so far and the progress (between 0 and 1) * Plymouth.SetRootMountedFunction: the callback function is called when a new root is mounted * Plymouth.SetKeyboardInputFunction: the callback function is called with a string containing a new character entered on the keyboard * Plymouth.SetUpdateStatusFunction: the callback function is called with the new boot status string * Plymouth.SetDisplayPasswordFunction: the callback function is called when the display should display a password dialogue. First arg is prompt string, the second is the number of bullets. * Plymouth.SetDisplayQuestionFunction: the callback function is called when the display should display a question dialogue. First arg is prompt string, the second is the entry contents. * Plymouth.SetDisplayNormalFunction: the callback function is called when the display should return to normal * Plymouth.SetMessageFunction: the callback function is called when new message should be displayed. First arg is message to display. e.g. [[!format txt """ fun progress_callback (time, progress) { progress_status = "We have waited " + time + "seconds and we are "+ (progress * 100) + "% though"; ... } Plymouth.SetBootProgressFunction (progress_callback); """]] To determine the mode of operation plymouth was started in use Plymouth.GetMode which returns a string of one of: "boot", "shutdown", "suspend", "resume" or unknown. [[!format txt """ if (Plymouth.GetMode () == "suspend") { ShowSuspendBackground(); } """]] ## Mathematics Functions There are some basic mathematics functions to * Math.Abs: Absolute (positive) of a number * Math.Min: The smaller of two numbers * Math.Max: The greater of two numbers * Math.Clamp: Takes 3 numbers, value, min and max. Function forces the value to be between min and max, otherwise either min or max are returned. * Math.Pi: The value of Pi (3.14159...) * Math.Cos: Cosine function * Math.Sin: Sine function * Math.Tan: Tangent function * Math.ATan2: Arc tangent function taking 2 values (see "man atan2") * Math.Sqrt: Square root * Math.Int: Returns the rounded down integer. * Math.Random: Returns a pseudo random number between 0 and 1.