View Single Post
Old 04-11-2012, 11:42 AM   #66
kaminkatze
Member
kaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with otherskaminkatze plays well with others
 
Posts: 17
Karma: 2600
Join Date: Mar 2012
Device: Kindle 3
The CW/CH/LH variables are set according to the width and height of the png image.
Added support for some of the color/cursor movement escape sequences.
Changed the end of page behaviour to auto scrolling.

Spoiler:

Code:
#!/bin/sh
#=============================
# titty - tiny tty (v1.6)
# display tiny text on eink
# requirements: titty.png.
# usage:
#   titty
#     cat self
#   titty [x y] [--] -|STRING|-f FILE
#     displays "STDIN", "echo STRING" or "cat FILE"
#       [x y]  initialize cursor at x y
#       [--]   treat as string
#   titty -mx|-my
#     return maximal x y coordinates
#   titty -v
#     return version
# hint: This runs at TTY speed.
#------------------------------
# Copyright (C) 2012 geekmaster
# MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#------------------------------
# Revision History (last change first):
# =ver= =date===== =author===== =description============================
# 1.6   2012-04-11 kaminkatze   png dimensions, invert, escape sequences
# 1.5   2012-04-06 kaminkatze   fix IFS "end of line" and '\' bug
# 1.4   2012-04-05 geekmaster   fix "end of page" bug
# 1.3   2012-04-05 kaminkatze   scrolling and options
# 1.2   2012-04-04 kaminkatze   k3 support and per line hexdump
# 1.1   2012-04-01 geekmaster   first release

# WARNING: If you don't stop using titty, you will go blind! :D

#===========================
# initvar - init global vars
#---------------------------
initvar() {
  V=1.6 CM="$0.png"; eips -c -g "$CM" # version, char map image
  DN=/dev/null DF=/dev/fb0 # devices
  set $(eips -i|grep res:); FW=$2 FH=$4 # fb0 width, height
  set $(eips -i|grep line); FS=$4 # fb0 stride
  CW=$((0x$(hexdump -s 16 -n 4 -ve '/1 "%02x"' "$CM")/96*FS/FW))
  CH=$((0x$(hexdump -s 20 -n 4 -ve '/1 "%02x"' "$CM")))
  LH=$((CH+1)) # char width, height, line height
  LM=2 TM=$((LH*2)) # left, top margin px
  MX=$((FW*FS/FW-CW)) MY=$((FH-LH)) # max X, Y
  MC=$((FS/CW-CW)) MR=$(((MY-TM)/LH)) # max column, row
  CX=$LM CY=$TM # cursor coords
  DD="dd if=$DF of=$DF bs=1 count=$CW" # ddblit
  C= # escape sequence
  I=false # inverted flag
  NL=$(echo -ne '\n') JFS=$IFS # normal field separator
}

#==============
# usage: scroll
#--------------
scroll() {
  dd if=$DF of=$DF bs=1 count=$((FS*LH*MR)) \
    skip=$((FS*(LH+TM))) seek=$((FS*TM)) 2>$DN
  dd if=$DF of=$DF bs=1 count=$((FS*LH)) \
    skip=$((FS*CH)) seek=$(((MR*LH+TM)*FS)) 2>$DN
  CY=$((CY-LH)); eips ''
}

#==============
# usage: invert
#--------------
invert() {
  dd bs=1 count=$((FS*CH)) if=$DF 2>$DN \
  | tr "\x00\x0f\xf0\xff" "\xff\xf0\x0f\x00" \
  | dd bs=1 count=$((FS*CH)) of=$DF 2>$DN
  $I && I=false || I=true
}

#================
# usage: killline
#----------------
killline() {
  if [[ $CX -eq $LM ]]
  then dd if=$DF of=$DF bs=1 count=$((FS*LH)) \
         skip=$((FS*CH)) seek=$((CY*FS)) 2>$DN
  else for y in $(seq 0 $((LH-1))); do
         dd if=$DF of=$DF bs=1 count=$((FS-CX)) \
           skip=$((FS*CH)) seek=$(((CY+y)*FS+CX)) 2>$DN
       done
  fi
}

#================
# usage: escape s
#----------------
escape() {
  case "$1" in
    '\e[0m') $I && invert;;
    *'m') $I || invert;;
    *'f'|*'H') IFS='\e[;fH'; set $(echo "$1"); IFS=$JFS
               CX=$((LM+$4*CW)) CY=$((TM+$5*LH));;
    *'A') IFS='\e[A'; set $(echo "$1"); IFS=$JFS
          CY=$((CY-$4*LH)); [[ $CY -lt 0 ]] && CY=0;;
    *'B') IFS='\e[A'; set $(echo "$1"); IFS=$JFS
          CY=$((CY+$4*LH)); [[ $CY -gt $MY ]] && CY=$((MR*LH));;
    *'C') IFS='\e[;C'; set $(echo "$1"); IFS=$JFS
          CX=$((CX+$4*CW)); [[ $CX -gt $MX ]] && CX=$((MC*CW));;
    *'D') IFS='\e[;C'; set $(echo "$1"); IFS=$JFS
          CX=$((CX-$4*CW)); [[ $CX -lt 0 ]] && CX=0;;
    '\e[K') killline;;
    '\e[2J') eips -c -g "$CM"; CX=$LM CY=$TM;;
    *) return 1;;
  esac; return 0
}
        
#=================
# titty - tiny tty
# displays STDIN
#------------------
titty() {
  awk '{gsub(/\\/,"\\\\");print $0}' | while IFS=$NL; read L; do IFS=$JFS
    for A in $(echo -n "$L" | hexdump -ve '/1 "%d\n"'); do
      if [[ -n "$C" ]]; then
        C=$C$(echo -e $(printf '\x%x' $A))
        escape $C && C=; continue
      elif [[ $A -eq 27 ]]; then C='\e'; continue; fi
      while [[ $CY -gt $MY ]]; do scroll; done
      RO=$(((A-32)*CW)) FO=$((CY*FS+CX))
      for y in $(seq 1 $CH);do
        $DD skip=$RO seek=$FO 2>$DN; RO=$((RO+FS)) FO=$((FO+FS))
      done; CX=$((CX+CW)); [[ $((CX%64)) -eq $LM ]] && eips ''
      if [[ $CX -gt $MX ]]; then CX=$LM CY=$((CY+LH))
        [[ $CY -gt $MY ]] && CY=$TM CX=$LM; fi
    done; eips ''; CX=$LM CY=$((CY+LH))
  done
}

# Do stuff!  :-)
initvar
if [[ "$1" == "" ]]; then
  cat "$0" | titty
else while [[ "$1" ]]; do
  case "$1" in
    -mx) echo $MC; shift;;
    -my) echo $MR; shift;;
    -f) cat "$2" | titty; shift;shift;;
    -) titty; shift;;
    --) echo "$2" | titty; shift;shift;;
    -v) echo $V; shift;;
    *) if [[ -n "$3" ]]
       then CX=$((LM+$1*CW)) CY=$((TM+$2*LH)); shift;shift
       else echo "$1" | titty; shift
       fi;;
  esac
done; fi


Tinysh mod which uses the escape sequences to control titty.

Spoiler:

Code:
#!/bin/sh
#===================================================
# tinysh - tiny limited onscreen shell (v1.0) for K3
#---------------------------------------------------
# Copyright (C) 2012 geekmaster
# MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#===========================
# initvar - init global vars
#---------------------------
initvar() {
  SYM=126 ENT=28 SHFT=42 SPC=57 DEL=14
  LEFT=105 RIGHT=106 UP=103 DOWN=108
  KN="1234567890____qwertyuiop____asdfghjkl_____zxcvbnm_."
  KS="1234567890____QWERTYUIOP____ASDFGHJKL_____ZXCVBNM_,"
  KP='1234567890____~@#$%^&*()____<>[]{}?/\_____;:"|-+=_?'
  KM=$KN
  CMD= # cmd line
  killall -stop cvm launchpad 2>/dev/null
}

#========
# cleanup
#--------
trap "cleanup" SIGTERM SIGINT
cleanup() {
  killall -cont cvm launchpad 2>/dev/null
}

#=============================================
# shcmd - emit shell command, preceeded by pwd
#---------------------------------------------
shcmd() {
  case "$CMD" in
    exit) cleanup; exit;;
    clear) echo 'echo -e "\033[2J"';;
    keymap) echo "echo -e '$KN\n$KS\n$KP'";;
    *) echo "$CMD";;
  esac
  echo 'echo -e "$PWD \$"'
  LCMD=$CMD
  CMD=
}

#===================================================
# getkb - get translated ascii keys from K3 keyboard
#---------------------------------------------------
getkb() {
  CMD=keymap
  shcmd
  while :; do
    set $(waitforkey); K=$1 D=$2
    if [[ $D -eq 0 ]]; then # up
      case $K in
        $SHFT) KM=$KN;;
        $SYM) KM=$KN;;
     esac; continue
    else A= # down
      case $K in
        $ENT) shcmd && continue;;
        $SHFT) KM=$KS && continue;;
        $SYM) KM=$KP && continue;;
        $DEL) if [[ ${#CMD} -gt 1 ]]
              then CMD=$(echo "$CMD" | cut -b-$((${#CMD}-1)))
              else CMD=
              fi;;
        $SPC) A=' ';;
        $UP) CMD=$LCMD;;
        $DOWN) CMD=;;
        *) [[ $K -le 52 ]] && A="$(echo \"$KM\"|cut -b$K)";;
      esac
    fi
    CMD="$CMD$A"
    echo "printf \"\033[1A\033[\$((\${#PWD}+3))C\033[1m%s\033[0m \n\" '$CMD'"
  done
}

PATH=$PATH:$(dirname $0)
initvar # init global vars
getkb | sh 2>&1 | titty -
cleanup

Last edited by kaminkatze; 04-11-2012 at 11:44 AM.
kaminkatze is offline   Reply With Quote