Come ottenere Plymouth per visualizzare i messaggi di avvio all'avvio?

19

Mi piacerebbe sapere come creare uno splash per Ubuntu Maverick con i messaggi di avvio che vengono visualizzati all'avvio così come una barra di avanzamento e un logo rotante.

Oppure, se possibile, come modificare uno splash che ha già un logo rotante e una barra di avanzamento e aggiungere messaggi di avvio ad esso.

Questo è il tema che vorrei modificare:

e vorrei qualcosa del genere:

o questo, che è esattamente lo splash che voglio creare:

Sono stato in grado di trovare questo sito Web che ha molte informazioni utili ma ho difficoltà a comprenderne un po '. non hai fatto nessuno script prima!

Crea il tuo splash schermata con i messaggi di avvio a scorrimento

Plymouth Scripting

e questo è un altro sito web che può aiutare con lo scripting

questo è lo script per la barra di avanzamento in splash:

    #----------------------------------------- Progress Bar --------------------------------

    progress_box.image = Image("progress_box.png");
    progress_box.sprite = Sprite(progress_box.image);

    progress_box.x = Window.GetX() + Window.GetWidth() / 2 - progress_box.image.GetWidth() / 2;
    progress_box.y = Window.GetY() + Window.GetHeight() * 0.65 - progress_box.image.GetHeight() / 2;
    progress_box.sprite.SetPosition(progress_box.x, progress_box.y, 0);

    progress_bar.original_image = Image("progress_bar.png");
    progress_bar.sprite = Sprite();

    progress_bar.x = Window.GetX() + Window.GetWidth()  / 2 -        progress_bar.original_image.GetWidth() / 2;
    progress_bar.y = Window.GetY() + Window.GetHeight() * 0.65  - progress_box.image.GetHeight() / 2 + (progress_box.image.GetHeight() - progress_bar.original_image.GetHeight()) / 2;
    progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 1);

    fun progress_callback (duration, progress)
      {
        if (progress_bar.image.GetWidth () != Math.Int (progress_bar.original_image.GetWidth () * progress))
          {
# add the * 3 to multiply the speed of the progress bar by 3
            progress_bar.image = progress_bar.original_image.Scale(progress_bar.original_image.GetWidth(progress_bar.original_image) * progress * 3, progress_bar.original_image.GetHeight());
            progress_bar.sprite.SetImage (progress_bar.image);
          }
      }

    Plymouth.SetBootProgressFunction(progress_callback);

OK, ho fatto molte più ricerche e sono stato in grado di imparare un po 'di più su Plymouth.

questi sono i siti che ho trovato utili. Guida tematica di Plymouth  Ci sono quattro parti dell'articolo che devi leggere attraverso di esse per ottenere il succo di ciò che stiamo facendo. (Stavo confrontando la sceneggiatura con la sceneggiatura del mio splash per capire di cosa si tratta, consiglio di farlo se qualcuno dovesse seguire le mie orme.)   Plymouth scripting Ok questo link ha 2 pagine dovevano passare attraverso di loro per capire cosa fare. Si è scoperto che stavano cercando la stessa cosa che ero, ovvero indirizzare i messaggi di avvio sullo splash di Plymouth dove ho già un logo rotante, sfondo, barra di avanzamento.

Così ho dovuto modificare il mio file /lib/lsb/init-functions e farlo in modo che inviasse il messaggio di errore di avvio / successo, ecc. a Plymouth aggiungendo questo paragrafo

# SEND MESSAGES TO PLYMOUTH
if [ -x /bin/plymouth ] && pidof plymouthd >/dev/null
then
    plymouth_send() {
        [ "" = '-n' ] && { # add a flag '>' for lines that will be extended
            shift
            /bin/plymouth message --text=">$*" || true
            return
        }
        [ "" = '-w' ] && { # add "warning" formatting
            shift
            /bin/plymouth update --status="warning" || true
            /bin/plymouth message --text="$*" || true
            /bin/plymouth update --status="normal" || true
            return
        }
        [ "" = '-f' ] && { # add "failed" formatting
            shift
            /bin/plymouth update --status="failed" || true
            /bin/plymouth message --text="$*" || true
            /bin/plymouth update --status="normal" || true
            return
        }
        /bin/plymouth message --text="$*" || true
    }
else
    plymouth_send() { :; }
fi

# int log_begin_message (char *message)
log_begin_msg () {
    if [ -z "${1:-}" ]; then
        return 1
    fi
    echo -n "[email protected]"
}

Oltre ad aggiungere

   # Only do the fancy stuff if we have an appropriate terminal
    # and if /usr is already mounted
    if log_use_fancy_output; then
        RED='$TPUT setaf 1'
        YELLOW='$TPUT setaf 3'
        NORMAL='$TPUT op'
    else
        RED=''
        YELLOW=''
        NORMAL=''
    fi

    if [  -eq 0 ]; then
        echo "."
        plymouth_send "."
    elif [  -eq 255 ]; then
        /bin/echo -e " ${YELLOW}(warning).${NORMAL}"
        plymouth_send -w " (warning)."
    else
        /bin/echo -e " ${RED}failed!${NORMAL}"
        plymouth_send -f " failed!"
    fi
    log_end_msg_post "[email protected]"
    return $retval
}

log_action_msg () {
    echo "[email protected]"
    plymouth_send "[email protected]"
}

log_action_begin_msg () {
    echo -n "[email protected]"
    plymouth_send -n "[email protected]"
}

log_action_cont_msg () {
    echo -n "[email protected]"
    plymouth_send -n "[email protected]"
}

log_action_end_msg () {
    log_action_end_msg_pre "[email protected]"
    if [ -z "${2:-}" ]; then
        end="."
    else
        end=" ()."
    fi

    if [  -eq 0 ]; then
        echo "done${end}"
        plymouth_send "done${end}"
    else
        if log_use_fancy_output; then
            RED='$TPUT setaf 1'
            NORMAL='$TPUT op'
            /bin/echo -e "${RED}failed${end}${NORMAL}"
        else
            echo "failed${end}"
            plymouth_send -f "failed${end}"
        fi
    fi
    log_action_end_msg_post "[email protected]"
}

Finora non sono stato in grado di trasmettere i messaggi a Plymouth, ma ho avuto una migliore comprensione di come funziona lo script di Plymouth!

