SHARE
TWEET

mouse-demo

a guest May 18th, 2018 5 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/bash
  2. # Mon Jan  5 10:59:00 EST 2004
  3. # NAME: mouse-demo
  4. # Copyright 2004, Chris F.A. Johnson
  5. # Released under the terms of the GNU General Public License
  6.  
  7. about() #== Information about mouse-demo
  8. {
  9.     cat <<EOF
  10.           ${B}mouse-demo${U}
  11.  
  12.               A bash script that can be controlled entirely with the
  13.               mouse.
  14.  
  15.           Requires: bash 2.0x or greater, ANSI/xterm window
  16.  
  17.           Author: Chris F.A. Johnson
  18.  
  19.           Date: 5 January 2004
  20.  
  21.           Copyright 2004 Chris F.A. Johnson
  22.           This program may be copied under the terms of the
  23.           GNU General Public License, Version 2.
  24. EOF
  25. }
  26.  
  27. clear_body()
  28. {
  29.     printat $(( $bar_line + 2 )) 1 "${NA}${cles}"
  30. }
  31.  
  32. help()
  33. {
  34.     local n=0
  35.     clear_body
  36.     while [ $n -lt ${#button_cmd[@]} ]
  37.     do
  38.       printat $(( $n + $bar_line + 2 )) 1
  39.       printf "%15.15s %-10.10s - %s"  ${button_keys[$n]} "(${button_cmd[$n]})" "${help_strings[$n]}"
  40.       n=$(( n + 1 ))
  41.     done
  42. }
  43.  
  44. now()
  45. {
  46.     local n=3
  47.     local DATE YEAR MONTH DAY TIME HOUR MINUTE SECOND
  48.     eval `date "+DATE=\"%c\" YEAR=%Y MONTH=%B DOW=%A DAY=%d TIME=%H:%M:%S HOUR=%H MINUTE=%M SECOND=%S"`
  49.     printat $((n += 1)) 20 "       DATE: $DATE"
  50.     printat $((n += 2)) 20 "       YEAR: $YEAR"
  51.     printat $((n += 1)) 20 "      MONTH: $MONTH"
  52.     printat $((n += 1)) 20 "        DAY: $DAY"
  53.     printat $((n += 1)) 20 "Day of week: $DOW"
  54.     printat $((n += 1)) 20 "       HOUR: $HOUR"
  55.     printat $((n += 1)) 20 "     MINUTE: $MINUTE"
  56.     printat $((n += 1)) 20 "     SECOND: $SECOND"
  57. }
  58.  
  59. d2c () #== convert a decimal number to the corresponding ASCII character
  60. {
  61.     x=`printf "%x" $1`
  62.     printf "%b" "\x$x"
  63. }
  64.  
  65. set_chars() #== load string of all 255 chars from file (create if necessary)
  66. {
  67.     charfile=$HOME/.chars
  68.     if ! [ -s $charfile ]
  69.     then
  70.       for c in `seq 1 255`; do
  71.     [ $c -eq 127 ] && c=9  ## 0x7f causes problems
  72.     d2c $c
  73.       done > $charfile
  74.     fi
  75.     chars=$(< $charfile)
  76. }
  77.  
  78. cls() #== clear screen
  79. {
  80.     printf "${CLS:=`clear`}"
  81. }
  82.  
  83. printat() #== print arguments 3-... at Y=$1 X=$2
  84. {
  85.     [ $# -lt 2 ] && return 1
  86.     local y=$1
  87.     local x=$2
  88.     shift 2
  89.     local msg="$*"
  90.     printf "${CSI}%d;%dH%b" ${y//[!0-9]} ${x//[!0-9]} "$msg"
  91. }
  92.  
  93. index() #== index return position of STR2 in STR1
  94. {
  95.     local idx
  96.     case $1 in
  97.         *$2*)
  98.             idx=${1%%"${2}"*};
  99.             _INDEX=$(( ${#idx} + 1 ))
  100.         ;;
  101.         *)
  102.             _INDEX=0
  103.         ;;
  104.     esac
  105. }
  106.  
  107. mouse_info() #== print mouse press information
  108. {
  109.     local frmt="%16s %3d"
  110.     clear_body
  111.     xx=$(( $COLUMNS / 3 ))
  112.     yy=3 ##$(( $LINES - 25 ))
  113.     printat $((yy++)) $xx
  114.     printf "$frmt" Button: $mouse_b
  115.     printat $((yy++)) $xx
  116.     printf "$frmt" Column: $mouse_x
  117.     printat $((yy++)) $xx
  118.     printf "$frmt" Row: $mouse_y
  119.     printat $((yy++)) $xx
  120.     printf "$frmt" "Mouse modifier:" $mouse_m
  121.     printat $((yy++)) $xx "$cle"
  122.     printf "Var. Length: B=%d X=%d Y=%d " ${#_MOUSE1} ${#_MOUSE2} ${#_MOUSE3}
  123.     printat $((yy++)) $xx "$cle"
  124.     printf "MOUSE1=%s MOUSE2=%s MOUSE3=%s " `ascii "$_MOUSE1$_MOUSE2$_MOUSE3"`
  125. }
  126.  
  127. mouse_pos() #== convert character to mouse position
  128. {
  129.     local MOUSE=$1
  130.     if [ "$MOUSE" = $'\x7f' ]
  131.     then
  132.       _MOUSE_POS=95
  133.     elif [ "$MOUSE" = "\\" ]
  134.     then
  135.       _MOUSE_POS=60
  136.     else
  137.       index "$mouse_val_str" "$MOUSE"
  138.       _MOUSE_POS=$_INDEX
  139.     fi
  140. }
  141.  
  142. read_mouse() #== decode mouse press information
  143. {
  144.     IFS= read -r -d '' -sn1 -t1 _MOUSE1 || break 2
  145.     IFS= read -r -d '' -sn1 -t1 _MOUSE2 || break 2
  146.     IFS= read -r -d '' -sn1 -t1 _MOUSE3 || break 2
  147.     index "$mouse_val_str" "$_MOUSE1"
  148.     mouse_b=$(( ($_INDEX & 3) + 1 ))
  149.     mouse_m=$(( $_INDEX & (4 | 8 | 16) ))
  150.     mouse_pos "$_MOUSE2"
  151.     mouse_x=$_MOUSE_POS
  152.     mouse_pos "$_MOUSE3"
  153.     mouse_y=$_MOUSE_POS
  154. }
  155.  
  156. get_key() #== store keypress from list of permissible characters
  157. {
  158.     local OKchars=${1:-"$allkeys"}
  159.     local k
  160.     local error=0
  161.     local gk_tmo=${getkey_time:-${DFLT_TIME_OUT:-600}}
  162.     local ESC_END=[a-zA-NP-Z~^$]
  163.     mouse_x=0 mouse_y=0 mouse_b=0 mouse_line=0
  164.     printf "$mouse_on"
  165.     stty -echo
  166.     while :; do
  167.       IFS= read -r -d '' -sn1 -t$gk_tmo _GET_KEY </dev/tty 2>&1 || break
  168.       index "$OKchars" "$_GET_KEY"
  169.       if [ "$_INDEX" -gt 0 ]
  170.       then
  171.     case $_GET_KEY in
  172.         ${ESC})
  173.         while :; do
  174.           IFS= read -rst1 -d '' -n1 k </dev/tty || break 2
  175.           _GET_KEY=$_GET_KEY$k
  176.            case $k in
  177.               $ESC_END)
  178.               [ "$_GET_KEY" = "$MSI" ] && { read_mouse; }
  179.               break 2
  180.               ;;
  181.           esac
  182.         done
  183.         ;;
  184.          *) break;;
  185.     esac
  186.       fi
  187.     done
  188.     printf "$mouse_off"
  189.     return $error
  190. }
  191.  
  192. button_widths() #== initialize width of buttons
  193. {
  194.     [ $verbose -gt 0 ] && {
  195.     yy=6
  196.     printat  $(( yy++ )) 1  " Configuring button widths:"
  197.     printat  $(( yy++ )) 1  "     COLUMNS=$COLUMNS"
  198.     }
  199.     bnum=${#buttons[@]}
  200.     bwidth=${buttons_width:=$(( $COLUMNS - 1 ))}
  201.     button_width=$(( ($bwidth - $bnum) / $bnum ))
  202.     button_junk=$(( $buttons_width - ( ($button_width + 1 ) * $bnum) + 1))
  203.     local n=0
  204.     while [ $n -lt $bnum ]; do
  205.     pad=${spaces:0:$(( ($button_width - ${#buttons[$n]}) / 2 ))}
  206.     [ ${#pad} -lt 0 ] && { printf ":$pad:\n"; break; }
  207.     buttons[$n]=${pad}${buttons[$n]}${pad}
  208.     [ ${#buttons[$n]} -lt $button_width ] && buttons[$n]="${buttons[$n]} "
  209.     n=$(( $n + 1 ))
  210.     done
  211.     bk_list=${button_keys[@]}
  212.     bk_list=${bk_list// /}
  213.     [ $verbose -gt 0 ] && {
  214.     printat  $(( yy++ )) 1  "     button_width=$button_width"
  215.     printat  $(( yy++ )) 1  "     button_junk=$button_junk"
  216.     printat  $(( yy++ )) 1  "     bk_list=$bk_list"
  217.     printat  $(( yy += 2 )) 1  "     PRESS ANY KEY"
  218.     read -sn1
  219.     }
  220. }
  221.  
  222. button_bar() #== print buttons
  223. {
  224.     button_width2=$(( $button_width + 1 ))
  225.     cmd=99
  226.     printat $bar_line ${buttons_left:-1} "$bar_attr$NA"
  227.     printf "$bar_attr%${button_width}.${button_width}b$NA " "${buttons[@]}"
  228.     printf "$cle"
  229. }
  230.  
  231. highlight_button()
  232. {
  233.     local num=${1:-$cmd}
  234.     good_button || return
  235.     printat $bar_line $(( ($num % ${#buttons[@]}) * $button_width2 + $buttons_left ))
  236.     printf "${highbar_attr}%${button_width}.${button_width}s${NA}" "${buttons[$num]}"
  237. }
  238.  
  239. button_pressed() #== check whether press was in the button area
  240. {
  241.     [ ${mouse_x:-0} -ge ${buttons_left} ] &&
  242.     [ ${mouse_y:-0} -eq $bar_line ] &&
  243.     [ ${mouse_x:-0} -le $(( $buttons_left + $buttons_width )) ]
  244. }
  245.  
  246. do_button()
  247. {
  248.     local cmd=${1:-$cmd}
  249.     highlight_button $cmd
  250.     printat $body_line 1 "${NA}${cles}"
  251.     printat $body_line 1
  252.     good_button || return
  253.     case ${button_cmd[$cmd]} in
  254.     exit) confirm_exit && exit ;;
  255.     *) body_lines=$(( ${LINES:=24} - 4 ))
  256.         ${button_cmd[$cmd]} | head -${body_lines#-}
  257.     esac
  258.     _DO_BUTTON=$cmd
  259. }
  260.  
  261. good_button()
  262. {
  263.     local num=${1:-$cmd}
  264.     [ $num -ge 0 ] && [ $num -lt ${#buttons[@]} ]
  265. }
  266.  
  267. next_button()
  268. {
  269.     local num=${1:-$_DO_BUTTON}
  270.     cmd=$(( (${num:-0} + 1) % ${#buttons[@]} ))
  271. }
  272.  
  273. prev_button()
  274. {
  275.     local num=${1:-$_DO_BUTTON}
  276.     cmd=$(( (${num:-0} + ${#buttons[@]} - 1) % ${#buttons[@]} ))
  277. #    [ $cmd -lt  ] && cmd=1
  278. }
  279.  
  280. confirm_exit()
  281. {
  282.     local _LAST_KEY=$_GET_KEY
  283.     _DO_BUTTON=${cmd}
  284.     clear_body
  285.     printat $(( $bar_line + 2 )) 10 "${B}Exit [y/N]?${NA}${CVIS}\a "
  286.     get_key "$alphanumeric" #"yYnNqQ$ESC$LF$RT$TAB"
  287.     case $_GET_KEY in
  288.     y|Y|q|Q) return 0 ;;
  289.     $LF) prev_button ;;
  290.     $RT) next_button ;;
  291.     esac
  292.     clear_body;printf "$CINV"
  293.     _GET_KEY=$_LAST_KEY
  294.     false
  295. }
  296.  
  297. action()
  298. {
  299.     button_bar
  300.     if button_pressed
  301.     then
  302.       cmd=$(( ($mouse_x - $buttons_left) / $button_width2 ))
  303.     else
  304.       case "$_GET_KEY" in
  305.       $NL) printf "\a" ;;
  306.       $MSI ) mouse_info; cmd=-1 ;;
  307.       $TAB|$RT ) next_button ;;
  308.       $LF) prev_button ;;
  309.       [$bk_list]) index $bk_list $_GET_KEY
  310.          [ $_INDEX -gt 0 ] && [ $_INDEX -le ${#buttons[@]} ] && {
  311.          cmd=$(( $_INDEX - 1 ))
  312.          }
  313.          ;;
  314.       e|q|x) confirm_exit && exit ;;
  315.       esac
  316.     fi
  317.     highlight_button ##$cmd
  318.     [ $cmd -lt 0 -a $cmd -ge ${#buttons[@]} ] && return
  319.     [ "${button_cmd[$cmd]:-c}" = exit ] && confirm_exit && exit || do_button
  320. }
  321.  
  322. cleanup() #== restore terminal
  323. {
  324.     trap 0
  325.     button_bar
  326.     stty $stty_orig
  327. #    stty sane
  328.     printf "%s${NL}${NL}${NL}${NL}" "$CVIS"
  329. #    tput reset
  330.     exit
  331. }
  332.  
  333. trap "COLUMNS=`tput cols`;LINES=`tput lines`; cls;button_widths; button_bar" SIGWINCH
  334.  
  335. [ $verbose -gt 0 ] && printat 10 10 COLUMNS=$COLUMNS
  336. verbose=0
  337. COLUMNS=${COLUMNS:-`tput cols`}
  338. LINE=${LINES:-`tput lines`}
  339.  
  340. case $1 in
  341.     -v) verbose=1;;
  342. esac
  343.  
  344. bra='['
  345. ket=']'
  346. ESC=$'\e'
  347. NL=$'\n'
  348. TAB=$'\t'
  349. CSI=${ESC}${bra}
  350. cle=${CSI}K
  351. cles=${CSI}J
  352. CVIS="${CSI}?25h"
  353. CINV="${CSI}0;8m"
  354. MSI=${CSI}M
  355. NA=${CSI}0m
  356. B=${CSI}1m
  357. U=${CSI}0m
  358. UP=${CSI}A
  359. DN=${CSI}B
  360. RT=${CSI}C
  361. LF=${CSI}D
  362. mouse_type[0]=${CSI}?9h     ## report mouse button press
  363. mouse_type[1]=${CSI}?1000h  ## report mouse button press and release
  364. mouse_on=${mouse_type[0]}
  365. mouse_off=${CSI}?9l${CSI}?1000l
  366. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
  367. lower=abcdefghijklmnopqrstuvwxyz
  368. numeric=0123456789
  369. alphanumeric=$upper$lower$numeric
  370. spaces='                                                                   '
  371. spaces=$spaces$spaces$spaces
  372. CVIS=${CSI}?25h
  373. CINV=${CSI}?25l
  374. allkeys=$chars
  375.  
  376. trap "cleanup" 0
  377. set_chars
  378. mouse_val_str=${chars:32}
  379. mouse_on=${mouse_type[0]}
  380. cls
  381.  
  382. ## commands to be placed in buttons
  383. button_cmd=( cal df uptime who ps "ls -l" now help about exit )
  384.  
  385. ## labels for button (customize if different from commands
  386. buttons=( "${button_cmd[@]}" )
  387.  
  388. ## keys for each button
  389. button_keys=( c d u w p l n h a q )
  390.  
  391. ## info to show with help command
  392. help_strings=(
  393.     "Display amount of free and used memory in the system"
  394.     "Report filesystem disk space usage"
  395.     "Tell how long the system has been running"
  396.     "Show who is logged on"
  397.     "Report process status"
  398.     "Long listing of as many files as will fit on screen"
  399.     "Display date and time information"
  400.     "Help!"
  401.     "About this script"
  402.     "Exit"
  403. )
  404.  
  405. bar_attr="${CSI}1;41;37m"
  406. highbar_attr="${CSI}1;37;40m"
  407.  
  408. bar_line=1
  409. body_line=$(( $bar_line + 2 ))
  410. buttons_left=1
  411. printf "$CINV"
  412. button_widths
  413. button_bar
  414.  
  415. stty_orig=`stty -g`
  416. while :; do
  417.   get_key "xe$bk_list$ESC$TAB$LF$RT"
  418.   case $_GET_KEY in
  419. #      $LF) printat 10 10 KEY=left;;
  420. #      $RT) printat 10 10 KEY=right;;
  421. #      q|exit) break ;;
  422.       \?) help;;
  423.   esac
  424.   action
  425. done
  426. cleanup
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top