Patch title: Release 95 bulk changes
Abstract:
File: /pliant/graphic/console/framebuffer_configure.pli
Key:
    Removed line
    Added line
module "/pliant/fullpliant/this_computer.pli"
module "/pliant/language/os.pli"
module "/pliant/linux/kernel/module.pli"
module "/pliant/linux/kernel/device.pli"
module "/pliant/graphic/console/framebuffer_common.pli"
module "/pliant/admin/execute.pli"
module "/pliant/language/ui/ansi_terminal.pli"

module "/pliant/language/stream.pli"
module "/pliant/language/os.pli"


gvar CBool info_from_scratch := false
gvar CBool force_mode_switch := false


function log msg
  arg Str msg
  if false
    (var Stream s) open "file:/log/framebuffer.log" append+safe
    s writechars msg
    s close
    os_sync


type FramebufferMode
  field Int size_x size_y bpp


function framebuffer_configure drivers modes -> driver_and_mode
  arg Array:Str drivers ; arg Array:FramebufferMode modes ; arg Str driver_and_mode
function framebuffer_configure drivers modes record -> driver_and_mode
  arg Array:Str drivers ; arg Array:FramebufferMode modes ; arg CBool record ; arg Str driver_and_mode
  for (var Int i) 0 drivers:size-1
    console "Trying " drivers:i " video driver" (repeat 30 " ") "[cr]"
    log "driver "+drivers:i+" "
    kernel_load_module drivers:i
    var Int fb := os_open "/dev/fb0" os_O_RDWR 0
    log (shunt fb>=0 "ok" "failed")+"[lf]"
    if fb>=0
      var Int err := os_ioctl fb FBIOGET_VSCREENINF0 addressof:(var fb_var_screeninfo info)
      if err=0
        for (var Int j) 0 modes:size-1
          console "Trying " (cast info:xres Int) "x" (cast info:yres Int) "x" (cast info:bits_per_pixel Int) " -> " modes:j:size_x "x" modes:j:size_y "x" modes:j:bpp " on " drivers:i (repeat 10 " ") "[cr]"
          var fb_var_screeninfo info2
          if info_from_scratch
            memory_clear addressof:info2 fb_var_screeninfo:size
          else
            info2 := info
          info2 xres := modes:j size_x
          info2 yres := modes:j size_y
          info2 xres_virtual := modes:j size_x
          info2 yres_virtual := modes:j size_y
          info2 bits_per_pixel := modes:j bpp
          info2 pixclock := 0
          info2 xoffset := 0
          info2 yoffset := 0
          if force_mode_switch
            info2 active := FB_ACTIVATE_NOW+FB_ACTIVATE_FORCE
          log "  mode "+(string modes:j:size_x)+"x"+(string modes:j:size_y)+"x"+(string modes:j:bpp)+" "
          if info:xres=modes:j:size_x and info:yres=modes:j:size_y and info:bits_per_pixel=modes:j:bpp and not force_mode_switch or (os_ioctl fb FBIOPUT_VSCREENINF0 addressof:info2)=0
            if (os_ioctl fb FBIOGET_VSCREENINF0 addressof:info)=0
              if info:xres=modes:j:size_x and info:yres=modes:j:size_y and info:bits_per_pixel=modes:j:bpp
                log "ok[lf]"
                console "Selected video mode is " modes:j:size_x "x" modes:j:size_y "x" modes:j:bpp " on " drivers:i (repeat 10 " ") eol
                os_close fb
                if record
                  this_computer "hardware" "video" "driver" := drivers i
                  this_computer "hardware" "screen" "horizontal_resolution" := string modes:j:size_x
                  this_computer "hardware" "screen" "vertical_resolution" := string modes:j:size_y
                  this_computer "hardware" "video" "bpp" := string modes:j:bpp
                return drivers:i+" "+(string modes:j:size_x)+"x"+(string modes:j:size_y)+"x"+(string modes:j:bpp)
          log "failed[lf]"
      os_close fb
    kernel_unload_module drivers:i
    console (repeat 40 " ") "[cr]"
  driver_and_mode := ""


