1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
|
% example_06.bc
%
% Draws simple menu and lets you select an entry and an boot option edit line.
%
% To use this example to boot from a real CD-ROM, do:
%
% # make -C themes/example_06
% # mkdir /tmp/foo
% # gfxboot -a themes/example_06/bootlogo --expand-archive /tmp/foo
% # cp /tmp/foo/* to_the_dir_on_your_ISO_where_isolinux.bin_is
%
% and add a line 'ui gfxboot bootlogo' to isolinux.cfg.
%
% To use this example with grub, do:
% # make -C themes/example_06
% # cp themes/example_06/message /boot/message
%
% and add a line like 'gfxmenu (hdX,Y)/boot/message' to menu.lst (replace
% X and Y with real values).
%
% Notes:
% - use 'Timeout' callback to display timeout countdown
%
% - boot when the timeout is up
%
% - pass kernel args correctly to grub
%
% Test with (from top level dir [/usr/share/gfxboot]) with
% 'gfxtest -t example_06' (isolinux) or
% 'gfxtest -t example_06 grub' (grub).
%
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% Some constants we probably need.
%
/true 0 0 eq def
/false 0 0 ne def
% some key codes
/keyEsc 0x0000001b def
/keyEnter 0x0000000d def
/keyUp 0x48000000 def
/keyLeft 0x4b000000 def
/keyRight 0x4d000000 def
/keyDown 0x50000000 def
% type values
/t_none 0 def
/t_string 4 def
/t_end 11 def
/t_ptr 12 def
% undefined (nil) value
/.undef 0 t_none settype def
% end token, stops execution
/.end 0 t_end settype def
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% Convert integer to pointer.
%
% ( int1 -- ptr1 )
%
/cvp { t_ptr settype } def
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% Convert object to string.
%
% ( obj ) ==> ( string )
%
/cvs { t_string settype } def
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% Allocate new string.
%
% ( size -- string )
%
/string {
1 add malloc cvs
} def
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% Arguments like snprintf.
%
% ( obj_1 ... obj_n string_1 string_2 -- )
%
/sprintf {
dup cvp length exch snprintf
} def
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% bootloader - boot loader type
%
% ( -- 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
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% findmode - find video mode number
%
% ( 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
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% 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 (that is, continue with the non-gfxboot
% bootloader interface)
% >=2: boot
%
% Notes:
% - key = 0 indicates the bootloader timeout is up.
% - input_buffer is the command line that you would have normally entered in the bootloader.
% note that for syslinux it must start with the menu label string but not for grub
% - menu_entry is the number of the menu entry you want to boot
%
/KeyEvent {
% pre-process keycode a bit
dup 0xff00 and 16 shl exch 0xff and dup 0xe0 eq { pop 0 } if add
dup 0xff and { 0xff and } if
/key exch def
% 'key' now holds the ASCII code for 'normal' keys and the scan code in
% the upper 8 bits if there is no ASCII code (e.g. F-keys, cursor keys)
% process key events...
key keyDown eq {
menu.entry menu.texts length 1 sub lt {
menu.entry menu.deselect
/menu.entry menu.entry 1 add def
menu.entry menu.select
} if
} if
key keyUp eq {
menu.entry 0 gt {
menu.entry menu.deselect
/menu.entry menu.entry 1 sub def
menu.entry menu.select
} if
} if
% enter or timeout
key keyEnter eq key 0 eq or {
% construct command line: [label] + append_args + user_args
grub {
% grub expects just '<args>'
cmdline
menu.args menu.entry get
"%s %s" cmdtmp sprintf
} {
% syslinux expects '<label> <args>'
cmdline
menu.args menu.entry get
menu.texts menu.entry get
"%s %s %s" cmdtmp sprintf
} ifelse
cmdtmp menu.entry 2 return
} if
% maybe it's a printable char...
% remember to set the correct color (and font if necessary)
input_color setcolor
edit_obj key edit.input
"" 0 0
} def
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% Setup boot menu.
%
% ( menu_entries_array cmdline_args_array defaultentry -- )
%
% This function is called before the first key event and gets passed the
% bootloader config data.
%
/MenuInit {
% this is a string
/menu.default_entry exch def
% both are arrays
/menu.args exch def
/menu.texts exch def
% find index of the default entry
/menu.entry 0 def
0 1 menu.texts length 1 sub {
menu.texts over get
menu.default_entry eq { /menu.entry exch def exit } if
pop
} for
% menu position
/menu.x 300 def
/menu.y 100 def
% 1.5 * font size
/menu.dy fontheight dup 2 div add def
menu_color setcolor
% draw menu
menu.x menu.y moveto
menu.texts {
% add black shadow
shadow_show
currentpoint exch pop menu.dy add menu.x exch moveto
} forall
% mark default entry
menu.entry menu.select
% draw boot option field
label_color setcolor
10 500 moveto "Boot:" shadow_show
input_color setcolor
% intialize edit object; you can set the edit buffer to some initial value
edit_obj "vga=0x317" edit.init
} def
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% Like 'show', but with black shadow.
%
% ( string -- )
%
/shadow_show {
currentcolor currentpoint
1 1 rmoveto
0 setcolor
3 index show
moveto setcolor
show
} def
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% Show selected item.
%
% ( index -- )
%
/menu.select {
menu.dy mul menu.y add
menu.x exch moveto
">" dup strsize pop neg 10 sub 0 rmoveto
arrow_color setcolor
show
} def
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% Show deselected item.
%
% ( index -- )
%
/menu.deselect {
menu.dy mul menu.y add
menu.x exch moveto
">" dup strsize pop neg 10 sub 0 rmoveto
currentpoint rot strsize image
} def
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% Boot timeout counter.
%
% ( timeout time -- )
%
% timeout: total time in 18.2Hz steps, time: current value.
%
% Note: if the user hits a key to stop the timeout this function is called
% with time = 0.
%
/Timeout {
/timeout.s.last timeout.s def
/timeout.s exch 10 mul 150 add 182 div def
pop % we don't need it
timeout.s timeout.s.last ne {
% clear old value
720 20 moveto currentpoint fontheight 5 mul fontheight image
timeout.s 0 ne {
timeout.s "%us" time_str sprintf
timeout_color setcolor
time_str shadow_show
} if
} if
} def
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% set 800x600 graphics mode
% try 32 bit first; if no mode can be found, exit and continue without gfxboot
%
800 600 32 findmode setmode not {
800 600 16 findmode setmode not {
false .end
} if
} if
% load and set font
"font.fnt" findfile setfont
% load and set background image
"clouds.jpg" findfile setimage
0 0 moveto
0 0 image.size image
% input command line
/cmdline 1024 string def
% used in KeyEvent
/cmdtmp 1024 string def
% to display timeout
/time_str 10 string def
% our input line
/edit_obj [
110 % x
500 % y
moveto currentpoint 600 fontheight savescreen % background image, defines input field size
cmdline % input buffer
dup cvp length 1 sub % buffer size
.undef % for internal use
] def
% our colors
/input_color 0x000000 def
/menu_color 0xe0e000 def
/arrow_color 0xffffff def
/label_color 0x00a000 def
/timeout_color 0xf0f0f0 def
% say we're fine ('false' tells bootloader not to use gfxboot)
true
|