Programming and Scripting :: murgaLua tests



Wow

Thanks for the tests ... I am currently traveling, but I hope to release a new version soon and will incorporate your feedback (and if it's OK), some of your tests.

I have some fixes and additions to the FLTK stuff and changes to the sqLite stuff that should reduce the size of the runtime.

Cheers
JohnM

sweet! =o)

Just please don't include the full ucitool (parts are fine, if anything is of use to you), since it is incomplete and represents the DSL project to an extent.

ucitool update

Shows mounted and available uci packages, and includes a very basic uci builder.  What this builder does is simply create a cloop from a chosen directory and place it in the current directory. I had considered adding more features to the builder, but i came to the conclusion that it would make the script much too complex for what little benefit it would give.

The directory containing available uci packages is /cdrom/mydsl/optional by default, but can be changed by setting the UCITOOL_DIR environment variable or by browsing from within the application.

Code Sample

-- mounts, umounts and builds .uci extensions
-- (c) 2005,2006 mikshaw
--
-- Changelog (yyyy/mm/dd)
--    2006/10/23: Fixed multiple trailing slashes on dir name
--                Sort the list of available packges
--                Consolidated mount and umount functions
--    2006/10/21: Added basic feature to build UCI packages
--                UCI directory can be specified via UCITOOL_DIR
--    2006/09/05: Port to MurgaLua
--                Added tabs and ability to mount packages
--                Output of mydsl-load is displayed in the gui
--    2005/12/30: Changed UI to match DSL tools
--                Added hotkey support
--                Auto-selects first line for better keyboard support
--    2005/12/09: Displays total number of mounted UCIs
--    2005/12/08: First release
--
-- TODO: Make it fully keyboard controllable (is that possible with fltk?)
-----------------------------------------------------------------------------

ww=400; wh=300;      -- window size
tx=2; ty=27;         -- tab position
tw=ww-4; th=wh-ty-2; -- tab size
bw=120; bh=30;       -- button size
tempfile="/tmp/"..os.getenv("USER")..".uci2ool"
pwd=os.getenv("PWD")
ucidir="/cdrom/mydsl/optional" -- default uci directory

-- check for UCITOOL_DIR environment variable
ucivar=os.getenv("UCITOOL_DIR")
if murgaLua.isDirectory(ucivar) then ucidir=ucivar end


-- done at startup, add/remove a uci, and when "refresh" is pressed
function build_uci_lists()
-- add mounted files from mtab to ufiles window
os.execute("grep \"^.*.uci \" /etc/mtab | awk '{print $1}' | sort >"..tempfile)
ufiles:clear()
for line in io.lines(tempfile) do ufiles:add(line) end
ufiles:redraw()
-- compare mtab UCI files (tempfile) with files in ucidir
if murgaLua.isDirectory(ucidir) then
input=io.open(tempfile,"r")
mounted=input:read("*a")
io.close(input)
allfiles=murgaLua.readDirectory(ucidir)
table.sort(allfiles)
mfiles:clear()
for i=0,table.getn(allfiles) do
if string.find(allfiles[i],".uci",-4,plain) then
-- list only *.uci files that are not in mtab
if not string.find(mounted,allfiles[i].."\n") then mfiles:add(ucidir.."/"..allfiles[i]) end
end
end
mfiles:redraw()
end
os.remove(tempfile)
end

-- choose a different uci directory
function browse_cb()
new_ucidir=fltk.fl_dir_chooser("choose a uci directory",ucidir,"*",0)
if murgaLua.isDirectory(new_ucidir) then
-- remove trailing slash if found
ucidir=string.gsub(new_ucidir,"%/*$","")
build_uci_lists() end
end

-- run mydsl-load on selected files
function mount_cb(self)
-- mount or umount? Uses the button label
if self:label() == "mount" then lst=mfiles; out=mntout else lst=ufiles; out=umntout end
for i = 1,lst:nitems() do
if lst:checked(i)==1 then
os.execute("mydsl-load "..lst:text(i).." &>"..tempfile)
-- print mydsl-load output (tempfile) to mntout or umntout
for line in io.lines(tempfile) do out:add(line) end
out:bottomline(out:size())
end
end
build_uci_lists()
end

-- BEGIN interface
w=fltk:Fl_Double_Window(ww,wh,"UCI Tool");

tabs=fltk:Fl_Tabs(tx,2,ww-4,wh-4);
tabs:selection_color(51);
tabs:color(1);

