Review your favorite Linux distribution.
Go Back > Articles > Technical
User Name


By stomfi at 2006-04-13 04:37
Power to the Users. Shell Scripting & GUI interfacing for Desktop Users. By Stomfi © 2006

Part 8 - Continuing Story Board Scripting

In this article you will create even more scripts to be called for by the Transcripts that were written in Part 6.

I've been a bit busy finishing off the Storyboard for my 'SCOOL application, adding the needed functionality to Dyne2 beta 5 and making sure everything worked as planned. My beta testers also gave me some feedback so I had to add a couple of extras to the Storyboard to satisfy their needs.

The modified dyne2 iso can be found at my site on This includes all the shell scripts you are likely to see here and the RunRev development files as well. The Storyboard system resides in Dyne in /opt under /opt/SCOOL so that all the calls from RunRev to shell scripts and from shell scripts to shell scripts will say /opt/SCOOL/bin instead of this projects $HOME/SB/bin, so beware of copying and not editing. I radically modified the Dyne2 iso using their dynesdk script, changing the splash screen to my own, adding my own menu items, and some extras I like to see on a system. It's a great system for hackers thanks to Jaromil and all the team at Rastasoft.

I included the old 'SCOOL app without storyboard on the site which installs into /opt in case any of you want to see how it all hangs together. This is only a 5MB file so not too bad to download. It will certainly give you some clues about simple shell and RunRev scripting.

You will notice that all the shell scripts include a GPL notice. Instead of typing these each time it is easier to include the text of this notice in a file called gplnotice.txt in the bin folder and include a line where it is supposed to appear in the script like this:

  . ./gplnotice.txt
The first dot (.) means source the following file. That will save a lot of typing and make your scripts a lot smaller.

While fixing up Storyboard for the 'SCOOL project I found some things in the scripts that I think ought to be changed, either to get rid of bugs or to make it run better.

A RunRev variable that is quite handy for placing the window into the centre of the screen when opening a stack is the screenLoc. You can include this line in the stack script.

  on openStack
    set the loc of stack “SB” to the screenLoc
  end openStack
This is another handy one when you are adding lines to a field and want to able to display the bottom ones. I use this in the Animate Test button script right after the line which says:

put return and DUNID after field “MESG”
set the scroll of field “MESG” to the formattedHeight of field “MESG”

You can add this second line anywhere you want to see the last lines of this field, but make sure that other activities like calls to shell scripts or programs have completed before you scroll the field.

When testing, I found that of all the image types the Windows “bmp” format didn't give the word “image” for the “file” shell command. Instead it gives the word “bitmap”. To get over this problem you will have to change the line in the CLICK ME button script for the LOAD PROJECT case. This is the new line:

  put ("(cd" && PDIR  && "; file * |  grep -E" && quote & "image|bitmap" & quote && "| cut -d: -f1 )" ) into DUIFILES
Note that the simple grep command is much more complex and includes the -E option for extended regular expression, a pipe symbol between the two word patterns which means “image” or “bitmap” and the addition of “quote &” and “& quote” surrounding the new expression as the shell expects to see this surrounded by double quotes.

Just in case you think I'm really clever, I had to run the file command on some bmp files to find out why they weren't reported as images and then look up the info page for grep to find out how to construct the command shown above. Thank goodness for Linux documentation otherwise I'd have looked really silly.

Here is a an addition to the LOAD PICTURE case in the CLICK ME button. The first line appear in the script. Add the others underneath it. This makes sure there is a project folder name in the PMESG field for single pictures.

   set the filename of image THISPIC to  PFILE
   #Add picture folder to PMESG
   put the shell of ("dirname" && PFILE) into PDNAME
   put PDNAME & return after field "PMESG"
   #Set a PDIR if empty
   if PDIR = empty
      put PDNAME into PDIR
   end if
This is a bug in the ANIMTEST button where not all the pictures in a layout get animated because I used the NUMPICS variable, so where it says:

  repeat for NUMPICS times
replace that with:

  repeat for 49 times
I also included an error check after the line which says:

   put it into RSIZE
   #check for blank entry
   if RSIZE = empty
     put "NONE" into RSIZE
   end if
I hope your editing skills are getting a good work out. Scripting does seem to entail a lot of that.

Now we need to write the animation script. This relies on gifsicle which if you haven't got it on your system, the next article will show you how to compile and install it.

#!/bin/bash imagelist layoutname resize
#Animate image list and return path to animation
# Copyright Stomfi (C) 2005
# This program is free software;
# you can redistribute it and/or modify it under the terms of the
# GNU General Public License as published by the Free Software Foundation;
# either version 2 of the License, or any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#Check for gifsicle location
GIFSIC=`whereis gifsicle | cut -d “ “ -f2`
if [ ! -e $GIFSIC ]
   #Can't animate without gifsicle
   echo “Cannot find animation program gifsicle”
   exit 1