Non so che altro dovrei fare per farlo funzionare! sperando che qualcuno qui mi possa aiutare

Ohh ed ecco la mia versione dello script per Splash su cui sto lavorando.

# INT2MIL-Ubuntu-10.10-Eng splashy like theme

Window.GetMaxWidth = fun (){
  i = 0;
  width = 0;
  while (Window.GetWidth(i)){
    width = Math.Max(width, Window.GetWidth(i));
    i++;
    }
  return width;
};

Window.GetMaxHeight = fun (){
  i = 0;
  height = 0;
  while (Window.GetHeight(i)){
    height = Math.Max(height, Window.GetHeight(i));
    i++;
    }
  return height;
};

anim.imagecount = 100;
anim.target_width =  0.2* 0.46 * Window.GetWidth();
anim.target_height =  0.2* 0.46 * Window.GetWidth();

fun RotatedImage (index){
    index = Math.Int(index);
    if (!RotatedImageCache[index])
        RotatedImageCache[index] = anim.original_image.Rotate((Math.Pi*2*index)/anim.imagecount).Scale(anim.target_width, anim.target_height);

    return RotatedImageCache[index];
    }


if (Plymouth.GetMode() == "suspend" || Plymouth.GetMode() == "resume") {
  background.original_image = ImageNew("suspend.png");
  Window.SetBackgroundTopColor(1, 0, 0);
  Window.SetBackgroundBottomColor(0, 1, 0);
}
else {
  logo.original_image = ImageNew("logo.png");
  background.original_image = ImageNew("background.png");
  Window.SetBackgroundTopColor(0.234, 0.43, 0.705);
  Window.SetBackgroundBottomColor(0.16, 0.25, 0.44);

  anim.image= ImageNew("animation.png");
  anim.original_image= anim.image.Scale(anim.target_width, anim.target_width);

  anim.sprite = SpriteNew();
  anim.sprite.SetImage(RotatedImage (0));
  anim.sprite.SetX((Window.GetX() + Window.GetWidth() - RotatedImage(0).GetWidth()) / 2);
  anim.sprite.SetY(Window.GetY() + Window.GetHeight() * 0.37);
  anim.angle = 0;
  anim.index = 0;


}
#change reduction size to make logo bigger
ratio =  logo.original_image.GetWidth() / logo.original_image.GetHeight();
reduction = 0.4;
logo.image = logo.original_image.Scale(reduction * Window.GetMaxWidth() , reduction / ratio *  Window.GetMaxWidth());
logo.sprite = SpriteNew();
logo.sprite.SetImage(logo.image);
logo.opacity_angle = 0;
#change logo location
logo.sprite.SetX((Window.GetX() + Window.GetMaxWidth()  - logo.image.GetWidth())  / 2);
logo.sprite.SetY(Window.GetY() + Window.GetHeight() * 0.37);
#background image attributs x,z,y
background.image = background.original_image.Scale(Window.GetMaxWidth() , Window.GetMaxHeight());
background.sprite = SpriteNew();
background.sprite.SetImage(background.image);
background.sprite.SetPosition(Window.GetX(), Window.GetY(), -10);

sprite_prompt = SpriteNew();

fun refresh_callback ()
  {
    if (status == "normal")
      {
#anim.index=speed of rotation
    anim.index += 1;
    anim.index %= anim.imagecount;
    anim.sprite.SetImage(RotatedImage (anim.index));
        #anim.sprite.SetOpacity (1);
    motif.sprite.SetOpacity(motif.opacity);
      }
    else
      {
        anim.sprite.SetOpacity(0);
    motif.sprite.SetOpacity(0);
      }

  }

if (Plymouth.GetMode() != "suspend" && Plymouth.GetMode() != "resume") {
  Plymouth.SetRefreshFunction (refresh_callback);
}

#----------------------------------------- Dialog --------------------------------

status = "normal";

fun dialog_setup()
  {
    local.box;
    local.lock;
    local.entry;
    local.prompt_sprite;

    box.image = ImageNew("box.png");
    lock.image = ImageNew("lock.png");
    entry.image = ImageNew("entry.png");

    box.sprite = SpriteNew();
    box.sprite.SetImage(box.image);
    box.x = Window.GetX() + Window.GetWidth()  / 2 - box.image.GetWidth()/2;
    box.y = Window.GetY() + Window.GetHeight() / 2 - box.image.GetHeight()/2;
    box.z = 10000;
    box.sprite.SetPosition(box.x, box.y, box.z);

    lock.sprite = SpriteNew();
    lock.sprite.SetImage(lock.image);
    lock.x = box.x + box.image.GetWidth()/2 - (lock.image.GetWidth() + entry.image.GetWidth()) / 2;
    lock.y = box.y + box.image.GetHeight()/2 - lock.image.GetHeight()/2;
    lock.z = box.z + 1;
    lock.sprite.SetPosition(lock.x, lock.y, lock.z);

    entry.sprite = SpriteNew();
    entry.sprite.SetImage(entry.image);
    entry.x = lock.x + lock.image.GetWidth();
    entry.y = box.y + box.image.GetHeight()/2 - entry.image.GetHeight()/2;
    entry.z = box.z + 1;
    entry.sprite.SetPosition(entry.x, entry.y, entry.z);

    prompt_sprite = SpriteNew();
    prompt_sprite.SetPosition(box.x, box.y - 20, box.z);

    global.dialog.box = box;
    global.dialog.lock = lock;
    global.dialog.entry = entry;
    global.dialog.bullet_image = ImageNew("bullet.png");
    global.dialog.prompt_sprite = prompt_sprite;
    dialog_opacity (1);
  }

fun dialog_opacity(opacity)
  {
    dialog.box.sprite.SetOpacity(opacity);
    dialog.lock.sprite.SetOpacity(opacity);
    dialog.entry.sprite.SetOpacity(opacity);
    dialog.prompt_sprite.SetOpacity(opacity);
    for (index = 0; dialog.bullet[index]; index++)
      {
        dialog.bullet[index].sprite.SetOpacity(opacity);
      }
  }

fun display_normal_callback ()
  {
    global.status = "normal";
    if (global.dialog)
      dialog_opacity (0);
  }

