diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 16 | ||||
-rw-r--r-- | src/bsplash.inc | 291 | ||||
-rw-r--r-- | src/button.inc | 116 | ||||
-rw-r--r-- | src/common.inc | 1682 | ||||
-rw-r--r-- | src/dia_about.inc | 75 | ||||
-rw-r--r-- | src/dia_bits.inc | 101 | ||||
-rw-r--r-- | src/dia_dud.inc | 165 | ||||
-rw-r--r-- | src/dia_help.inc | 46 | ||||
-rw-r--r-- | src/dia_install.inc | 344 | ||||
-rw-r--r-- | src/dia_kernelopts.inc | 94 | ||||
-rw-r--r-- | src/dia_keymap.inc | 105 | ||||
-rw-r--r-- | src/dia_lang.inc | 309 | ||||
-rw-r--r-- | src/dia_profile.inc | 137 | ||||
-rw-r--r-- | src/dia_video.inc | 263 | ||||
-rw-r--r-- | src/help.inc | 684 | ||||
-rw-r--r-- | src/keytables.inc | 62 | ||||
-rw-r--r-- | src/locale.inc | 267 | ||||
-rw-r--r-- | src/main.bc | 30 | ||||
-rw-r--r-- | src/menu.inc | 488 | ||||
-rw-r--r-- | src/panel.inc | 201 | ||||
-rw-r--r-- | src/penguin.inc | 351 | ||||
-rw-r--r-- | src/serial.inc | 517 | ||||
-rw-r--r-- | src/speech.inc | 121 | ||||
-rw-r--r-- | src/system.inc | 1406 | ||||
-rw-r--r-- | src/timeout.inc | 149 | ||||
-rw-r--r-- | src/window.inc | 711 | ||||
-rw-r--r-- | src/xmenu.inc | 414 |
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 + + |