tab1 = fltk:Fl_Group(tx,ty,tw,th,"  mount  ");
-- checklist of unmounted ucis
mfiles=fltk:Fl_Check_Browser(tx+2,ty+2,tw-4,th-bh-80); mfiles:box(fltk.FL_THIN_DOWN_BOX);
-- output from mydsl-load
mntout=fltk:Fl_Browser(tx+2,ty+th-bh-76,tw-4,76); mntout:box(fltk.FL_THIN_DOWN_BOX)
mntout:format_char(0);
-- this label MUST be "mount"
mount=fltk:Fl_Button(tx,wh-bh-2,bw,bh,"mount"); mount:box(fltk.FL_THIN_UP_BOX);
mount:callback(mount_cb);
browse=fltk:Fl_Button(ww-bw-2,wh-bh-2,bw,bh,"change directory"); browse:box(fltk.FL_THIN_UP_BOX);
browse:callback(browse_cb);
fltk:Fl_End();

tab2 = fltk:Fl_Group(tx,ty,tw,th,"  umount  ");
-- checklist of mounted ucis
ufiles=fltk:Fl_Check_Browser(tx+2,ty+2,tw-4,th-bh-80); ufiles:box(fltk.FL_THIN_DOWN_BOX);
-- output from mydsl-load
umntout=fltk:Fl_Browser(tx+2,ty+th-bh-76,tw-4,76); umntout:box(fltk.FL_THIN_DOWN_BOX)
umount=fltk:Fl_Button(tx,wh-bh-2,bw,bh,"umount"); umount:box(fltk.FL_THIN_UP_BOX);
umount:callback(mount_cb);
refresh=fltk:Fl_Button(ww-bw-2,wh-bh-2,bw,bh,"refresh list"); refresh:box(fltk.FL_THIN_UP_BOX);
refresh:callback(build_uci_lists);
fltk:Fl_End();

tab3 = fltk:Fl_Group(tx,ty,tw,th,"  build  ");
frame=fltk:Fl_Box(tx+2,ty+2,tw-4,th-4); frame:box(fltk.FL_THIN_DOWN_BOX);
createinfo=fltk:Fl_Box(tx+12,ty+12,tw-24,th-24-(bh*2),"The \"MAKE PACKAGE\" button will build a UCI extension using the directory entered in the box below.\n\
Created files will include "..pwd.."/name.uci and "..pwd.."/name.uci.md5.txt, where \"name\" is the basename of the source directory.")
createinfo:align(fltk.FL_ALIGN_WRAP)
createdir=fltk:Fl_Input(tx+12,wh-bh*2-18,tw-bh-24,bh); createdir:box(fltk.FL_THIN_DOWN_BOX)
createdir:align(fltk.FL_ALIGN_TOP)
createbut=fltk:Fl_Button(tx+12,wh-bh-18,tw-24,bh,"MAKE PACKAGE")
createbut:box(fltk.FL_THIN_UP_BOX); createbut:labelfont(fltk.FL_HELVETICA_BOLD)
cdbut=fltk:Fl_Button(tw-40,wh-bh*2-18,bh,bh,"...")
cdbut:box(fltk.FL_THIN_UP_BOX)
cdbut:callback (
function(cd_cb)
ucisource=fltk.fl_dir_chooser("choose a source directory",pwd,"*",0)
if murgaLua.isDirectory(ucisource) then createdir:value(ucisource) end
end
)
createbut:callback (
function(make_package)
if murgaLua.isDirectory(createdir:value()) then
-- trim trailing slash(es), if needed
trim=string.gsub(createdir:value(),"%/*$","")
-- get basename
newuciname=string.gsub(trim,".*/","")
-- build uci
-- TODO: should the block size be user-configurable?
os.execute("cd "..trim.."/../ && aterm -e sudo su -c \"mkisofs -R -hide-rr-moved -cache-inodes -pad "..newuciname.."/ | create_compressed_fs - 65536 > "..pwd.."/"..newuciname..".uci\" && cd && md5sum "..newuciname..".uci > "..newuciname..".uci.md5.txt")
end
end
)
fltk:Fl_End();