fun display_password_callback (prompt, bullets)
  {
    global.status = "password";
    if (!global.dialog) 
    dialog_setup();
    else 
    dialog_opacity(1);
    motif.sprite.SetOpacity(0);
    anim.sprite.SetOpacity(0);

    dialog.prompt_sprite.SetImage(Image.Text(prompt, 1.0, 1.0, 1.0));
    for (index = 0; dialog.bullet[index] || index < bullets; index++)
      { 

        if (!dialog.bullet[index])
          {
            dialog.bullet[index].sprite = SpriteNew();
            dialog.bullet[index].sprite.SetImage(dialog.bullet_image);
            dialog.bullet[index].x = dialog.entry.x + index * dialog.bullet_image.GetWidth();
            dialog.bullet[index].y = dialog.entry.y + dialog.entry.image.GetHeight() / 2 - dialog.bullet_image.GetHeight() / 2;
            dialog.bullet[index].z = dialog.entry.z + 1;
            dialog.bullet[index].sprite.SetPosition(dialog.bullet[index].x, dialog.bullet[index].y, dialog.bullet[index].z);
          }
        if (index < bullets)
          dialog.bullet[index].sprite.SetOpacity(1);
        else
          dialog.bullet[index].sprite.SetOpacity(0);
      }
  }

fun display_message_callback (prompt)
  {

prompt = Image.Text(prompt,1.0, 1.0, 1.0);
sprite_prompt.SetImage(prompt);
sprite_prompt.SetPosition(Window.GetX() + (Window.GetWidth() - prompt.GetWidth()) / 2, Window.GetY() + Window.GetHeight() * 0.93, 2);
  }

/* instantiate dialog at startup, to ensure all icons are loaded in memory before initrd is unmounted, in case /usr isn't mounted yet */
dialog_setup(); dialog_opacity(0);
Plymouth.SetDisplayNormalFunction(display_normal_callback);
Plymouth.SetDisplayPasswordFunction(display_password_callback);
Plymouth.SetMessageFunction(display_message_callback);

#----------------------------------------- Progress Bar --------------------------------

progress_box.image = Image("progress_box.png");
progress_box.sprite = Sprite(progress_box.image);

progress_box.x = Window.GetX() + Window.GetWidth() / 2 - progress_box.image.GetWidth() / 2;
progress_box.y = Window.GetY() + Window.GetHeight() * 0.65 - progress_box.image.GetHeight() / 2;
progress_box.sprite.SetPosition(progress_box.x, progress_box.y, 0);

progress_bar.original_image = Image("progress_bar.png");
progress_bar.sprite = Sprite();

progress_bar.x = Window.GetX() + Window.GetWidth()  / 2 -        progress_bar.original_image.GetWidth() / 2;
progress_bar.y = Window.GetY() + Window.GetHeight() * 0.65  - progress_box.image.GetHeight() / 2 + (progress_box.image.GetHeight() - progress_bar.original_image.GetHeight()) / 2;
progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 1);

fun progress_callback (duration, progress)
  {
    if (progress_bar.image.GetWidth () != Math.Int (progress_bar.original_image.GetWidth () * progress))
      {
        progress_bar.image = progress_bar.original_image.Scale(progress_bar.original_image.GetWidth(progress_bar.original_image) * progress * 3, progress_bar.original_image.GetHeight());
        progress_bar.sprite.SetImage (progress_bar.image);
      }
  }

Plymouth.SetBootProgressFunction(progress_callback);

#----------------------------------------- Status Update --------------------------------

NUM_SCROLL_LINES = 5;
LINE_WIDTH = 55;
# width of one character
CHAR_WIDTH = 7;
# height of one character
CHAR_HEIGHT = 10;

msg_color = [0.5,0.5,0.5]; # msg_color is array

fun update_status_callback(sta) {
  if (sta == "failed") msg_color = [1,0,0];
  if (sta == "warning") msg_color = [0.8,0.8,0];
  if (sta == "normal") msg_color = [0.5,0.5,0.5];
}

fun StringLength(string) {
  index = 0;
  str = String(string);
  while(str.CharAt(index)) index++;
  return index;
}

// Initialising text images and their positions
// 20 is the height (including line spacing) of each line
for (i=0; i < NUM_SCROLL_LINES; i++) {
  lines[i]= Image.Text("",0,0,0);
  message_sprite[i] = Sprite();
  message_sprite[i].SetX (Window.GetX() + (screen_width / 2 ) - (LINE_WIDTH * CHAR_WIDTH / 2));
  message_sprite[i].SetY (Window.GetY() + (screen_height / 2) + (logo_height /2) +(logo_height * 1.2)+ (i * CHAR_HEIGHT * 2) );
  message_sprite[i].SetZ (10000);
}

pretext = String("");

fun scroll_message_callback(text) {

 nobreak = 0;
   if (text.CharAt(0) == ">") {    # "no linebreak" flag, like "-n"
       text = text.SubString(1, StringLength(text)); # remove ">" at front
       nobreak = 1;
   }

   if (pretext == "") {

       if (nobreak == 1) pretext = text;

   // Truncate the message if too long
   if (StringLength(text) > LINE_WIDTH) {
     text = text.SubString(0, LINE_WIDTH - 3);
     text += "...";
   }

   // Shift messages one up
   for (i = 0; i < NUM_SCROLL_LINES - 1; i++) {
     lines[i] = lines[i+1];
   }
 else {    # the previous message was flagged to have no linebreak

          // Truncate the message if too long
       if (StringLength(text) > LINE_WIDTH - 5) { # leave min. 5 for pretext
         text = text.SubString(0, LINE_WIDTH - 8);
         text += "...";
       }

          # Truncate the previous message if too long
       if (StringLength(pretext) > (LINE_WIDTH - StringLength(text))) {
         pretext = pretext.SubString(0, LINE_WIDTH - StringLength(text) - 3);
         pretext += "...";
       }

       text = pretext + text;

       if (nobreak == 1) pretext = text;
       else pretext = "";

   }

   // Create the image for the latest message
#  original script had "lines[i]"   
   lines[i] = Image.Text( text, 0.5, 0.5, 0.5);

   // Re-allocate the text images to sprites
   for (i = 0; i < NUM_SCROLL_LINES; i++) {
     message_sprite[i].SetImage(lines[i]);
   }
}

Plymouth.SetUpdateStatusFunction(scroll_message_callback);

# messages get added to updates
Plymouth.SetMessageFunction(scroll_message_callback);

#----------------------------------------- Quit --------------------------------

fun quit_callback ()
{
 anim.sprite.SetOpacity (0);
  if (Plymouth.GetMode() == "shutdown") {
   motif.sprite.SetOpacity(0);
  }
}

Plymouth.SetQuitFunction(quit_callback);
  

OK, così ho fornito quasi tutte le informazioni necessarie, se qualcuno ha familiarità con questo fammi sapere cosa mi manca per far passare i messaggi di avvio a Plymouth. Grazie

    
posta Vitaly 27.06.2011 - 14:20

2 risposte

4

OK, ho lavorato a questo problema per 4 giorni consecutivi e l'ho quasi completamente risolto. Finora sono riuscito ad avviare Plymouth con i messaggi visualizzati, ma sfortunatamente i messaggi sono troncati. In questo momento sto provando a modificare gli script ma non so dove sia il problema nello script / lib / lsb / init-functions o in /lib/plymouth/themes/"theme-name"/mdv.script.

Ecco il mio lavoro fino ad ora.

per prima cosa devi fare in modo che init-functions invii messaggi a Plymouth facendolo apparire così (controlla ogni riga per vedere le differenze e copia la riga che corrisponde all'invio di Plymouth):

# /lib/lsb/init-functions for Debian -*- shell-script -*-
#
#Copyright (c) 2002-08 Chris Lawrence
#All rights reserved.
#
#Redistribution and use in source and binary forms, with or without
#modification, are permitted provided that the following conditions
#are met:
#1. Redistributions of source code must retain the above copyright
#   notice, this list of conditions and the following disclaimer.
#2. Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in the
#   documentation and/or other materials provided with the distribution.
#3. Neither the name of the author nor the names of other contributors
#   may be used to endorse or promote products derived from this software
#   without specific prior written permission.
#
#THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
#IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
#LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
#SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
#BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
#OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
#EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

start_daemon () {
    local force nice pidfile exec i args
    force=0
    nice=0
    pidfile=/dev/null

    OPTIND=1
    while getopts fn:p: opt ; do
        case "$opt" in
            f)  force=1;;
            n)  nice="$OPTARG";;
            p)  pidfile="$OPTARG";;
        esac
    done

    shift $(($OPTIND - 1))
    if [ "" = '--' ]; then
        shift
    fi

    exec=""; shift

    args="--start --nicelevel $nice --quiet --oknodo"
    if [ $force = 1 ]; then
        /sbin/start-stop-daemon $args --chdir "$PWD" --startas $exec --pidfile /dev/null -- "[email protected]"
    elif [ $pidfile ]; then
        /sbin/start-stop-daemon $args --chdir "$PWD" --exec $exec --oknodo --pidfile "$pidfile" -- "[email protected]"
    else
        /sbin/start-stop-daemon $args --chdir "$PWD" --exec $exec -- "[email protected]"
    fi
}

pidofproc () {
    local pidfile line i pids= status specified pid
    pidfile=
    specified=

    OPTIND=1
    while getopts p: opt ; do
        case "$opt" in
            p)  pidfile="$OPTARG"; specified=1;;
        esac
    done
    shift $(($OPTIND - 1))

    base=${1##*/}
    if [ ! "$specified" ]; then
        pidfile="/var/run/$base.pid"
    fi

    if [ -n "${pidfile:-}" -a -r "$pidfile" ]; then
        read pid < "$pidfile"
        if [ -n "${pid:-}" ]; then
            if $(kill -0 "${pid:-}" 2> /dev/null); then
                echo "$pid"
                return 0
            elif ps "${pid:-}" >/dev/null 2>&1; then
                echo "$pid"
                return 0 # program is running, but not owned by this user
            else
                return 1 # program is dead and /var/run pid file exists
            fi
        fi
    fi
    if [ -x /bin/pidof -a ! "$specified" ]; then
        status="0"
        /bin/pidof -o %PPID -x  || status="$?"
        if [ "$status" = 1 ]; then
            return 3 # program is not running
        fi
        return 0
    fi
    return 4 # Unable to determine status
}

# start-stop-daemon uses the same algorithm as "pidofproc" above.
killproc () {
    local pidfile sig status base i name_param is_term_sig
    pidfile=
    name_param=
    is_term_sig=no

    OPTIND=1
    while getopts p: opt ; do
        case "$opt" in
            p)  pidfile="$OPTARG";;
        esac
    done
    shift $(($OPTIND - 1))

    base=${1##*/}
    if [ ! $pidfile ]; then
        name_param="--name $base --pidfile /var/run/$base.pid"
    else
        name_param="--pidfile $pidfile"
    fi

    sig=$(echo ${2:-} | sed -e 's/^-\(.*\)//')
    sig=$(echo $sig | sed -e 's/^SIG\(.*\)//')
    if [ -z "$sig" -o "$sig" = 15 -o "$sig" = TERM ]; then
        is_term_sig=yes
    fi
    status=0
    if [ ! "$is_term_sig" = yes ]; then
        if [ -n "$sig" ]; then
            /sbin/start-stop-daemon --stop --signal "$sig" --quiet $name_param || status="$?"
        else
            /sbin/start-stop-daemon --stop --quiet $name_param || status="$?"
        fi
    else
        /sbin/start-stop-daemon --stop --quiet --oknodo $name_param || status="$?"
    fi
    if [ "$status" = 1 ]; then
        if [ -n "$sig" ]; then
            return 0
        fi
        return 3 # program is not running
    fi

    if [ "$status" = 0 -a "$is_term_sig" = yes -a "$pidfile" ]; then
        pidofproc -p "$pidfile" "" >/dev/null || rm -f "$pidfile"
    fi
    return 0
}

