#!/bin/bash set -e # Note: Syncing up stream-evemu-coords with stream-xinput-coords can be # a difficult process since the latter won't report events that don't # occur over its own window. If you're careful to bring the pen in prox # above the xinput window it can work, but otherwise you'll have to tweak # the relative position of the two streams after-the-fact by hand in e.g. # LibreOffice... function stream-evemu-coords { echo -e "X_EVEMU\tY_EVEMU" if [ "$EUID" -ne 0 ]; then echo "NOTE: No root rights. Disabling use of \`evemu-record\` as a data source." >&2 return 0 fi DEVICE_NODE=$(printf "%s" $(xinput list-props "$1" | awk -F\" '/Device Node/ {print $2}')) # Note: We're ignoring the first report (passing through tail -n +2) # since an X event doesn't seem# to ever actually generated for it, # throwing off the synchronization with stream-xinput-coords. awk \ 'BEGIN {X=-1;Y=-1;SKIP=0;} \ /^E:/ { \ if (index($0,"BTN_TOOL_PEN") != 0 && $5=="0000") { SKIP=1 } if (index($0,"ABS_X")) { X=$5 } \ if (index($0,"ABS_Y")) { Y=$5 } \ else if (index($0,"SYN_REPORT")) { if (!SKIP) { print X "\t" Y; } else { SKIP=0; } } \ }' <(evemu-record "$DEVICE_NODE") | tail -n +2 } function stream-xinput-coords { DEVICE_ID=$1 echo -e "X_RAW\tY_RAW\tX_VALUATOR\tY_VALUATOR\tX_ROOT\tY_ROOT" awk '/^ 0:/ { X_VALUATOR=$2; split($3,a,"[()]"); X_RAW=a[2];} \ /^ 1:/ { Y_VALUATOR=$2; split($3,a,"[()]"); Y_RAW=a[2];} \ /^ 0:/ {printf("%s\t%s\t%s\t%s\t%s\t%s\n", X_RAW, Y_RAW, X_VALUATOR, Y_VALUATOR, X_ROOT, Y_ROOT); } \ /^ root:/ {split($2,a,"/"); X_ROOT=a[1]; Y_ROOT=a[2]} \ /^ event:/ {split($2,a,"/"); X_EVENT=a[1]; Y_EVENT=a[2]}' <(xinput test-xi2 "$DEVICE_ID") } function stream-coords { DEVICE_ID=$1 AREA=($(xsetwacom get "$DEVICE_ID" area)) TABLET_GEOM=( $((${AREA[2]} - ${AREA[0]})) $((${AREA[3]} - ${AREA[1]})) ${AREA[0]} ${AREA[1]} ) DESKTOP_GEOM=($(xwininfo -root | sed -rn 's/.*geometry ([0-9]+)x([0-9]+)\+?(-?[0-9]+)\+?(-?[0-9]+)/\1 \2 \3 \4/p')) awk -v OFS="\t" \ -v TABLET_WIDTH=${TABLET_GEOM[0]} -v TABLET_HEIGHT=${TABLET_GEOM[1]} \ -v TABLET_X_ORIGIN=${TABLET_GEOM[2]} -v TABLET_Y_ORIGIN=${TABLET_GEOM[3]} \ -v DESKTOP_WIDTH=${DESKTOP_GEOM[0]} -v DESKTOP_HEIGHT=${DESKTOP_GEOM[1]} \ -v DESKTOP_X_ORIGIN=${DESKTOP_GEOM[2]} -v DESKTOP_Y_ORIGIN=${DESKTOP_GEOM[3]} \ 'function x_expected(x) { return (x-TABLET_X_ORIGIN)/TABLET_WIDTH * DESKTOP_WIDTH + DESKTOP_X_ORIGIN } \ function y_expected(y) { return (y-TABLET_Y_ORIGIN)/TABLET_HEIGHT * DESKTOP_HEIGHT + DESKTOP_Y_ORIGIN } \ NR == 1 { print $0, "EXPECTED_X_ROOT__EVEMU", "EXPECTED_Y_ROOT__EVEMU", "EXPECTED_X_ROOT__RAW", "EXPECTED_Y_ROOT__RAW", "EXPECTED_X_ROOT__VALUATOR", "EXPECTED_Y_ROOT__VALUATOR", "DELTA_X_ROOT__VALUATOR", "DELTA_Y_ROOT__VALUATOR"; } NR > 1 { \ if (NF==8) { X_EVEMU=$1; Y_EVEMU=$2; X_RAW=$3; Y_RAW=$4; X_VALUATOR=$5; Y_VALUATOR=$6; X_ROOT=$7; Y_ROOT=$8; } \ else if (NF==6) { X_EVEMU="***"; Y_EVEMU="***"; X_RAW=$1; Y_RAW=$2; X_VALUATOR=$3; Y_VALUATOR=$4; X_ROOT=$5; Y_ROOT=$6; } \ \ if (X_EVEMU != "***") { EXPECTED_X_ROOT__EVEMU = x_expected(X_EVEMU); } else { EXPECTED_X_ROOT__EVEMU = "***"; } \ if (Y_EVEMU != "***") { EXPECTED_Y_ROOT__EVEMU = y_expected(Y_EVEMU); } else { EXPECTED_Y_ROOT__EVEMU = "***"; } \ \ EXPECTED_X_ROOT__RAW = x_expected(X_RAW); \ EXPECTED_Y_ROOT__RAW = y_expected(Y_RAW); \ \ EXPECTED_X_ROOT__VALUATOR = x_expected(X_VALUATOR); \ EXPECTED_Y_ROOT__VALUATOR = y_expected(Y_VALUATOR); \ \ DELTA_X_ROOT__VALUATOR = X_ROOT - EXPECTED_X_ROOT__VALUATOR; \ DELTA_Y_ROOT__VALUATOR = Y_ROOT - EXPECTED_Y_ROOT__VALUATOR; \ \ print X_EVEMU, Y_EVEMU, X_RAW, Y_RAW, X_VALUATOR, Y_VALUATOR, X_ROOT, Y_ROOT, EXPECTED_X_ROOT__EVEMU, EXPECTED_Y_ROOT__EVEMU, EXPECTED_X_ROOT__RAW, EXPECTED_Y_ROOT__RAW, EXPECTED_X_ROOT__VALUATOR, EXPECTED_Y_ROOT__VALUATOR, DELTA_X_ROOT__VALUATOR, DELTA_Y_ROOT__VALUATOR; }' <(paste <(stream-evemu-coords "$DEVICE_ID") <(stream-xinput-coords "$DEVICE_ID")) } if [ $# -ne 1 ]; then echo "Usage: $0 " >&2 exit 1 fi if [[ $(xsetwacom get "$1" rawsample) != 1 ]]; then echo "X device has smoothing enabled. Please run \`xsetwacom set \"$1\" rawsample 1\`." >&2 exit 1 fi if [[ $(xsetwacom get "$1" suppress) != 0 ]]; then echo "X device has filtering enabled. Please run \`xsetwacom set \"$1\" suppress 0\`." >&2 exit 1 fi trap 'kill -- -$$' EXIT stream-coords $1