Patch title: Release 89 bulk changes
Abstract:
File: /linux/input/keyboard.pli
Key:
    Removed line
    Added line
   
module "/pliant/language/unsafe.pli"
module "/pliant/language/stream.pli"
module "/pliant/language/os.pli"
module "mapping.pli"
module "/pliant/fullpliant/this_computer.pli"
module "/pliant/linux/kernel/device.pli"

constant use_device true


constant os_KDSKBMODE 4B45h
constant os_K_RAW 0
constant os_K_XLAT 1

type os_TermIOs
  field uInt c_iflag c_oflag c_cflag c_lflag
  field uInt8 c_line
  field (Array uInt8 32) c_cc
  field uInt c_ispeed c_ospeed
  field (Array Byte 16) pliant_padding

constant os_TCGETS 5401h
constant os_TCSETS 5402h
constant os_ISIG 1
constant os_ICANON 2
constant os_ECHO 8
constant os_IXOFF 8^4


if use_device
  gvar Stream kbd
else
  gvar CBool first := true
gvar Str layout
gvar Str switch
gvar Str modifier
gvar Str last
gvar List:Str events

layout := this_computer:env:"hardware":"keyboard":"layout"

function keyboard_set_layout l
  arg Str l
  this_computer "hardware" "keyboard" "layout" := l
  layout := l


function keyboard_read -> c
  arg Str c
  if not (exists events:first)
    if use_device
      if kbd=failure
        var Str device := this_computer:env:"hardware":"keyboard":"device"
        if device=""
          device := "device:/tty0"
        kernel_make_device device
        kbd open device in+safe
        if kbd=success
          os_ioctl kbd:stream_handle os_TCGETS addressof:(var os_TermIOs ios)
          ios c_iflag := 0 # ios:c_iflag .and. .not. os_IXOFF
          ios c_lflag := 0 # ios:c_lflag .and. .not. os_ISIG .and. .not. os_ICANON .and. .not. os_ECHO
          os_ioctl kbd:stream_handle os_TCSETS addressof:ios
          os_ioctl kbd:stream_handle os_KDSKBMODE (cast os_K_RAW Address)
    else
      if first
        os_ioctl 0 os_TCGETS addressof:(var os_TermIOs ios)
        ios c_iflag := 0 # ios:c_iflag .and. .not. os_IXOFF
        ios c_lflag := 0 # ios:c_lflag .and. .not. os_ISIG .and. .not. os_ICANON .and. .not. os_ECHO
        os_ioctl 0 os_TCSETS addressof:ios
        os_ioctl 0 os_KDSKBMODE (cast os_K_RAW Address)
        first := false
    var Str extended := ""
    if use_device
      kbd raw_read addressof:(var uInt8 ch) 1
      if ch=224
        extended := "b" ; kbd raw_read addressof:(var uInt8 ch) 1
    else
      os_read 0 addressof:(var uInt8 ch) 1
      if ch=224
        extended := "b" ; os_read 0 addressof:(var uInt8 ch) 1
    var CBool pressed := (ch .and. 80h)=0
    var Str key := string:(cast (ch .and. 7Fh) Int)+extended
    events += (shunt pressed "press " "release ")+"key"+key
    var Data:KeyboardLayout l :> keyboard_database:data:layout layout
    if { var Data:Str k :> l:key key ; exists k }
      events += (shunt pressed "press " "release ")+k
    if { var Data:Str m :> l:modifier key ; m<>"" }
      if (shunt pressed 1 0)=(shunt (switch search m -1)=(-1) 1 0)
        if (modifier search m -1)=(-1)
          modifier += m+" "
      else
        modifier := replace modifier m+" " ""
    eif pressed and { var Data:Str s :> l:switch key ; s<>"" } and key<>last
      if (switch search s -1)=(-1)
        switch += s+" "
      else
        switch := replace switch s+" " ""
      modifier := switch
    eif pressed
      if { var Data:Str k :> l:key modifier+key ; exists k }
        events += k
      eif { var Data:Str k :> l:key key ; exists k }
        events += modifier+k
    last := shunt pressed key ""
  if (exists events:first)
    c := events first
    events remove events:first
  else
    c := ""

export keyboard_set_layout keyboard_read