# Return LSB status
status_of_proc () {
    local pidfile daemon name status

    pidfile=
    OPTIND=1
    while getopts p: opt ; do
        case "$opt" in
            p)  pidfile="$OPTARG";;
        esac
    done
    shift $(($OPTIND - 1))

    if [ -n "$pidfile" ]; then
        pidfile="-p $pidfile"
    fi
    daemon=""
    name=""

    status="0"
    pidofproc $pidfile $daemon >/dev/null || status="$?"
    if [ "$status" = 0 ]; then
        log_success_msg "$name is running"
        return 0
    elif [ "$status" = 4 ]; then
        log_failure_msg "could not access PID file for $name"
        return $status
    else
        log_failure_msg "$name is not running"
        return $status
    fi
}

log_use_fancy_output () {
    TPUT=/usr/bin/tput
    EXPR=/usr/bin/expr
    if [ -t 1 ] && [ "x${TERM:-}" != "x" ] && [ "x${TERM:-}" != "xdumb" ] && [ -x $TPUT ] && [ -x $EXPR ] && $TPUT hpa 60 >/dev/null 2>&1 && $TPUT setaf 1 >/dev/null 2>&1; then
        [ -z $FANCYTTY ] && FANCYTTY=1 || true
    else
        FANCYTTY=0
    fi
    case "$FANCYTTY" in
        1|Y|yes|true)   true;;
        *)              false;;
    esac
}

log_success_msg () {
    if [ -n "${1:-}" ]; then
        log_begin_msg [email protected]
    fi
    log_end_msg 0
}

log_failure_msg () {
    if [ -n "${1:-}" ]; then
        log_begin_msg [email protected] "..."
    fi
    log_end_msg 1 || true
}

log_warning_msg () {
    if [ -n "${1:-}" ]; then
        log_begin_msg [email protected] "..."
    fi
    log_end_msg 255 || true
}

#
# NON-LSB HELPER FUNCTIONS
#
# int get_lsb_header_val (char *scriptpathname, char *key)
get_lsb_header_val () {
        if [ ! -f "" ] || [ -z "${2:-}" ]; then
                return 1
        fi
        LSB_S="### BEGIN INIT INFO"
        LSB_E="### END INIT INFO"
        sed -n "/$LSB_S/,/$LSB_E/ s/# : \(.*\)//p" 
}

# SEND MESSAGES TO PLYMOUTH
if [ -x /bin/plymouth ] && pidof plymouthd >/dev/null
then
    plymouth_send() {
        [ "" = '-n' ] && { # add a flag '>' for lines that will be extended
            shift
            /bin/plymouth message --text=">$*" || true
            return
        }
        [ "" = '-w' ] && { # add "warning" formatting
            shift
            /bin/plymouth update --status="warning" || true
            /bin/plymouth message --text="$*" || true
            /bin/plymouth update --status="normal" || true
            return
        }
        [ "" = '-f' ] && { # add "failed" formatting
            shift
            /bin/plymouth update --status="failed" || true
            /bin/plymouth message --text="$*" || true
            /bin/plymouth update --status="normal" || true
            return
        }
        /bin/plymouth message --text="$*" || true
    }
else
    plymouth_send() { :; }
fi

# int log_begin_message (char *message)
log_begin_msg () {
    if [ -z "${1:-}" ]; then
        return 1
    fi
    echo -n "[email protected]"
    plymouth_send -n "[email protected]"
}

# Sample usage:
# log_daemon_msg "Starting GNOME Login Manager" "gdm"
#
# On Debian, would output "Starting GNOME Login Manager: gdm"
# On Ubuntu, would output " * Starting GNOME Login Manager..."
#
# If the second argument is omitted, logging suitable for use with
# log_progress_msg() is used:
#
# log_daemon_msg "Starting remote filesystem services"
#
# On Debian, would output "Starting remote filesystem services:"
# On Ubuntu, would output " * Starting remote filesystem services..."

log_daemon_msg () {
    if [ -z "${1:-}" ]; then
        return 1
    fi
    log_daemon_msg_pre "[email protected]"

    if [ -z "${2:-}" ]; then
        echo -n ":"
        plymouth_send -n ":"
        return
    fi

    echo -n ": "
    plymouth_send -n ": "
    log_daemon_msg_post "[email protected]"
}

# #319739
#
# Per policy docs:
#
#     log_daemon_msg "Starting remote file system services"
#     log_progress_msg "nfsd"; start-stop-daemon --start --quiet nfsd
#     log_progress_msg "mountd"; start-stop-daemon --start --quiet mountd
#     log_progress_msg "ugidd"; start-stop-daemon --start --quiet ugidd
#     log_end_msg 0
#
# You could also do something fancy with log_end_msg here based on the
# return values of start-stop-daemon; this is left as an exercise for
# the reader...
#
# On Ubuntu, one would expect log_progress_msg to be a no-op.
log_progress_msg () {
    if [ -z "${1:-}" ]; then
        return 1
    fi
    echo -n " [email protected]"
    plymouth_send -n " [email protected]"
}


# int log_end_message (int exitstatus)
log_end_msg () {
    # If no arguments were passed, return
    if [ -z "${1:-}" ]; then
        return 1
    fi

    retval=

    log_end_msg_pre "[email protected]"

    # Only do the fancy stuff if we have an appropriate terminal
    # and if /usr is already mounted
    if log_use_fancy_output; then
        RED='$TPUT setaf 1'
        YELLOW='$TPUT setaf 3'
        NORMAL='$TPUT op'
    else
        RED=''
        YELLOW=''
        NORMAL=''
    fi

    if [  -eq 0 ]; then
        echo "."
        plymouth_send "."
    elif [  -eq 255 ]; then
        /bin/echo -e " ${YELLOW}(warning).${NORMAL}"
        plymouth_send -w "warning"
    else
        /bin/echo -e " ${RED}failed!${NORMAL}"
        plymouth_send -f "failed"
    fi
    log_end_msg_post "[email protected]"
    return $retval
}

log_action_msg () {
    echo "[email protected]"
    plymouth_send "[email protected]"
}

log_action_begin_msg () {
    echo -n "[email protected]"
    plymouth_send -n "[email protected]"
}

log_action_cont_msg () {
    echo -n "[email protected]"
    plymouth_send -n "[email protected]"
}

