Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

Adjust touchscreen input for fullscreen aspect ratio

My Thinkpad X230 of course has the 1366x768 display endemic to the era. I wanted to use an old program that is best viewed in a full-screen, 640x480 resolution. Of course xrandr can set this resolution no problem, but the tablet input needs to be adjusted to scale to the size of the display.

Here is my solution for that.

#!/bin/sh
# File: set-touchscreen-resolution.sh
# Locations:
#    LTB-019:/usr/local/bin/
#    /mnt/public/Support/Platforms/Thinkpad-X230/screen/
# Author: bstack15
# Startdate: 2021-10-30 20:42
# Title: Script that Adjusts Thinkpad Touchscreen to Aspect Ratios of Smaller Resolutions
# Purpose: change touchscreen input to match resolution.
# History:
# Usage:
#    set-touchscreen-resolution.sh 640 480
# References:
#    https://stackoverflow.com/questions/20558710/bc-truncate-floating-point-number/20562313#20562313
# Improve:
#    discover how to actually make the logic work with 1366x768
# Dependencies:
#    xsetwacom
# Documentation:
#    full height input is always useful on the Thinkpad X230, so we are only calculating X.
# get touchscreen native aspect ratio
xi="$( xinput list )"
stylus="$( echo "${xi}" | awk '/stylus.*slave.*pointer/{print}' | awk -F'=' '{print $2}' | awk '{print $1}' )"
touch="$( echo "${xi}" | awk '/touch.*slave.*pointer/{print}' | awk -F'=' '{print $2}' | awk '{print $1}' )"
eraser="$( echo "${xi}" | awk '/eraser.*slave.*pointer/{print}' | awk -F'=' '{print $2}' | awk '{print $1}' )"
#desiredx=640
#desiredy=480
desiredx="${1}"
desiredy="${2}"
# for some reason the real aspect ratio does not work, but setting a 1x1 ratio will make the tablet input work
test "${desiredx}" = "1366" && test "${desiredy}" = "768" && { desiredx=1 ; desiredy=1 ; }
test -z "${desiredx}" && test -z "${desiredy}" && { desiredx=1 ; desiredy=1 ; }
# For each item, because the resolution can be different across items.
for word in ${touch} ${stylus} ${eraser} ;
do
   origArea="$( xsetwacom get "${word}" Area )"
   xsetwacom set "${word}" ResetArea
   resetarea="$( xsetwacom --get "${word}" Area )"
   xsetwacom set "${word}" Area ${origArea}
   fullx="$( echo "${resetarea}" | awk '{print $3}' )"
   fully="$( echo "${resetarea}" | awk '{print $4}' )"
   width="$( printf "scale=4\na=(${fullx}/(${desiredx}/${desiredy}))\na\n" | bc )"
   x1="$( printf "scale=4\ndefine trunc(x) { auto s; s=scale; scale=0; x=x/1; scale=s; return x }\na=(${fullx}/2)-(${width}/2)\ntrunc(a)\n" | bc )"
   x2="$( printf "scale=4\ndefine trunc(x) { auto s; s=scale; scale=0; x=x/1; scale=s; return x }\na=${x1}+${width}\ntrunc(a)\n" | bc )"
   #echo "For width=${width} run:"
   echo "setting device ${word} Area ${x1} 0 ${x2} ${fully}"
   test -n "${APPLY}" && {
      xsetwacom set "${word}" Area ${x1} 0 ${x2} ${fully}
   }
done

Any guidance on the mathematics for the aspect ratios would be welcome! Notice how I had to hardcode the full resolution of the display (1366x768). Apparently my math is... off.

References

  1. A lot of my own lousy mathematics
  2. Wacom tablet - ArchWiki
  3. linux - bc truncate floating point number - Stack Overflow

Comments