2018-04-05 14:23:02 +02:00
|
|
|
#!/bin/sh
|
|
|
|
|
2018-04-05 19:00:35 +02:00
|
|
|
if [ -z "$KEYBOARD_ID" ]; then
|
|
|
|
KEYBOARD_ID="AT Translated Set 2 keyboard"
|
|
|
|
fi
|
2018-04-05 14:23:02 +02:00
|
|
|
|
|
|
|
# cpm: characters per minute
|
|
|
|
# wpm: words per minute (1 word = 5 characters)
|
2018-04-05 19:00:35 +02:00
|
|
|
if [ -z "$METRIC" ]; then
|
|
|
|
METRIC=cpm
|
|
|
|
fi
|
2018-04-05 14:23:02 +02:00
|
|
|
|
2018-04-05 19:00:35 +02:00
|
|
|
if [ -z "$ICON" ]; then
|
|
|
|
ICON="#"
|
|
|
|
fi
|
2018-04-05 14:23:02 +02:00
|
|
|
|
2018-04-05 19:00:35 +02:00
|
|
|
if [ -z "$FORMAT" ]; then
|
|
|
|
FORMAT="$ICON %d $METRIC"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -z "$INTERVAL" ]; then
|
|
|
|
INTERVAL=20
|
|
|
|
fi
|
|
|
|
|
|
|
|
# If you have a keyboard layout that is not listed here yet, create a condition yourself. $3 is the key index.
|
|
|
|
# Use `xinput test "AT Translated Set 2 keyboard"` to see key codes in real time.
|
|
|
|
# Be sure to open a pull request for your layout's condition!
|
|
|
|
if [ -z "$LAYOUT" ]; then
|
|
|
|
LAYOUT=qwerty
|
|
|
|
fi
|
|
|
|
if [ -z "$CONDITION" ]; then
|
|
|
|
case "$LAYOUT" in
|
|
|
|
qwerty) CONDITION='($3 >= 10 && $3 <= 19) || ($3 >= 24 && $3 <= 33) || ($3 >= 37 && $3 <= 53) || ($3 >= 52 && $3 <= 58)'; ;;
|
|
|
|
azerty) CONDITION='($3 >= 10 && $3 <= 19) || ($3 >= 24 && $3 <= 33) || ($3 >= 37 && $3 <= 54) || ($3 >= 52 && $3 <= 57)'; ;;
|
|
|
|
dontcare) CONDITION='$3 == $3'; ;; # Just register all key presses, not only letters and numbers
|
|
|
|
*) echo "Unsupported layout \"$LAYOUT\""; exit 1; ;;
|
|
|
|
esac
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# We have to account for the fact we're not listening a whole minute
|
|
|
|
multiply_by=60
|
|
|
|
divide_by=$INTERVAL
|
2018-04-05 14:23:02 +02:00
|
|
|
|
|
|
|
case "$METRIC" in
|
2018-04-05 19:00:35 +02:00
|
|
|
wpm) divide_by=$((divide_by * 5)); ;;
|
|
|
|
cpm) ;;
|
2018-04-05 14:23:02 +02:00
|
|
|
*) echo "Unsupported metric \"$METRIC\""; exit 1; ;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
hackspeed_cache="$(mktemp -p '' hackspeed_cache.XXXXX)"
|
|
|
|
trap 'rm "$hackspeed_cache"' EXIT
|
|
|
|
|
|
|
|
# Write a dot to our cache for each key press
|
|
|
|
printf '' > "$hackspeed_cache"
|
2018-04-05 19:00:35 +02:00
|
|
|
xinput test "$KEYBOARD_ID" | \
|
2018-04-05 14:23:02 +02:00
|
|
|
stdbuf -o0 awk '$1 == "key" && $2 == "press" && ('"$CONDITION"') {printf "."}' >> "$hackspeed_cache" &
|
|
|
|
|
|
|
|
while true; do
|
2018-04-05 19:00:35 +02:00
|
|
|
# Ask the kernel how big the file is with the command `stat`. The number we
|
|
|
|
# get is the file size in bytes, which equals the amount of dots the file
|
|
|
|
# contains, and hence how much keys were pressed since the file was last
|
|
|
|
# cleared.
|
2018-04-05 14:23:02 +02:00
|
|
|
lines=$(stat --format %s "$hackspeed_cache")
|
|
|
|
|
2018-04-05 19:00:35 +02:00
|
|
|
# Truncate the cache file so that in the next iteration, we only count new
|
|
|
|
# keypresses
|
2018-04-05 14:23:02 +02:00
|
|
|
printf '' > "$hackspeed_cache"
|
|
|
|
|
2018-04-05 19:00:35 +02:00
|
|
|
# The shell only does integer operations, so make sure to first multiply and
|
|
|
|
# then divide
|
|
|
|
value=$(($lines * $multiply_by / $divide_by))
|
|
|
|
|
|
|
|
printf "$FORMAT\n" "$value"
|
|
|
|
|
|
|
|
sleep $INTERVAL
|
2018-04-05 14:23:02 +02:00
|
|
|
done
|
2018-04-05 19:00:35 +02:00
|
|
|
|
|
|
|
# vim: set noet :
|