log_action_end_msg () {
    log_action_end_msg_pre "[email protected]"
    if [ -z "${2:-}" ]; then
        end="."
    else
        end=" ()."
    fi

    if [  -eq 0 ]; then
        echo "done${end}"
        plymouth_send "done${end}"
    else
        if log_use_fancy_output; then
            RED='$TPUT setaf 1'
            NORMAL='$TPUT op'
            /bin/echo -e "${RED}failed${end}${NORMAL}"
            plymouth_send -f "failed${end}"
        else
            echo "failed${end}"
            plymouth_send -f "failed${end}"
        fi
    fi
    log_action_end_msg_post "[email protected]"
}

# Hooks for /etc/lsb-base-logging.sh
log_daemon_msg_pre () { :; }
log_daemon_msg_post () { :; }
log_end_msg_pre () { :; }
log_end_msg_post () { :; }
log_action_end_msg_pre () { :; }
log_action_end_msg_post () { :; }

FANCYTTY=
[ -e /etc/lsb-base-logging.sh ] && . /etc/lsb-base-logging.sh || true

Ora, dopo averlo aggiunto alle funzioni di init, devi modificare il tuo tema di Plymouth mdv.script

Questa è la mia ultima versione aggiornata dello script:

# INT2MIL-Ubuntu-10.10-Eng splashy like theme

Window.GetMaxWidth = fun (){
  i = 0;
  width = 0;
  while (Window.GetWidth(i)){
    width = Math.Max(width, Window.GetWidth(i));
    i++;
    }
  return width;
};

Window.GetMaxHeight = fun (){
  i = 0;
  height = 0;
  while (Window.GetHeight(i)){
    height = Math.Max(height, Window.GetHeight(i));
    i++;
    }
  return height;
};
#change animcount to increase/decrease speed of spinning arrows
anim.imagecount = 100;
anim.target_width =  0.2* 0.46 * Window.GetWidth();
anim.target_height =  0.2* 0.46 * Window.GetWidth();

fun RotatedImage (index){
    index = Math.Int(index);
    if (!RotatedImageCache[index])
        RotatedImageCache[index] = anim.original_image.Rotate((Math.Pi*2*index)/anim.imagecount).Scale(anim.target_width, anim.target_height);

    return RotatedImageCache[index];
    }


if (Plymouth.GetMode() == "suspend" || Plymouth.GetMode() == "resume") {
  background.original_image = ImageNew("suspend.png");
  Window.SetBackgroundTopColor(1, 0, 0);
  Window.SetBackgroundBottomColor(0, 1, 0);
}
else {
  logo.original_image = ImageNew("logo.png");
  background.original_image = ImageNew("background.png");
  Window.SetBackgroundTopColor(0.234, 0.43, 0.705);
  Window.SetBackgroundBottomColor(0.16, 0.25, 0.44);

  anim.image= ImageNew("animation.png");
  anim.original_image= anim.image.Scale(anim.target_width, anim.target_width);

  anim.sprite = SpriteNew();
  anim.sprite.SetImage(RotatedImage (0));
  anim.sprite.SetX((Window.GetX() + Window.GetWidth() - RotatedImage(0).GetWidth()) / 2);
  anim.sprite.SetY(Window.GetY() + Window.GetHeight() * 0.37);
  anim.angle = 0;
  anim.index = 0;


}
#change reduction size to make logo bigger
ratio =  logo.original_image.GetWidth() / logo.original_image.GetHeight();
reduction = 0.4;
logo.image = logo.original_image.Scale(reduction * Window.GetMaxWidth() , reduction / ratio *  Window.GetMaxWidth());
logo.sprite = SpriteNew();
logo.sprite.SetImage(logo.image);
logo.opacity_angle = 0;
#change logo location
logo.sprite.SetX((Window.GetX() + Window.GetMaxWidth()  - logo.image.GetWidth())  / 2);
logo.sprite.SetY(Window.GetY() + Window.GetHeight() * 0.37);
#background image attributs x,z,y
background.image = background.original_image.Scale(Window.GetMaxWidth() , Window.GetMaxHeight());
background.sprite = SpriteNew();
background.sprite.SetImage(background.image);
background.sprite.SetPosition(Window.GetX(), Window.GetY(), -100);

sprite_prompt = SpriteNew();

fun refresh_callback ()
  {
    if (status == "normal")
      {
#anim.index=speed of rotation
    anim.index += 1;
    anim.index %= anim.imagecount;
    anim.sprite.SetImage(RotatedImage (anim.index));
        #anim.sprite.SetOpacity (1);
    motif.sprite.SetOpacity(motif.opacity);
      }
    else
      {
        anim.sprite.SetOpacity(1);
    motif.sprite.SetOpacity(1);
      }

  }

if (Plymouth.GetMode() != "suspend" && Plymouth.GetMode() != "resume") {
  Plymouth.SetRefreshFunction (refresh_callback);
}

#----------------------------------------- Dialog --------------------------------

status = "normal";

fun dialog_setup()
  {
    local.box;
    local.lock;
    local.entry;
    local.prompt_sprite;

    box.image = ImageNew("box.png");
    lock.image = ImageNew("lock.png");
    entry.image = ImageNew("entry.png");

    box.sprite = SpriteNew();
    box.sprite.SetImage(box.image);
    box.x = Window.GetX() + Window.GetWidth()  / 2 - box.image.GetWidth()/2;
    box.y = Window.GetY() + Window.GetHeight() / 2 - box.image.GetHeight()/2;
    box.z = 10000;
    box.sprite.SetPosition(box.x, box.y, box.z);

    lock.sprite = SpriteNew();
    lock.sprite.SetImage(lock.image);
    lock.x = box.x + box.image.GetWidth()/2 - (lock.image.GetWidth() + entry.image.GetWidth()) / 2;
    lock.y = box.y + box.image.GetHeight()/2 - lock.image.GetHeight()/2;
    lock.z = box.z + 1;
    lock.sprite.SetPosition(lock.x, lock.y, lock.z);

    entry.sprite = SpriteNew();
    entry.sprite.SetImage(entry.image);
    entry.x = lock.x + lock.image.GetWidth();
    entry.y = box.y + box.image.GetHeight()/2 - entry.image.GetHeight()/2;
    entry.z = box.z + 1;
    entry.sprite.SetPosition(entry.x, entry.y, entry.z);

    prompt_sprite = SpriteNew();
    prompt_sprite.SetPosition(box.x, box.y - 20, box.z);

    global.dialog.box = box;
    global.dialog.lock = lock;
    global.dialog.entry = entry;
    global.dialog.bullet_image = ImageNew("bullet.png");
    global.dialog.prompt_sprite = prompt_sprite;
    dialog_opacity (1);
  }