tab4 = fltk:Fl_Group(tx,ty,tw,th,"  about  ");
about=fltk:Fl_Box(tx+2,ty+2,tw-4,th-4,"UCITOOL 2: THE REMOUNTENING - Beta\n\n\
A MurgaLua tool for creating and managing\
*.uci MyDSL packages in Damn Small Linux.\
\n\n(c)2006 mikshaw [mrblog|yahoo|com]");
about:box(fltk.FL_THIN_DOWN_BOX);
fltk:Fl_End();

build_uci_lists();

w:show();
Fl:run();


EDIT: cleared up some misplaced/vague comments
EDIT2: fixed the multiple slash issue
EDIT3: sorted uci list and joined the mount & umount functions

A couple of changes...removed the "about" tab and fixed a build problem with md5sum not finding the package if you're not in $HOME.
I have to work on the default uci location...probably use /opt/.mydsl_dir to be consistent with other DSL tools.

Code Sample
#!/bin/murgaLua
-- mounts, umounts and builds .uci extensions
-- (c) 2005,2006 mikshaw
--
-- Changelog (yyyy/mm/dd)
--    2006/11/12: Fixed md5sum not finding uci file
--                Removed unnecessary "about" tab
--    2006/10/23: Fixed multiple trailing slashes on dir name
--                Sort the list of available packges
--                Consolidated mount and umount functions
--    2006/10/21: Added basic feature to build UCI packages
--                UCI directory can be specified via UCITOOL_DIR
--    2006/09/05: Port to MurgaLua
--                Added tabs and ability to mount packages
--                Output of mydsl-load is displayed in the gui
--    2005/12/30: Changed UI to match DSL tools
--                Added hotkey support
--                Auto-selects first line for better keyboard support
--    2005/12/09: Displays total number of mounted UCIs
--    2005/12/08: First release
--
-- TODO: Make it fully keyboard controllable (is that possible with fltk?)
-----------------------------------------------------------------------------

ww=400; wh=300;      -- window size
tx=2; ty=27;         -- tab position
tw=ww-4; th=wh-ty-2; -- tab size
bw=120; bh=30;       -- button size
tempfile="/tmp/"..os.getenv("USER")..".uci2ool"
pwd=os.getenv("PWD")
ucidir="/cdrom/mydsl/optional" -- default uci directory

-- check for UCITOOL_DIR environment variable
ucivar=os.getenv("UCITOOL_DIR")
if murgaLua.isDirectory(ucivar) then ucidir=ucivar end


-- done at startup, add/remove a uci, and when "refresh" is pressed
function build_uci_lists()
-- add mounted files from mtab to ufiles window
os.execute("grep \"^.*.uci \" /etc/mtab | awk '{print $1}' | sort >"..tempfile)
ufiles:clear()
for line in io.lines(tempfile) do ufiles:add(line) end
ufiles:redraw()
-- compare mtab UCI files (tempfile) with files in ucidir
if murgaLua.isDirectory(ucidir) then
input=io.open(tempfile,"r")
mounted=input:read("*a")
io.close(input)
allfiles=murgaLua.readDirectory(ucidir)
table.sort(allfiles)
-- list only *.uci files that are not in mtab
mfiles:clear()
for i=0,table.getn(allfiles) do
if string.find(allfiles[i],".uci",-4,plain) then
if not string.find(mounted,allfiles[i].."\n") then mfiles:add(ucidir.."/"..allfiles[i]) end
end
end
mfiles:redraw()
end
os.remove(tempfile)
end

-- choose a different uci directory
function browse_cb()
new_ucidir=fltk.fl_dir_chooser("choose a uci directory",ucidir,"*",0)
if murgaLua.isDirectory(new_ucidir) then
-- remove trailing slash if found
ucidir=string.gsub(new_ucidir,"%/*$","")
build_uci_lists() end
end

-- run mydsl-load on selected files
function mount_cb(self)
-- mount or umount? Uses the button label
if self:label() == "mount" then lst=mfiles; out=mntout else lst=ufiles; out=umntout end
for i = 1,lst:nitems() do
if lst:checked(i)==1 then
os.execute("mydsl-load "..lst:text(i).." &>"..tempfile)
-- print mydsl-load output (tempfile) to mntout or umntout
for line in io.lines(tempfile) do out:add(line) end
out:bottomline(out:size())
end
end
build_uci_lists()
end

-- BEGIN interface
w=fltk:Fl_Double_Window(ww,wh,"UCI Tool");

tabs=fltk:Fl_Tabs(tx,2,ww-4,wh-4);
tabs:selection_color(51);
tabs:color(1);

tab1 = fltk:Fl_Group(tx,ty,tw,th,"  mount  ");
-- checklist of unmounted ucis
mfiles=fltk:Fl_Check_Browser(tx+2,ty+2,tw-4,th-bh-80); mfiles:box(fltk.FL_THIN_DOWN_BOX);
-- output from mydsl-load
mntout=fltk:Fl_Browser(tx+2,ty+th-bh-76,tw-4,76); mntout:box(fltk.FL_THIN_DOWN_BOX)
mntout:format_char(0);
-- this label MUST be "mount"
mount=fltk:Fl_Button(tx,wh-bh-2,bw,bh,"mount"); mount:box(fltk.FL_THIN_UP_BOX);
mount:callback(mount_cb);
browse=fltk:Fl_Button(ww-bw-2,wh-bh-2,bw,bh,"change directory"); browse:box(fltk.FL_THIN_UP_BOX);
browse:callback(browse_cb);
fltk:Fl_End();

tab2 = fltk:Fl_Group(tx,ty,tw,th,"  umount  ");
-- checklist of mounted ucis
ufiles=fltk:Fl_Check_Browser(tx+2,ty+2,tw-4,th-bh-80); ufiles:box(fltk.FL_THIN_DOWN_BOX);
-- output from mydsl-load
umntout=fltk:Fl_Browser(tx+2,ty+th-bh-76,tw-4,76); umntout:box(fltk.FL_THIN_DOWN_BOX)
umount=fltk:Fl_Button(tx,wh-bh-2,bw,bh,"umount"); umount:box(fltk.FL_THIN_UP_BOX);
umount:callback(mount_cb);
refresh=fltk:Fl_Button(ww-bw-2,wh-bh-2,bw,bh,"refresh list"); refresh:box(fltk.FL_THIN_UP_BOX);
refresh:callback(build_uci_lists);
fltk:Fl_End();

tab3 = fltk:Fl_Group(tx,ty,tw,th,"  build  ");
frame=fltk:Fl_Box(tx+2,ty+2,tw-4,th-4); frame:box(fltk.FL_THIN_DOWN_BOX);
createinfo=fltk:Fl_Box(tx+12,ty+12,tw-24,th-24-(bh*2),"The \"MAKE PACKAGE\" button will build a UCI extension using the directory entered in the box below.\n\
Created files will include "..pwd.."/name.uci and "..pwd.."/name.uci.md5.txt, where \"name\" is the basename of the source directory.")
createinfo:align(fltk.FL_ALIGN_WRAP)
createdir=fltk:Fl_Input(tx+12,wh-bh*2-18,tw-bh-24,bh); createdir:box(fltk.FL_THIN_DOWN_BOX)
createdir:label("source directory:"); createdir:align(fltk.FL_ALIGN_LEFT_TOP)
createbut=fltk:Fl_Button(tx+12,wh-bh-18,tw-24,bh,"MAKE PACKAGE")
createbut:box(fltk.FL_THIN_UP_BOX); createbut:labelfont(fltk.FL_HELVETICA_BOLD)
cdbut=fltk:Fl_Button(tw-40,wh-bh*2-18,bh,bh,"...")
cdbut:box(fltk.FL_THIN_UP_BOX)
cdbut:callback (
function(cd_cb)
ucisource=fltk.fl_dir_chooser("choose a source directory",pwd,"*",0)
if murgaLua.isDirectory(ucisource) then createdir:value(ucisource) end
end
)
createbut:callback (
function(make_package)
if murgaLua.isDirectory(createdir:value()) then
-- trim trailing slash(es), if needed
trim=string.gsub(createdir:value(),"%/*$","")
-- get basename
newuciname=string.gsub(trim,".*/","")
-- build uci
-- TODO: should the block size be user-configurable?
os.execute("cd `dirname "..createdir:value().."` && aterm -e sudo su -c \"mkisofs -R -hide-rr-moved -cache-inodes -pad "..newuciname.."/ | create_compressed_fs - 65536 > "..pwd.."/"..newuciname..".uci\" && cd "..pwd.." && md5sum "..newuciname..".uci > "..newuciname..".uci.md5.txt")
end
end
)
fltk:Fl_End();

build_uci_lists();

w:show();
Fl:run();

Here's a murgaLua frontend for the xdesktopwaves application.
It should work with the xdesktopwaves mydsl extension, but you may need to change the "program" variable to point to the proper executable. I think it's /opt/xdesktopwaves/xdesktopwaves, but I can't recall exactly.
As always, feedback is appreciated.

