summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPascal Rigaux <pixel@mandriva.com>2009-01-27 17:30:08 +0000
committerPascal Rigaux <pixel@mandriva.com>2009-01-27 17:30:08 +0000
commit5ce8d30439463838f845c78bc926cc9b310a8743 (patch)
treebb1852dc58711c7baee31216a765067dfa49b65b /src
parent10658e71475bd964263d09f1a661f24fadfaf496 (diff)
downloadbootloader-theme-5ce8d30439463838f845c78bc926cc9b310a8743.tar
bootloader-theme-5ce8d30439463838f845c78bc926cc9b310a8743.tar.gz
bootloader-theme-5ce8d30439463838f845c78bc926cc9b310a8743.tar.bz2
bootloader-theme-5ce8d30439463838f845c78bc926cc9b310a8743.tar.xz
bootloader-theme-5ce8d30439463838f845c78bc926cc9b310a8743.zip
imported openSUSE.tar.bz2 (from gfxboot-4.1.19-2.1.src.rpm)4.1.19.1
Diffstat (limited to 'src')
-rw-r--r--src/Makefile16
-rw-r--r--src/bsplash.inc291
-rw-r--r--src/button.inc116
-rw-r--r--src/common.inc1682
-rw-r--r--src/dia_about.inc75
-rw-r--r--src/dia_bits.inc101
-rw-r--r--src/dia_dud.inc165
-rw-r--r--src/dia_help.inc46
-rw-r--r--src/dia_install.inc344
-rw-r--r--src/dia_kernelopts.inc94
-rw-r--r--src/dia_keymap.inc105
-rw-r--r--src/dia_lang.inc309
-rw-r--r--src/dia_profile.inc137
-rw-r--r--src/dia_video.inc263
-rw-r--r--src/help.inc684
-rw-r--r--src/keytables.inc62
-rw-r--r--src/locale.inc267
-rw-r--r--src/main.bc30
-rw-r--r--src/menu.inc488
-rw-r--r--src/panel.inc201
-rw-r--r--src/penguin.inc351
-rw-r--r--src/serial.inc517
-rw-r--r--src/speech.inc121
-rw-r--r--src/system.inc1406
-rw-r--r--src/timeout.inc149
-rw-r--r--src/window.inc711
-rw-r--r--src/xmenu.inc414
27 files changed, 9145 insertions, 0 deletions
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..886441a
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,16 @@
+BINDIR := $(shell [ -x ../../../gfxboot-compile ] && echo ../../../ )
+
+GFXBOOT_COMPILE = $(BINDIR)gfxboot-compile
+BFLAGS = -O -v -L ../..
+
+all: main.bin
+
+main.bin: main.bc *.inc ../po/.ready
+ $(GFXBOOT_COMPILE) $(BFLAGS) -l main.log -c main.bc $@
+
+../po/.ready:
+ make -C ../po
+
+clean:
+ rm -f main.bin *.log *~
+
diff --git a/src/bsplash.inc b/src/bsplash.inc
new file mode 100644
index 0000000..0b93692
--- /dev/null
+++ b/src/bsplash.inc
@@ -0,0 +1,291 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Boot loader splash code.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Some global vars.
+
+/.b_init 0 def
+/.b_done 1 def
+/.b_run 2 def
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Init splash.
+%
+% ( ) ==> ( )
+%
+/bsplash.init {
+ /bsplash.list [
+ config.welcome 2 eq { [ /b1.init /b1.done /b1.run ] } if
+ [ /b2.init /b2.done /b2.run ]
+ ] def
+
+ bsplash.list { dup .b_init get exec } forall
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Free splash memory.
+%
+% ( ) ==> ( )
+%
+/bsplash.free {
+ bsplash.list { dup .b_done get exec } forall
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show boot loader splash.
+%
+% ( ) ==> ( )
+%
+/bsplash.show {
+ currentimage
+
+ "welcome.jpg" findfile /splash.file over def setimage
+
+ 0 0 moveto 0 0 image.size image
+
+ bsplash.init
+
+ bsplash.skip not { 100000 usleep } if
+
+ bsplash.skip not {
+ {
+ 0 usleep
+ bsplash.skip { exit } if
+ bsplash.run { exit } if
+ } loop
+ } if
+
+ bsplash.free
+
+ setimage
+
+ /splash.file xfree
+
+} def
+
+
+% Run splash animations. Return 'true' when done.
+%
+% ( ) ==> ( true|false )
+%
+/bsplash.run {
+ true
+
+ bsplash.list { dup .b_run get exec and } forall
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Just wait.
+%
+% ( ) ==> ( )
+%
+/bsplash.done {
+ bsplash.skip not {
+ 1500000 usleep
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Check if we should skip the intro.
+%
+% ( ) ==> ( true|false )
+%
+/bsplash.skip {
+ % any key pressed?
+ getkey 0xffff and {
+ /bsplash.skip true def
+ true
+ } {
+ false
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Init.
+%
+% ( array ) ==> ( )
+%
+/b1.init {
+ pop
+
+ /b1_ok false def
+
+ /b1_cd "cd.jpg" readimage def
+ /b1_cd_mask "cd_a.jpg" readimage def
+
+ b1_cd .undef eq b1_cd_mask .undef eq or { return } if
+
+ /b1_cd_tmp b1_cd imgsize 0 0 moveto savescreen def
+
+ 20 350 moveto
+ /b1_orig 300 150 savescreen def
+ /b1_buf 300 150 savescreen def
+
+ /b1_idx 0 def
+ /b1_steps 20 def
+
+ /b1_ok true def
+} def
+
+
+/b1_x [ 0 2 6 15 25 37 51 67 83 98 113 125 136 144 148 150 ] def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Cleanup.
+%
+% ( array ) ==> ( )
+%
+/b1.done {
+ pop
+
+ b1_ok not { return } if
+
+ /b1_cd xfree
+ /b1_cd_mask xfree
+ /b1_cd_tmp xfree
+
+ /b1_orig xfree
+ /b1_buf xfree
+
+ /b1_ok false def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Run animation.
+%
+% Return true when finished.
+%
+% ( array ) ==> ( true|false )
+%
+/b1.run {
+ pop
+
+ b1_ok not { true return } if
+
+ /b1_idx inc
+
+ b1_idx b1_steps gt { true return } if
+
+ b1_buf b1_orig over length memcpy
+
+ b1_cd_tmp b1_cd_mask over length memcpy
+ 0 255 b1_idx 20 mul sub 0 max b1_cd_tmp blend
+
+ /b1_dx_cur b1_x b1_idx aget dup .undef eq { pop 150 } if def
+
+ 150 0 moveto
+ b1_cd b1_cd_tmp b1_buf blend
+
+ 150 b1_dx_cur 2 div sub 0 moveto
+ b1_cd b1_cd_tmp b1_buf blend
+
+ 150 b1_dx_cur sub 0 moveto
+ b1_cd b1_cd_tmp b1_buf blend
+
+
+ 20 350 moveto b1_buf restorescreen
+
+ false
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Init.
+%
+% ( array ) ==> ( )
+%
+/b2.init {
+ pop
+
+ /b2_ok false def
+
+ /b2_text "text.jpg" readimage def
+ % /b2_spot "spotlite.jpg" readimage def
+
+ b2_text .undef eq { return } if
+
+ /b2_text_tmp b2_text imgsize 0 0 moveto savescreen def
+ % /b2_spot_tmp b2_spot imgsize 0 0 moveto savescreen def
+
+ 600 160 moveto
+ /b2_orig b2_text imgsize savescreen def
+ /b2_buf b2_text imgsize savescreen def
+
+ /b2_idx 0 def
+ /b2_start 10 def
+ /b2_steps 20 def
+
+ /b2_ok true def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Cleanup.
+%
+% ( array ) ==> ( )
+%
+/b2.done {
+ pop
+
+ b2_ok not { return } if
+
+ /b2_text xfree
+ /b2_text_tmp xfree
+
+ /b2_orig xfree
+ /b2_buf xfree
+
+ /b2_ok false def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Run animation.
+%
+% Return true when finished.
+%
+% ( array ) ==> ( true|false )
+%
+/b2.run {
+ pop
+
+ b2_ok not { true return } if
+
+ /b2_idx inc
+
+ b2_idx b2_start b2_steps add gt { true return } if
+
+ b2_idx b2_start lt { false return } if
+
+ b2_buf b2_orig over length memcpy
+
+ b2_text_tmp b2_text over length memcpy
+ 0 255 b2_idx b2_start sub 20 mul sub 0 max b2_text_tmp blend
+
+ % b2_spot_tmp b2_spot over length memcpy
+ % 0 255 b2_idx b2_start sub 20 mul sub 0 max b2_spot_tmp blend
+
+ % 0 0 moveto
+ % 0x80ff80 b2_spot_tmp b2_buf blend
+ 0 0 moveto
+ 0xffffff b2_text_tmp b2_buf blend
+
+ 600 160 moveto b2_buf restorescreen
+
+ false
+
+} def
+
+
diff --git a/src/button.inc b/src/button.inc
new file mode 100644
index 0000000..372ef54
--- /dev/null
+++ b/src/button.inc
@@ -0,0 +1,116 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% button handling
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Button templates.
+%
+% [ x y width height label selected hotkey action ]
+%
+/button.ok { [ 0 0 90 25 txt_ok false 0 0 ] } def
+/button.cancel { [ 0 0 90 25 txt_cancel false keyEsc 0 ] } def
+/button.reboot { [ 0 0 90 25 txt_reboot false 0 0 ] } def
+/button.continue { [ 0 0 90 25 txt_continue false 0 0 ] } def
+% /button.eject { [ 0 0 90 25 "Eject" false 0 0 ] } def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Set default button.
+%
+% ( button ) => ( button )
+%
+/button.default {
+ dup 5 true put
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Make it _not_ the default button.
+%
+% ( button ) => ( button )
+%
+/button.notdefault {
+ dup 5 false put
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Set button position.
+%
+% ( button x y ) ==> ( button )
+%
+/button.moveto {
+ rot dup 0 5 -1 roll put exch over 1 rot put
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Assign action to button.
+%
+% ( button action ) => ( button )
+%
+/button.setaction {
+ over 7 rot put
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Draw button.
+%
+% ( button ) ==> ( )
+%
+/button.show {
+ /bt.x over 0 get def
+ /bt.y over 1 get def
+ /bt.width over 2 get def
+ /bt.height over 3 get def
+ /bt.text over 4 get def
+ /bt.default exch 5 get def
+
+ bt.text strsize
+ bt.height sub neg 2 div /bt.y.textofs exch def
+ bt.width sub neg 2 div /bt.x.textofs exch def
+
+ bt.x bt.y moveto
+ currentpoint currentpoint currentpoint
+
+ currentpoint bt.width bt.height window.current .color.bg get setcolor fillrect moveto
+
+ bt.default {
+ black black
+ } {
+ window.current .color.bg get dup
+ } ifelse
+ bt.width bt.height drawborder
+ moveto 1 1 rmoveto white black bt.width 2 sub bt.height 2 sub drawborder
+ moveto
+ % 2 2 rmoveto white black bt.width 4 sub bt.height 4 sub drawborder
+
+ window.current .color.fg get setcolor
+ moveto bt.x.textofs bt.y.textofs rmoveto bt.text show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Press button.
+%
+% ( button ) ==> ( )
+%
+/button.press {
+ /bt.x over 0 get def
+ /bt.y over 1 get def
+ /bt.width over 2 get def
+ /bt.height exch 3 get def
+
+ bt.x 3 add bt.y 3 add moveto
+ bt.width 7 sub bt.height 7 sub savescreen
+ 1 1 rmoveto dup restorescreen free
+
+ bt.x 1 add bt.y 1 add moveto black white bt.width 2 sub bt.height 2 sub drawborder
+ % bt.x 2 add bt.y 2 add moveto black white bt.width 4 sub bt.height 4 sub drawborder
+} def
+
+
diff --git a/src/common.inc b/src/common.inc
new file mode 100644
index 0000000..b527464
--- /dev/null
+++ b/src/common.inc
@@ -0,0 +1,1682 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Main part.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+% max command line length
+/cmdlinelength 512 def
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Install source is 64bit?
+%
+% ( ) ==> ( true|false )
+%
+/64bit_source {
+ % 64 bit dir exists and is != 32 bit dir
+ 64bit_boot_dir 32bit_boot_dir ne
+ 64bit_boot_dir .undef ne and
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Are we a dvd?
+%
+% ( ) ==> ( true|false )
+%
+/is_dvd {
+ % check only once
+ is_dvd.result .undef ne { is_dvd.result return } if
+
+ /is_dvd.result
+ mediatype m_cdrom eq {
+ 0x10 readsector
+ dup 0x50 add getdword exch free
+ 9 shr % iso size in MB
+ 720 gt % assume dvd if > 720 MB
+ } {
+ false
+ } ifelse
+ def
+
+ is_dvd.result return
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Install source is 32 & 64bit?
+%
+% ( ) ==> ( true|false )
+%
+/32+64bit_source {
+ 32bit_boot_dir .undef ne
+ % uncomment next line to automatically warn about 32bit software on 64bit machines, too
+ % 64bit_boot_dir .undef ne and
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Enough memory?
+%
+% ( ) ==> ( true|false )
+%
+/enough_mem {
+ biosmem 4 20 shl lt
+ biosmem mem.check 20 shl ge or
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Check if there are boot directories for 32 & 64bit.
+%
+% Assumes 32bit to be in *i386* and 64bit in *x86_64*.
+%
+% ( ) ==> ( )
+%
+/check_arch_boot_dir {
+ getcwd dup .undef ne {
+ /64bit.tmp 256 string def
+
+ dup "i386" strstr 0 ne over "x86_64" strstr 0 ne or {
+ dup "i386" strstr {
+ /32bit_boot_dir exch def
+ /64bit_boot_dir 32bit_boot_dir "i386" "x86_64" strreplace
+ } {
+ /64bit_boot_dir exch def
+ /32bit_boot_dir 64bit_boot_dir "x86_64" "i386" strreplace
+ } ifelse
+
+ dup "%s/isolinux.cfg" 64bit.tmp sprintf
+ 64bit.tmp filesize .undef ne { def } { free pop } ifelse
+
+ } {
+ /32bit_boot_dir over def
+ /64bit_boot_dir exch def
+ } ifelse
+
+ 64bit.tmp free
+
+ % font.normal setfont
+ % 0 400 moveto 32bit_boot_dir print
+ % 0 420 moveto 64bit_boot_dir print dtrace
+
+ } {
+ pop
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% input event handling
+%
+% ( key ) ==> ( input_buffer menu_entry action )
+%
+% key
+% bit 0-7 ascii
+% bit 8-15 scan code
+% bit 16-32 status bits (ctrl, shift...)
+%
+% action
+% 0: ok, stay in input loop
+% 1: switch to text mode
+% >=2: start linux
+%
+/KeyEvent {
+ % timeout
+
+ dup 0 eq { boot.ed.list buildcmdline 2 return } if
+
+ debug 4 ge {
+ % print keycode somewhere
+ -1 settransparentcolor
+ white setcolor
+ 500 0 moveto dup print " " print
+ } if
+
+ dup 0xff00 and 16 shl over 0xff and dup 0xe0 eq { pop 0 } if add /key exch def
+ 16 shr 0xffff and /keystat exch def
+
+ key 24 shr 0xff and dup 0xf0 ge exch 0xf4 le and { key serial.input return } if
+
+ key
+
+ config.keymap { mapkey } if
+
+ dup 0xffffff and dup { exch } if pop
+
+ debug 4 ge {
+ % print mapped key somewhere
+ -1 settransparentcolor
+ white setcolor
+ 500 20 moveto dup print " " print
+ } if
+
+ ptheme {
+ % reverse direction
+ /p.xmas.dx p.xmas.dx neg def
+
+ key keyF9 eq
+ key keyF7 eq or {
+ % call super penguin
+ p.call.super
+ } {
+ key keyF1 ge
+ key keyF10 le and {
+ % read something
+ /p.read.timer rand 0x31 and neg -30 add def
+ } if
+ } ifelse
+
+ } if
+
+ % some special keys
+ debug.input
+
+ % put key through normal input queue
+ window.input
+
+ pop
+
+ window.action actExit eq {
+ /window.action actNothing def
+ "" -1 1 return
+ } if
+
+ window.action actCloseInfo eq {
+ /window.action actNothing def
+ % cd change dialog
+ info.type 5 eq info.type 6 eq or {
+ % 'chdir' triggers fs metadata re-read
+ getcwd dup .undef ne { chdir } { pop } ifelse
+ } if
+
+ "" -1 3 return
+ } if
+
+ window.action actPassword eq {
+ /window.action actNothing def
+ password.dialog {
+ password.dialog .ed.buffer.list get 0 get
+ } { "" } ifelse
+ -1 3 return
+ } if
+
+ window.action actStart eq {
+ /window.action actNothing def
+ /load_error false def
+
+ syslinux {
+ menu.texts menu.entry 0 max menu.texts length 1 sub min get
+ dup "mem.min[%s]" mem.min sprintf
+ "mem.msg[%s]" mem.msg sprintf
+
+ enough_mem not {
+ nomem_popup
+ "" -1 0 return
+ } if
+ } if
+
+ % some tricks to make it possible to review the complete command line
+ debug 3 ge xxx.cmdline .undef eq and {
+ /window.action actNothing def
+
+ boot.ed.list buildcmdline /xxx.menu exch def /xxx.cmdline exch def
+
+ /dia window.dialog def
+ dia .title "Kernel command line" put
+ dia .text "" put
+ % Must all be of same size!
+ dia .ed.list 1 array put
+ dia .ed.buffer.list [ xxx.cmdline ] put
+ dia .ed.text.list [ "All options\n" ] put
+
+ dia .ed.focus 0 put
+ dia .ed.width 600 put
+ dia .ed.font font.normal put
+ dia .buttons
+ [ button.ok button.default actStart button.setaction ]
+ put
+ dia window.init
+ dia window.show
+
+ "" -1 0
+ } {
+ sound.done
+
+ xxx.cmdline .undef ne {
+ xxx.cmdline xxx.menu
+ /xxx.cmdline .undef def
+ } {
+ boot.ed.list buildcmdline
+ } ifelse
+ 2 return
+ } ifelse
+ } if
+
+ window.action actRedraw eq {
+ /window.action actNothing def
+ main.redraw
+ } if
+
+ window.action actRedrawPanel eq {
+ /window.action actNothing def
+ panel.show
+ } if
+
+ window.action actInstallOK eq {
+ /window.action actNothing def
+ install.ok
+ } if
+
+ window.action actInstallCancel eq {
+ /window.action actNothing def
+ install.cancel
+ } if
+
+ "" -1 0
+} def
+
+
+/bc.cmd cmdlinelength string def
+/mem.min 128 string def
+/mem.msg 256 string def
+
+
+% ( edit_object_list ) ==> ( cmdline menu_entry )
+%
+/buildcmdline {
+ menu.entry 0 lt menu.entry menu.texts length ge or { pop "" -1 return } if
+
+ [ over
+ {
+ dup .inp_show get {
+ build1cmdline strdup
+ } {
+ pop
+ } ifelse
+ } forall
+
+ % empty? -> pass at least the first edit object
+ dup [ eq { over 0 get build1cmdline strdup } if
+
+ ]
+
+ dup boot.splitstr join bc.cmd over strcpy pop free
+ dup { free } forall free
+
+ pop bc.cmd menu.entry
+
+} def
+
+
+% ( edit_object ) ==> ( cmdline )
+%
+% grub:
+% just return
+%
+% syslinux & lilo:
+% add kernel name at start of command line
+%
+/build1cmdline {
+ syslinux {
+ % set new working directory
+ xmenu.bits .xm_current get 1 eq { 64bit_boot_dir } { 32bit_boot_dir } ifelse
+ dup .undef ne {
+ dup getcwd ne { chdir } { pop } ifelse
+ } {
+ pop
+ } ifelse
+ } if
+ % getcwd 0 300 moveto show trace
+
+ % lilo & syslinux: prepend kernel/label name
+ grub {
+ bc.cmd 0 0 put
+ } {
+ menu.texts menu.entry get "%s " bc.cmd sprintf
+ } ifelse
+
+ syslinux {
+ /splash_file 32 string def
+
+ video.modes.list xmenu.video .xm_current get get
+ dup .vm_mode get 0 ge {
+ dup .vm_height get exch .vm_width get
+ ",%04d%04d.spl" splash_file sprintf
+ } { pop } ifelse
+
+ % check whether splash file exists
+ splash_file 1 add filesize .undef eq {
+ splash_file 0 0 put % empty string
+ } if
+ } if
+
+ xmenu.kernelopts {
+ kernelopts.options xmenu.kernelopts .xm_current get get dup "" ne {
+ "%s " bc.cmd dup length add sprintf
+ } { pop } ifelse
+ } if
+
+ /cmdline.hidden over dup length .inp_hidden ge { .inp_hidden get } { pop .undef } ifelse def
+
+ cmdline.hidden {
+ cmdline.hidden "" ne {
+ splash_file {
+ /bc.tmp cmdline.hidden length splash_file length add string def
+ cmdline.hidden "initrd=" bootopt.find dup .undef ne {
+ skipnonspaces
+ dup
+ dup 0 get over 0 0 put
+ splash_file cmdline.hidden "%s%s" bc.tmp sprintf
+ 0 exch put
+ "%s" bc.tmp dup length add sprintf
+ } {
+ pop
+ bc.tmp cmdline.hidden strcpy pop
+ } ifelse
+
+ bc.tmp "%s " bc.cmd dup length add sprintf
+
+ bc.tmp free /bc.tmp .undef def
+ } {
+ cmdline.hidden "%s " bc.cmd dup length add sprintf
+ } ifelse
+ } if
+ } if
+
+ /splash_file xfree
+
+ syslinux {
+ video.modes.list xmenu.video .xm_current get get .vm_mode get
+
+ dup 0 ge {
+ 0x200 add "vga=0x%x " bc.cmd dup length add sprintf
+ } {
+ -1 eq {
+ "textmode=1 " bc.cmd dup length add sprintf
+ } if
+ } ifelse
+
+ config.lang {
+ config.lang "en_US" ne {
+ config.lang "lang=%s " bc.cmd dup length add sprintf
+ } if
+ } if
+
+ v_impaired 1 ge {
+ "braille=1 " bc.cmd dup length add sprintf
+ } if
+
+ v_impaired 2 ge {
+ "linemode=1 " bc.cmd dup length add sprintf
+ } if
+ } if
+
+ xmenu.dud {
+ xmenu.dud .xm_current get .dud_url eq {
+ input.edit.dud_url 0 get dup "" ne {
+ "dud=%s " bc.cmd dup length add sprintf
+ } { pop } ifelse
+ } {
+ xmenu.dud .xm_current get .dud_file eq {
+ input.edit.dud_file 0 get dup "" ne {
+ "driverupdate=%s " bc.cmd dup length add sprintf
+ } { pop } ifelse
+ } {
+ dud.options xmenu.dud .xm_current get get dup "" ne {
+ "%s " bc.cmd dup length add sprintf
+ } { pop } ifelse
+ } ifelse
+ } ifelse
+ } if
+
+ xmenu.profile {
+ profile.options xmenu.profile .xm_current get get dup "" ne {
+ "%s " bc.cmd dup length add sprintf
+ } { pop } ifelse
+ } if
+
+ xmenu.install {
+ config.noinstallopt menu.texts menu.entry get iselement not {
+ install.option "" ne {
+ install.option "%s " bc.cmd dup length add sprintf
+ } if
+ } if
+ } if
+
+ % add user-supplied options
+
+ bc.cmd exch .inp_buf get strcat " " strcat pop
+
+ % remove all but last 'vga' & 'initrd' options
+ [ "vga" "initrd" ] dup {
+ {
+ bc.cmd over bootopt.find2 .undef eq { pop exit } if
+ bc.cmd over bootopt.remove free
+ } loop
+ } forall free
+
+ bc.cmd "driverupdate" bootopt.find dup .undef ne {
+ % exclude 'driverupdate=0 and driverupdate=1'
+ "driverupdate=" length get
+ dup '0' ne exch '1' ne and {
+
+ /bc.tmp bc.cmd "driverupdate" bootopt.remove def
+ bc.tmp .undef ne {
+ /bc.tmp bc.tmp "driverupdate=" length add ',' split bc.tmp free def
+ /bc.tmp2 cmdlinelength string def
+
+ bc.tmp2 "initrd=" strcpy pop
+
+ bc.tmp length 0 gt {
+ % add '+' to first arg unless it starts with '+' or '-'
+ bc.tmp 0 get 0 get
+ dup '-' eq { % remove '-'
+ bc.tmp 0 get dup 1 add strdup exch free
+ bc.tmp exch 0 exch put
+ pop '+'
+ } if
+ '+' ne { % add '+'
+ bc.tmp 0 get length 1 add string "+" strcat bc.tmp 0 get strcat
+ bc.tmp 0 get free bc.tmp exch 0 exch put
+ } if
+
+ bc.tmp length 1 sub -1 0 {
+ bc.tmp exch get
+ bc.tmp2 exch strcat "," strcat pop
+ } for
+ } if
+
+ bc.tmp dup { free } forall free
+
+ % last 'initrd' option
+ /bc.tmp .undef def
+ {
+ bc.cmd "initrd" bootopt.remove dup .undef ne {
+ bc.tmp free /bc.tmp exch def
+ } {
+ pop exit
+ } ifelse
+ } loop
+
+ % re-add new 'initrd' option
+ bc.tmp {
+ bc.tmp2 bc.tmp "initrd=" length add strcat pop
+ bc.tmp free
+ bc.cmd bc.tmp2 strcat " " strcat pop
+ } if
+ } if
+
+ } if
+ } { pop } ifelse
+
+ syslinux {
+ % find out initrd sizes for kernel loading progress bar
+ bc.cmd "initrd" bootopt.find dup .undef ne {
+ "initrd=" length add
+ dup dup skipnonspaces
+ sub neg
+ string
+ exch strcpy
+ % it's a ',' separated list
+ dup ',' split exch free
+ dup
+ {
+ dup
+ % skip leading '+' or '-'
+ dup 0 get dup '+' eq exch '-' eq or { 1 add } if
+ filesize dup .undef ne {
+ sectorsize 1 sub add
+ sectorsize div /progress_extra exch progress_extra add def
+ } { pop } ifelse
+ free
+ } forall
+ free
+ } { pop } ifelse
+ } if
+
+ % remove final space
+ bc.cmd dropspaces
+
+ bc.cmd
+} def
+
+
+/iso.needscheck {
+ false
+
+ /i_tmp 0x10 readsector def
+ i_tmp {
+ i_tmp dup length 1 sub 0 put
+ /i_tmp2 i_tmp 0x373 add cvs def
+ i_tmp2 "check=1" strstr {
+ pop true
+ } if
+
+ i_tmp free
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( menu_entries_array cmdline_args_array defaultentry ) == > ( )
+/MenuInit {
+ bsplash.done
+
+ colorbits 8 le {
+ 0 setcolor 0 0 moveto screen.size fillrect loadpalette
+ } if
+
+ init
+
+ /menu.entry -1 def
+
+ /menu.dentry exch def
+ /menu.args exch def
+ /menu.texts exch def
+
+ /mi_name "mediacheck" "" gfxconfig.set.str
+
+ mi_name {
+ /remove.mediachk false def
+ sectorsize 0x800 eq {
+ /remove.mediachk iso.needscheck not def
+ } if
+ } {
+ /remove.mediachk false def
+ } ifelse
+
+ remove.mediachk menu.dentry mi_name ne and {
+ /mi_tmp 0 def
+ menu.texts {
+ mi_name eq { exit } if
+ /mi_tmp inc
+ } forall
+
+ mi_tmp menu.texts length lt {
+ /mi_tmp2 0 def
+ /menu.texts
+ [
+ menu.texts { mi_tmp2 mi_tmp eq { pop } if /mi_tmp2 inc } forall
+ ]
+ def
+
+ /mi_tmp2 0 def
+ /menu.args
+ [
+ menu.args { mi_tmp2 mi_tmp eq { pop } if /mi_tmp2 inc } forall
+ ]
+ def
+ } if
+ } if
+
+ window.main
+ dup window.init
+ window.show
+
+ config.beep { 3000 50000 beep } if
+
+ config.talk {
+ load_talk_dialog
+ menu.texts menu.idx get menuitemmap speak
+ } if
+
+ syslinux {
+ 32+64bit_source not {
+
+ 64bit {
+ 64bit_source not { notimeout 32bit_popup } if
+ } {
+ 64bit_source { notimeout 64bit_popup } if
+ } ifelse
+
+ } if
+ } if
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( text errorcode ) ==> ( )
+% errorcode:
+% 0 normal info
+% 1 fatal error
+% 2 missing file
+% 3 disk change
+% 4 disk change failed
+% 5 ask for cd change
+% 6 change cd back to original
+%
+
+/info.tmpmsg 256 string def
+
+/InfoBoxInit {
+ /info.type exch def
+ /info.msg exch def
+
+ window.dialog
+
+ info.type 1 eq {
+ dup .title.bg window.title.error.bg put
+ dup .title txt_error_title put
+ dup .buttons
+ [
+ button.reboot button.default actCloseInfo button.setaction
+ ] put
+ } {
+ dup .title txt_info_title put
+ dup .buttons
+ [
+ button.ok button.default actCloseInfo button.setaction
+% button.cancel button.notdefault actCloseInfo button.setaction
+ ] put
+ } ifelse
+
+ syslinux info.type 2 eq and {
+ dup .title "I/O Error" put
+ info.msg "File not found: %s" info.tmpmsg sprintf
+ /info.msg info.tmpmsg def
+ /load_error true def
+ } if
+
+ syslinux info.type 3 eq and {
+ dup .title txt_change_disk_title put
+ 0 getinfo 1 add txt_insert_disk info.tmpmsg sprintf
+ /info.msg info.tmpmsg def
+ } if
+
+ syslinux info.type 4 eq and {
+ dup .title txt_change_disk_title put
+ 1 getinfo 15 not and {
+ 0 getinfo 1 add
+ txt_insert_disk3 info.tmpmsg sprintf
+ } {
+ 0 getinfo 1 add 1 getinfo 1 add
+ txt_insert_disk2 info.tmpmsg sprintf
+ } ifelse
+ /info.msg info.tmpmsg def
+ } if
+
+ syslinux info.type 5 eq and {
+ dup .title "Driver Update" put
+ info.msg "Insert driver update CD-ROM for\n\"%s\"." info.tmpmsg sprintf
+ /info.msg info.tmpmsg def
+ } if
+
+ syslinux info.type 6 eq and {
+ dup .title "Driver Update" put
+ /info.msg "Put the openSUSE CD-ROM back into the drive." def
+ } if
+
+ dup .text info.msg put
+
+ serial.line.status {
+ serial.infobox .undef eq {
+ /serial.infobox .xm_size array def
+ serial.infobox .xm_current 0 put
+ } if
+
+ serial.infobox .xm_title 2 index .title get put
+ serial.infobox .xm_text info.msg put
+ serial.infobox .xm_list [ info.type 1 eq { "reboot" } { "ok" } ifelse ] put
+
+ serial.infobox.setup
+ } if
+
+ dup window.init
+ window.show
+
+} def
+
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+% progress bar code
+
+
+% Show percentage of progress bar.
+%
+% ( percentage ) ==> ( )
+%
+/progress.percent {
+ 0 max 100 min % so people don't ask silly questions...
+ "100%" strsize over neg progress.text.x add progress.text.y moveto
+ window.current .color.bg get setcolor
+ fillrect
+
+ "%3u%%" 8 string dup 4 1 roll sprintf
+
+ dup strsize pop neg progress.text.x add progress.text.y moveto
+ window.current .color.fg get setcolor
+
+ serial.line.status {
+ "\x08\x08\x08\x08" serial.show
+ dup serial.show
+ } if
+
+ dup show
+ free
+
+} def
+
+
+% Show n-th progress bar symbol.
+%
+% ( n ) ==> ( )
+%
+/progress.sym.show {
+ /progress.sym.current exch def
+
+ progress.bar.x progress.bar.y moveto
+ progress.sym.width progress.sym.current 1 sub mul 1 add 1 rmoveto
+ progress.sym.width 2 sub
+ progress.bar.height 2 sub
+ progress.bar.color setcolor
+ fillrect
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( kernel_name ) ==> ( )
+/ProgressInit {
+ /progress.kname exch def
+
+ boot.ed.list { edit.hidecursor } forall
+
+ /dia window.dialog def
+
+ dia .width.min 350 put
+ dia .position 10 put
+
+ dia .title txt_load_kernel_title put
+ dia .text
+ progress.kname "memtest" eq {
+ txt_load_memtest
+ } {
+ txt_load_kernel
+ } ifelse
+ put
+
+ dia window.init
+ dia window.show
+
+ % now add progress bar
+
+ dia .x get dia .y get moveto
+ dia .text.x get dia .text.y get 28 add rmoveto
+
+ /progress.bar.height 19 def
+ /progress.bar.width dia .width get 75 sub def
+
+ /progress.sym.width 10 def
+ /progress.bar.width
+ progress.bar.width progress.sym.width div
+ /progress.syms over def progress.sym.width mul
+ def
+
+ currentpoint over 1 sub over 2 sub moveto
+ black white progress.bar.width 2 add progress.bar.height 4 add drawborder
+
+ /progress.bar.y exch def
+ /progress.bar.x exch def
+
+ /progress.text.x progress.bar.x progress.bar.width 55 add add def
+ /progress.text.y progress.bar.y progress.bar.height fontheight sub 2 div add def
+
+ /progress.sym.current 0 def
+
+ 0 progress.percent
+
+ serial.line.status {
+ "\n" serial.show
+ dia .text get serial.show
+ " 0%" serial.show
+ } if
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( ) ==> ( )
+/ProgressDone {
+ window.done
+
+ load_error {
+ /load_error false def
+ boot.ed.list boot.window .ed.focus get get edit.showcursor
+ } if
+
+ serial.line.status { "\n\n" serial.show } if
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( max current ) ==> ( )
+%
+% Note: max is just kernel size (in sectors).
+%
+/ProgressUpdate {
+ exch progress_extra add exch
+
+ over over 100 mul exch 1 max div progress.percent
+
+ progress.syms mul progress.syms 2 div add exch 1 max div
+
+ 0 max progress.syms min
+
+ dup progress.sym.current gt {
+ progress.sym.current 1 add over 1 exch {
+ progress.sym.show
+ } for
+ } if
+ pop
+
+} def
+
+% initrd size (in sectors)
+/progress_extra 0 def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( time ) ==> ( )
+% /Timer { pop } def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( label correct_password ) ==> ( )
+%
+/PasswordInit {
+ /password.key exch def pop
+
+ /dia window.dialog def
+
+ /password.dialog dia def
+
+ dia .title txt_password_title put
+ dia .text "" put
+
+ % Must all be of same size!
+ dia .ed.list 1 array put
+ dia .ed.buffer.list [ 31 string ] put
+ dia .ed.text.list [ txt_password ] put
+
+ dia .ed.focus 0 put
+
+ dia .ed.width 200 put
+
+ dia .ed.font font.normal pwmode put
+
+ dia .buttons
+ [ button.ok button.default actPassword button.setaction ]
+ put
+
+ dia window.init
+ dia window.show
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( password ) ==> ( error )
+%
+% error:
+% true password ok
+% false wrong password
+%
+% ****** FIXME: test result seems to be unused
+%
+/PasswordDone {
+
+ password.key eq
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( text ) == > ( new_text )
+/menuitemmap {
+ translate
+ config._2space {
+ /mmm.tmp xfree
+ strdup /mmm.tmp over def
+ dup length 0 gt {
+ 0 1 2 index length 1 sub {
+ over over get '_' eq { over exch ' ' put } { pop } ifelse
+ } for
+ } if
+ } if
+ dup "memtest" eq over "memtest86" eq or { pop txt_memtest return } if
+ dup "firmware" eq { pop txt_firmware return } if
+ syslinux {
+ dup "live" eq { pop "openSUSE LiveCD" return } if
+ dup "kde" eq { pop "LiveCD - KDE" return } if
+ dup "gnome" eq { pop "LiveCD - GNOME" return } if
+ dup "linux" eq { pop txt_install return } if
+ dup "failsafe" eq { pop txt_safe_install return } if
+ dup "noacpi" eq { pop txt_noacpi_install return } if
+ dup "noapic" eq { pop txt_noapic_install return } if
+ dup "nolapic" eq { pop txt_nolapic_install return } if
+ dup "apic" eq { pop txt_apic return } if
+ dup "manual" eq { pop txt_manual_install return } if
+ dup "repair" eq { pop txt_repain_system return } if
+ dup "rescue" eq { pop txt_rescue return } if
+ dup "hwcheck" eq { pop "Hardware Check" return } if
+ dup "harddisk" eq { pop txt_boot_harddisk return } if
+ dup "mediachk" eq { pop txt_mediacheck return } if
+ dup "mediacheck" eq { pop txt_mediacheck return } if
+ } {
+ dup "linux" eq { pop "Linux" return } if
+ dup "failsafe" eq { pop txt_safe_linux return } if
+ dup "windows" eq { pop "Windows" return } if
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( color0 color1 width height ) ==> ( )
+/drawborder {
+ currentpoint /db.y0 exch def /db.x0 exch def
+
+ /db.y1 exch 1 sub db.y0 add def
+ /db.x1 exch 1 sub db.x0 add def
+ /db.col1 exch def
+ /db.col0 exch def
+
+ db.x0 db.y1 moveto
+
+ db.col0 setcolor
+ db.x0 db.y0 lineto db.x1 db.y0 lineto
+
+ db.col1 setcolor
+ db.x1 db.y1 lineto db.x0 db.y1 lineto
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( color0 color1 color2 width height ) ==> ( )
+% draw frame with shadow
+% color0: upper left, color1: lower right, color2: shadow
+/drawborder3 {
+ currentpoint /db.y0 exch def /db.x0 exch def
+
+ /db.y1 exch 1 sub db.y0 add def
+ /db.x1 exch 1 sub db.x0 add def
+ /db.col2 exch def
+ /db.col1 exch def
+ /db.col0 exch def
+
+ db.x0 db.y1 moveto
+
+ db.col0 setcolor
+ db.x0 db.y0 lineto db.x1 db.y0 lineto
+
+ db.col1 setcolor
+ db.x1 db.y1 lineto db.x0 db.y1 lineto
+
+ db.col2 -1 ne {
+ db.col2 setcolor
+ 1 1 rmoveto
+ db.x1 1 add db.y1 1 add lineto
+ db.x1 1 add db.y0 1 add lineto
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( color0 color1 width height ) ==> ( )
+/drawborder4 {
+ 3 index 4 1 roll rot dup 3 index 3 index
+ currentpoint 6 2 roll
+ 1 1 rmoveto drawborder
+ moveto drawborder
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% center text
+% ( text width height ) ==> ( )
+/centertext {
+ 3 -1 roll strsize
+ 4 2 roll
+ 4 1 roll exch 4 1 roll sub 2 div neg 3 1 roll sub 2 div neg
+} def
+
+
+% ( img ) => ( width heigh )
+/imgsize {
+ dup .undef eq {
+ pop 0 0
+ } {
+ getdword dup
+ 0xffff and exch 16 shr
+ } ifelse
+} def
+
+
+% ( pic pic_a -- )
+/showlogo {
+ /tmp.sc over imgsize savescreen def
+
+ currentpoint 4 2 roll
+ 0 0 moveto tmp.sc blend
+ moveto tmp.sc restorescreen
+
+ tmp.sc free
+} def
+
+
+% ( file_name ) ==> ( image )
+/readimage {
+ findfile dup .undef ne {
+ dup setimage 0 0 image.size unpackimage exch free
+ } if
+} def
+
+
+/init {
+ 0 0 moveto currentpoint clip.size image
+
+ ptheme { ptheme.init } if
+
+ % set default language
+ "lang" findfile dup {
+ /tmp over length 1 add 2 max string def
+ tmp exch {
+ dup ' ' eq over '\n' eq or { pop pop exit } if
+ over exch 0 exch put
+ 1 add
+ } forall
+ tmp dup setlang pop getkeymapfromlocale setkeymap
+ } {
+ pop
+ "en_US" dup setlang pop getkeymapfromlocale setkeymap
+ } ifelse
+
+ keymap.default "" ne { keymap.default setkeymap } if
+
+ font.large setfont
+
+ /menu.text.xofs 10 def
+ /menu.text.yofs 2 def
+ /menu.item.height fontheight dup ptheme { 3 } { 2 } ifelse div add def
+ /menu.bar.height fontheight menu.text.yofs dup add add def
+
+ font.normal setfont
+
+ /menu.bar.width menu.bar.min.width def
+
+ % false: no boot options line initially
+ /boot.show true def
+
+} def
+
+
+/chksum {
+ 0 exch
+ { add } forall
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Some special debug & test keys.
+%
+% ( key_in ) ==> ( key_out )
+%
+/debug.input {
+ dup keyShiftF4 eq debug 3 ge and {
+ currentcolor black setcolor
+ currentpoint 0 0 moveto
+ 64 string biosmem "mem = %u " 2 index sprintf dup show free
+ moveto setcolor
+ } if
+
+ dup keyF8 eq syslinux and {
+ kroete.file .undef eq { /kroete.file "kroete.dat" findfile def } if
+ kroete.file kroete.dir idle
+ /kroete.dir kroete.dir 1 xor def
+ } if
+
+ dup keyF9 eq syslinux and {
+ /v_impaired inc
+
+ v_impaired 1 eq config.talk not and {
+ /config.talk true def
+ load_talk_dialog
+ menu.texts menu.idx get menuitemmap speak
+ } {
+ sound.getsamplerate { sound.getsamplerate sound.setsamplerate } if
+ } ifelse
+
+ config.livecd not {
+ xmenu.video .xm_current 0 put
+ % redraw unless another menu is still open
+ window.current {
+ window.current .xmenu get .undef eq { video.update } if
+ } if
+ } if
+
+ .undef 0 idle
+ kroete.file free /kroete.file .undef def
+ pop 0
+ } if
+
+ dup keyShiftF3 eq syslinux and debug 3 ge and {
+ currentcolor black setcolor
+ currentpoint 0 0 moveto
+ "eject " print bootdrive eject print
+ moveto setcolor
+ } if
+
+ dup keyShiftF5 eq syslinux and debug 3 ge and {
+ currentcolor black setcolor
+ currentpoint 100 0 moveto
+ bootdrive print
+ moveto setcolor
+ } if
+
+ dup keyShiftF8 eq debug 3 ge and {
+ currentcolor debug 1 and { white } { black } ifelse setcolor
+
+ currentpoint 300 0 moveto
+ 0 memsize print "/" print print " " print
+ moveto
+
+ currentpoint 300 20 moveto
+ 1 memsize print "/" print print " " print
+ moveto
+
+ currentpoint 300 40 moveto
+ 2 memsize print "/" print print " " print
+ moveto
+
+ currentpoint 300 60 moveto
+ 3 memsize print "/" print print " " print
+ moveto
+
+ currentpoint 300 80 moveto
+ 4 memsize print "/" print print " " print
+ moveto
+
+ setcolor
+ } if
+
+ dup keyShiftF9 eq debug 3 ge and {
+ dumpmem
+ } if
+
+ dup keyShiftF10 eq {
+ /debug debug 1 add def
+ } if
+
+ dup keyShiftF11 eq {
+ 400 0 moveto "ani_%04d.jpg" play_movie
+ } if
+
+ dup keyShiftF1 eq {
+ /transp transp 0x10 sub 0 max def
+
+ /player 0 def
+ player "hapysuse.mod" findfile dup
+ {
+ mod.load
+ config.volume sound.setvolume
+ player 0 mod.play
+ /player player 1 add 3 and def
+ } {
+ pop
+ } ifelse
+
+ pop 0
+ } if
+
+ dup keyShiftF3 eq {
+ "fsfsong.wav" findfile dup
+ {
+ config.volume sound.setvolume
+ wav.play
+ } {
+ pop
+ } ifelse
+
+ pop 0
+ } if
+
+ dup keyShiftF4 eq {
+ % sound test XXXXXXXX
+
+ sound.done
+
+ } if
+
+ dup keyF11 eq debug 1 ge and {
+
+ /dit {
+ dup 0xff and rand 0xff and gt { 0xff add } if
+ 8 shr
+ } def
+
+ /c13.r rand 0x7f00 and def
+ /c02_13.r rand 0x7f00 and c13.r sub def
+ /c23.r rand 0x7f00 and def
+ /c01_23.r rand 0x7f00 and c23.r sub def
+ /c13.g rand 0x7f00 and def
+ /c02_13.g rand 0x7f00 and c13.g sub def
+ /c23.g rand 0x7f00 and def
+ /c01_23.g rand 0x7f00 and c23.g sub def
+ /c13.b rand 0x7f00 and def
+ /c02_13.b rand 0x7f00 and c13.b sub def
+ /c23.b rand 0x7f00 and def
+ /c01_23.b rand 0x7f00 and c23.b sub def
+
+ screen.size /h exch def /w exch def
+
+ 0 1 screen.size exch pop {
+ 0 1 screen.size pop {
+ over moveto
+
+ currentpoint c01_23.r mul h div exch c02_13.r mul w div add c13.r add c23.r add
+ dit 0 max 0xff min 16 shl
+ currentpoint c01_23.g mul h div exch c02_13.g mul w div add c13.g add c23.g add
+ dit 0 max 0xff min 8 shl
+ currentpoint c01_23.b mul h div exch c02_13.b mul w div add c13.b add c23.b add
+ dit 0 max 0xff min add add
+
+ setcolor putpixel
+ } for
+ pop
+ } for
+
+ pop 0
+ } if
+
+ dup keyF12 eq debug 3 ge and {
+ % mouse support testing
+
+ 1 keepmode
+
+ /mouse xxx def
+ 0xc00000 setcolor
+ mouse .undef eq {
+ 700 580 moveto "no mouse" show
+ } {
+ {
+ mouse getdword 16 shl 16 shr screen.size pop 2 div add
+ mouse getdword 16 shr neg screen.size exch pop 2 div add
+ moveto 4 4 fillrect
+
+ mouse 4 add getdword 7 and
+ dup 1 and { 0xc00000 setcolor } if
+ dup 2 and { 0x0000a0 setcolor } if
+ dup 4 and { 0x009000 setcolor } if
+
+ 3 and 3 eq { exit } if
+
+ } loop
+ } ifelse
+ pop 0
+ } if
+
+ dup keyShiftF12 eq {
+ /transp transp 0x10 add 0x100 min def
+ pop 0
+ } if
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show exit popup.
+%
+% ( ) ==> ( )
+%
+/exit_popup {
+ window.dialog
+
+ dup .title txt_exit_title put
+ dup .text txt_exit_dialog put
+ dup .buttons [
+ button.ok button.default actExit button.setaction
+ button.cancel button.notdefault actNothing button.setaction
+ config.rtl { exch } if
+ ] put
+ dup window.init
+ window.show
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show help window.
+%
+% ( ) ==> ( )
+%
+/show_help {
+ window.help
+
+ dup window.init
+ window.show
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show dvd popup.
+%
+% ( ) ==> ( )
+%
+/dvd_popup {
+ window.dialog
+
+ dup .title txt_dvd_warning_title put
+ dup .text txt_dvd_warning2 put
+ dup .buttons [
+% button.eject button.default actEject actNoClose or button.setaction
+ button.continue button.default actNothing button.setaction
+ ] put
+ dup window.init
+ window.show
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Warn that we are about to install 32bit software on a 64bit system.
+%
+% ( ) ==> ( )
+%
+/32bit_popup {
+ window.dialog
+
+ dup .title "Cool computer, but..." put
+ dup .text "You are about to install 32-bit software on a 64-bit computer." put
+ dup .buttons [
+ button.continue button.default actNothing button.setaction
+ ] put
+ dup window.init
+ window.show
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Warn that we are about to install 64bit software on a 32bit system.
+%
+% ( ) ==> ( )
+%
+/64bit_popup {
+ window.dialog
+
+ dup .title "Cool software, but..." put
+ dup .text "This is a 32-bit computer. You cannot use 64-bit software on it." put
+ dup .buttons [
+ button.reboot button.default actReboot actNoClose or button.setaction
+ ] put
+ dup window.init
+ window.show
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Warn that we don't have enough memory.
+%
+% ( ) ==> ( )
+%
+/nomem_popup {
+ window.dialog
+
+ dup .title "Sorry, but..." put
+ dup .text mem.show put
+ dup .buttons [
+ button.ok button.default actNothing button.setaction
+ ] put
+ dup window.init
+ window.show
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show "power off" popup.
+%
+% ( ) ==> ( )
+%
+/power_off {
+ window.dialog
+
+ dup .title txt_power_off_title put
+ dup .text txt_power_off put
+ dup .buttons [
+ button.ok button.notdefault actPowerOff actNoClose or button.setaction
+ button.cancel button.default actNothing button.setaction
+ config.rtl { exch } if
+ ] put
+ dup window.init
+ window.show
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Set global config variables.
+%
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% For monitor tests: fake DDC info.
+%
+
+% "ddc" findfile test1
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% First, figure out video mode.
+%
+
+/config.screen.width /config.screen.height "screen.size" 800 600 gfxconfig.set.int2
+
+/screen.fallback false def
+
+config.screen.width config.screen.height 32 findmode setmode not {
+ config.screen.width config.screen.height 16 findmode setmode not {
+ /screen.fallback true def
+ 640 480 16 findmode setmode not {
+ 640 480 32 findmode setmode not {
+ false .end
+ } if
+ } if
+ } if
+} if
+
+% prepend fallback section to layout section list
+screen.fallback {
+ /gfxconfig.layout [ "640x480" gfxconfig.layout { } forall ] gfxconfig.layout free def
+} if
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Figure out whether to use penguin theme.
+%
+
+/config.penguin "penguin" 0 gfxconfig.set.int
+
+% more likely during winter...
+config.penguin -1 eq {
+ date
+ 0
+
+ over month 12 eq { 5 add } if
+ over month 1 le { 5 add } if
+ over weekday 5 eq { 2 mul } if
+ over weekday 6 eq { 4 mul } if
+ over dup month 12 eq exch day dup 24 ge exch 6 eq or and { pop 100 } if
+ over dup month 1 eq exch day 1 eq and { pop 100 } if
+
+ /config.penguin exch def
+ pop
+} if
+
+/ptheme rand pop rand 100 mod config.penguin lt def
+
+0x417 cvp getbyte 0x40 and 0 ne { /ptheme true def } if
+0x417 cvp getbyte 0x10 and 0 ne { /ptheme false def } if
+
+% prepend penguin section to layout section list
+ptheme {
+ /gfxconfig.layout [ "penguin" gfxconfig.layout { } forall ] gfxconfig.layout free def
+} if
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Then, read the other config variables (might depend on video mode).
+%
+
+/config.welcome "welcome" 0 gfxconfig.set.int
+/config.beep "beep" false gfxconfig.set.bool
+/config.volume "volume" 70 gfxconfig.set.int
+/config.talk "talk" false gfxconfig.set.bool
+/config.livecd "livecd" false gfxconfig.set.bool
+/config._2space "_2space" false gfxconfig.set.bool
+/transp "menu.transparency" 0x20 gfxconfig.set.int
+/config.screen.width
+/config.screen.height "screen.size" 800 600 gfxconfig.set.int2
+/config.background "background" "back.jpg" gfxconfig.set.str
+/config.font.normal "font.normal" "16x16.fnt" gfxconfig.set.str
+/config.font.large "font.large" "16x16.fnt" gfxconfig.set.str
+/progress.bar.color "progress.bar.color" white gfxconfig.set.int
+/xmenu.normal.bg "menu.normal.bg" black gfxconfig.set.int
+/xmenu.normal.fg "menu.normal.fg" white gfxconfig.set.int
+/xmenu.selected.bg "menu.selected.bg" white gfxconfig.set.int
+/xmenu.selected.fg "menu.selected.fg" black gfxconfig.set.int
+/window.color.bg "window.bg" white gfxconfig.set.int
+/window.color.fg "window.fg" black gfxconfig.set.int
+/window.title.bg "window.title.bg" black gfxconfig.set.int
+/window.title.fg "window.title.fg" white gfxconfig.set.int
+/window.title.error.bg "window.title.error.bg" 0xc00000 gfxconfig.set.int
+/help.link.fg "help.link.fg" 0x0000a0 gfxconfig.set.int
+/help.link.selected.fg "help.link.selected.fg" white gfxconfig.set.int
+/help.link.selected.bg "help.link.selected.bg" 0x0000a0 gfxconfig.set.int
+/help.highlight.fg "help.highlight.fg" 0x009000 gfxconfig.set.int
+/menu.text.normal "mainmenu.normal.fg" white gfxconfig.set.int
+/menu.text.select "mainmenu.selected.fg" black gfxconfig.set.int
+/boot.text.options "bootopt.label.fg" white gfxconfig.set.int
+/boot.text.normal "bootopt.text.fg" white gfxconfig.set.int
+/menu.bar.color "mainmenu.bar.color" white gfxconfig.set.int
+/menu.bar.min.width "mainmenu.bar.minwidth" 300 gfxconfig.set.int
+/menu.bar.transparency "mainmenu.bar.transparency" 70 gfxconfig.set.int
+/menu.start.x
+/menu.start.y "mainmenu.pos" 253 170 gfxconfig.set.int2
+/menu.max.entries "mainmenu.entries" 8 gfxconfig.set.int
+/boot.pos.x
+/boot.pos.y "bootopt.pos" 263 480 gfxconfig.set.int2
+/panel.normal.fg "panel.normal.fg" white gfxconfig.set.int
+/panel.title.fg "panel.title.fg" white gfxconfig.set.int
+/panel.f-key.fg "panel.f-key.fg" black gfxconfig.set.int
+/keymap.submenu "keymap.submenu" false gfxconfig.set.bool
+/keymap.mainmenu "keymap.mainmenu" false gfxconfig.set.bool
+/keymap.default "keymap" "" gfxconfig.set.str
+
+/install.default "install" "" gfxconfig.set.str
+/install.http.server "install.http.server" "" gfxconfig.set.str
+/install.http.path "install.http.path" "" gfxconfig.set.str
+
+/install.nfs.server "install.nfs.server" "" gfxconfig.set.str
+/install.nfs.path "install.nfs.path" "" gfxconfig.set.str
+
+/install.ftp.server "install.ftp.server" "" gfxconfig.set.str
+/install.ftp.path "install.ftp.path" "" gfxconfig.set.str
+/install.ftp.user "install.ftp.user" "" gfxconfig.set.str
+/install.ftp.password "install.ftp.password" "" gfxconfig.set.str
+
+/install.smb.server "install.smb.server" "" gfxconfig.set.str
+/install.smb.share "install.smb.share" "" gfxconfig.set.str
+/install.smb.path "install.smb.path" "" gfxconfig.set.str
+/install.smb.domain "install.smb.domain" "" gfxconfig.set.str
+/install.smb.user "install.smb.user" "" gfxconfig.set.str
+/install.smb.password "install.smb.password" "" gfxconfig.set.str
+
+/install.hd.device "install.hd.device" "" gfxconfig.set.str
+/install.hd.path "install.hd.path" "" gfxconfig.set.str
+
+/dud.default "dud" "" gfxconfig.set.str
+/dud.file "dud.file" "" gfxconfig.set.str
+/dud.url "dud.url" "" gfxconfig.set.str
+/dud.url.name "dud.url.name" "" gfxconfig.set.str
+
+/serial.line0 "serial.line0" [ ] gfxconfig.set.array_str
+/serial.line1 "serial.line1" [ ] gfxconfig.set.array_str
+/serial.line2 "serial.line2" [ ] gfxconfig.set.array_str
+/serial.line3 "serial.line3" [ ] gfxconfig.set.array_str
+
+/serial.lines [
+ serial.line0 serial.line1 serial.line2 serial.line3
+] def
+
+% Array of menu entries with no boot option input field.
+/config.nobootoptions "nobootoptions" [ ] gfxconfig.set.array_str
+
+% Array of menu entries which should not get an 'install' option appended.
+/config.noinstallopt "noinstallopt" [ ] gfxconfig.set.array_str
+
+% Mininum required memory in MB.
+/mem.check {
+ mem.min gfxconfig.int dup .undef eq { pop 0 } if
+} def
+
+% Message to print if we fail minimum memory requirement.
+/mem.show {
+ mem.msg gfxconfig.str dup .undef eq { pop "Not enough memory." } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+% drawing area size
+/clip.size { screen.size } def
+
+% set background image
+config.background findfile setimage
+
+% get font(s)
+/font.normal config.font.normal findfile def
+/font.large
+ % don't load it twice
+ config.font.normal config.font.large eq {
+ font.normal
+ } {
+ config.font.large findfile
+ } ifelse
+def
+
+% default kroet direction (idle task)
+/kroete.dir 0 def
+
+% default debug level
+/debug 0 def
+
+% no specials for visual impaired people
+/v_impaired 0 def
+
+% show welcome animation?
+ptheme
+screen.fallback or
+CapsLock or
+config.welcome 0 eq or
+{
+ /bsplash.done { } def
+} {
+ bsplash.show
+} ifelse
+
+% check for bi-arch config
+check_arch_boot_dir
+
diff --git a/src/dia_about.inc b/src/dia_about.inc
new file mode 100644
index 0000000..2055ea6
--- /dev/null
+++ b/src/dia_about.inc
@@ -0,0 +1,75 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Panel 'about' entry.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show help window.
+%
+% ( ) => ( )
+%
+/panel.about {
+ panel 0 panel.entry.help put
+ about.popup
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Return width of 'about' entry.
+%
+% ( ) => ( width )
+%
+/panel.about.width {
+ "About" strsize pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Redraw panel entry.
+%
+% ( panel ) => ( )
+%
+/panel.about.update {
+ panel.text.moveto
+ "About" show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show 'about' box.
+%
+% ( ) ==> ( )
+%
+/about.popup {
+ window.dialog
+
+ dup .title "About" put
+ dup .text about.msg put
+ dup .buttons [
+ button.ok button.default actRedraw button.setaction
+ ] put
+ dup window.init
+ window.show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Return 'about' text, if any.
+%
+% ( -- obj1 )
+%
+% obj1: string with message or .undef
+%
+/about.msg {
+
+ /about.msg
+ ptheme { "pabout.txt" } { "about.txt" } ifelse findfile dup .undef ne {
+ dup length string dup cvp rot dup length memcpy
+ } if
+ def
+
+ about.msg
+
+} def
+
diff --git a/src/dia_bits.inc b/src/dia_bits.inc
new file mode 100644
index 0000000..01a4ea8
--- /dev/null
+++ b/src/dia_bits.inc
@@ -0,0 +1,101 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% 32/64 bit install selection dialog.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Some global vars.
+%
+/bits.default 0 def
+
+/bits.suffix [
+ .undef
+ "64"
+] def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Build menu list.
+%
+% ( ) ==> ( )
+%
+/bits.init {
+ /xmenu.bits .xm_size array def
+
+ /xmenu xmenu.bits def
+
+ xmenu .xm_list [ "x86" ] put
+
+ 32+64bit_source {
+ 64bit {
+ /bits.default 1 def
+ xmenu .xm_list [ "x86" "x86-64" ] put
+ } if
+ } if
+
+ % no '64' suffix
+ 32bit_boot_dir 64bit_boot_dir ne {
+ bits.suffix 1 .undef put
+ } if
+
+ xmenu .xm_title /txt_arch put
+
+ xmenu .xm_current bits.default put
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Update bit selection menu.
+%
+% ( ) ==> ( )
+%
+/bits.update {
+ /xmenu xmenu.bits def
+
+ /window.action actRedrawPanel def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show bit selection menu.
+%
+% ( ) => ( )
+%
+/panel.bits {
+ "bits" help.setcontext
+
+ window.xmenu
+ dup .xmenu xmenu.bits put
+ dup .xmenu.update /bits.update put
+ dup window.init
+ window.show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Return width of panel entry.
+%
+% ( ) => ( width )
+%
+/panel.bits.width {
+ /xmenu xmenu.bits def
+
+ pmenu.width
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Redraw panel entry.
+%
+% ( panel ) => ( )
+%
+/panel.bits.update {
+ /xmenu xmenu.bits def
+
+ pmenu.panel.update
+} def
+
+
diff --git a/src/dia_dud.inc b/src/dia_dud.inc
new file mode 100644
index 0000000..647965c
--- /dev/null
+++ b/src/dia_dud.inc
@@ -0,0 +1,165 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Driver update dialog.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Some global vars.
+%
+/.dud_yes 0 def
+/.dud_no 1 def
+/.dud_file 2 def
+/.dud_url 3 def
+
+/dud.last .dud_no def
+
+/dud.options [
+ "dud=1"
+ ""
+ .undef
+ .undef
+] def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Build driver update menu.
+%
+% ( ) ==> ( )
+%
+/dud.init {
+ /xmenu.dud .xm_size array def
+
+ /xmenu xmenu.dud def
+
+ /input.edit.dud_file [ 127 string ] def
+ /input.edit.dud_url [ 127 string ] def
+
+ dud.read.config
+
+ xmenu .xm_current dud.last put
+ xmenu .xm_list [ /txt_yes /txt_no /txt_file dud.url.name ] put
+
+ xmenu .xm_title /txt_driver_update put
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Update driver update mode.
+%
+% ( ) ==> ( )
+%
+/dud.update {
+ /xmenu xmenu.dud def
+
+ xmenu .xm_current get dup .dud_file eq over .dud_url eq or {
+ dud.dialog
+ } if
+ /window.action actRedrawPanel def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show driver update menu.
+%
+% ( ) => ( )
+%
+/panel.dud {
+ "driverupdate" help.setcontext
+
+ window.xmenu
+ dup .xmenu xmenu.dud put
+ dup .xmenu.update /dud.update put
+ dup window.init
+ window.show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Return width of panel entry.
+%
+% ( ) => ( width )
+%
+/panel.dud.width {
+ /xmenu xmenu.dud def
+
+ pmenu.width
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Redraw panel entry.
+%
+% ( panel ) => ( )
+%
+/panel.dud.update {
+ /xmenu xmenu.dud def
+
+ pmenu.panel.update
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+/dud.dialog {
+
+ /dia window.dialog def
+
+ dia .text "" put
+
+ xmenu .xm_current get
+
+ dup .dud_file eq {
+ dia .title txt_driver_update2 put
+
+ % Must all be of same size!
+ dia .ed.list 1 array put
+ dia .ed.buffer.list input.edit.dud_file put
+ dia .ed.text.list [ txt_dud_file_msg ] put
+ } if
+
+ dup .dud_url eq {
+ dia .title txt_dud_download put
+
+ % Must all be of same size!
+ dia .ed.list 1 array put
+ dia .ed.buffer.list input.edit.dud_url put
+ dia .ed.text.list [ txt_dud_enter_url ] put
+ } if
+
+ pop
+
+ dia .ed.focus 0 put
+ dia .ed.width 300 put
+
+ dia .buttons [
+ button.ok button.default actNothing button.setaction
+ button.cancel button.notdefault actNothing button.setaction
+ config.rtl { exch } if
+ ] put
+
+ dia window.init
+ dia window.show
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Read default values.
+%
+% ( -- )
+%
+/dud.read.config {
+ dud.default
+ dup "yes" eq { /dud.last .dud_yes def } if
+ dup "no" eq { /dud.last .dud_no def } if
+ dup "file" eq { /dud.last .dud_file def } if
+ dup "url" eq { /dud.last .dud_url def } if
+ pop
+
+ input.edit.dud_file 0 get dud.file strcpy pop
+ input.edit.dud_url 0 get dud.url strcpy pop
+
+ dud.url.name "" eq { /dud.url.name "URL" def } if
+
+} def
diff --git a/src/dia_help.inc b/src/dia_help.inc
new file mode 100644
index 0000000..86db5aa
--- /dev/null
+++ b/src/dia_help.inc
@@ -0,0 +1,46 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Panel help entry.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show help window.
+%
+% ( ) => ( )
+%
+/panel.help {
+ help.context "opt" eq {
+ findbootoption
+ help.mapcontext
+ dup help.findpage
+ "" eq { pop } { help.setcontext } ifelse
+ } if
+ show_help
+
+ config.talk { txt_help speak } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Return width of help entry.
+%
+% ( ) => ( width )
+%
+/panel.help.width {
+ txt_help strsize pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Redraw panel entry.
+%
+% ( panel ) => ( )
+%
+/panel.help.update {
+ panel.text.moveto
+
+ txt_help show.rtl
+} def
+
+
diff --git a/src/dia_install.inc b/src/dia_install.inc
new file mode 100644
index 0000000..635146f
--- /dev/null
+++ b/src/dia_install.inc
@@ -0,0 +1,344 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Install mode selection dialog.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Some global vars.
+%
+/install.option 255 string def
+
+% install types
+/.inst_cdrom 0 def
+/.inst_slp 1 def
+/.inst_ftp 2 def
+/.inst_http 3 def
+/.inst_nfs 4 def
+/.inst_smb 5 def
+/.inst_hd 6 def
+
+/install.last .inst_cdrom def
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Build install mode list.
+%
+% ( ) ==> ( )
+%
+/install.init {
+ /xmenu.install .xm_size array def
+
+ /xmenu xmenu.install def
+
+ /input.edit.ftp [ 63 string 127 string 31 string 31 string ] def
+ /input.edit.http [ 63 string 127 string ] def
+ /input.edit.nfs [ 63 string 127 string ] def
+ /input.edit.smb [ 63 string 31 string 127 string 31 string 31 string 31 string ] def
+ /input.edit.hd [ 63 string 127 string ] def
+
+ install.read.config
+
+ xmenu .xm_current install.last put
+
+ % see install types (.inst_*)
+ xmenu .xm_list [ is_dvd { "DVD" } { "CD-ROM" } ifelse "SLP" "FTP" "HTTP" "NFS" "SMB / CIFS" /txt_harddisk ] put
+
+ xmenu .xm_title /txt_install_source put
+
+ install.set.install.option
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Update install mode.
+%
+% ( ) ==> ( )
+%
+/install.update {
+ /xmenu xmenu.install def
+
+ xmenu .xm_current get dup .inst_cdrom eq exch .inst_slp eq or {
+ /install.last xmenu .xm_current get def
+
+ install.set.install.option
+
+ /window.action actRedrawPanel def
+ } {
+ install.dialog
+ }
+ ifelse
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show install menu.
+%
+% ( ) => ( )
+%
+/panel.install {
+ "install_src" help.setcontext
+
+ window.xmenu
+ dup .xmenu xmenu.install put
+ dup .xmenu.update /install.update put
+ dup window.init
+ window.show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Return width of panel entry.
+%
+% ( ) => ( width )
+%
+/panel.install.width {
+ /xmenu xmenu.install def
+
+ pmenu.width
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Redraw panel entry.
+%
+% ( panel ) => ( )
+%
+/panel.install.update {
+ /xmenu xmenu.install def
+
+ pmenu.panel.update
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+/install.dialog {
+
+ /dia window.dialog def
+
+ dia .text "" put
+
+ xmenu .xm_current get
+
+ dup .inst_ftp eq {
+ dia .title txt_ftp_title put
+
+ % Must all be of same size!
+ dia .ed.list 4 array put
+ dia .ed.buffer.list input.edit.ftp put
+ dia .ed.text.list [ txt_server txt_directory txt_user1 txt_password ] put
+
+ dia .ed.font font.normal put
+ dia .ed.pw_field 3 put
+
+ } if
+
+ dup .inst_http eq {
+ dia .title txt_http_title put
+
+ % Must all be of same size!
+ dia .ed.list 2 array put
+ dia .ed.buffer.list input.edit.http put
+ dia .ed.text.list [ txt_server txt_directory ] put
+
+ } if
+
+ dup .inst_nfs eq {
+ dia .title txt_nfs_title put
+
+ % Must all be of same size!
+ dia .ed.list 2 array put
+ dia .ed.buffer.list input.edit.nfs put
+ dia .ed.text.list [ txt_server txt_directory ] put
+
+ } if
+
+ dup .inst_smb eq {
+ dia .title txt_smb_title put
+
+ % Must all be of same size!
+ dia .ed.list 6 array put
+ dia .ed.buffer.list input.edit.smb put
+ dia .ed.text.list [ txt_server txt_share txt_directory txt_domain txt_user2 txt_password ] put
+
+ dia .ed.font font.normal put
+ dia .ed.pw_field 5 put
+
+ } if
+
+ dup .inst_hd eq {
+ dia .title txt_harddisk_title put
+
+ % Must all be of same size!
+ dia .ed.list 2 array put
+ dia .ed.buffer.list input.edit.hd put
+ dia .ed.text.list [ txt_hd_diskdevice txt_directory ] put
+
+ } if
+
+ pop
+
+ dia .ed.focus 0 put
+ dia .ed.width 300 put
+
+ dia .buttons [
+ button.ok button.default actInstallOK actNoClose or button.setaction
+ button.cancel button.notdefault actInstallCancel button.setaction
+ config.rtl { exch } if
+ ] put
+
+ dia window.init
+ dia window.show
+
+} def
+
+
+
+/install.ok {
+ /xmenu xmenu.install def
+
+ window.done
+
+ /install.last xmenu .xm_current get def
+
+ /window.action actRedrawPanel def
+
+ pmenu.update
+
+ install.set.install.option
+
+} def
+
+
+/install.cancel {
+ /xmenu xmenu.install def
+
+ xmenu .xm_current install.last put
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Set 'install=' boot option.
+%
+% ( -- )
+%
+/install.set.install.option {
+ xmenu .xm_current get
+
+ % default: .inst_cdrom
+ install.option "" strcpy pop
+
+ dup .inst_slp eq {
+ install.option "install=slp:/" strcpy pop
+ } if
+
+ dup .inst_ftp eq {
+ input.edit.ftp
+
+ "install=ftp://" install.option sprintf
+
+ % add user name & password
+ dup 2 get "" ne {
+ dup 2 get "%s" install.option dup length add sprintf
+ dup 3 get "" ne {
+ dup 3 get ":%s" install.option dup length add sprintf
+ } if
+ "@" install.option dup length add sprintf
+ } if
+
+ dup 1 get exch 0 get "%s/%s" install.option dup length add sprintf
+ } if
+
+ dup .inst_http eq {
+ input.edit.http
+ dup 1 get dup 0 get '/' eq { 1 add } if
+ exch 0 get
+ "install=http://%s/%s" install.option sprintf
+ } if
+
+ dup .inst_nfs eq {
+ input.edit.nfs
+ dup 1 get dup 0 get '/' eq { 1 add } if
+ exch 0 get
+ "install=nfs://%s/%s" install.option sprintf
+ } if
+
+ dup .inst_smb eq {
+ input.edit.smb
+
+ "install=smb://" install.option sprintf
+
+ % add domain
+ dup 3 get "" ne {
+ dup 3 get "%s;" install.option dup length add sprintf
+ } if
+
+ % add user name & password
+ dup 4 get "" ne {
+ dup 4 get "%s" install.option dup length add sprintf
+ dup 5 get "" ne {
+ dup 5 get ":%s" install.option dup length add sprintf
+ } if
+ "@" install.option dup length add sprintf
+ } if
+
+ dup 2 get dup 0 get '/' eq { 1 add } if
+ over 1 get rot 0 get
+ "%s/%s/%s" install.option dup length add sprintf
+ } if
+
+ dup .inst_hd eq {
+ input.edit.hd
+ dup 1 get dup 0 get '/' eq { 1 add } if
+ exch 0 get dup 0 get '/' eq { 1 add } if
+ "install=hd://%s/%s" install.option sprintf
+ } if
+
+ pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Read default values.
+%
+% ( -- )
+%
+/install.read.config {
+ install.default
+ dup "cdrom" eq { /install.last .inst_cdrom def } if
+ dup "slp" eq { /install.last .inst_slp def } if
+ dup "ftp" eq { /install.last .inst_ftp def } if
+ dup "http" eq { /install.last .inst_http def } if
+ dup "nfs" eq { /install.last .inst_nfs def } if
+ dup "smb" eq { /install.last .inst_smb def } if
+ dup "hd" eq { /install.last .inst_hd def } if
+ pop
+
+ input.edit.http 0 get install.http.server strcpy pop
+ input.edit.http 1 get install.http.path strcpy pop
+
+ input.edit.nfs 0 get install.nfs.server strcpy pop
+ input.edit.nfs 1 get install.nfs.path strcpy pop
+
+ input.edit.ftp 0 get install.ftp.server strcpy pop
+ input.edit.ftp 1 get install.ftp.path strcpy pop
+ input.edit.ftp 2 get install.ftp.user strcpy pop
+ input.edit.ftp 3 get install.ftp.password strcpy pop
+
+ input.edit.smb 0 get install.smb.server strcpy pop
+ input.edit.smb 1 get install.smb.share strcpy pop
+ input.edit.smb 2 get install.smb.path strcpy pop
+ input.edit.smb 3 get install.smb.domain strcpy pop
+ input.edit.smb 4 get install.smb.user strcpy pop
+ input.edit.smb 5 get install.smb.password strcpy pop
+
+ input.edit.hd 0 get install.hd.device strcpy pop
+ input.edit.hd 1 get install.hd.path strcpy pop
+
+} def
+
+
diff --git a/src/dia_kernelopts.inc b/src/dia_kernelopts.inc
new file mode 100644
index 0000000..942efb6
--- /dev/null
+++ b/src/dia_kernelopts.inc
@@ -0,0 +1,94 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Kernel options dialog.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Some global vars.
+%
+/kernelopts.default 0 def
+
+/kernelopts.options [
+ ""
+ "apm=off acpi=off mce=off barrier=off ide=nodma idewait=50 i8042.nomux psmouse.proto=bare irqpoll pci=nommconf"
+ "acpi=off"
+ "nolapic"
+] def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Build kernelopts list.
+%
+% ( ) ==> ( )
+%
+/kernelopts.init {
+ /xmenu.kernelopts .xm_size array def
+
+ /xmenu xmenu.kernelopts def
+
+ xmenu .xm_current kernelopts.default put
+ xmenu .xm_list [
+ /txt_kernel_default
+ /txt_kernel_safe
+ /txt_kernel_noacpi
+ /txt_kernel_nolapic
+ ] put
+ xmenu .xm_title /txt_kernel put
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Update kernelopts mode.
+%
+% ( ) ==> ( )
+%
+/kernelopts.update {
+ /xmenu xmenu.kernelopts def
+
+ /window.action actRedrawPanel def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show kernelopts menu.
+%
+% ( ) => ( )
+%
+/panel.kernelopts {
+ "main" help.setcontext
+
+ window.xmenu
+ dup .xmenu xmenu.kernelopts put
+ dup .xmenu.update /kernelopts.update put
+ dup window.init
+ window.show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Return width of panel entry.
+%
+% ( ) => ( width )
+%
+/panel.kernelopts.width {
+ /xmenu xmenu.kernelopts def
+
+ pmenu.width
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Redraw panel entry.
+%
+% ( panel ) => ( )
+%
+/panel.kernelopts.update {
+ /xmenu xmenu.kernelopts def
+
+ pmenu.panel.update
+} def
+
+
diff --git a/src/dia_keymap.inc b/src/dia_keymap.inc
new file mode 100644
index 0000000..2f3a939
--- /dev/null
+++ b/src/dia_keymap.inc
@@ -0,0 +1,105 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% keyboard map selection dialog.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Some global vars.
+%
+
+/keymap.setdefault {
+ xmenu.keymap .xm_current
+
+ 0
+ keymaps {
+ .km.id get config.keymap.id eq { exit } if
+ 1 add
+ } forall
+
+ dup keymaps length ge { pop 0 } if
+
+ put
+
+} def
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Build menu list.
+%
+% ( ) ==> ( )
+%
+/keymap.init {
+ /xmenu.keymap .xm_size array def
+
+ /xmenu xmenu.keymap def
+
+ xmenu .xm_list [
+ keymaps { .km.name get } forall
+ ] put
+
+ xmenu .xm_title "Keyboard" put
+
+ keymap.setdefault
+
+ % just once (see lang.init)
+ /keymap.init { } def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Update keybaord selection menu.
+%
+% ( ) ==> ( )
+%
+/keymap.update {
+ /xmenu xmenu.keymap def
+
+ keymaps xmenu .xm_current get get .km.id get setkeymap
+
+ /window.action actRedrawPanel def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show keymap selection menu.
+%
+% ( ) => ( )
+%
+/panel.keymap {
+ "keymap" help.setcontext
+
+ keymap.setdefault
+
+ window.xmenu
+ dup .xmenu xmenu.keymap put
+ dup .xmenu.update /keymap.update put
+ dup window.init
+ window.show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Return width of panel entry.
+%
+% ( ) => ( width )
+%
+/panel.keymap.width {
+ /xmenu xmenu.keymap def
+
+ pmenu.width
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Redraw panel entry.
+%
+% ( panel ) => ( )
+%
+/panel.keymap.update {
+ /xmenu xmenu.keymap def
+
+ pmenu.panel.update
+} def
+
+
diff --git a/src/dia_lang.inc b/src/dia_lang.inc
new file mode 100644
index 0000000..c8b2f58
--- /dev/null
+++ b/src/dia_lang.inc
@@ -0,0 +1,309 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Language selection dialog.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Some global vars.
+%
+
+% fallback if there is no "languages"
+/lang.items [ "en_US" ] def
+/lang.names [ "English (US)" ] def
+
+/.la.locale 0 def
+/.la.keymap 1 def
+/.la.rtl 2 def
+/.la.name 3 def
+
+/lang.defaultnames [
+ [ "af_ZA" "en_US" false "Afrikaans" ] % Afrikaans
+% [ "ar_EG" "en_US" true "\u064a\u0628\u0631\u0639" ] % Arabic
+ [ "ar_EG" "en_US" true "\ufef2\ufe91\ufeae\ufecb" ] % Arabic
+ [ "bg_BG" "en_US" false "Български" ] % Bulgarian
+ [ "bn_BD" "en_US" false "\u09ac\u09be\u0982\u09b2\u09be" ] % Bengali
+ [ "bs_BA" "en_US" false "Bosanski" ] % Bosnian
+ [ "ca_ES" "en_US" false "Català" ] % Catalan
+ [ "cs_CZ" "czech" false "Čeština" ] % Czech
+ [ "cy_GB" "en_US" false "Cymraeg" ] % Welsh
+ [ "da_DK" "danish" false "Dansk" ] % Danish
+ [ "de_DE" "german" false "Deutsch" ] % German
+ [ "el_GR" "greek" false "Ελληνικά" ] % Greek
+ [ "en_GB" "en_US" false "English (UK)" ] % English
+ [ "en_US" "en_US" false "English (US)" ] % English
+ [ "es_ES" "spanish" false "Español" ] % Spanish
+ [ "et_EE" "estonian" false "Eesti" ] % Estonian
+ [ "fa_IR" "en_US" true "\ufbfd\ufeb4\u0631\ufe8e\ufed3" ] % Farsi
+ [ "fi_FI" "en_US" false "Suomi" ] % Finnish
+ [ "fr_FR" "french" false "Français" ] % French
+ [ "gl_ES" "en_US" false "Galego" ] % Galician
+ [ "ka_GE" "en_US" false "ქართული" ] % Kartuli
+ [ "gu_IN" "en_US" false "\u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0" ] % Gujarati
+ [ "he_IL" "en_US" false "תירבע" ] % Hebrew
+% [ "hi_IN" "en_US" false "\u0939\u093f\u0928\u094d\u0926\u0940" ] % Hindi
+ [ "hi_IN" "en_US" false "\u0939\u093f\u0902\u0926\u0940" ] % Hindi
+ [ "hr_HR" "en_US" false "Hrvatski" ] % Croatian
+ [ "hu_HU" "hungarian" false "Magyar" ] % Hungarian
+ [ "id_ID" "en_US" false "Bahasa Indonesia" ] % Indonesian
+ [ "it_IT" "italian" false "Italiano" ] % Italian
+ [ "ja_JP" "japanese" false "日本語" ] % Japanese
+ [ "jv_ID" "en_US" false "Basa Jawa" ] % Javanese
+% [ "km_KH" "en_US" false "\u1781\u17d2\u1798\u17c2\u179a" ] % Khmer
+ [ "km_KH" "en_US" false "Khmer" ] % Khmer
+ [ "ko_KR" "en_US" false "한글" ] % Korean
+ [ "lo_LA" "en_US" false "\u0e9e\u0eb2\u0eaa\u0eb2\u0ea5\u0eb2\u0ea7" ] % Lao
+ [ "lt_LT" "en_US" false "Lietuvių" ] % Lithuanian
+ [ "mk_MK" "en_US" false "Македонски" ] % Macedonian
+ [ "mr_IN" "en_US" false "\u092e\u0930\u093e\u0920\u0940" ] % Marathi
+ [ "nb_NO" "norwegian" false "Norsk" ] % Norwegian
+ [ "nl_NL" "en_US" false "Nederlands" ] % Dutch
+ [ "pa_IN" "en_US" false "\u0a2a\u0a70\u0a1c\u0a3e\u0a2c\u0a40" ] % Punjabi
+ [ "pl_PL" "polish" false "Polski" ] % Polish
+ [ "pt_BR" "portugese-br" false "Português (Brasil)" ] % Portuguese (Brazilian)
+ [ "pt_PT" "portugese" false "Português" ] % Portuguese
+ [ "ro_RO" "en_US" false "Română" ] % Romanian
+ [ "ru_RU" "russian" false "Русский" ] % Russian
+ [ "si_LK" "en_US" false "\u0dc3\u0dd2\u0d82\u0dc4\u0dbd" ] % Sinhala
+ [ "sk_SK" "slovak" false "Slovenčina" ] % Slovak
+ [ "sl_SI" "slovene" false "Slovenščina" ] % Slovenian
+ [ "sr_CS" "en_US" false "Srpski" ] % Serbian
+ [ "sv_SE" "swedish" false "Svenska" ] % Swedish
+ [ "ta_IN" "en_US" false "\u0ba4\u0bae\u0bbf\u0bb4\u0bcd" ] % Tamil
+ [ "th_TH" "en_US" false "\u0e20\u0e32\u0e29\u0e32\u0e44\u0e17\u0e22" ] % Thai
+ [ "tr_TR" "turkish" false "Türkçe" ] % Turkish
+ [ "uk_UA" "en_US" false "Українська" ] % Ukrainian
+ [ "vi_VN" "en_US" false "Tiếng Việt" ] % Vietnamese
+ [ "wa_BE" "en_US" false "Walon" ] % Walloon
+ [ "xh_ZA" "en_US" false "isiXhosa" ] % Xhosa
+ [ "zh_CN" "en_US" false "简体中文" ] % Simplified Chinese
+ [ "zh_TW" "en_US" false "繁體中文 (台灣)" ] % Traditional Chinese
+ [ "zu_ZA" "en_US" false "isiZulu" ] % Zulu
+] def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Get language property.
+%
+% Returns .undef if not found.
+%
+% ( locale prop ) ==> ( obj )
+%
+/lang.getprop {
+ lang.defaultnames {
+ dup .la.locale get 3 index eq { exch get exch pop return } { pop } ifelse
+ } forall
+
+ % try a loose match
+ lang.defaultnames {
+ dup .la.locale get 3 index locale.cmp { exch get exch pop return } { pop } ifelse
+ } forall
+
+ pop pop .undef
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Get language name.
+%
+% Returns locale if not found.
+%
+% ( locale ) ==> ( name )
+%
+/lang.getdefname {
+ dup
+ .la.name lang.getprop
+ dup .undef ne { exch } if
+ pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Check for rtl.
+%
+% ( locale ) ==> ( bool )
+%
+/lang.getrtl {
+ .la.rtl lang.getprop
+ dup .undef eq { pop false } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Parse "languages" file.
+%
+% ( ) ==> ( )
+%
+/lang.parsedata {
+ /lang.default 0 def
+
+ "languages" findfile dup { /lang.data exch def } { pop return } ifelse
+
+ /la.tmp.datalen lang.data length def
+ /la.tmp.str lang.data cvs def
+
+ la.tmp.datalen 0 eq { return } if
+ la.tmp.str la.tmp.datalen 1 sub get '\n' ne { return } if
+
+ '\n' seteotchar
+
+ /lang.items [
+
+ /la.tmp.len 0 def
+ /la.tmp.cnt 0 def
+ {
+ la.tmp.str la.tmp.len add strdup
+ dup dup length 0 put
+ /la.tmp.len over length 1 add la.tmp.len add def
+
+ dup 0 get '*' eq { 1 add /lang.default la.tmp.cnt def } if
+
+ la.tmp.len la.tmp.datalen ge { exit } if
+
+ /la.tmp.cnt inc
+ } loop
+
+ ] def
+
+ ' ' seteotchar
+
+ /lang.names [
+
+ lang.items {
+
+ dup dup length add
+
+ dup 0 get {
+ dup 0 0 put 1 add
+ exch pop
+ } {
+ pop lang.getdefname
+ } ifelse
+
+ } forall
+
+ keymap.submenu {
+ /lang.submenu.keyboard
+ } if
+
+ ] def
+
+ /lang.submenu.idx keymap.submenu { lang.names length 1 sub } { -1 } ifelse def
+
+ 0 seteotchar
+
+} def
+
+
+/lang.submenu.keyboard.buf 64 string def
+/lang.submenu.keyboard {
+ /txt_keyboard exec "\x09%s" lang.submenu.keyboard.buf sprintf
+ lang.submenu.keyboard.buf
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Build language list.
+%
+% ( ) ==> ( )
+%
+/lang.init {
+ /xmenu.lang .xm_size array def
+ /xmenu xmenu.lang def
+
+ lang.parsedata
+
+ xmenu .xm_current lang.default put
+ xmenu .xm_list lang.names put
+
+ xmenu .xm_title /txt_language put
+
+ % make menu smaller if there are more than 19 language entries
+ %lang.items length 19 gt {
+ % xmenu .xm_vspace 2 put
+ %} if
+
+ % start with current lang
+
+ /la.tmp.cnt 0 def
+ lang.items {
+ config.lang locale.cmp { xmenu .xm_current la.tmp.cnt put exit } if
+ /la.tmp.cnt inc
+ } forall
+
+ /la.tmp.cnt 0 def
+ lang.items {
+ config.lang eq { xmenu .xm_current la.tmp.cnt put exit } if
+ /la.tmp.cnt inc
+ } forall
+
+ % needed in case menu is only attached to lang menu
+ keymap.init
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Update language.
+%
+% ( ) ==> ( )
+%
+/lang.update {
+ /xmenu xmenu.lang def
+
+ xmenu .xm_current get lang.submenu.idx eq {
+ xmenu .xm_current over .xm_last get put
+ panel.keymap
+ } {
+ lang.items xmenu .xm_current get get
+ dup
+ setlang { /window.action actRedraw def } if
+ getkeymapfromlocale setkeymap
+ keymap.setdefault
+ } ifelse
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show language menu.
+%
+% ( ) => ( )
+%
+/panel.lang {
+ "keytable" help.setcontext
+
+ window.xmenu
+ dup .xmenu xmenu.lang put
+ dup .xmenu.update /lang.update put
+ dup window.init
+ window.show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Return width of panel entry.
+%
+% ( ) => ( width )
+%
+/panel.lang.width {
+ /xmenu xmenu.lang def
+
+ pmenu.width
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Redraw panel entry.
+%
+% ( panel ) => ( )
+%
+/panel.lang.update {
+ /xmenu xmenu.lang def
+
+ pmenu.panel.update
+
+ xmenu.keymap .xm_panel_x xmenu.lang .xm_panel_x get put
+} def
+
+
diff --git a/src/dia_profile.inc b/src/dia_profile.inc
new file mode 100644
index 0000000..64eede6
--- /dev/null
+++ b/src/dia_profile.inc
@@ -0,0 +1,137 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Profile selection dialog.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Some global vars.
+%
+
+% fallback if we can't parse "profiles"
+/profile.options [ "" ] def
+/profile.items [ "Broken Profiles" ] def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Parse "profiles" file.
+%
+% ( ) ==> ( )
+%
+/profile.parsedata {
+ /pf.tmp.datalen profile.data length def
+ /pf.tmp.str profile.data cvs def
+
+ /profile.default 0 def
+
+ pf.tmp.datalen 0 eq { return } if
+ pf.tmp.str pf.tmp.datalen 1 sub get '\n' ne { return } if
+
+ '\n' seteotchar
+
+ /profile.items [
+
+ /pf.tmp.len 0 def
+ /pf.tmp.cnt 0 def
+ {
+ pf.tmp.str pf.tmp.len add strdup
+ dup dup length 0 put
+ /pf.tmp.len over length 1 add pf.tmp.len add def
+
+ dup 0 get '*' eq { 1 add /profile.default pf.tmp.cnt def } if
+
+ pf.tmp.len pf.tmp.datalen ge { exit } if
+
+ /pf.tmp.cnt inc
+ } loop
+
+ ] def
+
+ ' ' seteotchar
+
+ /profile.options [
+
+ profile.items {
+ dup length add
+ dup 0 0 put
+ 1 add
+ } forall
+
+ ] def
+
+ 0 seteotchar
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Build profile list.
+%
+% ( ) ==> ( )
+%
+/profile.init {
+ /xmenu.profile .xm_size array def
+ /xmenu xmenu.profile def
+
+ profile.parsedata
+
+ xmenu .xm_title "Profile" put
+
+ xmenu .xm_current profile.default put
+ xmenu .xm_list profile.items put
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Update profile.
+%
+% ( ) ==> ( )
+%
+/profile.update {
+ /xmenu xmenu.profile def
+
+ /window.action actRedrawPanel def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show profile menu.
+%
+% ( ) => ( )
+%
+/panel.profile {
+ "profile" help.setcontext
+
+ window.xmenu
+ dup .xmenu xmenu.profile put
+ dup .xmenu.update /profile.update put
+ dup window.init
+ window.show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Return width of panel entry.
+%
+% ( ) => ( width )
+%
+/panel.profile.width {
+ /xmenu xmenu.profile def
+
+ pmenu.width
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Redraw panel entry.
+%
+% ( panel ) => ( )
+%
+/panel.profile.update {
+ /xmenu xmenu.profile def
+
+ pmenu.panel.update
+} def
+
+
diff --git a/src/dia_video.inc b/src/dia_video.inc
new file mode 100644
index 0000000..84ab80d
--- /dev/null
+++ b/src/dia_video.inc
@@ -0,0 +1,263 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Video mode selection dialog.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Some global vars.
+%
+% video mode array fields
+/.vm_mode 0 def
+/.vm_width 1 def
+/.vm_height 2 def
+
+% We have kernel splash images for at least these sizes.
+/video.splashsizes [
+ 0 0 % special: for text mode
+ 1 0 % special: for VESA mode
+ 800 600
+ 1024 600
+ 1024 768
+ 1280 800
+ 1280 1024
+ 1400 1050
+ 1600 1200
+ 1680 1050
+ 1920 1200
+] def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Create sort key for video modes.
+%
+% ( vm_index ) ==> ( sort_index )
+%
+/vmsortindex {
+ video.modes.list exch get
+ dup
+ .vm_width get 16 shl
+ exch .vm_height get add
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Swap video mode entries.
+% (Helper for video mode sorting.)
+%
+% ( vm_index_1 vm_index_2 ) ==> ( )
+%
+/vmsortexch {
+ over video.modes.list exch get
+ over video.modes.list exch get
+ video.modes.list
+ 5 -1 roll rot put
+ video.modes.list 3 1 roll put
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Check if we have a splash in that resolution.
+%
+% ( video_mode_list_entry ) ==> ( true|false )
+%
+/video.havesplash {
+ false exch
+
+ 0 2 video.splashsizes length 1 sub {
+ over over over
+ .vm_height get rot .vm_width get rot video.splashsizes exch get eq
+ rot 1 add video.splashsizes exch get rot eq and
+ { exch pop true exch exit } if
+ } for
+
+ pop
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Build video mode list.
+%
+% ( ) ==> ( )
+%
+/video.init {
+ /xmenu.video .xm_size array def
+
+ /xmenu xmenu.video def
+
+ % build list of video modes
+ /video.modes.list [
+ [ -1 0 0 ] % special: text mode
+ [ -2 1 0 ] % special: VESA mode (width = 1 to make it sort)
+
+ % first, try 16 bit
+ /vm_color_bits 16 def
+
+ {
+ 0 1 videomodes {
+ videomodeinfo dup .undef eq {
+ pop pop pop pop
+ } {
+ [
+ over 0xbfff and 6 2 roll
+ 0x4000 and % fb support
+ exch vm_color_bits eq and % color bits
+ over 600 ge and % height >= 600
+ 2 index 800 ge and % width >= 800
+ { ] } { pop pop pop pop } ifelse
+ } ifelse
+ } for
+
+ % no modes added? -> try 8 bit
+ dup .vm_mode get -2 eq vm_color_bits 8 ne and {
+ /vm_color_bits 8 def
+ } {
+ exit
+ } ifelse
+ } loop
+
+ ] def
+
+ % sort video.modes.list
+
+ video.modes.list length 3 gt {
+ 0 1 video.modes.list length 2 sub {
+ dup 1 add 1 video.modes.list length 1 sub {
+ over vmsortindex over vmsortindex gt {
+ over over vmsortexch
+ } if
+ pop
+ } for
+ pop
+ } for
+ } if
+
+ % remove duplicates
+ % (assumes text or vesa entry to be first)
+
+ /video.modes.list
+ [
+ video.modes.list {
+ dup .vm_mode get 0 gt { % ensure it's not the first entry
+ over .vm_width get over .vm_width get eq
+ 2 index .vm_height get 2 index .vm_height get eq and {
+ free
+ } if
+ } if
+ } forall
+ ]
+ video.modes.list free
+ def
+
+ % create mode strings
+
+ /video.modes.text [
+ video.modes.list {
+ dup .vm_width get
+ dup 0 eq {
+ pop pop /txt_text_mode
+ } {
+ dup 1 eq {
+ pop pop "VESA"
+ } {
+ exch .vm_height get exch "%d x %d" 32 string dup 5 1 roll sprintf
+ } ifelse
+ } ifelse
+ } forall
+ ] def
+
+ % add to menu
+
+ xmenu .xm_list video.modes.text put
+ xmenu .xm_title /txt_video_mode put
+
+ % select largest mode the monitor supports
+
+ boot_failsafe 4 and { 0 0 } { monitorsize } ifelse
+ exch 800 max exch 600 max % at least 800x600
+
+ % ATI quirk: avoid 1280x1024, older chips (<= 8MB, max res 1280x1024) use
+ % interlaced there
+
+ video.modes.list dup length 1 sub get
+ dup .vm_width get 1280 eq exch .vm_height get 1024 eq and {
+ video.memory 0x2000 le {
+ video.oem "ATI " strstr 1 eq {
+ exch 1024 min exch 768 min % down to 1024x768
+ } if
+ } if
+ } if
+
+ xmenu .xm_current -1 put
+
+ -1
+ video.modes.list {
+ exch 1 add exch
+
+ dup .vm_width get 4 index le
+ over .vm_height get 4 index le and
+ exch video.havesplash and {
+ xmenu .xm_current 2 index put
+ } if
+
+ } forall
+ pop
+
+ pop pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Update video mode.
+%
+% ( ) ==> ( )
+%
+/video.update {
+ /xmenu xmenu.video def
+
+ /window.action actRedrawPanel def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show video menu.
+%
+% ( ) => ( )
+%
+/panel.video {
+ "videomode" help.setcontext
+
+ window.xmenu
+ dup .xmenu xmenu.video put
+ dup .xmenu.update /video.update put
+ dup window.init
+ window.show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Return width of video entry.
+%
+% ( ) => ( width )
+%
+/panel.video.width {
+ /xmenu xmenu.video def
+
+ pmenu.width
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Redraw panel entry.
+%
+% ( panel ) => ( )
+%
+/panel.video.update {
+ /xmenu xmenu.video def
+
+ pmenu.panel.update
+} def
+
+
diff --git a/src/help.inc b/src/help.inc
new file mode 100644
index 0000000..8c4651c
--- /dev/null
+++ b/src/help.inc
@@ -0,0 +1,684 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% help system
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+% global vars used by help system
+
+
+/help.context "main" def
+
+/help.light white def
+/help.dark black def
+/help.font font.normal def
+/help.normal.bg window.color.bg def
+/help.normal.fg window.color.fg def
+
+/help.x 80 def
+/help.y 50 def
+/help.width 480 def
+/help.height 322 def
+
+clip.size pop 800 eq {
+ /help.x 120 def
+ /help.y 90 def
+ /help.width 560 def
+ /help.height 359 def
+} if
+
+/help.text.x help.x 10 add def
+/help.text.y help.y 30 add def
+
+/help.text.width help.width 20 sub def
+/help.text.height help.height help.text.y sub help.y add 4 sub def
+/help.text.rightmargin help.text.x help.text.width add def
+
+/help.title.x help.x 10 add def
+/help.title.y help.y 3 add def
+/help.title.height 20 def
+/help.title.font font.normal def
+
+/help.hist.page 16 array def
+/help.hist.startrow help.hist.page length array def
+/help.hist.selectedlink help.hist.page length array def
+
+
+% for boot option lookup
+/bo.opt.max 32 def
+/bo.opt bo.opt.max 3 add string def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Map help context.
+%
+% ( context ) ==> ( new_context )
+%
+% Note: obsolete.
+%
+/help.mapcontext {
+ % dup "xxx" eq { pop "yyy" } if
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Set help context.
+%
+% ( context ) ==> ( )
+%
+/help.setcontext {
+ help.mapcontext /help.context exch def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Find boot option the cursor is positioned at.
+%
+% ( ) ==> ( option )
+%
+/findbootoption {
+ boot.window .ed.list get boot.window .ed.focus get get
+ /bo.buf over .inp_buf get def
+ /bo.len over .inp_buf_len get def
+ /bo.pos exch .inp_int get .inp_int_cur get def
+
+ {
+ bo.pos 0 eq { exit } if
+ bo.buf bo.pos 1 sub get ' ' le { exit } if
+ /bo.pos bo.pos 1 sub def
+ } loop
+
+ /bo.buf bo.buf bo.pos add def
+
+ bo.buf 0 get ' ' le { "" return } if
+
+ % "o_" + option name is the help text label
+ "o_" bo.opt sprintf
+
+ 0 1 bo.opt.max 1 sub {
+ dup
+ bo.buf exch get
+ dup ' ' le over '=' eq or { pop pop exit } if
+ over bo.opt 2 add exch rot put
+ bo.opt 3 add exch 0 put
+ } for
+
+ bo.opt
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Find help page.
+%
+% returns help page or empty string if no page was found
+%
+% ( label ) ==> ( help_text )
+%
+% Shows first help page if label is not found.
+%
+/help.findpage {
+ dup length 3 add dup string
+ "\x12%s\x14"
+ 3 1 roll dup 5 1 roll snprintf
+ help.getmessages over strstr
+ dup { 2 sub } if 1 add
+ help.getmessages add
+ exch free
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Find help page.
+%
+% returns n-th help page or empty string if no page was found
+%
+% ( n ) ==> ( help_text )
+%
+/help.findpagebyindex {
+ help.getmessages exch
+ {
+ dup "\x04" strstr
+ dup { add } { pop pop "" exit } ifelse
+ } repeat
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Init & display help page.
+%
+% ( help_text start_row selected_link ) ==> ( )
+%
+/help.initpage {
+ /help.selectedlink exch def
+ /help.startrow exch def
+
+ /help.currenttext over def
+
+ window.title.bg setcolor
+ help.x 1 add help.y 1 add moveto
+ help.width 2 sub help.title.height 1 sub fillrect
+
+ help.text.x help.text.y moveto
+ currentmaxrows 0 setmaxrows exch formattext setmaxrows
+
+ white setcolor
+ currenteotchar 16 seteotchar
+ help.title.x help.title.y moveto currenttitle
+ currentfont help.title.font setfont exch show setfont
+ seteotchar
+
+ getlinks { help.selectedlink setlink } if
+
+ help.updatepage
+
+ % 500 0 moveto gettextrows print
+ % 400 0 moveto getlinks print
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Redraw help page.
+%
+% ( ) ==> ( )
+%
+/help.updatepage {
+ help.normal.bg setcolor
+ help.text.x help.text.y moveto
+ help.text.width help.text.height fillrect
+
+ help.normal.fg help.highlight.fg help.link.fg help.link.selected.fg settextcolors
+
+ help.startrow setstartrow
+
+ help.text.x help.text.y moveto
+ help.currenttext show
+
+ 0 setstartrow
+
+ true help.selectedlink help.redrawlink
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Used to iterate over all help pages (for debugging).
+%
+% get the n-th page starting from current pos
+%
+% ( n ) ==> ( help_text )
+%
+/help.test {
+ help.test.cnt add
+ dup 1 lt { pop 1 } if
+ /help.test.cnt over def
+ help.findpagebyindex
+ dup "" eq {
+ % one page back
+ pop help.test.cnt 1 sub /help.test.cnt over def
+ help.findpagebyindex
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Redraw link.
+%
+% selected: true or false.
+%
+% ( selected n ) ==> ( )
+%
+%
+/help.redrawlink {
+ getlinks 0 eq { pop pop return } if
+ getlink
+ dup help.startrow lt
+ over help.startrow help.text.rows add ge or {
+ 5 { pop } repeat return
+ } if
+ help.startrow sub lineheight mul help.text.y add
+ moveto
+ rot
+
+ 16 seteotchar
+
+ {
+ currenttextcolors 4 1 roll pop pop pop
+ help.link.selected.bg
+ } {
+ currenttextcolors 4 2 roll pop pop pop
+ help.normal.bg
+ } ifelse
+
+ setcolor over currentpoint rot strsize fillrect moveto
+
+ setcolor show
+
+ 4 seteotchar
+
+ pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Select n-th link.
+%
+% ( n ) ==> ( )
+%
+/help.selectlink {
+ help.selectedlink over eq {
+ pop
+ } {
+ % deselect old link
+ false help.selectedlink help.redrawlink
+
+ /help.selectedlink over dup setlink def
+
+ % select link
+ true exch help.redrawlink
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Select first visible link.
+%
+% No screen update if 'update' is false.
+%
+% ( update ) ==> ( )
+%
+/help.sel.firstlink {
+ getlinks {
+ 0 1 getlinks 1 sub {
+ dup
+ getlink 4 1 roll pop pop pop
+ dup help.startrow help.text.rows add ge {
+ pop pop exit
+ } if
+ dup help.startrow ge {
+ pop
+ over { help.selectlink } { /help.selectedlink exch dup setlink def } ifelse
+ exit
+ } if
+ pop pop
+ } for
+ } if
+ pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Select last visible link.
+%
+% No screen update if 'update' is false.
+%
+% ( update ) ==> ( )
+%
+/help.sel.lastlink {
+ getlinks {
+ getlinks 1 sub -1 0 {
+ dup
+ getlink 4 1 roll pop pop pop
+ dup help.startrow lt {
+ pop pop exit
+ } if
+ dup help.startrow help.text.rows add lt {
+ pop
+ over { help.selectlink } { /help.selectedlink exch dup setlink def } ifelse
+ exit
+ } if
+ pop pop
+ } for
+ } if
+ pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Push current help context to history.
+%
+% ( ) ==> ( )
+%
+/help.add2history {
+ help.hist.index help.hist.page length lt {
+ help.hist.page help.hist.index help.currenttext put
+ help.hist.startrow help.hist.index help.startrow put
+ help.hist.selectedlink help.hist.index help.selectedlink put
+ /help.hist.index help.hist.index 1 add def
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Follow currently selected link.
+%
+% ( ) ==> ( )
+%
+/help.followlink {
+ getlinks {
+ help.selectedlink getlink pop pop pop
+ help.add2history
+ help.findpage
+ dup "" eq {
+ pop
+ } {
+ 0 0 help.initpage
+ } ifelse
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Go back to previous page.
+%
+% ( ) ==> ( )
+%
+/help.prevlink {
+ help.hist.index 0 gt {
+ /help.hist.index help.hist.index 1 sub def
+ help.hist.page help.hist.index get
+ help.hist.startrow help.hist.index get
+ help.hist.selectedlink help.hist.index get
+ help.initpage
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Scroll a page down.
+%
+% ( ) ==> ( )
+%
+/help.key.pagedown {
+ help.startrow
+ gettextrows help.text.rows gt {
+ pop
+ gettextrows help.text.rows sub
+ help.startrow help.text.rows add
+ min
+ } if
+
+ dup help.startrow eq {
+ pop
+ true help.sel.lastlink
+ } {
+ /help.startrow exch def
+ false help.sel.firstlink
+ help.updatepage
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Scroll a page up.
+%
+% ( ) ==> ( )
+%
+/help.key.pageup {
+ help.startrow
+ gettextrows help.text.rows gt {
+ pop
+ 0
+ help.startrow help.text.rows sub
+ max
+ } if
+
+ dup help.startrow eq {
+ pop
+ true help.sel.firstlink
+ } {
+ /help.startrow exch def
+ false help.sel.firstlink
+ help.updatepage
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Go to page start.
+%
+% ( ) ==> ( )
+%
+/help.key.home {
+ help.startrow 0 eq {
+ true help.sel.firstlink
+ } {
+ /help.startrow 0 def
+ false help.sel.firstlink
+ help.updatepage
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Go to page end.
+%
+% ( ) ==> ( )
+%
+/help.key.end {
+ gettextrows help.text.rows sub 0 max
+ dup help.startrow eq {
+ pop
+ true help.sel.lastlink
+ } {
+ /help.startrow exch def
+ false help.sel.lastlink
+ help.updatepage
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Next link or scroll down.
+%
+% ( ) ==> ( )
+%
+/help.key.down {
+ help.selectedlink getlinks 1 sub lt {
+ help.selectedlink 1 add getlink 4 1 roll pop pop pop
+ dup help.startrow help.text.rows add lt {
+ % link visible
+ pop help.selectedlink 1 add help.selectlink
+ return
+ } {
+ help.startrow help.text.rows add eq {
+ % link visible after scrolling down
+ /help.selectedlink help.selectedlink 1 add dup setlink def
+ } if
+ } ifelse
+ } if
+
+ % scroll down
+
+ help.startrow help.text.rows add gettextrows lt {
+ /help.startrow help.startrow 1 add def
+ help.updatepage
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Previous link or scroll up.
+%
+% ( ) ==> ( )
+%
+/help.key.up {
+ help.selectedlink 0 gt {
+ help.selectedlink 1 sub getlink 4 1 roll pop pop pop
+ % row
+ dup help.startrow ge {
+ % link visible
+ pop help.selectedlink 1 sub help.selectlink
+ return
+ } {
+ help.startrow 1 sub eq {
+ % link visible after scrolling up
+ /help.selectedlink help.selectedlink 1 sub dup setlink def
+ } if
+ } ifelse
+ } if
+
+ % scroll up
+
+ help.startrow 0 gt {
+ /help.startrow help.startrow 1 sub def
+ help.updatepage
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Handle keyboard input.
+%
+% ( key_in ) ==> ( key_out )
+%
+/help.input {
+ dup 0 eq { return } if
+
+ dup keyEsc eq { /window.action actNothing def window.done } if
+ dup keyCtrlDown eq { 1 help.test 0 0 help.initpage } if
+ dup keyCtrlUp eq { -1 help.test 0 0 help.initpage } if
+ dup keyDown eq { help.key.down } if
+ dup keyUp eq { help.key.up } if
+ dup keyPgDown eq { help.key.pagedown } if
+ dup keyPgUp eq { help.key.pageup } if
+ dup keyHome eq { help.key.home } if
+ dup keyEnd eq { help.key.end } if
+ dup keyRight eq { help.followlink } if
+ dup keyEnter eq { help.followlink } if
+ dup 0xff and ' ' eq { help.followlink } if
+ dup keyLeft eq { help.prevlink } if
+ dup 0xff and '\x08' eq { help.prevlink } if
+ dup keyF1 eq {
+ "help" help.findpage
+ dup help.currenttext eq {
+ pop
+ } {
+ help.add2history
+ 0 0 help.initpage
+ } ifelse
+ } if
+% dup keyF9 eq {
+% /help.font help.font 8 add 10 mod def help.reinit
+% help.currenttext help.startrow help.selectedlink help.initpage
+% } if
+ pop 0
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Recalculate some sizes and redraw help screen.
+%
+% ( ) ==> ( )
+%
+/help.reinit {
+ help.normal.bg setcolor
+ help.x help.y moveto
+ help.width help.height fillrect
+
+ help.x 1 add help.y 1 add help.title.height add moveto
+ help.dark help.light
+ help.width 2 sub help.height 2 sub help.title.height sub
+ drawborder
+
+ help.font setfont
+
+ /help.text.rows help.text.height lineheight div def
+ help.text.rows setmaxrows
+
+ help.text.rightmargin settextwrap
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Initialize help window.
+%
+% ( window ) ==> ( )
+%
+/help.init {
+ /help.tmp exch def
+
+ help.x 1 sub help.y 1 sub moveto
+ help.light help.dark
+ help.width 2 add help.height 2 add
+ over over
+ savescreen
+ help.tmp .saved rot put
+ drawborder
+
+ help.reinit
+
+ 4 seteotchar
+
+ /help.hist.index 0 def
+
+ /help.test.cnt 1 def
+
+ help.context help.findpage 0 0 help.initpage
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Draw help window.
+%
+% ( window ) ==> ( )
+%
+/help.show {
+ window.push
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Close current help window.
+%
+% ( ) ==> ( )
+%
+/help.done {
+ 0 settextwrap
+ 0 seteotchar
+ 0 setmaxrows
+} def
+
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Create new help window.
+%
+% ( ) ==> ( window )
+%
+/window.help {
+ widget.size array
+ dup .type t_help put
+
+ dup .x help.x put
+ dup .y help.y put
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Find help texts.
+%
+% ( ) ==> ( start_of_help_messages )
+%
+% Note: must always return something (fake a message if necessary).
+%
+/help.getmessages {
+
+ help.messages .undef eq {
+ % load help texts
+ /help.messages
+ config.lang "%s.hlp" locale.findfile
+ dup .undef eq { pop "en_US" "%s.hlp" locale.findfile } if
+ dup .undef eq { pop "\x04\x12\x14No Help Texts\x10Sorry, no help texts found." } if
+ cvs
+ def
+ } if
+
+ help.messages
+
+} def
+
+
diff --git a/src/keytables.inc b/src/keytables.inc
new file mode 100644
index 0000000..6510ad5
--- /dev/null
+++ b/src/keytables.inc
@@ -0,0 +1,62 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Keyboard mappings.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% keymap layout (diff to us map):
+%
+% key_code, plain, shift, altgr
+%
+
+/.km.name 0 def
+/.km.locale 1 def
+/.km.id 2 def
+/.km.map 3 def
+
+%% include ../keymaps/keymap.cs_CZ.inc
+%% include ../keymaps/keymap.da_DK.inc
+%% include ../keymaps/keymap.de_DE.inc
+%% include ../keymaps/keymap.et_EE.inc
+%% include ../keymaps/keymap.el_GR.inc
+%% include ../keymaps/keymap.es_ES.inc
+%% include ../keymaps/keymap.fr_FR.inc
+%% include ../keymaps/keymap.hu_HU.inc
+%% include ../keymaps/keymap.it_IT.inc
+%% include ../keymaps/keymap.ja_JP.inc
+%% include ../keymaps/keymap.nb_NO.inc
+%% include ../keymaps/keymap.pl_PL.inc
+%% include ../keymaps/keymap.pt_BR.inc
+%% include ../keymaps/keymap.pt_PT.inc
+%% include ../keymaps/keymap.ru_RU.inc
+%% include ../keymaps/keymap.sk_SK.inc
+%% include ../keymaps/keymap.sl_SI.inc
+%% include ../keymaps/keymap.sv_SE.inc
+%% include ../keymaps/keymap.tr_TR.inc
+
+% array must not be empty
+/keymaps [
+ [ "Czech" "cs_CZ" "czech" keymap.cs_CZ ]
+ [ "Danish" "da_DK" "danish" keymap.da_DK ]
+ [ "German" "de_DE" "german" keymap.de_DE ]
+ [ "Estonian" "et_EE" "estonian" keymap.et_EE ]
+ [ "English-US" "en_US" "english-us" .undef ]
+ [ "Greek" "el_GR" "greek" keymap.el_GR ]
+ [ "Spanish" "es_ES" "spanish" keymap.es_ES ]
+ [ "French" "fr_FR" "french" keymap.fr_FR ]
+ [ "Hungarian" "hu_HU" "hungarian" keymap.hu_HU ]
+ [ "Italian" "it_IT" "italian" keymap.it_IT ]
+ [ "Japanese" "ja_JP" "japanese" keymap.ja_JP ]
+ [ "Norwegian" "nb_NO" "norwegian" keymap.nb_NO ]
+ [ "Polish" "pl_PL" "polish" keymap.pl_PL ]
+ [ "Portuguese-BR" "pt_BR" "portuguese-br" keymap.pt_BR ]
+ [ "Portuguese" "pt_PT" "portuguese" keymap.pt_PT ]
+ [ "Russian" "ru_RU" "russian" keymap.ru_RU ]
+ [ "Slovak" "sk_SK" "slovak" keymap.sk_SK ]
+ [ "Slovene" "sl_SI" "slovene" keymap.sl_SI ]
+ [ "Swedish" "sv_SE" "swedish" keymap.sv_SE ]
+ [ "Turkish" "tr_TR" "turkish" keymap.tr_TR ]
+] def
+
+
diff --git a/src/locale.inc b/src/locale.inc
new file mode 100644
index 0000000..cfd07c1
--- /dev/null
+++ b/src/locale.inc
@@ -0,0 +1,267 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Handle translations.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Set language.
+%
+% ( locale ) ==> ( true|false )
+%
+/setlang {
+ config.lang over eq { pop false return } if
+
+ /config.lang exch def
+
+ /config.rtl config.lang lang.getrtl def
+
+ % clear old help texts
+ /help.messages xfree
+
+ translation.texts {
+ translation.texts dup { free } forall free
+ /translation.texts .undef def
+ } if
+
+ findtexts
+
+ true
+} def
+
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Set keyboard map.
+%
+% ( locale|keymap ) ==> ( )
+%
+/setkeymap {
+ config.keymap.name over eq { pop return } if
+ /config.keymap.name exch def
+
+ config.keymap.id config.keymap.name eq { return } if
+
+ /config.keymap .undef def
+ /config.keymap.id .undef def
+
+ keymaps {
+ dup .km.id get config.keymap.name eq
+ over .km.locale get config.keymap.name eq or {
+ dup .km.map get /config.keymap exch def
+ .km.id get /config.keymap.id exch def
+ } { pop } ifelse
+ } forall
+
+ config.keymap.id .undef eq {
+ keymaps {
+ dup .km.locale get config.keymap.name locale.cmp {
+ dup .km.map get /config.keymap exch def
+ .km.id get /config.keymap.id exch def
+ } { pop } ifelse
+ } forall
+ } if
+
+ config.keymap.id .undef eq {
+ /config.keymap.id "en_US" def
+ } if
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Look up keymap in languale locale list.
+%
+% ( locale ) ==> ( keymap|locale )
+%
+/getkeymapfromlocale {
+ /kbd.tmp exch def
+ /kbd.tmp.locale .undef def
+
+ lang.defaultnames {
+ dup .la.locale get kbd.tmp eq { .la.keymap get /kbd.tmp.locale exch def exit } { pop } ifelse
+ } forall
+
+ kbd.tmp.locale .undef eq {
+ lang.defaultnames {
+ dup .la.locale get kbd.tmp locale.cmp { .la.keymap get /kbd.tmp.locale exch def exit } { pop } ifelse
+ } forall
+ } if
+
+ kbd.tmp.locale .undef ne { /kbd.tmp kbd.tmp.locale def } if
+
+ kbd.tmp
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Set texts for current language.
+%
+% ( ) ==> ( )
+%
+/findtexts {
+ /locale.texts afree
+ /locale.texts config.lang "%s.tr" loadtexts def
+
+ 0 texts {
+ over locale.texts exch aget dup .undef eq { pop "No Texts!" } if def
+ 1 add
+ } forall
+ pop
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Load texts for current language.
+%
+% ( str1 str2 -- array1 )
+%
+% str1: locale
+% str2: file name template (like "foo.%s")
+% array1: array with texts (empty if no file was found)
+%
+/loadtexts {
+ locale.findfile
+ dup .undef eq { pop "en_US" "%s.tr" locale.findfile } if
+ dup .undef eq { pop [ ] return } if
+
+ /ft.len over length def
+ /ft.str over cvs def
+ /ft.pos 0 def
+
+ [
+ {
+ ft.pos ft.str length add ft.len lt {
+ ft.str strdup
+ /ft.str ft.str dup length 1 add /ft.pos over ft.pos add def add def
+ } {
+ exit
+ } ifelse
+ } loop
+ ]
+
+ exch free
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Translate menu entry.
+%
+% ( text ) ==> ( text )
+%
+/translate {
+ translations.init
+
+ translation.texts length 2 lt { return } if
+
+ 0 2 translation.texts length -2 and 1 sub {
+ translation.texts over get 2 index eq {
+ 1 add translation.texts exch get exch pop exit
+ } { pop } ifelse
+ } for
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Read menu translations.
+%
+% ( ) ==> ( )
+%
+/translations.init {
+ translation.texts { return } if
+
+ /translation.texts [ ] def
+
+ config.lang .undef eq { return } if
+
+ config.lang "translations.%s" locale.findfile dup {
+
+ /la.tmp.datalen over length def
+ /la.tmp.str exch cvs def
+
+ la.tmp.datalen 0 eq { return } if
+ la.tmp.str la.tmp.datalen 1 sub get '\n' ne { return } if
+
+ '\n' seteotchar
+
+ /translation.texts [
+
+ /la.tmp.len 0 def
+
+ {
+ la.tmp.str la.tmp.len add strdup
+ dup dup length 0 put
+ /la.tmp.len over length 1 add la.tmp.len add def
+
+ la.tmp.len la.tmp.datalen ge { exit } if
+
+ } loop
+
+ ] def
+
+ 0 seteotchar
+ } { pop } ifelse
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Read locale-specific file.
+%
+% ( str1 str2 -- ptr1 )
+%
+% str1: locale
+% str2: file name template (like "foo.%s")
+% ptr1: buffer with file data (or .undef)
+%
+/locale.findfile {
+ over length over length add string
+
+ rot strdup rot
+
+ over over 4 index sprintf 2 index findfile
+
+ dup .undef eq {
+ pop
+ exch
+ dup "_" strstr dup {
+ 1 sub
+ over exch 0 put
+ exch
+ over over 4 index sprintf 2 index findfile
+ } {
+ pop exch .undef
+ } ifelse
+ } if
+
+ exch pop exch free exch free
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Compare two locale names.
+%
+% ( str1 str2 -- int1 )
+%
+% str1: locale1
+% str2: locale2
+% int1: 0 = no match, 1 = loose match, 2 = identical
+%
+/locale.cmp {
+ over over eq { pop pop 2 return } if
+
+ currenteotchar '_' seteotchar
+
+ rot strdup rot strdup
+
+ over over eq rot free exch free
+
+ exch seteotchar
+
+ { 1 } { 0 } ifelse
+} def
+
+
diff --git a/src/main.bc b/src/main.bc
new file mode 100644
index 0000000..abbb584
--- /dev/null
+++ b/src/main.bc
@@ -0,0 +1,30 @@
+%% include system.inc
+%% include bsplash.inc
+
+%% include timeout.inc
+%% include common.inc
+%% include serial.inc
+
+%% include ../po/text.inc
+%% include window.inc
+%% include button.inc
+%% include help.inc
+%% include menu.inc
+%% include xmenu.inc
+%% include dia_video.inc
+%% include dia_lang.inc
+%% include dia_dud.inc
+%% include dia_help.inc
+%% include dia_profile.inc
+%% include dia_install.inc
+%% include dia_bits.inc
+%% include dia_about.inc
+%% include dia_kernelopts.inc
+%% include dia_keymap.inc
+%% include panel.inc
+%% include keytables.inc
+%% include locale.inc
+%% include speech.inc
+
+%% include penguin.inc
+
diff --git a/src/menu.inc b/src/menu.inc
new file mode 100644
index 0000000..d473cb8
--- /dev/null
+++ b/src/menu.inc
@@ -0,0 +1,488 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Main menu (boot entry + boot options + panel).
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+% max number of boot option input fields
+/boot.ed.max 2 def
+
+% boot option input line separator
+/boot.splitchar 1 def
+/boot.splitstr 1 string dup 0 boot.splitchar put def
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Create new main window.
+%
+% ( ) ==> ( window )
+%
+/window.main {
+ widget.size array
+ dup .type t_main put
+ dup .font font.normal put
+ dup .ed.font font.normal put
+ dup .color.fg boot.text.normal put
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Initialize main window.
+%
+% ( window ) ==> ( )
+%
+/main.init {
+ pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Redraw main window.
+% (E.g. after selecting a new language.)
+%
+% ( window ) ==> ( )
+%
+/main.redraw {
+
+ % boot.drawlabels
+
+ main.drawmenu
+ /keepbootoptions 1 def
+ menu.entry true MenuSelect
+ /keepbootoptions .undef def
+
+ panel.show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Draw boot option input field labels.
+%
+% ( ) == > ( )
+%
+/boot.drawlabels {
+ boot.show not { return } if
+
+ boot.text.options setcolor
+ window.current .font get setfont
+ boot.ed.list {
+ dup .inp_x get 10 sub over .inp_y get moveto
+ currentpoint
+ currentpoint 0 exch moveto
+ currentpoint rot 1 add fontheight image
+ moveto
+ dup .inp_show get {
+ .inp_label get exec showright
+ } { pop } ifelse
+ } forall
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Setup boot option input field.
+%
+% ( ) == > ( )
+%
+/boot.input.setup {
+ % boot.show not { return } if
+
+ boot.ed.list {
+ dup .inp_x get over .inp_y get boot.ed.height add moveto
+
+ currentpoint boot.ed.width 2 image
+
+ currentcolor
+ currenttransparency
+
+ white setcolor
+ 0xe0 settransparency
+
+ 2 index .inp_show get {
+ boot.ed.width 2 fillrect
+ } if
+
+ settransparency
+ setcolor
+
+ pop
+
+ } forall
+} def
+
+
+/boot.input.preinit {
+
+ boot.ed.list { dup .inp_show false put .inp_buf get 0 0 put } forall
+
+ menu.args menu.entry get boot.splitchar split
+
+ 0 1 boot.ed.list length 1 sub {
+ over over aget dup .undef ne {
+ boot.ed.list rot get dup .inp_show true put .inp_buf get exch strcpy pop
+ } {
+ pop pop exit
+ } ifelse
+ } for
+
+ free
+
+ config.nobootoptions menu.texts menu.entry get iselement {
+ boot.ed.list 0 get .inp_show false put
+ } if
+
+ boot.ed.list { splitcmdline } forall
+
+} def
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Activate boot option input field.
+%
+% ( ) == > ( )
+%
+/bootoptions.init {
+ window.current .color.fg get setcolor
+ window.current .ed.font get setfont
+
+ boot.ed.list boot.window .ed.focus get get edit.hidecursor
+
+ boot.window .ed.focus 0 put
+
+ boot.show {
+ boot.ed.list {
+ dup .inp_show get {
+ dup
+ dup dup .inp_buf get exch over edit.init
+ "" ne { ' ' edit.input } { pop } ifelse
+ edit.hidecursor
+ } {
+ edit.done
+ } ifelse
+ } forall
+ boot.ed.list boot.window .ed.focus get get dup .inp_show get { edit.showcursor } { pop } ifelse
+
+ boot.ed.list {
+ dup .inp_show get .inp_visible exch put
+ } forall
+
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Redraw boot option input field.
+%
+% ( ) == > ( )
+%
+/bootoptions.redraw {
+
+ % clear old options
+
+ boot.text.options setcolor
+ window.current .font get setfont
+ boot.ed.list {
+ dup .inp_x get 10 sub over .inp_y get moveto
+ currentpoint
+ currentpoint 0 exch moveto
+ currentpoint rot 1 add fontheight image
+ moveto
+ dup .inp_show get {
+ .inp_label get exec showright
+ } { pop } ifelse
+ } forall
+
+ boot.drawlabels
+ boot.input.setup
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Draw boot menu.
+%
+% No entry is marked as selected.
+%
+% ( ) == > ( )
+%
+/main.drawmenu {
+ menu.text.normal setcolor
+
+ /x menu.start.x def
+ /y menu.start.y def
+
+ /menu.bar.width.old menu.bar.width def
+
+ /menu.bar.width
+ menu.bar.min.width
+ menu.texts { menuitemmap strsize pop menu.text.xofs 2 mul add 2 add max } forall
+ def
+
+ 0 1 menu.visible.entries 1 sub {
+ x y moveto currentpoint menu.bar.width.old menu.bar.height image
+ x config.rtl { menu.bar.width menu.text.xofs sub } { menu.text.xofs } ifelse add
+ y menu.text.yofs add moveto
+ menu.texts exch menu.shift add get menuitemmap
+ currentfont exch font.large setfont show.rtl setfont
+ /y y menu.item.height add def
+ } for
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Select/deselect menu entry.
+%
+% If an entry is selected (status = true), the boot options input field is
+% initialized.
+%
+% ( entry status ) ==> ( )
+%
+% status:
+% false not selected
+% true selected
+%
+% Note: menu.bar.width must be valid even if status = false.
+%
+/MenuSelect {
+ /menu.status exch def
+
+ /menu.idx over def
+
+ menu.shift sub
+ menu.item.height mul menu.start.y add
+ menu.start.x exch
+ moveto
+
+ currentpoint
+ menu.status {
+ menu.bar.color setcolor
+ currenttransparency
+ menu.bar.transparency settransparency
+ menu.bar.width menu.bar.height
+ fillrect
+ settransparency
+ } {
+ currentpoint menu.bar.width menu.bar.height image
+ } ifelse
+ moveto
+
+ config.rtl { menu.bar.width menu.text.xofs sub } { menu.text.xofs } ifelse
+ menu.text.yofs rmoveto
+ menu.status {
+ menu.text.select
+ } {
+ menu.text.normal
+ } ifelse
+ setcolor
+ menu.texts menu.idx get menuitemmap
+ menu.status { config.talk { dup speak } if } if
+ currentfont exch font.large setfont show.rtl setfont
+
+ menu.status {
+ % init boot options
+ keepbootoptions .undef eq {
+
+ boot.input.preinit
+
+ false
+ boot.ed.list {
+ dup .inp_show get exch .inp_visible get xor or
+ } forall
+ {
+ boot.input.setup
+ boot.drawlabels
+ } if
+
+ bootoptions.init
+ } {
+ bootoptions.redraw
+ } ifelse
+
+ % set help context
+ "main" help.setcontext
+ menu.texts menu.idx get
+ dup help.findpage "" eq {
+ pop
+ } {
+ help.setcontext
+ } ifelse
+ } if
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Draw main window.
+%
+% ( window ) ==> ( )
+%
+/main.show {
+ window.push
+
+ /menu.shift 0 def
+ /menu.visible.entries menu.texts length menu.max.entries min def
+
+ % get index of default entry
+ /menu.entry 0 def
+ 0 1 menu.texts length 1 sub {
+ dup menu.texts exch get menu.dentry eq { /menu.entry exch def exit } { pop } ifelse
+ } for
+
+ menu.entry menu.visible.entries sub 0 ge {
+ /menu.shift menu.entry menu.texts length menu.visible.entries sub min def
+ } if
+
+ boot.text.options setcolor
+
+ window.current .font get setfont
+
+ /boot.ed.width screen.size pop boot.pos.x boot.pos.y pop sub ptheme { 60 } { 20 } ifelse sub def
+ /boot.ed.height fontheight 2 add def
+
+ /boot.window window.current def
+
+ /boot.ed.list [
+ 0 1 boot.ed.max 1 sub {
+ [
+ boot.pos.x boot.pos.y exch 10 add exch 1 sub 4 -1 roll boot.ed.height 5 add mul add
+ over over moveto boot.ed.width boot.ed.height savescreen
+ cmdlinelength string
+ cmdlinelength
+ .undef
+ cmdlinelength string
+ "More Options"
+ false
+ false
+ ]
+ } for
+ ] def
+
+ boot.ed.list 0 get .inp_label /txt_bootoptions put
+
+ boot.window .ed.list boot.ed.list put
+ boot.window .ed.focus 0 put
+
+ main.drawmenu
+
+ boot.drawlabels
+
+ menu.entry true MenuSelect
+
+ % find default splash mode
+ % 0 1 splash.options length 1 sub {
+ % splash.options over get menu.args menu.entry get exch strstr {
+ % /splash.default exch def
+ % } {
+ % pop
+ % } ifelse
+ % } for
+
+ panel.init
+
+ "main" help.setcontext
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Split command line into hidden and normal part.
+%
+% ( edit_object ) == > ( )
+%
+/splitcmdline {
+ dup length .inp_hidden le { pop return } if
+ dup .inp_hidden get .undef eq { pop return } if
+
+ dup .inp_hidden get over .inp_buf get strcpy pop
+
+ dup .inp_hidden get "showopts" bootopt.find dup {
+ dup "showopts" length add skipspaces
+ 2 index .inp_buf get exch strcpy dropspaces
+ 0 0 put
+ .inp_hidden get dropspaces
+ } {
+ pop dup .inp_hidden get 0 0 put
+ .inp_buf get dropspaces
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Handle keyboard input.
+%
+% ( key_in ) ==> ( key_out )
+%
+/main.input {
+ dup 0 eq { return } if
+
+ % handle panel entries
+ panel.input
+
+ dup keyF10 eq {
+ power_off
+ pop 0
+ } if
+
+ dup keyEsc eq { exit_popup pop 0 } if
+
+ dup keyEnter eq {
+ /window.action actStart def
+ pop 0
+ } if
+
+ dup keyUp eq {
+ menu.entry 0 gt {
+ menu.entry false MenuSelect
+ menu.entry menu.shift eq {
+ /menu.shift menu.shift 1 sub def main.drawmenu
+ } if
+ /menu.entry menu.entry 1 sub def
+ menu.entry true MenuSelect
+ } if
+ pop 0
+ } if
+
+ dup keyDown eq {
+ menu.entry menu.texts length 1 sub lt {
+ menu.entry false MenuSelect
+ menu.visible.entries menu.entry menu.shift sub sub 1 eq {
+ /menu.shift menu.shift 1 add def main.drawmenu
+ } if
+ /menu.entry menu.entry 1 add def
+ menu.entry true MenuSelect
+ } if
+ pop 0
+ } if
+
+ dup keyPgUp eq {
+ menu.entry 0 gt {
+ menu.entry false MenuSelect
+ /menu.entry 0 def
+ menu.shift 0 ne {
+ /menu.shift 0 def main.drawmenu
+ } if
+ menu.entry true MenuSelect
+ } if
+ pop 0
+ } if
+
+ dup keyPgDown eq {
+ menu.entry menu.texts length 1 sub lt {
+ menu.entry false MenuSelect
+ /menu.entry menu.texts length 1 sub def
+ menu.texts length menu.visible.entries sub dup menu.shift ne {
+ /menu.shift exch def main.drawmenu
+ } {
+ pop
+ } ifelse
+ menu.entry true MenuSelect
+ } if
+ pop 0
+ } if
+
+ dup 0 ne {
+ "opt" help.setcontext
+ } if
+
+} def
+
+
diff --git a/src/panel.inc b/src/panel.inc
new file mode 100644
index 0000000..1d3e89a
--- /dev/null
+++ b/src/panel.inc
@@ -0,0 +1,201 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Panel handling.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Some global vars.
+%
+/panel.size { clip.size pop 48 } def
+/panel.y { clip.size exch pop panel.size exch pop sub 5 sub } def
+/panel.text.y { panel.y 5 add } def
+/panel.text.Fy 0 def
+/panel.font font.normal def
+
+/panel.expert false def
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Init panel.
+%
+% ( ) ==> ( )
+%
+/panel.init {
+
+ /panel.back 0 panel.y moveto panel.size savescreen def
+
+ /panel.entry.help [ keyF1 0 "F1" /panel.help /panel.help.width /panel.help.update .undef ] def
+ /panel.entry.about [ keyF1 0 "F1" /panel.about /panel.about.width /panel.about.update .undef ] def
+
+ % define panel layout
+ /panel.full [
+
+ % [ key x label show_func width_func update_func init_func ]
+
+ about.msg {
+ panel.entry.about
+ } {
+ panel.entry.help
+ } ifelse
+
+ syslinux {
+
+ config.livecd {
+
+ [ keyF2 0 "F2" /panel.lang /panel.lang.width /panel.lang.update /lang.init ]
+ [ keyF3 0 "F3" /panel.video /panel.video.width /panel.video.update /video.init ]
+
+ } {
+
+ [ keyF2 0 "F2" /panel.lang /panel.lang.width /panel.lang.update /lang.init ]
+ [ keyF3 0 "F3" /panel.video /panel.video.width /panel.video.update /video.init ]
+ [ keyF4 0 "F4" /panel.install /panel.install.width /panel.install.update /install.init ]
+ [ keyF5 0 "F5" /panel.kernelopts /panel.kernelopts.width /panel.kernelopts.update /kernelopts.init ]
+ [ keyF6 0 "F6" /panel.dud /panel.dud.width /panel.dud.update /dud.init ]
+
+ 32+64bit_source {
+ 64bit {
+ 32bit_boot_dir .undef ne
+ 64bit_boot_dir .undef ne
+ 32bit_boot_dir 64bit_boot_dir ne
+ and and {
+ [ keyF7 0 "F7" /panel.bits /panel.bits.width /panel.bits.update /bits.init ]
+ } if
+ } if
+ } if
+
+ keymap.mainmenu {
+ [ keyF8 0 "F8" /panel.keymap /panel.keymap.width /panel.keymap.update /keymap.init ]
+ } if
+
+ } ifelse
+
+ xmenu.bits .undef eq { bits.init } if
+
+ } {
+
+ [ keyF2 0 "F2" /panel.lang /panel.lang.width /panel.lang.update /lang.init ]
+ "profiles" findfile dup {
+ /profile.data exch def
+ [ keyF3 0 "F3" /panel.profile /panel.profile.width /panel.profile.update /profile.init ]
+ } { pop } ifelse
+
+ keymap.mainmenu {
+ [ keyF4 0 "F4" /panel.keymap /panel.keymap.width /panel.keymap.update /keymap.init ]
+ } if
+
+ } ifelse
+
+ ] def
+
+ % initialize all
+ panel.full { 6 get dup .undef ne { exec } { pop } ifelse } forall
+
+ /panel panel.full def
+
+ panel.show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show panel.
+%
+% ( ) ==> ( )
+%
+/panel.show {
+ panel.font setfont
+
+% panel.bg setcolor
+ 0 panel.y moveto
+% currentpoint
+ panel.back restorescreen
+% currenttransparency
+% 50 settransparency
+% panel.size fillrect
+% settransparency
+% moveto
+
+% panel.border.color setcolor
+% 0 -1 rmoveto
+% 0 1 clip.size pop 3 div { pop putpixel 3 0 rmoveto } for
+
+ % don't change xmenu
+ /xmenu xmenu
+
+ /panel.x config.rtl { clip.size pop } { 0 } ifelse def
+ panel { dup {
+ dup 1 panel.x put
+ dup 4 get exec over 2 get strsize pop add 20 add panel.x exch
+ config.rtl { sub } { add } ifelse
+ /panel.x exch def
+ dup 5 get exec
+ } { pop } ifelse } forall
+
+ def
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Handle keyboard input.
+%
+% ( key_in ) ==> ( key_out )
+%
+/panel.input {
+ panel { dup {
+ dup 0 get 2 index eq { over panel.extra pop 3 get exec pop 0 exit } { pop } ifelse
+ } { pop } ifelse } forall
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Draw panel entry label and move to text field.
+%
+% ( panel ) => ( )
+%
+/panel.text.moveto {
+ /panel.tmp.x over 1 get 10 config.rtl { sub } { add } ifelse def
+ /panel.tmp.F exch 2 get def
+
+ panel.tmp.x panel.text.y panel.text.Fy add moveto
+ panel.f-key.fg setcolor panel.tmp.F show.rtl
+ panel.normal.fg setcolor
+
+ 6 config.rtl { neg } if panel.text.Fy neg rmoveto
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Do some extra things.
+%
+% ( key ) => ( key )
+%
+/panel.extra {
+ % move down one menu entry; but only once
+ % see keyDown in main::main.input
+
+ % only for install CDs
+ syslinux not { return } if
+
+ % not for live cd
+ config.livecd { return } if
+
+ % not for F1
+ dup keyF1 eq { return } if
+
+ panel.extra.fkey .undef eq
+ menu.entry 0 eq
+ menu.entry menu.texts length 1 sub lt
+ and and {
+ /panel.extra.fkey 1 def
+ menu.entry false MenuSelect
+ menu.visible.entries menu.entry menu.shift sub sub 1 eq {
+ /menu.shift menu.shift 1 add def main.drawmenu
+ } if
+ /menu.entry menu.entry 1 add def
+ menu.entry true MenuSelect
+ } if
+} def
+
+
diff --git a/src/penguin.inc b/src/penguin.inc
new file mode 100644
index 0000000..66ac9b0
--- /dev/null
+++ b/src/penguin.inc
@@ -0,0 +1,351 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% "Penguins" boot screen.
+%
+% Copyright (C) 2001-2002, Raphael Quinet <quinet@gamers.org>
+% Copyright (C) 2005 Steffen Winterfeldt <snwint@suse.de>
+%
+% 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
+% (at your option) 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
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+%
+% Revision history:
+% 2001-11-15 - (xray-blue.config) file derived from xray-green.config
+% 2002-01-04 - file derived from xray-blue.config
+% 2002-01-05 - keystrokes can influence penguins, added timeout message
+% 2002-01-10 - adjusted the speed of the penguins
+% 2005-08-21 - reworked graphics for 800x600 @ 16 bit color
+% - reimplemented to fit to current openSUSE layout
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Original comment by Raphael:
+%
+% This script is based on those included in SuSE 7.2 and SuSE 7.3, modified
+% by Raphael Quinet. The walking penguins were extracted from the program
+% "xpenguins" (http://xpenguins.seul.org/), which had borrowed them from the
+% game "Pingus" (http://pingus.seul.org/). The original "walker" was created
+% by Joel Fauche <joel.fauche@wanadoo.fr>, the "tumbler" was created by Craig
+% Timpany <timpany@es.co.nz>, the "reader" and the "superpenguin" were
+% created by Rob Gietema <tycoon@planetdescent.com>, Robin Hogan
+% <R.J.Hogan@reading.ac.uk> and Brian Chu <chub@stuy.yi.org>.
+%
+% Requires the patched syslinux version included in openSUSE 10.0 or later.
+%
+% For more information on the original work done by Raphael, see:
+% http://www.gamers.org/~quinet/lilo/.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% penguin animations
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+/p.xmas.xmin 192 def
+/p.xmas.xmax 556 def
+/p.xmas.x 500 def
+/p.xmas.y 89 def
+/p.xmas.dx -4 def
+/p.xmas.frame 0 def
+/p.xmas.frames 8 def
+/p.xmas.src.x 252 def
+/p.xmas.src.y 0 def
+/p.xmas.src.w 32 def
+/p.xmas.src.h 45 def
+
+
+/p.walk.xmin 80 def
+/p.walk.xmax 720 def
+/p.walk.x 200 def
+/p.walk.y 523 def
+/p.walk.dx 4 def
+/p.walk.frame 0 def
+/p.walk.frames 8 def
+/p.walk.src.x 3 def
+/p.walk.src.y 1 def
+/p.walk.src.w 30 def
+/p.walk.src.h 30 def
+
+/p.read.timer 0 def
+/p.read.frame 0 def
+/p.read.frames 4 def
+/p.read.src.x 515 def
+/p.read.src.y 1 def
+
+
+/p.fall.ymax 520 def
+/p.fall.ymin -31 def
+/p.fall.x 762 def
+/p.fall.y 0 def
+/p.fall.frame 0 def
+/p.fall.frames 8 def
+/p.fall.src.x 3 def
+/p.fall.src.y 65 def
+/p.fall.src.w 30 def
+/p.fall.src.h 25 def
+/p.fall.dy -4 def % for super penguin
+
+/p.super false def % show super penguin
+/p.super.frames 2 def
+/p.super.src.x 644 def
+/p.super.src.y 0 def
+/p.super.src.h 31 def
+
+
+/ptheme.init {
+ currentimage
+
+ "panim.jpg" findfile dup setimage 0 0 image.size unpackimage /panim.img exch def free
+ "panim_a.jpg" findfile dup setimage 0 0 image.size unpackimage /panim_a.img exch def free
+
+ setimage
+
+
+ % xmas penguin
+
+ % save drawing background
+ p.xmas.xmin p.xmas.y moveto
+ /p.xmas.back
+ p.xmas.xmax p.xmas.xmin sub p.xmas.src.w add p.xmas.dx abs add
+ p.xmas.src.h savescreen
+ def
+
+ % it just needs the right size
+ /p.xmas.single 0 0 moveto p.xmas.src.w p.xmas.dx abs add p.xmas.src.h savescreen def
+
+
+ % walking penguin
+
+ % save drawing background
+ p.walk.xmin p.walk.y moveto
+ /p.walk.back
+ p.walk.xmax p.walk.xmin sub p.walk.src.w add p.walk.dx abs add
+ p.walk.src.h savescreen
+ def
+
+ % it just needs the right size
+ /p.walk.single 0 0 moveto p.walk.src.w p.walk.dx abs add p.walk.src.h savescreen def
+
+
+ % falling penguin
+
+ % save drawing background
+ /p.fall.back p.fall.x 10 moveto p.fall.src.w p.fall.src.h savescreen def
+
+ % one background line
+ /p.fall.back1 p.fall.x 10 moveto p.fall.src.w 1 savescreen def
+
+ % it just needs the right size
+ /p.fall.single 0 0 moveto p.fall.src.w p.fall.src.h savescreen def
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Draw next Xmas penguin frame.
+%
+% ( ) ==> ( )
+%
+/p.xmas.animate {
+ p.xmas.dx 0 lt {
+ p.xmas.dx p.xmas.x add p.xmas.xmin lt {
+ /p.xmas.dx p.xmas.dx neg def
+ } if
+ } {
+ p.xmas.dx p.xmas.x add p.xmas.xmax gt {
+ /p.xmas.dx p.xmas.dx neg def
+ } if
+ }
+ ifelse
+
+ /p.xmas.x p.xmas.x p.xmas.dx add def
+ /p.xmas.frame p.xmas.frame 1 add p.xmas.frames mod def
+
+ % copy background
+ p.xmas.x p.xmas.xmin sub 0 moveto
+ p.xmas.back 0xff p.xmas.single blend
+
+ % add penguin
+ p.xmas.src.x p.xmas.src.w p.xmas.frame mul add
+ p.xmas.src.y p.xmas.dx 0 gt { p.xmas.src.h add } if moveto
+ panim.img panim_a.img p.xmas.single blend
+
+ % draw
+ p.xmas.x p.xmas.y moveto p.xmas.single restorescreen
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Draw next walking penguin frame.
+%
+% ( ) ==> ( )
+%
+/p.walk.animate {
+ /p.read.timer p.read.timer 1 add 0 min def
+
+ p.read.timer 0 lt {
+ % slow down reading
+ p.read.timer 2 mod 0 eq { return } if
+ /p.read.frame p.read.frame 1 add p.read.frames mod def
+ } {
+ p.walk.dx 0 lt {
+ p.walk.dx p.walk.x add p.walk.xmin lt {
+ /p.walk.dx p.walk.dx neg def
+ } if
+ } {
+ p.walk.dx p.walk.x add p.walk.xmax gt {
+ /p.walk.dx p.walk.dx neg def
+ } if
+ }
+ ifelse
+
+ /p.walk.x p.walk.x p.walk.dx add def
+ /p.walk.frame p.walk.frame 1 add p.walk.frames mod def
+ } ifelse
+
+ % copy background
+ p.walk.x p.walk.xmin sub 0 moveto
+ p.walk.back 0xff p.walk.single blend
+
+ p.read.timer 0 lt {
+ % add penguin
+ p.read.src.x p.walk.src.w p.read.frame mul add
+ p.read.src.y
+ } {
+ % add penguin
+ p.walk.src.x p.walk.src.w p.walk.frame mul add
+ p.walk.src.y p.walk.dx 0 gt { p.walk.src.h add } if
+ } ifelse
+ moveto
+ panim.img panim_a.img p.walk.single blend
+
+ % draw
+ p.walk.x p.walk.y moveto p.walk.single restorescreen
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Draw next super penguin frame.
+%
+% ( ) ==> ( )
+%
+/p.super.animate {
+ p.fall.y p.fall.dy add p.fall.ymin lt {
+ /p.fall.y 0 def
+
+ /p.super false def
+
+ return
+ } if
+
+ /p.fall.y p.fall.y p.fall.dy add def
+ /p.fall.frame p.fall.frame 1 add p.fall.frames mod def
+
+ % copy background
+ 0 0 moveto
+ p.fall.back 0xff p.fall.single blend
+
+ % add penguin
+ p.fall.src.x
+ p.fall.src.y p.fall.src.h p.fall.frame mul add moveto
+ panim.img panim_a.img p.fall.single blend
+
+ % draw
+ p.fall.x p.fall.y moveto p.fall.single restorescreen
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Draw falling penguin.
+%
+% ( timeout time ) ==> ( )
+%
+/p.timeout.animate {
+ dup 0 le {
+ pop pop
+
+ % it vanishes...
+ p.fall.x p.fall.y moveto p.fall.back restorescreen
+
+ p.call.super
+
+ return
+ } if
+
+ over sub neg p.fall.ymax mul exch div
+
+ dup p.fall.y gt {
+ p.fall.y 1 2 index 1 sub {
+ p.fall.x exch moveto p.fall.back1 restorescreen
+ } for
+ } if
+ /p.fall.y exch def
+ /p.fall.frame p.fall.frame 1 add p.fall.frames mod def
+
+ % copy background
+ 0 0 moveto
+ p.fall.back 0xff p.fall.single blend
+
+ % add penguin
+ p.fall.src.x p.fall.src.w p.fall.frame mul add
+ p.fall.src.y moveto
+ panim.img panim_a.img p.fall.single blend
+
+ % draw
+ p.fall.x p.fall.y moveto p.fall.single restorescreen
+
+} def
+
+
+% call super penguin
+/p.call.super {
+ p.super { return } if
+
+ /p.super true def
+
+ p.fall.y 0 le {
+ /p.fall.y p.fall.ymax def
+ } if
+
+ % super penguin has different height
+ /p.fall.src.x p.super.src.x def
+ /p.fall.src.y p.super.src.y def
+ /p.fall.src.h p.super.src.h def
+
+ % and less frames
+ /p.fall.frames p.super.frames def
+
+ % change them
+ p.fall.back free
+ /p.fall.back p.fall.x 10 moveto p.fall.src.w p.fall.src.h savescreen def
+
+ p.fall.single free
+ /p.fall.single 0 0 moveto p.fall.src.w p.fall.src.h savescreen def
+} def
+
+
+ptheme {
+ % ( time ) ==> ( )
+ /Timer {
+ dup 3 mod 0 eq { p.xmas.animate } if
+ dup 3 mod 1 eq { p.walk.animate } if
+ pop
+ p.super { p.super.animate } if
+ } def
+
+} if
+
+
diff --git a/src/serial.inc b/src/serial.inc
new file mode 100644
index 0000000..94e5434
--- /dev/null
+++ b/src/serial.inc
@@ -0,0 +1,517 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Some vars.
+
+/act.nop 0 def
+/act.boot 1 def
+
+/.sm.setup 0 def
+/.sm.ok 1 def
+
+/serial.action act.nop def
+
+/serial.setup /serial.setup.start def
+
+/serial.menu.index 0 def
+
+/serial.line.status 0 def
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% serial line input event handling
+%
+% ( key -- input_buffer menu_entry action )
+%
+% key
+% bit 0-7 ascii
+% bit 24-32 scan code (0xf0 + serial line number)
+%
+% action
+% 0: ok, stay in input loop
+% 1: switch to text mode
+% >=2: start linux
+%
+/serial.input {
+ dup 24 shr 0x0f and 1 exch shl serial.line.status or /serial.line.status exch def
+
+ 0xffffff and
+
+ % ^? -> ^H
+ dup 0x7f eq { pop 8 } if
+
+ serial.setup exec
+
+ serial.edit
+ dup 0 eq { pop "" -1 0 return } if
+
+ 1 eq { serial.menu.ok } { serial.menu.prev } ifelse
+
+ window.action actCloseInfo eq {
+ /window.action actNothing def
+ window.done
+ } if
+
+ serial.action act.boot eq {
+ % /serial.setup serial.menu.layout serial.menu.index get .sm.setup get def
+
+ serial.cmdline serial.menu_idx 2
+ return
+ } if
+
+ "" -1 0
+} def
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Write string to serial line.
+%
+% ( str1 -- )
+%
+/serial.show {
+ {
+ dup 0x0a eq { 0x0d serial.putc } if
+ serial.putc
+ } forall
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( str1 -- )
+%
+/serial.edit.init {
+ serial.edit.buf exch strcpy
+ "> " serial.show serial.show
+} def
+
+/serial.edit.buf 1024 string def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( int1 -- int2 )
+%
+/serial.edit {
+ dup 0x0d eq {
+ "\n\n" serial.show
+ pop 1 return
+ } if
+
+ dup 0x1b eq {
+ "\n\n" serial.show
+ pop 2 return
+ } if
+
+ dup 0x08 eq {
+ serial.edit.buf length 0 gt {
+ serial.edit.buf dup length 1 sub 0 put
+ "\x08 \x08" serial.show
+ } if
+ pop 0 return
+ } if
+
+ dup 0x15 eq {
+ serial.edit.buf length 0 gt {
+ serial.edit.buf length {
+ "\x08 \x08" serial.show
+ } repeat
+ serial.edit.buf 0 0 put
+ } if
+ pop 0 return
+ } if
+
+ dup 0x20 ge over 0x7e le and {
+ serial.edit.buf cvp length serial.edit.buf length 1 add gt {
+ serial.edit.buf dup length add dup 1 0 put 0 2 index put
+
+ serial.putc 0 return
+ } if
+ } if
+
+ pop 0
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% ( -- )
+%
+/serial.smenu.init {
+ "\n=== " serial.show
+ smenu .xm_title get exec serial.show
+ " ===\n\n" serial.show
+ smenu .xm_text get exec serial.show
+ "\n\n" serial.show
+
+ /serial.smenu.cnt 0 def
+ /serial.smenu.tmp 256 string def
+
+ smenu .xm_list get {
+ exec
+ serial.smenu.cnt smenu .xm_current get eq { " * " } { " " } ifelse
+ /serial.smenu.cnt inc
+ serial.smenu.cnt
+ smenu .xm_list get length 10 ge { "%2d)%s%s\n" } { "%d)%s%s\n" } ifelse
+ serial.smenu.tmp sprintf
+ serial.smenu.tmp serial.show
+ } forall
+
+ /serial.smenu.tmp xfree
+
+ "\n" serial.show
+
+ "" serial.edit.init
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Draw main menu.
+%
+% ( int1 -- int2 )
+%
+% int1: key
+% int2: key
+%
+/serial.setup.start {
+ /serial.menu.layout [
+ [ /serial.main.setup /serial.main.ok ]
+ xmenu.bits .xm_list get length 1 gt { [ /serial.bits.setup /serial.bits.ok ] } if
+ xmenu.kernelopts .undef ne { [ /serial.kernel.setup /serial.kernel.ok ] } if
+ [ /serial.options.setup /serial.options.ok ]
+ [ /serial.infobox.setup /serial.infobox.ok ]
+ ] def
+
+ % go for text mode (or use 0?)
+ xmenu.video .xm_current 1 put
+
+ "\nopenSUSE 11.1 installation\n\n" serial.show
+
+ /serial.setup /serial.nop def
+
+ serial.menu.again
+
+ pop 0
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Setup main menu.
+%
+% ( -- )
+%
+/serial.main.setup {
+ smenu.main .undef eq {
+ /smenu.main .xm_size array def
+
+ smenu.main .xm_current menu.entry put
+ smenu.main .xm_title "Main Menu" put
+ smenu.main .xm_text "Select a boot entry." put
+ smenu.main .xm_list [ menu.texts { menuitemmap } forall ] put
+ } if
+
+ /smenu smenu.main def
+
+ serial.smenu.init
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Leave main menu.
+%
+% ( -- )
+%
+/serial.main.ok {
+ serial.edit.buf to_number
+
+ menu.entry false MenuSelect
+
+ serial.smenu.select {
+ /menu.entry smenu .xm_current get def
+ serial.menu.next
+ } {
+ serial.menu.again
+ } ifelse
+
+ menu.entry true MenuSelect
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Setup kernel menu.
+%
+% ( -- )
+%
+/serial.kernel.setup {
+ xmenu.kernelopts .xm_text "Select a predefined set of kernel options." put
+
+ /smenu xmenu.kernelopts def
+
+ serial.smenu.init
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Leave kernel menu.
+%
+% ( -- )
+%
+/serial.kernel.ok {
+ serial.edit.buf to_number
+ serial.smenu.select { serial.menu.next } { serial.menu.again } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Setup arch menu.
+%
+% ( -- )
+%
+/serial.bits.setup {
+ xmenu.bits .xm_text "32 or 64 bit?" put
+
+ /smenu xmenu.bits def
+
+ serial.smenu.init
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Leave arch menu.
+%
+% ( -- )
+%
+/serial.bits.ok {
+ serial.edit.buf to_number
+ serial.smenu.select { serial.menu.next } { serial.menu.again } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Setup lang menu.
+%
+% ( -- )
+%
+/serial.lang.setup {
+ /smenu xmenu.lang def
+
+ serial.smenu.init
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Leave lang menu.
+%
+% ( -- )
+%
+/serial.lang.ok {
+ serial.edit.buf to_number
+ serial.smenu.select { serial.menu.next } { serial.menu.again } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Setup options menu.
+%
+% ( -- )
+%
+/serial.options.setup {
+ "=== Boot Options ===\n" serial.show
+
+"
+Edit boot options.
+
+- lang=<locale> selects the default language
+- install=<url> sets the install repository
+- dud=<url> adds a driverupdate (option can be given more than once)
+
+"
+ serial.show
+
+ boot.ed.list buildcmdline /serial.menu_idx exch def /serial.cmdline exch def
+
+ serial.console.option dup .undef ne {
+ " %s" serial.cmdline dup length add sprintf
+ } { pop } ifelse
+
+ serial.cmdline serial.edit.init
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Options -> Boot.
+%
+% ( -- )
+%
+/serial.options.ok {
+ serial.cmdline serial.edit.buf strcpy pop
+
+ % point to infobox
+ /serial.menu.index inc
+
+ /serial.action act.boot def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Setup infobox.
+%
+% ( -- )
+%
+/serial.infobox.setup {
+ /smenu serial.infobox def
+
+ serial.smenu.init
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Leave infobox.
+%
+% ( -- )
+%
+/serial.infobox.ok {
+ serial.edit.buf to_number
+ serial.smenu.select {
+ serial.menu.prev
+ /window.action actCloseInfo def
+ } {
+ serial.menu.again
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Do nothing.
+%
+% ( -- )
+%
+/serial.nop {
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Convert String to number.
+%
+% ( str1 -- int1 )
+%
+% Returns -1 if str1 is not a number.
+%
+/to_number {
+ dup cvn
+ dup 0 ne { exch pop return } if
+ pop
+ dup "" eq exch "0" eq or { 0 } { -1 } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Ensure serial.menu.index has a valid value.
+%
+% ( -- )
+%
+/serial.menu.index.normalize {
+ serial.menu.index serial.menu.layout length gt { /serial.menu.index serial.menu.layout length def } if
+ serial.menu.index 0 lt { /serial.menu.index 0 def } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Reinit current menu.
+%
+% ( -- )
+%
+/serial.menu.again {
+ serial.menu.index.normalize
+ serial.menu.layout serial.menu.index get .sm.setup get exec
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Run 'ok' action for current menu.
+%
+% ( -- )
+%
+/serial.menu.ok {
+ serial.menu.index.normalize
+ serial.menu.layout serial.menu.index get .sm.ok get exec
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Go to next menu.
+%
+% ( -- )
+%
+/serial.menu.next {
+ /serial.menu.index inc
+ serial.menu.again
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Go to previous menu.
+%
+% ( -- )
+%
+/serial.menu.prev {
+ /serial.menu.index dec
+ serial.menu.again
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Select menu item (update smenu->.xm_current).
+%
+% ( int1 -- bool1 )
+%
+/serial.smenu.select {
+ smenu .xm_list get length over lt over 0 lt or {
+ pop
+
+ false
+ } {
+ dup 0 eq { pop smenu .xm_current get 1 add } if
+
+ 1 sub smenu .xm_current rot put
+
+ true
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Build 'console' option for kernel.
+%
+% ( -- str1 )
+%
+/serial.console.option {
+
+ /serial.tmp.bm 0 def
+ {
+ serial.line.status 1 serial.tmp.bm shl and { exit } if
+ /serial.tmp.bm inc
+ serial.tmp.bm 8 ge { /serial.tmp.bm .undef def exit } if
+ } loop
+
+ serial.tmp.bm .undef eq { .undef return } if
+ serial.lines length serial.tmp.bm le { .undef return } if
+
+ serial.lines serial.tmp.bm get 2 aget dup .undef ne {
+ serial.tmp.bm serial.getbaud exch
+ "console=%s,%d" serial.console.buf sprintf
+ serial.console.buf
+ } if
+
+} def
+
+/serial.console.buf 64 string def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Setup serial lines.
+%
+0 1 serial.lines length 1 sub {
+ serial.lines over get dup length 2 ge {
+ dup 0 get cvn exch 1 get cvn serial.setconfig
+ } {
+ pop pop
+ } ifelse
+} for
+
+serial.init
+
diff --git a/src/speech.inc b/src/speech.inc
new file mode 100644
index 0000000..49eb646
--- /dev/null
+++ b/src/speech.inc
@@ -0,0 +1,121 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Speech related function.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+/.talk_text 0 def
+/.talk_sound 1 def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% ( text -- )
+%
+/speak {
+ % skip leading TAB
+ dup 0 get '\x09' eq { 1 add } if
+
+ /last.spoken xfree
+ /last.spoken over strdup def
+
+ dup _speak { pop return } if
+ dup retranslate dup rot ne { _speak } if pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Say text.
+%
+% ( str -- bool )
+%
+% str: text
+% bool: sound sample found
+%
+/_speak {
+ talk_array {
+ dup .talk_text get 2 index eq {
+ .talk_sound get wav.playlater
+ pop true return
+ } {
+ pop
+ } ifelse
+ } forall
+ pop
+ false
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Load sound samples.
+%
+% ( -- )
+%
+/load_talk {
+ /talk_file "en.tlk" findfile def
+
+ talk_file .undef eq { return } if
+
+ talk_file getdword 0x692741e8 ne { return } if
+
+ locale.texts.en .undef eq {
+ /locale.texts.en "en_US" "%s.tr" loadtexts def
+ } if
+
+ talk_array .undef ne {
+ talk_array { free } forall
+ } if
+
+ /talk_array xfree
+
+ /talk_array [
+ 0 1 talk_file 4 add getdword 1 sub {
+ [
+ exch 8 mul 8 add talk_file add
+ dup getdword talk_file add cvs
+ exch 4 add getdword talk_file add
+ ]
+ } for
+ ] def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Load sound samples.
+%
+% ( -- )
+%
+/load_talk_dialog {
+ window.dialog
+ dup .title "Just a second..." put
+ dup .text "Please wait while speech files are being loaded..." put
+ dup window.init window.show
+
+ load_talk
+ config.volume sound.setvolume
+
+ window.done
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Get english text from translated text.
+%
+% ( str1 -- str2 )
+%
+% str1: text
+% str2: text in en_US
+%
+/retranslate {
+ 0 locale.texts {
+ 2 index eq {
+ locale.texts.en exch aget dup .undef eq { pop dup } if exch pop
+ return
+ } if
+ 1 add
+ } forall
+ pop
+} def
+
+
diff --git a/src/system.inc b/src/system.inc
new file mode 100644
index 0000000..a08945b
--- /dev/null
+++ b/src/system.inc
@@ -0,0 +1,1406 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Some basic definitions.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% some key codes
+/keyEsc 0x0000001b def
+/keyEnter 0x0000000d def
+/keyTab 0x00000009 def
+/keyShiftTab 0x0f000000 def
+/keyF1 0x3b000000 def
+/keyF2 0x3c000000 def
+/keyF3 0x3d000000 def
+/keyF4 0x3e000000 def
+/keyF5 0x3f000000 def
+/keyF6 0x40000000 def
+/keyF7 0x41000000 def
+/keyF8 0x42000000 def
+/keyF9 0x43000000 def
+/keyF10 0x44000000 def
+/keyF11 0x85000000 def
+/keyF12 0x86000000 def
+/keyHome 0x47000000 def
+/keyUp 0x48000000 def
+/keyPgUp 0x49000000 def
+/keyLeft 0x4b000000 def
+/keyRight 0x4d000000 def
+/keyEnd 0x4f000000 def
+/keyDown 0x50000000 def
+/keyPgDown 0x51000000 def
+/keyIns 0x52000000 def
+/keyDel 0x53000000 def
+/keyShiftF1 0x54000000 def
+/keyShiftF2 0x55000000 def
+/keyShiftF3 0x56000000 def
+/keyShiftF4 0x57000000 def
+/keyShiftF5 0x58000000 def
+/keyShiftF6 0x59000000 def
+/keyShiftF7 0x5a000000 def
+/keyShiftF8 0x5b000000 def
+/keyShiftF9 0x5c000000 def
+/keyShiftF10 0x5d000000 def
+/keyShiftF11 0x87000000 def
+/keyShiftF12 0x88000000 def
+/keyCtrlF1 0x5e000000 def
+/keyCtrlF2 0x5f000000 def
+/keyCtrlF3 0x60000000 def
+/keyCtrlF4 0x61000000 def
+/keyCtrlF5 0x62000000 def
+/keyCtrlF6 0x63000000 def
+/keyCtrlF7 0x64000000 def
+/keyCtrlF8 0x65000000 def
+/keyCtrlF9 0x66000000 def
+/keyCtrlF10 0x67000000 def
+/keyAltF1 0x68000000 def
+/keyAltF2 0x69000000 def
+/keyAltF3 0x6a000000 def
+/keyAltF4 0x6b000000 def
+/keyAltF5 0x6c000000 def
+/keyAltF6 0x6d000000 def
+/keyAltF7 0x6e000000 def
+/keyAltF8 0x6f000000 def
+/keyAltF9 0x70000000 def
+/keyAltF10 0x71000000 def
+/keyCtrlLeft 0x73000000 def
+/keyCtrlRight 0x74000000 def
+/keyCtrlEnd 0x75000000 def
+/keyCtrlDown 0x76000000 def
+/keyCtrlHome 0x76000000 def
+/keyCtrlUp 0x84000000 def
+/keyStatus 0xff000000 def
+
+/statusAlt 0x0208 def
+/statusAltL 0x0200 def
+/statusAltR 0x0008 def
+/statusCtrl 0x0104 def
+/statusShift 0x0003 def
+
+/CapsLock { 0x417 cvp getbyte 0x40 and 0 ne } def
+
+/black 0 def
+/white 0xffffff def
+
+% input object fields
+/.inp_x 0 def % x pos
+/.inp_y 1 def % y pos
+/.inp_back 2 def % background pixmap
+/.inp_buf 3 def % input buffer
+/.inp_buf_len 4 def % input buffer length
+/.inp_int 5 def % internal state array, see below
+% optional fields
+/.inp_hidden 6 def % hidden buffer
+/.inp_label 7 def % input field label
+/.inp_visible 8 def % field is visible
+/.inp_show 9 def % field should be visible
+
+/.inp_int_cur 0 def % current edit char offset
+/.inp_int_cursor 1 def % cursor pos (pixel)
+/.inp_int_shift 2 def % input line shifted (pixel)
+/.inp_int_flags 3 def % bit 0: cursor visible
+/.inp_int_saved_cursor 4 def % saved cursor background
+
+% boot loader
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% bootloader - boot loader type
+%
+% group: system
+%
+% ( -- int1 )
+%
+% int1: boot loader type (0: lilo, 1:syslinux/isolinux, 2: grub)
+%
+/bootloader sysconfig getbyte def
+
+/lilo bootloader 0 eq def
+/syslinux bootloader 1 eq def
+/grub bootloader 2 eq def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% boot_failsafe - failsafe options the user selected (bitmask)
+%
+% group: system
+%
+% ( -- int1 )
+%
+% int1: option bitmask
+% bit 0: SHIFT pressed
+% bit 1: no graphics
+% bit 2: no monitor detection
+%
+/boot_failsafe sysconfig 3 add getbyte def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% bootdrive - drive the BIOS booted from
+%
+% group: system
+%
+% ( -- int1 )
+%
+% int1: BIOS drive id
+%
+/bootdrive sysconfig 5 add getbyte def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% mediatype - type of media we booted from
+%
+% group: system
+%
+% ( -- int1 )
+%
+% int1: media type (0 disk, 1 floppy, 2 cdrom)
+%
+/mediatype sysconfig 2 add getbyte def
+
+/m_disk 0 def
+/m_floppy 1 def
+/m_cdrom 2 def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% biosmem - BIOS reported memory size
+%
+% group: mem
+%
+% ( -- int1 )
+%
+% int1: total memory size according to BIOS
+%
+/biosmem sysconfig 20 add getdword def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% sectorsize - sector size
+%
+% group: mem system
+%
+% ( -- int1 )
+%
+% int1: sector size in bytes
+%
+/sectorsize
+ 1
+ sysconfig 1 add getbyte
+ 20 min % max. 1 MB
+ dup 0 eq { pop 9 } if
+ shl
+def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% getinfo - type of info box
+%
+% group: system
+%
+% ( int1 -- int2 )
+%
+% int1: type of info box we have to show
+% int2: some data
+%
+% Note: really weird, should be replaced by something more obvious.
+%
+/getinfo {
+ 2 shl
+ sysconfig 12 add exch add getdword
+} def
+
+
+% bool values
+/true 0 0 eq def
+/false 0 0 ne def
+
+% type values
+/t_none 0 def
+/t_int 1 def
+/t_unsigned 2 def
+/t_bool 3 def
+/t_string 4 def
+/t_code 5 def
+/t_ret 6 def
+/t_prim 7 def
+/t_sec 8 def
+/t_dict_idx 9 def
+/t_array 10 def
+/t_end 11 def
+/t_ptr 12 def
+
+/.value { t_int settype } def
+/.undef 0 t_none settype def
+/.end 0 t_end settype def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Print string (for debugging).
+%
+% ( string ) ==> ( )
+%
+/string.print {
+ dup
+ currentpoint currentpoint 5 -1 roll strsize image moveto
+ show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Print number (for debugging).
+%
+% ( number ) ==> ( )
+%
+/number.print {
+ 32 string
+ exch over
+ "%08x" exch sprintf
+ dup string.print
+ free
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Print obj (for debugging).
+%
+% ( obj ) ==> ( )
+%
+/obj.print {
+ 64 string
+ exch dup
+ .value exch gettype
+ "%x:%08x" 3 index sprintf
+ dup string.print
+ free
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Print (for debugging).
+%
+% ( obj ) ==> ( )
+%
+/print {
+ dup gettype t_int eq { number.print return } if
+ dup gettype t_string eq { string.print return } if
+ obj.print
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Convert object to pointer.
+%
+% ( obj ) ==> ( ptr )
+%
+/cvp { t_ptr settype } def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Convert object to string.
+%
+% ( obj ) ==> ( string )
+%
+/cvs { t_string settype } def
+
+
+% base num char
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Convert object to number.
+%
+% ( obj ) ==> ( int )
+%
+/cvn {
+ dup gettype t_string eq {
+ 1 % sign
+ exch dup 0 get '-' eq {
+ exch pop 1 add -1 exch
+ } if
+ 10 % initial base
+ 0 % value
+ rot
+ {
+ dup 'a' ge { 0x20 sub } if
+ dup 'X' eq { pop pop pop 16 0 '0' } if
+ '0' sub
+ dup 9 gt { 7 sub } if
+ dup 0 lt over 4 index ge or { pop exit } if
+ exch 2 index mul add
+ } forall
+ exch pop mul
+ } {
+ t_int settype
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Arguments like snprintf.
+%
+% ( obj_1 ... obj_n string_1 string_2 ) ==> ( )
+%
+/sprintf {
+ dup cvp length exch snprintf
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Allocate new string.
+%
+% ( size ) ==> ( string )
+/string {
+ 1 add malloc cvs
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Increment variable.
+%
+% ( dict_ref ) ==> ( )
+%
+/inc {
+ dup exec 1 add def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Decrement variable.
+%
+% ( dict_ref ) ==> ( )
+%
+/dec {
+ dup exec 1 sub def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Copy src to dst.
+%
+% Watch overlapping src & dst!
+%
+% ( dst src ) ==> ( dst )
+%
+/strcpy {
+ "%s" 2 index sprintf
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Duplicate string.
+%
+% ( string ) ==> ( string )
+%
+/strdup {
+ dup length string exch strcpy
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Concatenate strings.
+%
+% ( string1 string2 ) ==> ( string1 )
+%
+/strcat {
+ over dup length add exch strcpy pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Test for AltGr.
+%
+% ( ) ==> ( bool )
+%
+/is_altGr {
+ keystat statusAltR and 0 ne keystat statusAltL and 0 eq and
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Keyboard mapping.
+%
+% ( key ) ==> ( key )
+%
+/mapkey {
+ dup 24 shr 0xff and /key.code exch def
+ is_altGr {
+ % bios is too smart...
+ key.code 0x78 ge key.code 0x83 le and { /key.code key.code 0x76 sub def } if
+ } if
+ 0 1 config.keymap length 1 sub {
+ config.keymap exch get
+ dup 0 get key.code eq {
+ 1
+ keystat statusShift and { pop 2 } if
+ is_altGr { pop 3 } if
+ get
+ exch pop
+ } {
+ pop
+ } ifelse
+ } for
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Set password mode font property.
+%
+% ( font ) ==> ( font )
+%
+/pwmode {
+ dup gettype t_ptr eq {
+ .value 0x80000000 or t_ptr settype
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Test for password mode.
+%
+% ( font -- true|false )
+%
+/is.pwmode {
+ dup gettype t_ptr eq {
+ .value 0x80000000 and 0 ne
+ } {
+ false
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show one-line string right aligned.
+%
+% ( string ) ==> ( )
+%
+/showright1 {
+ dup strsize pop neg 0 rmoveto currentpoint rot show currentpoint exch pop exch pop moveto
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show string right aligned.
+%
+% ( string ) ==> ( )
+%
+/showright {
+ '\n' split
+ currentpoint pop
+ false 2 index
+
+ % array x not_first? array
+ {
+ % array x not_first? elem
+
+ over {
+ "\n" show
+ 2 index currentpoint exch pop moveto
+ } if
+
+ dup showright1 free
+
+ pop true
+ } forall
+ pop pop
+ free
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show string right/left aligned.
+%
+% ( string ) ==> ( )
+%
+/show.rtl {
+ config.rtl { showright } { show } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show string centered.
+%
+% ( string ) ==> ( )
+%
+/showcenter {
+ dup strsize pop 2 div neg 0 rmoveto show
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Generate pseudo random number.
+% Good enough for boot loader splash screen.
+%
+% ( ) ==> ( int )
+%
+/rand {
+ rand.start 59 mul 97 add 0x7fffffff and
+ /rand.start over def
+} def
+
+% start value
+/rand.start time def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% ( date ) ==> ( weekday )
+%
+% (Monday: 0)
+%
+% d + [26*(m+1)/10] + j + [j/4] + [c/4] - 2 c - 2
+%
+/weekday {
+ dup day exch
+ dup year exch
+ month dup 2 le { 12 add exch 1 sub exch } if
+ 1 add 26 mul 10 div
+ exch dup
+ 100 mod dup 4 div add
+ exch 100 div dup 4 div exch 2 mul sub
+ add add add
+ 7 mod 12 add
+ 7 mod
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% ( date ) ==> ( day )
+%
+/day {
+ 0xff and
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% ( date ) ==> ( month )
+%
+/month {
+ 8 shr 0xff and
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% ( date ) ==> ( year )
+%
+/year {
+ 16 shr
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Read CMOS RAM.
+%
+% ( index ) ==> ( value )
+%
+/nvram {
+ 0x70 exch outbyte
+ 0x71 inbyte
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% readsector - read sector
+%
+% group: system
+%
+% ( int1 -- ptr1 )
+%
+% int1: sector number
+% ptr1: buffer with sector data or .undef. Use @free to free the buffer.
+%
+% Note: does not return on error. Returns .undef if function is not implemented.
+%
+/readsector {
+ _readsector
+ dup .undef eq { return } if
+
+ sectorsize malloc dup rot over length memcpy
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.data - return array with gfxboot config entries
+%
+% Reads and parses "gfxboot.cfg" when called first time.
+%
+% group: system
+%
+% ( -- array1 )
+%
+% array1: config values
+%
+% array1 may be empty but is never .undef.
+% Elements of array1 (if any) are arrays of three strings: [ section key value ].
+%
+/gfxconfig.data {
+
+ % read file and copy to temp string (we need the final 0)
+ "gfxboot.cfg" findfile dup .undef ne {
+ dup dup length dup string dup cvp 4 2 roll memcpy exch free
+ } {
+ pop ""
+ } ifelse
+
+ % free temp string and create temp array
+ /gfxconfig.data over '\n' split def free
+
+ % modifies gfxconfig.data
+ /gfxconfig.data [
+
+ "base" % default section
+
+ gfxconfig.data {
+
+ skipspaces
+
+ dup 0 get dup 0 eq over ';' eq or exch '#' eq or {
+ % empty or comment
+ pop
+ } {
+ dup 0 get '[' eq {
+ % [section]
+ 1 add
+ dup "]" strstr dup {
+ % put new section on stack
+ 1 sub over exch 0 put
+ exch free
+ } {
+ % wrong [section] entry
+ pop pop
+ } ifelse
+ } {
+ % key=value?
+ dup "=" strstr dup {
+ over over 1 sub over exch 0 put add
+ [ 3 index 4 2 roll ] exch
+ } {
+ % no "="
+ pop pop
+ } ifelse
+ } ifelse
+ } ifelse
+ } forall
+
+ free
+ ]
+
+ % free temp array
+ gfxconfig.data free
+
+ def
+
+ gfxconfig.data
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.layout - return array with config file sections
+%
+% group: system
+%
+% ( -- array1 )
+%
+% array1: section names
+%
+% array1 may be empty but is never .undef.
+%
+/gfxconfig.layout {
+
+ /gfxconfig.layout [ "base" ] def
+
+ "layout" gfxconfig.array_str
+ dup .undef ne {
+ gfxconfig.layout free
+ [ exch { } forall "base" ] /gfxconfig.layout exch def
+ } {
+ pop
+ } ifelse
+
+ gfxconfig.layout
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.getentry_s - return gfxboot config file entry
+%
+% group: system
+%
+% ( str1 str2 -- str3 )
+%
+% str1: section
+% str2: config entry key
+% str3: config value (or .undef)
+%
+/gfxconfig.getentry_s {
+ .undef
+ gfxconfig.data {
+ 3 index over 0 get eq 3 index 2 index 1 get eq and {
+ 2 get exch pop exit
+ } {
+ pop
+ } ifelse
+ } forall
+
+ exch pop exch pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.getentry - return raw gfxboot config file entry
+%
+% group: system
+%
+% ( str1 -- str2 )
+%
+% str1: config entry key
+% str2: config value (or .undef)
+%
+/gfxconfig.getentry {
+ .undef
+
+ gfxconfig.layout {
+ 2 index gfxconfig.getentry_s
+ dup .undef eq {
+ pop
+ } {
+ exch pop
+ exit
+ } ifelse
+ } forall
+
+ exch pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.str - return gfxboot config file entry: string
+%
+% group: system
+%
+% ( str1 -- str2 )
+%
+% str1: config entry key
+% str2: config value (or .undef)
+%
+/gfxconfig.str {
+ gfxconfig.getentry dup .undef ne { strdup dup dropspaces } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.int - return gfxboot config file entry: integer
+%
+% group: system
+%
+% ( str1 -- int1 )
+%
+% str1: config entry key
+% int1: config value (or .undef)
+%
+/gfxconfig.int {
+ gfxconfig.getentry dup .undef ne { cvn } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.int2 - return gfxboot config file entry: two integers
+%
+% group: system
+%
+% ( str1 -- int1 int2 )
+%
+% str1: config entry key
+% int1: first config value (or .undef)
+% int2: second config value (or .undef)
+%
+/gfxconfig.int2 {
+ gfxconfig.array_int dup .undef eq { pop [ ] } if
+ dup 0 aget over 1 aget rot free
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.array_str - return gfxboot config file entry: array of strings
+%
+% group: system
+%
+% ( str1 -- array1 )
+%
+% str1: config entry key
+% array1: config value (or .undef)
+%
+/gfxconfig.array_str {
+ gfxconfig.getentry dup .undef ne { ',' split } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.array_int - return gfxboot config file entry: array of integers
+%
+% group: system
+%
+% ( str1 -- array1 )
+%
+% str1: config entry key
+% array1: config value (or .undef)
+%
+/gfxconfig.array_int {
+ gfxconfig.array_str dup .undef ne {
+ [ exch
+ { dup .undef ne { cvn } if } forall
+ ]
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.set.str - initialize variable with gfxboot config file entry
+%
+% group: system
+%
+% ( dict1 str1 str2 -- )
+%
+% dict1: variable to modify
+% str1: config entry key
+% str2: default value
+%
+/gfxconfig.set.str {
+ exch gfxconfig.str
+ dup .undef ne { exch } if pop def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.set.int - initialize variable with gfxboot config file entry
+%
+% group: system
+%
+% ( dict1 str1 int1 -- )
+%
+% dict1: variable to modify
+% str1: config entry key
+% int1: default value
+%
+/gfxconfig.set.int {
+ exch gfxconfig.int
+ dup .undef ne { exch } if pop def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.set.int2 - initialize two variables with gfxboot config file entry
+%
+% group: system
+%
+% ( dict1 dict2 str1 int1 int2 -- )
+%
+% dict1: first variable to modify
+% dict2: second variable to modify
+% str1: config entry key
+% int1: first default value
+% int2: second default value
+%
+/gfxconfig.set.int2 {
+ rot gfxconfig.int2
+ % dict1 dict2 def1 def2 val1 val2
+ exch 4 -1 roll exch
+ % dict1 dict2 def2 val2 def1 val1
+ dup .undef ne { exch } if pop
+ 5 -1 roll exch def
+ % dict2 def2 val2
+ dup .undef ne { exch } if pop def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.set.bool - initialize variable with gfxboot config file entry
+%
+% group: system
+%
+% ( dict1 str1 bool1 -- )
+%
+% dict1: variable to modify
+% str1: config entry key
+% bool1: default value
+%
+/gfxconfig.set.bool {
+ exch gfxconfig.int
+ dup .undef ne { 0 ne exch } if pop def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.set.array_str - initialize variable with gfxboot config file entry
+%
+% group: system
+%
+% ( dict1 str1 array1 -- )
+%
+% dict1: variable to modify
+% str1: config entry key
+% array1: default value
+%
+/gfxconfig.set.array_str {
+ exch gfxconfig.array_str
+ dup .undef ne { exch } if pop def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% gfxconfig.set.array_int - initialize variable with gfxboot config file entry
+%
+% group: system
+%
+% ( dict1 str1 array1 -- )
+%
+% dict1: variable to modify
+% str1: config entry key
+% array1: default value
+%
+/gfxconfig.set.array_int {
+ exch gfxconfig.array_int
+ dup .undef ne { exch } if pop def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% split - split string
+%
+% group:
+%
+% ( str1 int1 -- array1 )
+%
+% str1: string
+% int1: char
+% array1: array of strings
+%
+/split {
+
+ % split does not work if str1 is in a special memory region (where
+ % 'cvp length' does not work). So we dup it first.
+
+ exch strdup dup rot
+
+ currenteotchar exch seteotchar exch
+
+ [ exch
+
+ {
+ dup strdup exch
+ dup length add
+
+ dup cvp length 1 le { pop exit } if
+
+ 1 add
+
+ } loop
+
+ ]
+
+ exch seteotchar
+
+ exch free
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% join - join array of strings
+%
+% group:
+%
+% ( array1 str1 -- str2 )
+%
+% array1: array of strings
+% str1: separator
+% str2: complete string
+%
+/join {
+ over length 0 eq { pop pop 0 string return } if
+
+ over length 1 sub over length mul
+ 2 index { length add } forall
+ string
+
+ % note: last element is not followed by separator because it exceeds
+ % the destination string size
+ rot {
+ strcat over strcat
+ } forall
+
+ exch pop
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Skip leading non-spaces.
+%
+% ( string ) ==> ( string )
+%
+/skipnonspaces {
+ { dup 0 get dup 0 ne exch ' ' ne and { 1 add } { exit } ifelse } loop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Skip leading spaces.
+%
+% ( string ) ==> ( string )
+%
+/skipspaces {
+ { dup 0 get ' ' eq { 1 add } { exit } ifelse } loop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Drop spaces at string end.
+% Modifies string!
+%
+% ( string ) ==> ( )
+%
+/dropspaces {
+ dup length
+ dup 0 eq {
+ pop pop
+ } {
+ 1 sub
+ -1 0 {
+ over over get ' ' eq { over exch 0 put } { pop exit } ifelse
+ } for
+ pop
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Test if string[ofs-1]/string[ofs] is a word boundary.
+%
+% ( string ofs ) ==> ( true|false )
+%
+% boundary is either space/non-space or non-space/(space|'=')
+%
+/iswordboundary {
+ dup 0 eq { pop pop true return } if
+
+ add dup 1 sub 0 get exch 0 get
+
+ over ' ' eq over ' ' gt and { pop pop true return } if
+ over ' ' gt over dup ' ' eq exch dup '=' eq exch 0 eq or or and { pop pop true return } if
+
+ pop pop false
+} def
+
+
+%% findmode - find video mode number
+%
+% group: gfx.screen
+%
+% ( int1 int2 int3 -- int4 )
+%
+% int1, int2: width, height
+% int3: color bits
+% int4: mode number (or .undef)
+%
+% example
+% 1024 768 16 findmode setmode % 1024x768, 16-bit color mode
+%
+/findmode {
+ 0 1 videomodes {
+ videomodeinfo dup .undef eq {
+ pop pop pop pop
+ } {
+ % compare width, height, colors
+ 6 index 4 index eq 6 index 4 index eq and 5 index 3 index eq and {
+ 7 1 roll 6 { pop } repeat 0xbfff and return
+ } {
+ pop pop pop pop
+ } ifelse
+ } ifelse
+ } for
+
+ pop pop pop .undef
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% Replace substring. Returns newly allocated string.
+%
+% ( str key value ) ==> ( new_str )
+%
+% Replaces first occurence of 'key' in str with 'value'.
+%
+/strreplace {
+ 2 index 2 index strstr dup 0 ne {
+ 1 sub
+ over length 3 index length sub 4 index length add string
+ dup cvp 5 index cvp 3 index memcpy
+ dup 6 1 roll over add exch 5 -1 roll exch add
+ 4 -1 roll length add 3 1 roll "%s%s" exch sprintf
+ } {
+ pop pop pop strdup
+ } ifelse
+
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Search for option in cmdline.
+% Returns .undef if not found.
+%
+% ( cmdline option_name ) ==> ( option_start )
+%
+/bootopt.find {
+ /_bo.opt exch def
+ /_bo.cmdline exch def
+ /_bo.= _bo.opt dup length 1 sub get '=' eq def
+
+ {
+ _bo.cmdline _bo.opt strstr
+ dup {
+ dup 1 eq {
+ true
+ } {
+ dup 2 sub _bo.cmdline exch get ' ' eq
+ } ifelse
+
+ {
+ _bo.cmdline over _bo.opt length add 1 sub get
+ dup '=' eq
+ over ' ' eq or
+ exch 0 eq or
+ _bo.= or
+ } {
+ false
+ } ifelse
+
+ _bo.cmdline rot add exch
+
+ {
+ 1 sub exit
+ } {
+ /_bo.cmdline exch def
+ } ifelse
+ } {
+ pop
+ .undef exit
+ } ifelse
+ } loop
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Search for second occurence of option in cmdline.
+% Returns .undef if not found.
+%
+% ( cmdline option_name ) ==> ( option_start )
+%
+/bootopt.find2 {
+ over over bootopt.find dup .undef eq {
+ pop pop pop .undef
+ } {
+ 1 add rot pop exch bootopt.find
+ } ifelse
+} def
+
+
+% Remove option from cmdline. Returns removed option or .undef.
+%
+% cmdline is modified, option_entry is allocated dynamicyll and must be
+% freed later.
+%
+% ( cmdline option_name -- option_entry )
+%
+/bootopt.remove {
+ bootopt.find dup .undef ne {
+ dup
+ skipnonspaces dup skipspaces 2 index sub rot rot over sub string over strcpy
+ rot rot
+ {
+ over over exch get
+ over over 0 exch put {
+ 1 add
+ } {
+ exit
+ } ifelse
+ } loop
+ pop pop
+ } if
+} def
+
+
+% Video memory in kb.
+%
+% ( -- int )
+%
+/video.memory {
+ /video.memory 0 sysinfo def
+ video.memory
+} def
+
+
+% Graphics card OEM info.
+%
+% ( -- string )
+%
+/video.oem {
+ /video.oem 1 sysinfo strdup def
+ video.oem
+} def
+
+
+% Graphics card vendor name.
+%
+% ( -- string )
+%
+/video.vendor {
+ /video.vendor 2 sysinfo strdup def
+ video.vendor
+} def
+
+
+% Graphics card product name.
+%
+% ( -- string )
+%
+/video.product {
+ /video.product 3 sysinfo strdup def
+ video.product
+} def
+
+
+% Graphics card revision.
+%
+% ( -- string )
+%
+/video.revision {
+ /video.revision 4 sysinfo strdup def
+ video.revision
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Free memory.
+%
+% Like free, but accepts dict entries, too.
+%
+% ( obj -- )
+%
+/xfree {
+ dup gettype
+ t_dict_idx eq {
+ dup exec exch .undef def
+ } if
+ free
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Free array and all its elements.
+%
+% If array is a dict entries, undefines it, too.
+%
+% ( array -- )
+%
+/afree {
+ dup .undef ne {
+ dup gettype t_dict_idx eq { dup exec exch .undef def } if
+ dup { free } forall
+ free
+ } {
+ pop
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Get array element.
+%
+% Like get, but returns .undef if index is outside array bounds.
+%
+% ( array index -- obj )
+%
+/aget {
+ over length over gt { get } { pop pop .undef } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Search for array element.
+%
+% ( array key -- bool )
+%
+/iselement {
+ false rot {
+ 2 index eq { pop true exit } if
+ } forall
+ exch pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% pc speaker beep.
+%
+% ( freq duration -- )
+%
+% freq in Hz, duration in microseconds.
+%
+/beep {
+ exch
+ 0x61 inbyte
+ dup 3 or 0x61 exch outbyte
+ 0x43 0xb6 outbyte
+ exch 2386360 exch div
+
+ dup 0x42 exch outbyte
+ 8 shr 0x42 exch outbyte
+
+ exch usleep
+
+ 0x61 exch outbyte
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Play movie.
+%
+% ( str1 -- )
+%
+% Image filename template.
+%
+/play_movie {
+ 64 string
+
+ 0
+
+ {
+ 1 add
+ dup 3 index 3 index sprintf
+
+ over findfile dup .undef eq {
+ pop exit
+ } {
+ 10000 usleep
+ currentimage
+ over setimage 0 0 image.size image
+ setimage
+ free
+ } ifelse
+
+
+ } loop
+
+ pop free pop
+
+} def
+
+
diff --git a/src/timeout.inc b/src/timeout.inc
new file mode 100644
index 0000000..93027b8
--- /dev/null
+++ b/src/timeout.inc
@@ -0,0 +1,149 @@
+%
+% include before common.inc
+%
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Boot timeout counter.
+%
+% ( timeout time ) ==> ( )
+%
+% timeout: total time in 18.2Hz steps, time: current value.
+%
+% The code below assumes we're showing seconds and some symbolic counter.
+%
+/Timeout {
+ % first time
+ timeout.current .undef eq { over timeout.init } if
+
+ ptheme { over over p.timeout.animate } if
+
+ % no counter
+ timeout.steps .undef eq { return } if
+
+ /timeout.s.last timeout.s.current def
+ /timeout.s.current over 10 mul 150 add 182 div def
+
+ /timeout.last timeout.current def
+ over sub neg timeout.steps mul exch div
+ /timeout.current exch def
+
+ timeout.current timeout.steps ge {
+ % last run
+ timeout.s.done
+ timeout.done
+ } {
+ % 0 270 moveto timeout.last print "<" print timeout.current print "<" print
+
+ timeout.s.last timeout.s.current ne { timeout.s.current timeout.s.update } if
+
+ timeout.last timeout.current ne {
+ timeout.last 1 add 1 timeout.current { timeout.update } for
+ } if
+
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Initialize timeout indicator.
+%
+% ( time ) ==> ( )
+%
+/timeout.init {
+ "timer_a.jpg" findfile /timeout.file over def dup .undef ne {
+ currentimage exch setimage
+ 0 0 image.size unpackimage /timeout.image exch def
+ setimage
+
+ /timeout.steps timeout.image imgsize div def
+
+ /timeout.width timeout.image imgsize exch pop def
+
+ /timeout.x menu.start.x menu.bar.width add 24 sub def
+ /timeout.y menu.start.y 2 sub menu.entry menu.item.height mul add def
+
+ timeout.x timeout.y moveto
+ /timeout.bg timeout.width dup savescreen def
+ % just a few buffers
+ /timeout.img_buf timeout.width dup savescreen def
+ /timeout.alpha_buf timeout.width dup savescreen def
+
+ /timeout.current 0 def
+
+ timeout.current timeout.update
+ } { pop } ifelse
+
+ /timeout.s.buf 64 string def
+ /timeout.s.x 100 def
+ /timeout.s.y 250 def
+ /timeout.s.current -1 def
+
+ pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Update timeout indicator.
+%
+% ( index ) ==> ( )
+%
+% index runs from 0 to timeout.steps - 1. It is guaranteed that index is
+% 1 larger than the last index. Never a step twice and no step is left out.
+%
+/timeout.update {
+ timeout.width mul 0 moveto
+ timeout.image 255 timeout.alpha_buf blend
+
+ timeout.img_buf timeout.bg dup length memcpy
+
+ 0 0 moveto
+ black timeout.alpha_buf timeout.img_buf blend
+
+ timeout.x timeout.y moveto
+ timeout.img_buf restorescreen
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Clear timeout indicator.
+%
+% ( ) ==> ( )
+%
+/timeout.done {
+ timeout.x timeout.y moveto
+ timeout.bg restorescreen
+
+ /timeout.bg timeout.bg free .undef def
+ /timeout.img_buf timeout.img_buf free .undef def
+ /timeout.alpha_buf timeout.alpha_buf free .undef def
+ /timeout.image timeout.image free .undef def
+ /timeout.file timeout.file free .undef def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Update seconds counter.
+%
+% ( time_in_s ) ==> ( )
+%
+/timeout.s.update {
+% white setcolor
+% timeout.s.x timeout.s.y moveto -30 0 rmoveto
+% currentpoint 30 fontheight image
+% "%ds" timeout.s.buf sprintf
+% timeout.s.x timeout.s.y moveto timeout.s.buf showright
+ pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Clear seconds counter.
+%
+% ( ) ==> ( )
+%
+/timeout.s.done {
+% timeout.s.x timeout.s.y moveto -30 0 rmoveto
+% currentpoint 30 fontheight image
+} def
+
+
diff --git a/src/window.inc b/src/window.inc
new file mode 100644
index 0000000..a151a8d
--- /dev/null
+++ b/src/window.inc
@@ -0,0 +1,711 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% window code
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% public words:
+%
+% window.dialog ( ) ==> ( window )
+% - create a new dialog
+%
+% window.init ( window ) ==> ( )
+% - initialize window
+%
+% window.show ( window ) ==> ( )
+% - draw window
+%
+% window.current ( ) ==> ( window )
+% - the top level window
+%
+% window.action ( ) ==> ( action )
+% - recent window action
+%
+% window.input ( key_in ) ==> ( key_out )
+% - handle keyboard input
+%
+% window.done ( ) ==> ( )
+% - close top level window
+%
+%
+% constants:
+% - window.action
+% actNothing - do nothing
+% actExit - leave boot menu
+% actCloseInfo - close info window
+% actPassword - password entered
+% actStart - boot kernel
+% actEject - eject CD
+% actPowerOff - turn computer off
+% actReboot - reboot computer
+% actRedraw - redraw everything
+% actNoClose - don't close dialog (it's a flag)
+%
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% window related global variables
+%
+
+% all open windows are stacked here
+/window.list 8 array def
+/window.list.index 0 def
+
+% the top level window
+% /window.current
+
+% action selected by closing window
+/window.action actNothing def
+
+% window field definitions
+/widget.size 0 def
+/newfield { widget.size def /widget.size widget.size 1 add def } def
+
+/.type newfield
+/.x newfield
+/.y newfield
+/.width newfield
+/.height newfield
+/.width.min newfield
+/.position newfield
+/.color.fg newfield
+/.color.bg newfield
+/.font newfield
+/.saved newfield
+/.saved.areas newfield
+/.title newfield
+/.title.fg newfield
+/.title.bg newfield
+/.title.height newfield
+/.text newfield
+/.text.x newfield
+/.text.y newfield
+/.buttons newfield
+/.button.y newfield
+/.ed newfield
+/.ed.font newfield
+/.ed.list newfield
+/.ed.buffer.list newfield
+/.ed.text.list newfield
+/.ed.width newfield
+/.ed.focus newfield
+/.ed.pw_field newfield
+/.xmenu newfield
+/.xmenu.update newfield
+
+% window types
+/t_dialog 100 def
+/t_help 101 def
+/t_main 102 def
+/t_xmenu 103 def
+
+% actions
+/actNothing 0 def
+/actExit 1 def
+/actCloseInfo 2 def
+/actPassword 3 def
+/actStart 4 def
+/actEject 5 def
+/actPowerOff 6 def
+/actRedraw 7 def
+/actRedrawPanel 8 def
+/actInstallOK 9 def
+/actInstallCancel 10 def
+/actReboot 11 def
+/actNoClose 0x100 def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Create new dialog window.
+%
+% ( ) ==> ( window )
+%
+/window.dialog {
+ widget.size array
+ dup .type t_dialog put
+ dup .position 8 put % centered at 8/10 of screen height
+ dup .x 0 put
+ dup .y 0 put
+ dup .width.min 0 put
+ dup .color.fg window.color.fg put
+ dup .color.bg window.color.bg put
+ dup .font font.normal put
+ dup .title.fg window.title.fg put
+ dup .title.bg window.title.bg put
+ dup .title.height help.title.height put
+ dup .text.x 12 put
+ dup .text.y help.title.height 10 add put
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Handle keyboard input.
+%
+% ( key_in ) ==> ( key_out )
+%
+/window.input {
+ window.current .undef ne {
+ window.current .type get
+ dup t_dialog eq { exch dialog.input exch } if
+ dup t_help eq { exch help.input exch } if
+ dup t_main eq { exch main.input dialog.input exch } if
+ dup t_xmenu eq { exch xmenu.input exch } if
+ pop
+
+ % % maybe there is an editable input field
+ % dup 0 ne {
+ % window.current .ed get .undef ne {
+ % window.current .ed.font get setfont
+ % window.current .color.fg get setcolor
+ % window.current .ed get exch edit.input
+ % 0
+ % } if
+ % } if
+
+ % only top level window gets input
+ pop 0
+
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Initialize window.
+%
+% ( window ) ==> ( )
+%
+/window.init {
+ dup .type get
+ dup t_dialog eq { pop dialog.init return } if
+ dup t_help eq { pop help.init return } if
+ dup t_main eq { pop main.init return } if
+ dup t_xmenu eq { pop xmenu.init return } if
+ pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Show window.
+%
+% ( window ) ==> ( )
+%
+/window.show {
+ dup .type get
+ dup t_dialog eq { pop dialog.show return } if
+ dup t_help eq { pop help.show return } if
+ dup t_main eq { pop main.show return } if
+ dup t_xmenu eq { pop xmenu.show return } if
+ pop
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Add window to list.
+%
+% ( window ) ==> ( )
+%
+/window.push {
+ window.list.index window.list length ge { pop return } if
+ /window.current over def
+ window.list window.list.index rot put
+ /window.list.index window.list.index 1 add def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Remove window from list.
+%
+% ( ) ==> ( window )
+%
+/window.pop {
+ window.list.index 0 eq { .undef return } if
+ /window.list.index window.list.index 1 sub def
+ window.list window.list.index get
+ window.list window.list.index .undef put
+ /window.current
+ window.list.index 0 eq { .undef } { window.list window.list.index 1 sub get } ifelse
+ def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Close top level window.
+%
+% ( ) ==> ( )
+%
+/window.done {
+ window.current .undef ne {
+ window.current dup .type get
+ dup t_help eq { help.done } if
+ dup t_xmenu eq { xmenu.done } if
+ pop
+ % restore saved background and free bg image
+ dup .saved get .undef ne {
+ dup .x get 1 sub over .y get 1 sub moveto
+ dup .saved get dup restorescreen free
+ dup .saved .undef put
+ } if
+ % restore & free saved background areas
+ dup .saved.areas get .undef ne {
+ % list of [ x y screen ]
+ dup .saved.areas get {
+ dup { } forall
+ 3 1 roll moveto dup restorescreen free
+ free
+ } forall
+ dup .saved.areas get free
+ dup .saved.areas .undef put
+ } if
+ % free input field memory
+ dup .ed get .undef ne {
+ dup .ed get 2 get free % background
+ dup .ed get free
+ dup .ed .undef put
+ } if
+ dup .ed.text.list get free
+ dup .ed.list get dup {
+ { dup 2 get free free } forall
+ } { pop } ifelse
+ dup .ed.list get free
+ pop
+ % remove it from window list
+ window.pop
+ % free buttons & button list
+ dup .buttons get
+ dup .undef ne {
+ dup length 0 gt {
+ dup length 1 sub 0 1 rot {
+ over exch get free
+ } for
+ } if
+ } if
+ free
+ % free window
+ free
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Handle keyboard input.
+%
+% ( key_in ) ==> ( key_out )
+%
+/dialog.input {
+ dup 0 eq { return } if
+
+ /window.buttons window.current .buttons get def
+
+ /has_buttons window.buttons .undef ne { window.buttons length 0 gt } { false } ifelse def
+
+ dup keyEnter eq has_buttons and {
+ window.buttons window.findselected
+ over over get 7 get /window.action exch def get
+ dup button.press 100000 usleep
+ window.action actNoClose and {
+ window.action dialog.specialaction { button.show } if
+ } {
+ pop window.done
+ } ifelse
+ pop 0
+ } if
+
+ window.current .ed.list get {
+
+ window.current .ed.list get window.current .ed.focus get get .inp_show aget false ne {
+
+ dup keyDown eq over keyTab eq or {
+ window.current .ed.focus get
+ window.current .ed.list get over get edit.hidecursor
+
+ 1 add window.current .ed.list get length mod
+ window.current .ed.list get over get .inp_show aget false ne { } { pop 0 } ifelse
+ window.current .ed.focus 2 index put
+ window.current .ed.list get exch get edit.showcursor
+ dialog.say.label
+ pop 0
+ } if
+
+ dup keyUp eq over keyShiftTab eq or {
+ window.current .ed.focus get
+ window.current .ed.list get over get edit.hidecursor
+
+ 1 sub window.current .ed.list get length exch over add exch mod
+ {
+ dup 0 eq { exit } if
+ window.current .ed.list get over get .inp_show aget false ne { exit } { 1 sub } ifelse
+ } loop
+ window.current .ed.focus 2 index put
+ window.current .ed.list get exch get edit.showcursor
+ dialog.say.label
+ pop 0
+ } if
+
+ % dup keyTab eq {
+ % window.findselected 1 add window.buttons length mod
+ % window.selectbutton
+ % pop 0
+ % } if
+
+ } if
+
+ } {
+ has_buttons {
+ dup keyTab eq over keyRight eq or over keyDown eq or {
+ window.findselected 1 add window.buttons length mod
+ window.selectbutton
+ pop 0
+ } if
+
+ dup keyShiftTab eq over keyLeft eq or over keyUp eq or {
+ window.findselected window.buttons length 1 sub add window.buttons length mod
+ window.selectbutton
+ pop 0
+ } if
+ } if
+ } ifelse
+
+ has_buttons {
+ dup window.findkey dup 0 ge {
+ window.buttons exch
+ over over get 7 get /window.action exch def get
+ dup button.press 100000 usleep
+ window.action actNoClose and {
+ window.action dialog.specialaction { button.show } if
+ } {
+ pop window.done
+ } ifelse
+ pop 0
+ } {
+ pop
+ } ifelse
+ } if
+
+
+ % maybe there are input fields
+ dup 0 ne {
+ window.current .ed.list get dup {
+ window.current .ed.font get
+ window.current .ed.focus get window.current .ed.pw_field get eq { pwmode } if
+ setfont
+ window.current .color.fg get setcolor
+
+ window.current .ed.focus get get dup .inp_show aget false ne {
+ exch over over edit.input
+ % only if real key
+ 24 shr 0xff and 0xff ne config.talk and currentfont is.pwmode not and {
+ edit.getleft dup 'A' ge over 'Z' le and { 0x20 add } if
+ dialog.input.tmp1 0 rot put dialog.input.tmp1 speak
+ } {
+ pop
+ } ifelse
+ } {
+ pop pop
+ } ifelse
+ 0
+ } { pop } ifelse
+ } if
+
+} def
+
+/dialog.input.tmp1 1 string def
+
+/dialog.say.label {
+ config.talk { window.current .ed.text.list get window.current .ed.focus get get speak } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Find selected button.
+%
+% ( ) ==> ( button_idx )
+%
+/window.findselected {
+ 0
+ 0 1 window.buttons length 1 sub {
+ dup
+ window.buttons exch get 5 get
+ {
+ exch pop exit
+ } {
+ pop
+ } ifelse
+ } for
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Find button for key.
+%
+% ( key ) ==> ( button_idx )
+%
+% button_idx = -1 if not found
+%
+/window.findkey {
+ /window.key exch def
+ -1
+ window.key 0 eq { return } if
+ 0 1 window.buttons length 1 sub {
+ dup
+ window.buttons exch get 6 get window.key eq
+ {
+ exch pop exit
+ } {
+ pop
+ } ifelse
+ } for
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Select button.
+%
+% ( button_idx ) ==> ( )
+%
+/window.selectbutton {
+ window.findselected
+ over over eq {
+ pop pop
+ } {
+ window.buttons exch get button.notdefault button.show
+ window.buttons exch get button.default button.show
+ } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Initialize dialog window.
+%
+% ( window ) ==> ( )
+%
+/dialog.init {
+ /dialog.tmp exch def
+
+ dialog.tmp .font get setfont
+
+ dialog.tmp .text get dup "" ne { strsize } { pop 0 0 } ifelse
+ /dialog.height exch dialog.tmp .text.y get 10 add add def
+ /dialog.width exch dialog.tmp .text.x get 1 add 2 mul add dialog.tmp .width.min get max def
+
+ /dialog.width dialog.tmp .title get strsize pop dialog.tmp .text.x get 1 add 2 mul add dialog.width max def
+
+ dialog.tmp .ed.text.list get dup {
+ /dialog.width
+ dialog.tmp .ed.width get dialog.tmp .text.x get 1 add 2 mul add 8 add dialog.width max
+ def
+ {
+ strsize
+ /dialog.height exch dialog.height add def
+ /dialog.width exch dialog.tmp .text.x get 1 add 2 mul add dialog.width max def
+ } forall
+ } { pop } ifelse
+
+ dialog.tmp .ed.buffer.list get dup {
+ length lineheight 20 add mul /dialog.height exch dialog.height add def
+ } { pop } ifelse
+
+ /window.buttons dialog.tmp .buttons get def
+
+ /dialog.button.y dialog.height 5 add def
+
+ window.buttons .undef ne { window.buttons length {
+ /dialog.height window.buttons 0 get 3 get dialog.button.y add 8 add def
+ } if } if
+
+ /dialog.y screen.size exch pop dialog.tmp .position get mul 10 div dialog.height sub 2 div 10 max def
+
+ window.buttons .undef ne { window.buttons length {
+ 10
+ 0 1 window.buttons length 1 sub {
+ window.buttons exch get
+ dup 1 dialog.button.y dialog.y add put
+ 2 get 10 add add
+ } for
+
+ dialog.width max /dialog.width exch def
+ } if } if
+
+ % adjust to window size
+ dialog.tmp .ed.width get .undef ne {
+ dialog.tmp .ed.width over over get dialog.width 30 sub max put
+ } if
+
+ /dialog.x screen.size pop dialog.width sub 2 div def
+
+ window.buttons .undef ne { window.buttons length {
+ % calculate button x positions
+ dialog.width 0
+ 0 1 window.buttons length 1 sub {
+ window.buttons exch get 2 get add
+ } for
+ sub window.buttons length 1 add div
+ dialog.x over add
+ 0 1 window.buttons length 1 sub {
+ window.buttons exch get
+ over over 0 rot put
+ 2 get add over add
+ } for
+ pop pop
+ } if } if
+
+ % store values
+
+ dialog.tmp
+ dup .x dialog.x put
+ dup .y dialog.y put
+ dup .width dialog.width put
+ dup .height dialog.height put
+ .button.y dialog.button.y put
+
+ /dialog.tmp .undef def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Draw dialog window.
+%
+% ( window ) ==> ( )
+%
+/dialog.show {
+ /dialog.tmp exch def
+
+ % put into list early, so drawing functions can access it there
+ dialog.tmp window.push
+
+ % now start drawing
+
+ dialog.tmp .x get 1 sub dialog.tmp .y get 1 sub moveto
+ white black
+ dialog.tmp .width get 2 add dialog.tmp .height get 2 add
+ over over
+ savescreen
+ dialog.tmp .saved rot put
+ drawborder
+
+ dialog.tmp .color.bg get setcolor
+ dialog.tmp .x get dialog.tmp .y get moveto
+ dialog.tmp .width get dialog.tmp .height get fillrect
+
+ dialog.tmp .title.bg get setcolor
+ dialog.tmp .x get 1 add dialog.tmp .y get 1 add moveto
+ dialog.tmp .width get 2 sub dialog.tmp .title.height get 1 sub fillrect
+
+ dialog.tmp .x get 10 add dialog.tmp .y get 3 add moveto
+ dialog.tmp .title.fg get setcolor
+ dialog.tmp .title get config.rtl { dialog.tmp .width get 20 sub 0 rmoveto } if show.rtl
+
+ dialog.tmp .color.fg get setcolor
+ dialog.tmp .x get dialog.tmp .y get moveto
+ dialog.tmp .text.x get dialog.tmp .text.y get rmoveto
+
+ config.talk { dialog.tmp .title get speak } if
+
+ /dialog.tmp.x currentpoint pop def
+
+ config.rtl { dialog.tmp .text.x get -2 mul dialog.tmp .width get add 0 rmoveto } if
+
+ dialog.tmp .text get config.talk { dup speak } if show.rtl
+
+ currentpoint exch pop dialog.tmp.x exch moveto
+
+ dialog.tmp .ed.text.list get dup {
+ /dialog.tmp.idx 0 def
+ {
+ % really '2 add'?
+ config.rtl { dialog.tmp .ed.width get 2 add 0 rmoveto } if show.rtl
+ currentpoint exch pop dialog.tmp.x exch moveto
+
+ dialog.tmp .ed.buffer.list get dialog.tmp.idx get
+
+ dup {
+
+ 3 7 rmoveto
+
+ /dialog.tmp.buf [
+ currentpoint
+ dialog.tmp .ed.width get fontheight 2 add savescreen
+ 0 0
+ .undef
+ ] def
+
+ dialog.tmp.buf 3 2 index put
+ dialog.tmp.buf 4 rot cvp length put
+
+ dialog.tmp .ed.list get dialog.tmp.idx dialog.tmp.buf put
+
+ currentcolor
+ currentpoint over 1 sub over 2 sub moveto
+ black white dialog.tmp .ed.width get 2 add fontheight 5 add drawborder
+ moveto -3 lineheight 20 add 7 sub rmoveto
+ setcolor
+
+ currentfont
+ % hide text in password fields
+ dialog.tmp.idx dialog.tmp .ed.pw_field get eq {
+ dialog.tmp .ed.font get pwmode setfont
+ } if
+ dialog.tmp.buf dup 3 get edit.init
+ setfont
+
+ dialog.tmp .ed.focus get dialog.tmp.idx ne {
+ dialog.tmp.buf edit.hidecursor
+ } {
+ config.talk { dialog.tmp .ed.text.list get dialog.tmp.idx get speak } if
+ } ifelse
+
+ } { pop } ifelse
+
+ /dialog.tmp.idx inc
+ } forall
+ } { pop } ifelse
+
+ dialog.tmp .buttons get .undef ne { dialog.tmp .buttons get length {
+ 0 1 dialog.tmp .buttons get length 1 sub {
+ dialog.tmp .buttons get exch get button.show
+ } for
+ } if } if
+
+ /dialog.tmp .undef def
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Do something without closing the window.
+%
+% ( action ) ==> ( true|false )
+%
+% Returns whether the window still exists.
+%
+/dialog.specialaction {
+ actNoClose not and
+
+ true exch
+
+ dup actEject eq {
+ bootdrive eject pop
+ } if
+
+ dup actPowerOff eq {
+ poweroff
+ } if
+
+ dup actReboot eq {
+ reboot
+ } if
+
+ dup actInstallOK eq {
+ install.ok
+ exch not exch
+ } if
+
+% dup actInstallCancel eq {
+% install.cancel
+% exch not exch
+% } if
+
+ pop
+} def
+
+
diff --git a/src/xmenu.inc b/src/xmenu.inc
new file mode 100644
index 0000000..1d1d2bd
--- /dev/null
+++ b/src/xmenu.inc
@@ -0,0 +1,414 @@
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+%
+% List dialog handling.
+%
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Some global vars.
+%
+/xmenu.vspace.default { xmenu .xm_list get length 15 ge { 2 } { 4 } ifelse } def
+/xmenu.hspace 12 def
+/xmenu.light white def
+/xmenu.dark black def
+/xmenu.font font.normal def
+
+% xmenu layout
+%
+% [ selected_entry string_list x y panel_x ]
+%
+/.xm_current 0 def % selected entry
+/.xm_list 1 def % string list
+/.xm_x 2 def % menu x pos
+/.xm_y 3 def % menu y pos
+/.xm_width 4 def % menu width
+/.xm_height 5 def % menu height
+/.xm_panel_x 6 def % panel entry x pos
+/.xm_vspace 7 def % vspace per menu
+/.xm_title 8 def % xmenu title
+/.xm_text 9 def % xmenu text
+/.xm_last 10 def % last selected entry
+/.xm_size 11 def % xmenu size
+
+
+% short hands
+/xmenu.x { xmenu .xm_x get } def
+/xmenu.y { xmenu .xm_y get } def
+/xmenu.width { xmenu .xm_width get } def
+/xmenu.height { xmenu .xm_height get } def
+
+/xmenu.vspace { xmenu .xm_vspace get dup .undef ne { } { pop xmenu.vspace.default } ifelse } def
+
+/xmenu.saved { xmenu.saved.areas xmenu.column get 2 get } def
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Create new xmenu.
+%
+% ( ) ==> ( window )
+%
+/window.xmenu {
+ widget.size array
+ dup .type t_xmenu put
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Handle keyboad input.
+%
+% ( key_in ) ==> ( key_out )
+%
+/xmenu.input {
+ dup 0 eq { return } if
+
+ dup keyEsc eq {
+ xmenu .xm_current over .xm_last get put
+ window.done
+ pop 0
+ } if
+
+ dup keyEnter eq {
+ window.current .xmenu.update get
+ window.done
+ exec
+ pop 0
+ } if
+
+ dup keyDown eq {
+ xmenu .xm_current get 1 add xmenu.select
+ pop 0
+ } if
+
+ dup keyUp eq {
+ xmenu .xm_current get 1 sub xmenu.select
+ pop 0
+ } if
+
+ dup keyPgDown eq {
+ xmenu .xm_current get 5 add
+ xmenu .xm_list get length 1 sub min xmenu.select
+ pop 0
+ } if
+
+ dup keyPgUp eq {
+ xmenu .xm_current get 5 sub
+ 0 max xmenu.select
+ pop 0
+ } if
+
+ dup keyHome eq {
+ 0 xmenu.select
+ pop 0
+ } if
+
+ dup keyEnd eq {
+ xmenu .xm_list get length 1 sub xmenu.select
+ pop 0
+ } if
+
+ dup config.rtl { keyLeft } { keyRight } ifelse eq {
+ xmenu .xm_current get
+ xmenu .xm_list get length over sub xmenu.maxlines lt v_impaired and {
+ pop
+ } {
+ dup xmenu.maxlines div 1 add xmenu.columns mod xmenu.maxlines mul
+ exch xmenu.maxlines mod add
+ xmenu .xm_list get length 1 sub min xmenu.select
+ } ifelse
+ pop 0
+ } if
+
+ dup config.rtl { keyRight } { keyLeft } ifelse eq {
+ xmenu .xm_current get
+ dup xmenu.maxlines lt v_impaired and {
+ pop
+ } {
+ dup xmenu.maxlines div xmenu.columns add 1 sub xmenu.columns mod xmenu.maxlines mul
+ exch xmenu.maxlines mod add
+ xmenu .xm_list get length 1 sub min xmenu.select
+ } ifelse
+ pop 0
+ } if
+
+ dup keyF1 eq {
+ show_help
+ pop 0
+ } if
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Calculate menu sizes.
+%
+% ( ) ==> ( )
+%
+/xmenu.sizes {
+ /xmenu.lheight xmenu.font setfont fontheight xmenu.vspace dup add add def
+
+ /xmenu.maxlines
+ panel.text.y 1 sub xmenu.lheight div
+ def
+
+ /xmenu.columns xmenu .xm_list get length xmenu.maxlines add 1 sub xmenu.maxlines div def
+
+ /xmenu.lastheight
+ xmenu .xm_list get length xmenu.maxlines xmenu.columns 1 sub mul sub xmenu.lheight mul
+ def
+
+ xmenu .xm_height
+ xmenu .xm_list get length xmenu.maxlines min xmenu.lheight mul
+ put
+
+ xmenu .xm_width
+ 0 xmenu .xm_list get { exec strsize pop max } forall xmenu.hspace 2 mul add
+ put
+
+ xmenu .xm_y panel.text.y 1 sub xmenu.height sub put
+
+ xmenu .xm_x xmenu .xm_panel_x get config.rtl { xmenu .xm_width get sub } if put
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Init and show menu.
+%
+% ( window ) ==> ( )
+%
+% xmenu: [ selected_entry [ text0 text1 ... ] x y ]
+%
+/xmenu.init {
+ /xmenu over .xmenu get def
+
+ xmenu.sizes
+
+ dup .saved.areas xmenu.columns array /xmenu.saved.areas over def put
+
+ 0 1 xmenu.columns 1 sub {
+ /xmenu.column exch def
+
+ dup .saved.areas get xmenu.column
+
+ [
+ xmenu.column xmenu.width 2 add mul config.rtl { neg } if xmenu.x add 1 sub xmenu.y 1 sub moveto
+ currentpoint
+
+ xmenu.light xmenu.dark
+ xmenu.width 2 add
+ xmenu.column 1 add xmenu.columns eq { xmenu.lastheight } { xmenu.height } ifelse 2 add
+ over over savescreen 5 1 roll
+ drawborder
+
+ ] put
+
+ } for
+
+ 0 1 xmenu .xm_list get length 1 sub { xmenu.viewentry } for
+
+ xmenu .xm_last over .xm_current get put
+
+ dup .x xmenu.x put
+ .y xmenu.y put
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Close menu.
+%
+% ( ) ==> ( )
+%
+/xmenu.done {
+ /xmenu.tmpbuf xmenu.tmpbuf free .undef def
+ /xmenu.saved.normal xmenu.saved.normal free .undef def
+ /xmenu.saved.selected xmenu.saved.selected free .undef def
+ /xmenu.saved.areas .undef def
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Draw xmenu.
+%
+% ( window ) ==> ( )
+%
+/xmenu.show {
+ window.push
+
+ config.talk {
+ xmenu .xm_title get dup .undef ne { exec speak } { pop } ifelse
+ xmenu .xm_list get xmenu .xm_current get get exec speak
+ } if
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Draw single entry.
+%
+% ( entry ) ==> ( )
+%
+/xmenu.viewentry {
+ xmenu.font setfont
+
+ dup xmenu.maxlines mod xmenu.lheight mul xmenu.y add /xmenu.pos.y exch def
+
+ dup xmenu.maxlines div /xmenu.column over def
+ xmenu.width 2 add mul config.rtl { neg } if xmenu.x add /xmenu.pos.x exch def
+
+ xmenu.pos.x xmenu.pos.y moveto
+
+ dup xmenu .xm_current get eq { xmenu.saved.selected } { xmenu.saved.normal } ifelse
+
+ dup {
+ transp { pop } { restorescreen } ifelse
+ } {
+ pop
+
+ dup xmenu .xm_current get eq { xmenu.selected.bg } { xmenu.normal.bg } ifelse
+ setcolor xmenu.width xmenu.lheight fillrect
+
+ dup xmenu .xm_current get eq {
+ xmenu.pos.x xmenu.pos.y moveto
+ xmenu.dark xmenu.light xmenu.width xmenu.lheight drawborder
+ } if
+
+ dup xmenu .xm_current get eq { /xmenu.saved.selected } { /xmenu.saved.normal } ifelse
+ xmenu.pos.x xmenu.pos.y moveto
+ xmenu.width xmenu.lheight
+ savescreen
+ def
+ } ifelse
+
+
+ transp {
+ % copy entry to avoid reading the screen again
+ dup xmenu .xm_current get eq { xmenu.saved.selected } { xmenu.saved.normal } ifelse
+ xmenu.tmpbuf .undef eq {
+ dup length malloc /xmenu.tmpbuf exch def
+ } if
+ xmenu.tmpbuf exch dup length memcpy
+
+ 0 xmenu.pos.y xmenu.y sub moveto 1 1 rmoveto
+ xmenu.saved transp xmenu.tmpbuf blend
+
+ xmenu.pos.x xmenu.pos.y moveto xmenu.tmpbuf restorescreen
+ } if
+
+ dup xmenu .xm_current get eq { xmenu.selected.fg } { xmenu.normal.fg } ifelse setcolor
+
+ config.rtl {
+ xmenu.pos.x xmenu.width add xmenu.hspace sub xmenu.pos.y xmenu.vspace add moveto
+ } {
+ xmenu.pos.x xmenu.hspace add xmenu.pos.y xmenu.vspace add moveto
+ } ifelse
+
+ xmenu .xm_list get over get exec
+ dup 0 get '\x09' eq {
+ 1 add
+ currentpoint
+ currentcolor
+
+ xmenu.dark setcolor
+ xmenu.pos.x xmenu.pos.y moveto
+ xmenu.pos.x xmenu.width add xmenu.pos.y lineto
+ xmenu.light setcolor
+ xmenu.pos.x xmenu.pos.y 1 add moveto
+ xmenu.pos.x xmenu.width add xmenu.pos.y 1 add lineto
+
+ setcolor
+ moveto
+ show.rtl
+ config.rtl {
+ xmenu.pos.x 8 add xmenu.pos.y moveto "\u25c0" show
+ } {
+ xmenu.pos.x xmenu.width add 8 sub xmenu.pos.y moveto "\u25b6" showright1
+ } ifelse
+ } {
+ show.rtl
+ } ifelse
+
+ pop
+
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Select menu entry.
+%
+% ( new_entry ) ==> ( )
+%
+/xmenu.select {
+ dup 0 lt { v_impaired { 1 } { xmenu .xm_list get length } ifelse add } if
+ dup xmenu .xm_list get length ge { v_impaired { 1 } { xmenu .xm_list get length } ifelse sub } if
+
+ xmenu .xm_current get over xmenu .xm_current rot put
+ xmenu.viewentry
+ xmenu.viewentry
+
+ config.talk {
+ xmenu .xm_list get xmenu .xm_current get get exec speak
+ } if
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Panel/xmenu helper function.
+%
+% ( ) => ( )
+%
+/pmenu.panel.update {
+ panel.text.moveto
+
+ xmenu .xm_panel_x currentpoint pop xmenu.hspace config.rtl { neg } if sub put
+
+ pmenu.update
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Panel/xmenu helper function.
+%
+% ( ) => ( width )
+%
+/pmenu.width {
+ 0
+
+ xmenu .xm_title get
+ dup .undef ne { exec strsize pop max } { pop } ifelse
+
+ xmenu .xm_list get xmenu .xm_current get get
+ dup .undef ne { exec strsize pop max } { pop } ifelse
+} def
+
+
+% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+% Panel/xmenu helper function.
+%
+% ( ) => ( )
+%
+/pmenu.update {
+ % note: we're always redrawing the whole panel
+
+ panel.title.fg setcolor
+ panel.font setfont
+
+ xmenu .xm_panel_x get xmenu.hspace config.rtl { neg } if add
+ panel.text.y
+ moveto
+
+ currentpoint
+
+ xmenu .xm_title get
+ dup .undef ne { exec show.rtl } { pop } ifelse
+
+ moveto 0 lineheight 4 add rmoveto
+
+ panel.normal.fg setcolor
+
+ xmenu .xm_list get xmenu .xm_current get get
+ dup .undef ne { exec show.rtl } { pop } ifelse
+
+} def
+
+