fun dialog_opacity(opacity)
  {
    dialog.box.sprite.SetOpacity(opacity);
    dialog.lock.sprite.SetOpacity(opacity);
    dialog.entry.sprite.SetOpacity(opacity);
    dialog.prompt_sprite.SetOpacity(opacity);
    for (index = 0; dialog.bullet[index]; index++)
      {
        dialog.bullet[index].sprite.SetOpacity(opacity);
      }
  }

fun display_normal_callback ()
  {
    global.status = "normal";
    if (global.dialog)
      dialog_opacity (0);
  }

fun display_password_callback (prompt, bullets)
  {
    global.status = "password";
    if (!global.dialog) 
    dialog_setup();
    else 
    dialog_opacity(1);
    motif.sprite.SetOpacity(1);
    anim.sprite.SetOpacity(1);

    dialog.prompt_sprite.SetImage(Image.Text(prompt, 1.0, 1.0, 1.0));
    for (index = 0; dialog.bullet[index] || index < bullets; index++)
      { 

        if (!dialog.bullet[index])
          {
            dialog.bullet[index].sprite = SpriteNew();
            dialog.bullet[index].sprite.SetImage(dialog.bullet_image);
            dialog.bullet[index].x = dialog.entry.x + index * dialog.bullet_image.GetWidth();
            dialog.bullet[index].y = dialog.entry.y + dialog.entry.image.GetHeight() / 2 - dialog.bullet_image.GetHeight() / 2;
            dialog.bullet[index].z = dialog.entry.z + 1;
            dialog.bullet[index].sprite.SetPosition(dialog.bullet[index].x, dialog.bullet[index].y, dialog.bullet[index].z);
          }
        if (index < bullets)
          dialog.bullet[index].sprite.SetOpacity(1);
        else
          dialog.bullet[index].sprite.SetOpacity(0);
      }
  }

fun display_message_callback (prompt)
  {

prompt = Image.Text(prompt,1.0, 1.0, 1.0);
sprite_prompt.SetImage(prompt);
sprite_prompt.SetPosition(Window.GetX() + (Window.GetWidth() - prompt.GetWidth()) / 2, Window.GetY() + Window.GetHeight() * 0.93, 2);
  }

/* instantiate dialog at startup, to ensure all icons are loaded in memory before initrd is unmounted, in case /usr isn't mounted yet */
dialog_setup(); dialog_opacity(0);
Plymouth.SetDisplayNormalFunction(display_normal_callback);
Plymouth.SetDisplayPasswordFunction(display_password_callback);
Plymouth.SetMessageFunction(display_message_callback);

#----------------------------------------- Progress Bar --------------------------------

progress_box.image = Image("progress_box.png");
progress_box.sprite = Sprite(progress_box.image);

progress_box.x = Window.GetX() + Window.GetWidth() / 2 - progress_box.image.GetWidth() / 2;
progress_box.y = Window.GetY() + Window.GetHeight() * 0.65 - progress_box.image.GetHeight() / 2;
progress_box.sprite.SetPosition(progress_box.x, progress_box.y, 0);

progress_bar.original_image = Image("progress_bar.png");
progress_bar.sprite = Sprite();

progress_bar.x = Window.GetX() + Window.GetWidth()  / 2 -        progress_bar.original_image.GetWidth() / 2;
progress_bar.y = Window.GetY() + Window.GetHeight() * 0.65  - progress_box.image.GetHeight() / 2 + (progress_box.image.GetHeight() - progress_bar.original_image.GetHeight()) / 2;
progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 1);

fun progress_callback (duration, progress)
  {
    if (progress_bar.image.GetWidth () != Math.Int (progress_bar.original_image.GetWidth () * progress))
      {
# * 3 = multiply progress by 3
        progress_bar.image = progress_bar.original_image.Scale(progress_bar.original_image.GetWidth(progress_bar.original_image) * progress * 3, progress_bar.original_image.GetHeight());
        progress_bar.sprite.SetImage (progress_bar.image);
      }
  }

Plymouth.SetBootProgressFunction(progress_callback);

#----------------------------------------- Status Update --------------------------------

NUM_SCROLL_LINES=10;
LINE_WIDTH=55;

# width of one character doesnt work------------
CHAR_WIDTH = 7;
# height of one character
CHAR_HEIGHT = 10; 
#------------------------

msg_color = [1,1,1]; # msg_color is array

#status callback function

fun update_status_callback(sta) {
  if (sta == "failed") msg_color = [1,0,0];
  if (sta == "warning") msg_color = [0.8,0.8,0];
  if (sta == "normal") msg_color = [0.5,0.5,0.5];
}

screen_width = Window.GetWidth();
screen_height = Window.GetHeight();

#Initialising text images and their positions
# 20 is the height (including line spacing) of each line

for (i=0; i < NUM_SCROLL_LINES; i++) {
  lines[i]= Image.Text("", msg_color[0], msg_color[1], msg_color[2]);
  message_sprite[i] = Sprite();
  message_sprite[i].SetPosition(screen_width * 0.025, (screen_height * 0.6) + (i * 20), 10000);
}

fun StringLength(string) {

  index = 0;
  str = String(string);
  while(str.CharAt(index)) index++;
  return index;
}

pretext = String("");

#scroll message function