Latest update: Feb 07, 2007

Code Sample
#!/bin/murgaLua

-- A MurgaLua frontend for xdesktopwaves.
-- This does not cover all options, but should provide a decent
-- amount of control for most features.
-- Note: The 'z' variables are placeholders..dunno if there's a better way

-- Changelog
-- 2007-02-07: Custom colors persist for fl_color_chooser
--             Colors are set accurately with set_color instead of fl_color_cube
--             Tooltips added in case of too-dark color
--             More code cleanup
-- 2007-02-05: Fixed fl_color_chooser not ignoring change when cancelled
--             Code cleanup
-- 2007-02-04: Dumped Lua-FLTK
--             Added custom color controls
-- 2006-10-28: Can use either Lua-FLTK or MurgaLua
--             Removed unnecessary stuff (decoration, about, version, rc file)
-- 2005-01-28: First version (Lua-FLTK)

--program="/opt/xdesktopwaves/xdesktopwaves"
program="xdesktopwaves"

-- LAUNCH XDESKTOPWAVES
function start_waves()
if colors:value() > 0 then colscheme=" -c "..colors:value()
elseif usemycolor:value() == 1 then colscheme=" -wc "..watercolor.." -sc "..skycolor.." -lc "..lightcolor
else colscheme="" end
if tog1:value() == 1 then stip=" -t"   else stip=""   end
if tog2:value() == 1 then opaque=" -o" else opaque="" end
if tog3:value() == 1 then win=" -w"    else win=""    end
if tog4:value() == 1 then nwm=" -nwm"  else nwm=""    end
if tog5:value() == 1 then nww=" -nww"  else nww=""    end
os.execute(program..colscheme..stip..opaque..win..nwm..nww..
" -q   "..quals:value()..
" -rn  "..rains:value()..
" -st  "..winds:value()..
" -vs  "..viscs:value()..
" -si  "..skys:value()..
" -li  "..lights:value()..
" -lal "..alts:value()..
" -laz "..azs:value()..
" &")
end

-- MAIN WINDOW
wh = 240
ww = 480
w = fltk:Fl_Window(ww,wh, "xdesktopwaves")

sl = 120    -- slider left edge
sw = 190    -- slider width
sh = 18     -- slider height
st = 10     -- first slider y_position
ss = 20     -- spacing
bw=140      -- button width
bx=ww-bw-ss -- button x position

-- SLIDERS
colors = fltk:Fl_Value_Slider(sl,st,sw,sh,"color scheme ");
colors:type(fltk.FL_HORIZONTAL); colors:align(fltk.FL_ALIGN_LEFT);
colors:step(1); colors:minimum(0); colors:maximum(9); colors:value(0);
colors:tooltip("Preset color schemes ");
--
quals = fltk:Fl_Value_Slider(sl,st+ss,sw,sh,"wave quality ");
quals:type(fltk.FL_HORIZONTAL); quals:align(fltk.FL_ALIGN_LEFT);
quals:step(1); quals:minimum(0); quals:maximum(9); quals:value(5);
quals:tooltip("Overall quality of the waves. \nThe higher the quality, the \nhigher the CPU load. ");
--
rains = fltk:Fl_Value_Slider(sl,st+ss*2,sw,sh,"rain amount ");
rains:type(fltk.FL_HORIZONTAL); rains:align(fltk.FL_ALIGN_LEFT);
rains:step(1); rains:minimum(0); rains:maximum(10); rains:value(0);
rains:tooltip("Simulate raindrops falling on the water ");
--
winds = fltk:Fl_Value_Slider(sl,st+ss*3,sw,sh,"wind amount ");
winds:type(fltk.FL_HORIZONTAL); winds:align(fltk.FL_ALIGN_LEFT);
winds:step(1); winds:minimum(0); winds:maximum(10); winds:value(0);
winds:tooltip("Simulate a storm blowing on the water ");
--
viscs = fltk:Fl_Value_Slider(sl,st+ss*4,sw,sh,"viscosity ");
viscs:type(fltk.FL_HORIZONTAL); viscs:align(fltk.FL_ALIGN_LEFT);
viscs:step(1); viscs:minimum(1); viscs:maximum(5); viscs:value(3);
viscs:tooltip("The higher the viscosity, the \nshorter the lifetime of waves ");
--
skys = fltk:Fl_Value_Slider(sl,st+ss*5,sw,sh,"sky ");
skys:type(fltk.FL_HORIZONTAL); skys:align(fltk.FL_ALIGN_LEFT);
skys:step(1); skys:minimum(1); skys:maximum(10); skys:value(5);
skys:tooltip("Intensity of sky reflections ");
--
lights = fltk:Fl_Value_Slider(sl,st+ss*6,sw,sh,"light ");
lights:type(fltk.FL_HORIZONTAL); lights:align(fltk.FL_ALIGN_LEFT);
lights:step(1); lights:minimum(1); lights:maximum(10); lights:value(5);
lights:tooltip("Intensity of light reflections ");
--
alts = fltk:Fl_Value_Slider(sl,st+ss*7,sw,sh,"altitude ");
alts:type(fltk.FL_HORIZONTAL); alts:align(fltk.FL_ALIGN_LEFT);
alts:step(1); alts:minimum(0); alts:maximum(90); alts:value(30);
alts:tooltip("Altitude of light source \(degrees\) ");
--
azs = fltk:Fl_Value_Slider(sl,st+ss*8,sw,sh,"azimuth ");
azs:type(fltk.FL_HORIZONTAL); azs:align(fltk.FL_ALIGN_LEFT);
azs:step(1); azs:minimum(-360); azs:maximum(360); azs:value(-35);
azs:tooltip("Azimuth of light source \(degrees\) ");