#Place the folder paths into variable names
#Put the picture list into a variable
#Base the foldername on the layoutname
mkdir $ADIR/$2
#Copy files to ordered list
for pname in $PICS
  bname=`basename $pname`
  nameext=`echo $bname | cut -d. -f2`
  namedate=`date "+%y%m%d%H%M%S"`
  cp $pname $APDIR/$aname
  #Make sure we get a new date seconds number
  sleep 1
#create and return gif animation using gifsicle
#Convert all files to gif and put in gifanim folder
mkdir $HOME/SB/work/pics/animations/gifs/$2
for F in $FLIST
  EXTN=`echo $F | cut -d"." -f2`
  if [ $EXTN != "gif" ]
    GNAME=`echo $F| cut -d"." -f1`
    convert $F $GDIR/$GNAME.gif
    cp $F $GDIR
#Resize images to requested size 
#convert -size $RESIZE picture -scale $RESIZE outpic
if [ $RESIZE != "NONE" ]
   #Create SB/tmp/gifs/$2
   if [ ! -e $HOME/SB/tmp/gifs ]
       mkdir $HOME/SB/tmp/gifs
   mkdir $TDIR/$2
   #Copy the folder contents
   cp $GDIR/* $TDIR/$2
   #Remove originals leaving folder intact
   rm -f $GDIR/*
   #Make a list of all file names
   FLIST=`ls $TDIR/$2`
   #Work in temp folder
   cd $TDIR/$2
   #Loop round all files
   for C in $FLIST
      #Convert size and put back into original folder
      convert -size $RESIZE $C -resize $RESIZE $GDIR/$C
#Use gifsicle to create animation file. Dont report errors
$GIFSIC -w --colors 256 -d 100 $GDIR/* -o $OGDIR/$2.gif
#remove the building folders
rm -fR $GDIR
rm -fR $APDIR
#send the file name back to the calling program
echo $OGDIR/$2.gif
This is the script for the Animation Control button.
It checks that the filename is an animation by not being one of the others.

on menuPick theMenuItem
  put the filename of image "ANIM" into CHANGEA
  if CHANGEA <> $HOME & "/SB/sclblue.gif" or CHANGEA <> empty
    #Do the changes
    switch theMenuItem
    case "DELAY"
      ask "Enter number of hundredths seconds for delay between frames eg 100"
      put it into DSECS
      put ($HOME & "/SB/bin/" && CHANGEA && "DELAY" && DSECS) into DUMOD
      replace return with empty in DUMOD
      put the shell of DUMOD into DUNMOD
      #Replace the filename
      set the filename of image "ANIM" to empty
      set the filename of image "ANIM" to CHANGEA
    case "LOOP"
      ask "Enter number  of loops from 0 - forever to number"
      put it into LNUM
      put ($HOME & "/SB/bin/" && CHANGEA && "LOOP" && LNUM) into DUMOD
      replace return with empty in DUMOD
      put the shell of DUMOD into DUNMOD
      #Replace the filename
      set the filename of image "ANIM" to empty
      set the filename of image "ANIM" to CHANGEA
  end switch
  put DUNMOD after field "MESG"
  end if
end menuPick
And here is its shell script

# animationfile modtype modarg
#make changes to gif animations
. ./gplnotice.txt
GIFSIC=`whereis gifsicle | cut -d “ “ -f2`
if [ ! -e $GIFSIC ]
#move input file to temp file
if [ ! -e $HOME/SB/tmp/anims ]
   mkdir $HOME/SB/tmp/anims
rm -f $AFLDR/tempanim.gif
mv $ANIM $AFLDR/tempanim.gif
case $2 in
  "DELAY")  #Explode file
            mkdir $AFLDR/newdelay
	    $GIFSIC -e $AFLDR/tempanim.gif -o $AFLDR/newdelay/newone 
	    #Redo with new delay
	    $GIFSIC -d $3 $AFLDR/newdelay/* -o $AFLDR/tempanim.gif
	    #Replace to original
	    mv $AFLDR/tempanim.gif $ANIM
	    #Clean out working folders
	    rm -fR $AFLDR/newdelay
	    rm -f $AFLDR/tempanim.gif
   "LOOP")  #Explode file 	    
            mkdir $AFLDR/newloop
	    $GIFSIC -e $AFLDR/tempanim.gif -o $AFLDR/newloop/newone 
	    #Redo with new loop
	    $GIFSIC -l=$3 $AFLDR/newloop/* -o $AFLDR/tempanim.gif
	    #Replace to original
	    mv $AFLDR/tempanim.gif $ANIM
	    #Clean out working folders
	    rm -fR $AFLDR/newloop
	    rm -f $AFLDR/tempanim.gif
These are all the graphics scripts done.

Compiling gifsicle.
You may be able to get a compiled binary for your distribution from this page or you can download the source and follow these instructions to compile and install it.

This is the latest source code file gifsicle-1.44.tar.gz

Save it to your home folder and start up a root terminal console. Move the file to /usr/local/src. Enter this folder and run the command:

  tar xzvf gifsicle-1.44.tar.gz
The file will expand into a folder. Enter the folder and type the command:

The configure script will check that all dependencies are satisfied, and if they are create Makefiles and config files thus:

bash-3.00# ./configure
checking for a BSD-compatible install... /usr/bin/ginstall -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking how to run the C preprocessor... gcc -E
checking for an ANSI C-conforming const... yes
checking for inline... inline
checking for X... libraries /usr/X11/lib, headers
checking for gethostbyname... yes
checking for connect... yes
checking for remove... yes
checking for shmat... yes
checking for IceConnectionNumber in -lICE... yes
checking for gettimeofday prototype... 2
checking for random... yes
checking for strerror... yes
checking for strtoul... yes
checking for mkstemp... yes
checking for egrep... grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking sys/select.h usability... yes
checking sys/select.h presence... yes
checking for sys/select.h... yes
checking for inttypes.h... (cached) yes
checking for unistd.h... (cached) yes
checking for inttypes.h... (cached) yes
checking for sys/types.h... (cached) yes
checking for uintptr_t... yes
checking for void *... yes
checking size of void *... 4
checking for unsigned long... yes
checking size of unsigned long... 4
checking for unsigned int... yes
checking size of unsigned int... 4
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: executing depfiles commands
Everything worked nicely for me, so I can go to the next step which is to type the command:

The output will look like this as make gets its instructions from the Makefile for the gcc compiler, header include files and library linkers.

bash-3.00# make
make  all-recursive
make[1]: Entering directory `/usr/local/src/gifsicle-1.44'
Making all in src
make[2]: Entering directory `/usr/local/src/gifsicle-1.44/src'
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT clp.o -MD -MP -MF ".deps/clp.Tpo" -c -o clp.o clp.c; \
then mv -f ".deps/clp.Tpo" ".deps/clp.Po"; else rm -f ".deps/clp.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT giffunc.o -MD -MP -MF ".deps/giffunc.Tpo" -c -o giffunc.o giffunc.c; \
then mv -f ".deps/giffunc.Tpo" ".deps/giffunc.Po"; else rm -f ".deps/giffunc.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT gifread.o -MD -MP -MF ".deps/gifread.Tpo" -c -o gifread.o gifread.c; \
then mv -f ".deps/gifread.Tpo" ".deps/gifread.Po"; else rm -f ".deps/gifread.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT gifunopt.o -MD -MP -MF ".deps/gifunopt.Tpo" -c -o gifunopt.o gifunopt.c; \
then mv -f ".deps/gifunopt.Tpo" ".deps/gifunopt.Po"; else rm -f ".deps/gifunopt.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT merge.o -MD -MP -MF ".deps/merge.Tpo" -c -o merge.o merge.c; \
then mv -f ".deps/merge.Tpo" ".deps/merge.Po"; else rm -f ".deps/merge.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT optimize.o -MD -MP -MF ".deps/optimize.Tpo" -c -o optimize.o optimize.c; \
then mv -f ".deps/optimize.Tpo" ".deps/optimize.Po"; else rm -f ".deps/optimize.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT quantize.o -MD -MP -MF ".deps/quantize.Tpo" -c -o quantize.o quantize.c; \
then mv -f ".deps/quantize.Tpo" ".deps/quantize.Po"; else rm -f ".deps/quantize.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT support.o -MD -MP -MF ".deps/support.Tpo" -c -o support.o support.c; \
then mv -f ".deps/support.Tpo" ".deps/support.Po"; else rm -f ".deps/support.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT xform.o -MD -MP -MF ".deps/xform.Tpo" -c -o xform.o xform.c; \
then mv -f ".deps/xform.Tpo" ".deps/xform.Po"; else rm -f ".deps/xform.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT gifsicle.o -MD -MP -MF ".deps/gifsicle.Tpo" -c -o gifsicle.o gifsicle.c; \
then mv -f ".deps/gifsicle.Tpo" ".deps/gifsicle.Po"; else rm -f ".deps/gifsicle.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT gifwrite.o -MD -MP -MF ".deps/gifwrite.Tpo" -c -o gifwrite.o gifwrite.c; \
then mv -f ".deps/gifwrite.Tpo" ".deps/gifwrite.Po"; else rm -f ".deps/gifwrite.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT fmalloc.o -MD -MP -MF ".deps/fmalloc.Tpo" -c -o fmalloc.o fmalloc.c; \
then mv -f ".deps/fmalloc.Tpo" ".deps/fmalloc.Po"; else rm -f ".deps/fmalloc.Tpo"; exit 1; fi
gcc  -g -O2   -o gifsicle  clp.o giffunc.o gifread.o gifunopt.o merge.o optimize.o quantize.o support.o xform.o gifsicle.o fmalloc.o  gifwrite.o
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT gifx.o -MD -MP -MF ".deps/gifx.Tpo" -c -o gifx.o gifx.c; \
then mv -f ".deps/gifx.Tpo" ".deps/gifx.Po"; else rm -f ".deps/gifx.Tpo"; exit 1; fi
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT gifview.o -MD -MP -MF ".deps/gifview.Tpo" -c -o gifview.o gifview.c; \
then mv -f ".deps/gifview.Tpo" ".deps/gifview.Po"; else rm -f ".deps/gifview.Tpo"; exit 1; fi
gcc  -g -O2   -o gifview  clp.o giffunc.o gifread.o gifx.o gifview.o fmalloc.o   -L/usr/X11/lib  -lSM -lICE -lX11
if gcc -DHAVE_CONFIG_H -I. -I. -I..  -I../include    -g -O2 -MT gifdiff.o -MD -MP -MF ".deps/gifdiff.Tpo" -c -o gifdiff.o gifdiff.c; \
then mv -f ".deps/gifdiff.Tpo" ".deps/gifdiff.Po"; else rm -f ".deps/gifdiff.Tpo"; exit 1; fi
gcc  -g -O2   -o gifdiff  clp.o giffunc.o gifread.o gifdiff.o fmalloc.o
make[2]: Leaving directory `/usr/local/src/gifsicle-1.44/src'
make[2]: Entering directory `/usr/local/src/gifsicle-1.44'
make[2]: Nothing to be done for `all-am'.
make[2]: Leaving directory `/usr/local/src/gifsicle-1.44'
make[1]: Leaving directory `/usr/local/src/gifsicle-1.44'
The final step is too install the program. This can be done in two ways. If you have the program checkinstall and you have a package managed system like SUSE, RedHat and Mandriva rpm or Debian, you can give this command which will create a package for your system and put it in your package database. Or you can do it the simple way and give the command:

  make install

bash-3.00# make install
Making install in src
make[1]: Entering directory `/usr/local/src/gifsicle-1.44/src'
make[2]: Entering directory `/usr/local/src/gifsicle-1.44/src'
test -z "/usr/local/bin" || mkdir -p -- "/usr/local/bin"
  /usr/bin/ginstall -c 'gifsicle' '/usr/local/bin/gifsicle'
  /usr/bin/ginstall -c 'gifview' '/usr/local/bin/gifview'
  /usr/bin/ginstall -c 'gifdiff' '/usr/local/bin/gifdiff'
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/usr/local/src/gifsicle-1.44/src'
make[1]: Leaving directory `/usr/local/src/gifsicle-1.44/src'
make[1]: Entering directory `/usr/local/src/gifsicle-1.44'
make[2]: Entering directory `/usr/local/src/gifsicle-1.44'
make[2]: Nothing to be done for `install-exec-am'.
test -z "/usr/local/man/man1" || mkdir -p -- "/usr/local/man/man1"
 /usr/bin/ginstall -c -m 644 './gifsicle.1' '/usr/local/man/man1/gifsicle.1'
 /usr/bin/ginstall -c -m 644 './gifview.1' '/usr/local/man/man1/gifview.1'
 /usr/bin/ginstall -c -m 644 './gifdiff.1' '/usr/local/man/man1/gifdiff.1'
make[2]: Leaving directory `/usr/local/src/gifsicle-1.44'
make[1]: Leaving directory `/usr/local/src/gifsicle-1.44'
You can see from this output that everything is installed in the /usr/local folder tree. If you wanted it to install in the /usr folder tree, you can tell the configure script before you run the make command with this option:

  ./configure prefix=/usr
This shows you how easy it is to become an even more powerful user. One who can compile and install programs. If the configure script gives errors they will be about missing dependency libraries. You can find these on the Internet and compile and install them in the same way. When installing a library I have found it best to configure with the prefix=/usr option. After installing libraries it is best to run the command:

before trying to reconfigure your new program. This lets the system add the newly installed library to its library linking database so the configure script will be sure to find it.

We didn't get onto the sound this time, but the next article shows you how to add this to the story board. You might like to design it in the meantime so here is a picture. Create this window from the RunRev file menu using “New Substack of SB”

Picture of record window:


All times are GMT -5. The time now is 03:26 AM.

Main Menu
Write for LQ is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration