#!/bin/sh # console/shell dumb virtual keyboard v0.3 # (c) Denis Kaganovich # # pointer resolution = screen res # tell me about incompatible touchscreens or fix self LINE="" # To adaptive font resolution add into drivers/video/console/fbcon.c fbcon_startup: # printk(KERN_INFO "fbcon: font res: %dx%d\n", vc->vc_font.width, vc->vc_font.height); FONTRES=`dmesg|grep "fbcon: font res:"|sed -e 's%^.*font res: %%'` : ${FONTRES:=8x16} #kmapfile="us.map" resX=${FONTRES%x*} resY=${FONTRES#*x} # relative/mouse accelerate let relAccX=resX/2 let relAccY=resY/2 WIDTH=14 HEIGHT=4 KMAP='" 1b:00: 31:00: 32:00: 33:00: 34:00: 35:00: 36:00: 37:00: 38:00: 39:00: 30:00: 2d:00: 3d:00: 7f:00: 09:00: 71:0b: 77:0b: 65:0b: 72:0b: 74:0b: 79:0b: 75:0b: 69:0b: 6f:0b: 70:0b: 5b:00: 5d:00: 01:02: 02:07: 61:0b: 73:0b: 64:0b: 66:0b: 67:0b: 68:0b: 6a:0b: 6b:0b: 6c:0b: 3b:00: 27:00: 60:00: 5c:00: 7a:0b: 78:0b: 63:0b: 76:0b: 62:0b: 6e:0b: 6d:0b: 2c:00: 2e:00: 2f:00: 00:07: 03:07: 20:00: 07:02:" " 1b:00: 21:00: 40:00: 23:00: 24:00: 25:00: 5e:00: 26:00: 2a:00: 28:00: 29:00: 5f:00: 2b:00: 7f:00: 09:00: 51:0b: 57:0b: 45:0b: 52:0b: 54:0b: 59:0b: 55:0b: 49:0b: 4f:0b: 50:0b: 7b:00: 7d:00: 01:02: 02:07: 41:0b: 53:0b: 44:0b: 46:0b: 47:0b: 48:0b: 4a:0b: 4b:0b: 4c:0b: 3a:00: 22:00: 7e:00: 7c:00: 5a:0b: 58:0b: 43:0b: 56:0b: 42:0b: 4e:0b: 4d:0b: 3c:00: 3e:00: 3f:00: 00:07: 03:07: 20:00: 07:02:"' let X0=0 let X1=resX*WIDTH-1 let Y0=0 let Y1=resY*HEIGHT-1 let sX=X1-X0 let sY=Y1-Y0 X=0 Y=0 XX=1 YY=1 Z=1 T=0 TT=0 # detect byteorder case "`echo -ne "\x01\x02" |hexdump -e '"" 1/2 "%04x" ""'`" in 0102)b2w(){ let RES=$1*256+$2;};; 0201)b2w(){ let RES=$2*256+$1;};; *)echo "Unknown arch";exit 1;; esac case "`echo -ne "\x01\x02\x03\x04" |hexdump -e '"" 1/4 "%08x" ""'`" in *3*1*)w2d(){ let RES=$2*65536+$1;};; *1*3*)w2d(){ let RES=$1*65536+$2;};; *)echo "Unknown arch";exit 1;; esac loadkmap(){ local i=0 t k p=7 m KMAP="" for t in `hexdump -v -s 7 -n 256 -e '"" 1/1 "%x " ""' $1`; do let i=i+1 m="" if [ "$t" = 1 ]; then let p=p+256 m="`hexdump -v -s $p -n 256 -e '"" 2/1 "%02x:" " "' $1`" fi KMAP="$KMAP \"$m\"" done } keytab(){ local t=$1 eval "set $KMAP" shift $t RES="$1" } key(){ # echo "key? $1 $2" keytab $1 local k=$2 eval "set $RES" shift $k KEY="$1" } drawkbd(){ local s="\033[0;1f" local t=$1 key c b=0 xx i=0 x=1 y=1 k bb=0 kk='' eval "set $KMAP" shift $T while [ -z "$1" ]; do [ $T = $TT ] && let TT=TT+1 let T=T+1 if [ $T = 256 ]; then T=0 eval "set $KMAP" else shift fi done for key in $1; do if [ -n "$kmapfile" ]; then [ "${kk#*$key}" = "$kk" ] || continue kk="$kk $key" fi k=' ' case "$key" in 1b:00:) k='esc' ;; 00:07:) k='shift' ;; 7f:00:) k='bs ' ;; 01:02:) k='enter' ;; 02:07:) k='ctrl' ;; 03:07:) k='alt' ;; 07:02:) k='caps' ;; 09:00:) k='tab' ;; # 0c:03:) k="#$T " ;; # ??? 0*|1*) k='---' continue ;; 7f*) ;; *) k=" \x${key%%:*} " ;; esac let i=i+1 if [ "$b" != 1 ]; then s="$s\033[47;30m" b=1 else s="$s\033[0;37m" b=0 fi if [ $x = $XX ] && [ $y = $YY ]; then s="$s\033[45;30m" KEY="$key" fi let xx=x*3-2 s="$s\033[$y;${xx}f$k" let x=x+1 if [ $x -gt $WIDTH ]; then let xx=x*3-2 s="$s\033[$y;${xx}f\033[0;37m\033[0K" x=1 let y=y+1 [ $y -gt 4 ] && break let bb=1-bb b="$bb" fi done echo -ne "$s" >&2 } run(){ case "$1" in exit) fin 1 ;; esac echo "$*" echo -ne "\033[s" >&2 # eval "$*" } dokey(){ [ -n "$1" ] && case "$1" in 00:07:) let T=1-T ;; # shift 7f:00:) LINE="${LINE%?}" ;; # back 02:07:) ;; # ctrl 03:07:) ;; # alt # 0c:03:) let T=T+1; TT="$T" ;; # ??? 07:02:) let T=1-T ; TT="$T" ;; # caps # 07:02:) let T=T+1 ; TT="$T" ; echo "tab=$T" ;; # caps 01:02:) # enter echo -ne " \033[u\033[s$PROMPT" >&2 run "$LINE" LINE="" return ;; # *) echo -ne "\x${1%%:*}" ; T="$TT" ;; *) LINE="$LINE`echo -ne "\x${1%%:*}"`" T="$TT" ;; esac echo -ne "\033[u\033[s$PROMPT$LINE" >&2 } fin(){ killall hexdump >/dev/null 2>&1 [ -n "$1" ] && killall vkb >/dev/null 2>&1 } _d(){ w2d 0x$x11 0x$x12 d="$RES" [ "${d#??????????}" = "$d" ] || let d=d-4294967296 } vkb(){ [ -n "$kmapfile" ] && loadkmap "$kmapfile" local x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 d=" ." tty=`tty` buf=12 i while [ $buf != 0 ]; do d="$d $d" let buf=buf-1 done d="\"$d\n\"" { for i in $* ; do # unbuffer case $i in */event*) # while true ; do hexdump -v -n 24 -e "\": \" 12/2 \"%x \" \"\n\"" "$i"|| break ; done & # while true ; do hexdump -v -n 48 -e "\": \" 12/2 \"%x \" $d" "$i"|| break ; done & { hexdump -v -e "\": \" 12/2 \"%x \" $d" "$i";} & ;; */mice|*/mouse*) while true; do hexdump -v -n 3 -e '"+ . . . . . . . " 3/1 "%x " " . . .\n"' "$i";done & # { hexdump -v -e "\"+ . . . . . . . \" 3/1 \"%x \" $d" "$i";} & ;; esac done 2>/dev/null echo -ne "\033[s" >&2 drawkbd dokey read d <$tty && { echo ": . . . . . . . . . . . $d" killall hexdump } } | while read x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12; do case "$x9$x0$x10" in 0+0) if [ $x8 != 8 ]; then drawkbd dokey "$KEY" fi continue ;; *+*) i=0x$x9 let d=0x$x8/16%2 && let i=i-256 let X=X+i*relAccX if [ $X -gt $X1 ]; then X=$X1 elif [ $X -lt $X0 ]; then X=$X0 fi let XX=X-X0+resX let XX=XX/resX i=0x$x10 let d=0x$x8/32%2 && let i=i-256 let Y=Y-i*relAccY if [ $Y -gt $Y1 ]; then Y=$Y1 elif [ $Y -lt $Y0 ]; then Y=$Y0 fi let YY=Y-Y0+resY let YY=YY/resY ;; 2:0) _d let X=d*relAccX+X if [ $X -gt $X1 ]; then X=$X1 elif [ $X -lt $X0 ]; then X=$X0 fi let XX=X-X0+resX let XX=XX/resX ;; 2:1) _d let Y=d*relAccY+Y if [ $Y -gt $Y1 ]; then Y=$Y1 elif [ $Y -lt $X0 ]; then Y=$Y0 fi let YY=Y-Y0+resY let YY=YY/resY ;; 2:2) _d let Z=Y+d ;; 3:0) _d let X=d-X0 let XX=X%sX+X0+resX let XX=XX/resX ;; 3:1) _d let Y=d-Y0 let YY=Y%sY+Y0+resY let YY=YY/resY ;; 3:2) _d Z="$d" ;; # 3:18|1:*) _d 3:18) _d [ $d = 1 ] || continue if [ $d = 1 ]; then drawkbd dokey "$KEY" continue fi ;; .:.) run "$x12" break ;; *) continue ;; esac drawkbd dokey done fin return 99 } find_abs_pressure(){ local h="" a="" n="" while read i; do case "$i" in N:*) n="${i#*=}" ;; H:*) h="${i#*=}" ;; B:\ ABS=????????) a="${i#*=}" ;; ?*) ;; *) # 58=pressure if [ -n "$a" ] ; then for i in $h; do [ "${i#event}" != "$i" ] && echo "/dev/input/$i" done fi h="" a="" n="" ;; esac done