fun scroll_message_callback(text) {

 ##nobreak function 

  nobreak = 0;
   if (text.CharAt(0) == ">") {    # "no linebreak" flag, like "-n"
       text = text.SubString(1, StringLength(text)); # remove ">" at front
       nobreak = 1;
   }

   if ((pretext == "") || (StringLength(text) > 15))  {
   if (text == ".") return;    # ignore messages of only a single dot

       if (nobreak == 1) pretext = text;



#Truncate the message if too long


   if (StringLength(text) > LINE_WIDTH) {
     text = text.SubString(0, LINE_WIDTH - 0);
     text += "...";
   }




#Shift message one up

   for (i = 0; i < NUM_SCROLL_LINES - 1; i++) {
     lines[i] = lines[i+1];
   }


}
   else {    # the previous message was flagged to have no linebreak

          // Truncate the message if too long
       if (StringLength(text) > LINE_WIDTH - 5) { # leave min. 5 for pretext
         text = text.SubString(0, LINE_WIDTH - 8);
         text += "...";
       }

          # Truncate the previous message if too long
       if (StringLength(pretext) > (LINE_WIDTH - StringLength(text))) {
         pretext = pretext.SubString(0, LINE_WIDTH - StringLength(text) - 3);
         pretext += "...";
       }

       text = pretext + text;

       if (nobreak == 1) pretext = text;
       else pretext = ">";

   }


#Create the image for the latest message

     lines[i] = Image.Text(text, msg_color[0], msg_color[1], msg_color[2]);

#Re-positioning the text images

  for (i = 0; i < NUM_SCROLL_LINES; i++) {
     message_sprite[i].SetImage(lines[i]);
   }
}

 Plymouth.SetUpdateStatusFunction(update_status_callback);

 Plymouth.SetUpdateStatusFunction(scroll_message_callback);


#----------------------------------------- Quit --------------------------------

fun quit_callback ()
{
 anim.sprite.SetOpacity (1);
  if (Plymouth.GetMode() == "shutdown") {
   motif.sprite.SetOpacity(1);
  }
}

Plymouth.SetQuitFunction(quit_callback);

Fondamentalmente lo script può essere applicato a qualsiasi tema, tutto ciò che devi fare è fornire i nomi dei file delle immagini nella cartella. E cambiando alcune altre linee per regolare le immagini sullo schermo. O quello che fai è copiare la parte necessaria come il lascia che vuoi la parte di progresso, quindi tutto ciò che devi fare è copiare tutto da

----------------------------------------- Barra di avanzamento ---- ----------------------------

fino a

----------------------------------------- Aggiornamento di stato ---- ----------------------------

Dopo aver finito con la modifica di mdv.script assicurati di sudo update-initramfs -u e al tuo prossimo avvio vedrai il tuo nuovo splash.

Assicurati di controllare i link forniti nella mia domanda che sono molto istruttivi e ti faranno capire gli script di Plymouth in pochissimo tempo.

Ora, se hai fatto tutto ciò che ho detto qui, lo splash di avvio dovrebbe visualizzare i messaggi scorrevoli. Ora riguardo alla parte troncata, ci sto attualmente lavorando, ma è piuttosto fastidioso dover riavviare la mia macchina ogni volta che apporto qualche cambiamento. È possibile testare un processo di avvio mentre sono loggato come

sudo plymouthd ; sudo plymouth --show-splash ; sudo plymouth update --status="Hello" ; sleep 2 ; sudo plymouth update --status="This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. " ; sleep 10 ; sudo killall plymouthd

Un altro modo per testare Plymouth è copiare il comando precedente in un file di testo e aggiungere sudo plymouth update --status="your message" per far scorrere più messaggi. Quindi rendi eseguibile il file ed esegui il terminale.

Spero che questo aiuti chiunque altro voglia modificare il proprio splash di Plymouth. Buona fortuna !!!

    
risposta data Vitaly 01.07.2011 - 11:36
0

So che è un thread vecchio, ma penso di conoscere la risposta sul troncamento del testo o meno. Nel mio themename.script (non nel file themename.plymouth) uso due variabili.

1. NUM_SCROLL_LINES
2. LINE_WIDTH

con queste variabili posso impostare quante righe verranno visualizzate e per quanto tempo saranno le linee che verranno visualizzate. Lo script ha anche una funzione che tronca le linee se sono troppo lunghe da mostrare.

Spero che questo sia utile per qualcuno.

Il mio problema è in opensuse 42.1 Leap. plymouth non mostra i messaggi di avvio, come se fossero scritti su /var/log/boot.log. Mostra le chiamate systemd per i servizi.

Ho anche modificato / lib / lsb / init-functions in questo modo

if [ -x /usr/bin/plymouth ]; then
  /usr/bin/plymouth update --status="[email protected]"
fi

o quello

[ -x /usr/bin/plymouth ] && /usr/bin/plymouth update --status="[email protected]"

Niente ha funzionato per me. Qualcuno ha un'idea?

Qui è il themename.script che uso

NUM_SCROLL_LINES=52;
LINE_WIDTH=120;

wallpaper_image = Image("background.png");
screen_width = Window.GetWidth();
screen_height = Window.GetHeight();
resized_wallpaper_image = wallpaper_image.Scale(screen_width,screen_height);
wallpaper_sprite = Sprite(resized_wallpaper_image);
wallpaper_sprite.SetZ(-100);

// Initialising text images and their positions
// 20 is the height (including line spacing) of each line
for (i=0; i < NUM_SCROLL_LINES; i++) {
  lines[i]= Image.Text("", 0, 0, 0);
  message_sprite[i] = Sprite();
#  here you can set the hights and width of textdisplay. 0.005 uses almost the whole screen.
#  message_sprite[i].SetPosition(screen_width * 0.2, (screen_height * 0.6) + (i * 20), 10000);
  message_sprite[i].SetPosition(screen_width * 0.005, (screen_height * 0.005) + (i * 20), 10000);
}

// From ubuntu-logo
fun StringLength(string) {
  index = 0;
  str = String(string);
  while(str.CharAt(index)) index++;
    return index;
}

fun scroll_message_callback(text) {
  // Truncate the message if too long
  if (StringLength(text) > LINE_WIDTH) {
    text = text.SubString(0, LINE_WIDTH - 3);
    text += "...";
  }

  // Shift message one up
  for (i = 0; i < NUM_SCROLL_LINES - 1; i++) {
    lines[i] = lines[i+1];
  }

  // Create the image for the latest message
  # z.B. turquoise coloured text / (text, 0.28, 0.82, 0.80); // 1.0 = 100% 0.28 = 28% usw.
  lines[i] = Image.Text(text, 0.28, 0.82, 0.80);

  // Re-positioning the text images
  for (i = 0; i < NUM_SCROLL_LINES; i++) {
    message_sprite[i].SetImage(lines[i]);
  }

}

Plymouth.SetUpdateStatusFunction(scroll_message_callback);
    
risposta data user572252 25.07.2016 - 14:59

Leggi altre domande sui tag