function framebuffer_switch dm record
  arg Str dm ; arg CBool record
  if (dm parse word:"vesafb_tng" any)
    if kernel_load_module:"intelfb"=success
      log "switch from vesafb_tng to intelfb[lf]"
      kernel_unload_module "intelfb"
      kernel_unload_module "vesafb_tng"
      kernel_load_module "intel_agp"
      kernel_load_module "intelfb"
      log "switch done[lf]"
      if record
        this_computer "hardware" "video" "driver" := "vesafb_tng+intelfb"


function framebuffer_configure -> dm
  arg Str dm
  log "configuration begin at "+string:datetime+"[lf]"
  var Array:Str drivers
  var Str all := this_computer:env:"hardware":"video":"drivers"
  if all=""
    all := "nvidiafb rivafb radeonfb aty128fb atyfb savagefb i810fb intelfb vesafb_tng"
  while all<>""
    if not (all parse any:(var Str d) _ any:(var Str remain))
      d := all ; remain := ""
    drivers += d
    all := remain
  var Array:FramebufferMode modes
  var Str all := this_computer:env:"hardware":"video":"modes"
  if all=""
    all := "3840x2400x32 3840x2400x24 3200x2400x32 3200x2400x24 2048x1536x32 2048x1536x24 1920x1200x32 1920x1200x24 1600x1200x32 1600x1200x24 1400x1050x32 1400x1050x24 1280x1024x32 1280x1024x24 1024x768x32 1024x768x24"
  while (all parse (var FramebufferMode m):size_x "x" m:size_y "x" m:bpp any:(var Str remain))
    modes += m
    all := remain
  console character:27+"c"
  console "FullPliant will now try to auto configure your graphic card." eol
  console "On some hardware, it may end with too slow refresh frequency, unstable image" eol
  console "wrong resolution, just fail, freeze the system, or even worse." eol
  console "If you have such hardware, press the space bar now, and you will be prompted" eol
  console "Depending on your hardware, you may end up with either a slow refresh frequency, " eol
  console "an incorrect resolution,  a failed configuration, a frozen  system, or even worse." eol
  console "If you think you have such hardware, press the space bar now,  and you will be prompted" eol
  console "to manually select the configuration you want." eol
  console eol
  console "As a faster alternative, some keys (be warned that current keyboard mapping" eol
  console "is QWERTY) allow you to just restrict autoconfiguration:" eol
  console "'u' VESA driver, low resolution (1024x768)" eol
  console "'v' VESA driver, auto configure resolution" eol
  console "'l' auto select driver, low resolution (1024x768)" eol
  console "'m' auto select driver, medium resolution (1280x1024)" eol
  console "'h' auto select driver, high resolution (1600x1200)" eol
  console "Another alternative, is to restrict the autoconfiguration by selecting one of the options" eol
  console "below (be warned that current keyboard mapping is QWERTY):" eol
  console "Press 'a' for automatic configuration: just ignore configuration selected on last boot" eol
  console "      'u' for VESA driver, low resolution (1024x768)" eol
  console "      'v' for VESA driver, auto configure resolution" eol
  console "      'l' to auto-select your driver, low resolution (1024x768)" eol
  console "      'm' to auto-select your driver, medium resolution (1280x1024)" eol
  console "      'h' to auto select your driver, high resolution (1600x1200)" eol
  console eol
  console "When the graphic mode is set, the screen may remain black a fiew minutes." eol
  console "It does not mean that the computer freezed; it's just compiling Pliant" eol
  console "When the graphic mode is set, the screen may remain black a few minutes." eol
  console "It does not mean the computer is frozen; it's just compiling Pliant" eol
  console "applications. Please be patient." eol
  console eol
  var CBool console := true
  var CBool registers := true
  part read_kbd
    var Int c := keyboard_raw_readchar 15
    var Int c := keyboard_raw_readchar 60
    if c="s":number
      log "info from scratch[lf]"
      console "[cr]info from scratch" eol
      info_from_scratch := true
      restart read_kbd
    eif c="f":number
      log "force mode switch[lf]"
      console "[cr]force mode switch" eol
      force_mode_switch := true
      restart read_kbd
    eif c="c":number
      log "no console[lf]"
      console "[cr]no console" eol
      console := false
      restart read_kbd
    eif c="r":number
      log "no registers dump[lf]"
      console "[cr]no registers dump" eol
      registers := false
      restart read_kbd
  if c=" ":number
    console "[cr]Manual configuration." eol
    part choose
      console "Please first select the video driver you want to use." eol
      console "Use space bar to change travel the drivers list, then press enter key." eol
      var Int i := 0
      while { console drivers:i (repeat 30 " ") "[cr]" ; var Int c := keyboard_readchar ; c<>keyboard_enter }
        if c=" ":number
          i := (i+1)%drivers:size
      console "[lf]"
      console "Please now select the video mode you want to use." eol
      var Int j := 0
      while { console modes:j:size_x "x" modes:j:size_y "x" modes:j:bpp (repeat 30 " ") "[cr]" ; var Int c := keyboard_readchar ; c<>keyboard_enter }
        if c=" ":number
          j := (j+1)%modes:size
      console character:27+"c"
      (var Array:Str driver1) size := 1 ; driver1 0 := drivers i
      (var Array:FramebufferMode mode1) size := 1 ; mode1 0 := modes j
      dm := framebuffer_configure driver1 mode1
      dm := framebuffer_configure driver1 mode1 true
      if dm=""
        console "You selected video mode " modes:j:size_x "x" modes:j:size_y "x" modes:j:bpp " on " drivers:i eol
        console "Sorry, it does not work." eol eol
        restart choose    
  eif c="u":number
    console "[cr]VESA driver, low resolution (1024x768)" eol ; sleep 1
    (var Array:Str driver1) size := 1 ; driver1 0 := "vesafb_tng"
    (var Array:FramebufferMode mode1) size := 2
    mode1:0 size_x := 1024 ; mode1:0 size_y := 768 ; mode1:0 bpp := 32
    mode1:1 size_x := 1024 ; mode1:1 size_y := 768 ; mode1:1 bpp := 24
    dm := framebuffer_configure driver1 mode1
    dm := framebuffer_configure driver1 mode1 true
  eif c="v":number
    console "[cr]VESA driver, auto configure resolution" eol ; sleep 1
    (var Array:Str driver1) size := 1 ; driver1 0 := "vesafb_tng"
    dm := framebuffer_configure driver1 modes
    dm := framebuffer_configure driver1 modes true
  eif c="l":number
    console "[cr]auto select driver, low resolution (1024x768)" eol ; sleep 1
    (var Array:FramebufferMode mode1) size := 2
    mode1:0 size_x := 1024 ; mode1:0 size_y := 768 ; mode1:0 bpp := 32
    mode1:1 size_x := 1024 ; mode1:1 size_y := 768 ; mode1:1 bpp := 24
    dm := framebuffer_configure drivers mode1
    dm := framebuffer_configure drivers mode1 true
    framebuffer_switch dm true
  eif c="m":number
    console "[cr]auto select driver, medium resolution (1280x1024)" eol ; sleep 1
    (var Array:FramebufferMode mode1) size := 2
    mode1:0 size_x := 1280 ; mode1:0 size_y := 1024 ; mode1:0 bpp := 32
    mode1:1 size_x := 1280 ; mode1:1 size_y := 1024 ; mode1:1 bpp := 24
    dm := framebuffer_configure drivers mode1
    dm := framebuffer_configure drivers mode1 true
    framebuffer_switch dm true
  eif c="h":number
    console "[cr]auto select driver, high resolution (1600x1200)" eol ; sleep 1
    (var Array:FramebufferMode mode1) size := 2
    mode1:0 size_x := 1600 ; mode1:0 size_y := 1200 ; mode1:0 bpp := 32
    mode1:1 size_x := 1600 ; mode1:1 size_y := 1200 ; mode1:1 bpp := 24
    dm := framebuffer_configure drivers mode1
  eif c="w":number
    console "[cr]Load VESA first, then try to switch driver" eol ; sleep 1
    log "w vesa first begin[lf]"
    (var Array:Str driver1) size := 1 ; driver1 0 := "vesafb_tng"
    dm := framebuffer_configure driver1 modes
    log "w vesa first unload[lf]"
    kernel_unload_module "vesafb_tng"
    kernel_unload_module "vesafb_thread"
    log "w intel agp load[lf]"
    kernel_load_module "intel_agp"
    log "w driver scan begin[lf]"
    part load_driver
      for (var Int i) 0 drivers:size-1
        log "  w try "+drivers:i+"[lf]"
        kernel_load_module drivers:i
        var Int fb := os_open "/dev/fb0" os_O_RDWR 0
        if fb>=0
          os_close fb
          leave load_driver
        kernel_unload_module drivers:i
      log "w no driver found[lf]"
    log "w driver scan end[lf]"
    log "w intel agp unload[lf]"
    kernel_unload_module "intel_agp"
    log "w done[lf]"
  eif c="x":number
    console "[cr]Load VESA first, then try to switch driver and resolution" eol ; sleep 1
    log "x vesa first begin[lf]"
    (var Array:Str driver1) size := 1 ; driver1 0 := "vesafb_tng"
    framebuffer_configure driver1 modes
    log "x vesa first unload[lf]"
    kernel_unload_module "vesafb_tng"
    kernel_unload_module "vesafb_thread"
    log "x intel agp load[lf]"
    kernel_load_module "intel_agp"
    log "x driver scan begin[lf]"
    dm := framebuffer_configure drivers modes
    log "x driver scan end[lf]"
    log "x intel agp unload[lf]"
    kernel_unload_module "intel_agp"
    log "x done[lf]"
    dm := framebuffer_configure drivers mode1 true
    framebuffer_switch dm true
  else
    console "[cr]Fully automatic configuration" eol ; sleep 1
    dm := framebuffer_configure drivers modes
    if (dm parse word:"vesafb_tng" any)
      if kernel_load_module:"intelfb"=success
        log "switch from vesafb_tng to intelfb[lf]"
        kernel_unload_module "intelfb"
        kernel_unload_module "vesafb_tng"
        kernel_load_module "intel_agp"
        kernel_load_module "intelfb"
        log "switch done[lf]"
    part auto_configure
      if c<>"a":number
        if { var Str driver := this_computer:env:"hardware":"video":"driver" ; driver<>"" }
          if (this_computer:env:"hardware":"screen":"horizontal_resolution" parse (var Int size_x))
            if (this_computer:env:"hardware":"screen":"vertical_resolution" parse (var Int size_y))
              if (this_computer:env:"hardware":"video":"bpp" parse (var Int bpp))
                console "[cr]Recall existing configuration" eol ; sleep 1
                if not (driver parse any:(var Str first_driver) "+" any:(var Str second_driver))
                  first_driver := driver ; second_driver := ""
                (var Array:Str driver1) size := 1 ; driver1 0 := first_driver
                (var Array:FramebufferMode mode1) size := 1
                mode1:0 size_x := size_x ; mode1:0 size_y := size_y ; mode1:0 bpp := bpp
                dm := framebuffer_configure driver1 mode1 false
                if dm<>""
                  if second_driver<>""
                    framebuffer_switch dm false
                  leave auto_configure
      console "[cr]Fully automatic configuration" eol ; sleep 1
      dm := framebuffer_configure drivers modes true
      framebuffer_switch dm true
  if dm<>""
    if console
      kernel_load_module "fbcon"
  else
    console character:27+"c"
    console "Could not find any working configuration for your graphic card." eol
    console "The Pliant browser will not be usable. Sorry about that." eol
    console eol
  log "configuration end at "+string:datetime+" "+dm+"[lf]"

export framebuffer_configure