-- CUSTOM COLORS
function get_rgbh(i)
r,g,b=Fl:get_color(i:color(),r,g,b);
h=string.format("\\#%.2X%.2X%.2X",r,g,b);
return r,g,b,h
end

function mycolor(self)
get_rgbh(self);
c_ok,r,g,b=fltk.fl_color_chooser("pick color",r,g,b);
if c_ok == 1 then
Fl:set_color(self:color(),r,g,b)
hex=string.format("\\#%.2X%.2X%.2X",r,g,b)
if self:label() == "water color" then watercolor=hex
elseif self:label() == "sky color" then skycolor=hex
else lightcolor=hex end
end
end
-- colors 15, 6, and 255 are changed dynamically
usemycolor = fltk:Fl_Round_Button(bx,st,bw,ss,"Use My Colors: ");
usemycolor:tooltip("This option is overridden by \na nonzero color scheme");
wcolor = fltk:Fl_Button(bx,st+ss,bw,ss,"water color");
wcolor:color(15); wcolor:callback(mycolor); wcolor:tooltip("water color");
scolor = fltk:Fl_Button(bx,st+ss*2,bw,ss,"sky color");
scolor:color(6); scolor:callback(mycolor); scolor:tooltip("sky color");
hcolor = fltk:Fl_Button(bx,st+ss*3,bw,ss,"light color");
hcolor:color(255); hcolor:callback(mycolor); hcolor:tooltip("light color");
-- set initial "my colors"
z,z,z,watercolor=get_rgbh(wcolor);
z,z,z,skycolor=get_rgbh(scolor);
z,z,z,lightcolor=get_rgbh(hcolor);

-- CONTROLS: start, stop
bstart = fltk.Fl_Return_Button(bx,st+ss*5,bw,ss*2, "start");
bstop = fltk.Fl_Button(bx,st+ss*7,bw,ss*2, "stop");
bstart:callback(start_waves)
function stop_waves() os.execute(program.." -end") end
bstop:callback(stop_waves);
-- TOGGLES
tog1 = fltk:Fl_Round_Button(20,wh-40,80,25, "stipple");
tog1:tooltip("Fake transparency. \nThis option is not as \"transparent\" \nas the default transparency, but \nit is easier on your cpu.");
tog2 = fltk:Fl_Round_Button(110,wh-40,80,25, "opaque");
tog2:tooltip("No transparency ");
tog3 = fltk:Fl_Round_Button(200,wh-40,80,25, "window");
tog3:tooltip("Open in its own normal window \nrather than the root window.\nSome window managers\nmay require \"opaque\" as well.");
tog4 = fltk:Fl_Round_Button(290,wh-40,80,25, "ignore\n mouse");
tog4:tooltip("Mouse cursor does not create waves ");
tog5 = fltk:Fl_Round_Button(380,wh-40,80,25, " ignore\nwindows");
tog5:tooltip("Windows do not create waves ");

w:show()
Fl:run()

Next Page...
original here.