#!/usr/bin/env bash # https://aur.archlinux.org/packages/xwacomcalibrate print_help () { printf "\nUsage: xwacomcalibrate [-h] [-d] [-f [screen]] [-r (cw | half | ccw)]\n\n" printf " h: prints this help\n" printf " d: Uses xdotool to continously run the script\n" printf " f: Uses whole X screen as window size. If xrandr screen name is given, limits itself to that monitor\n" printf " r: Chooses the device rotation. When given, needs either \"cw\" for clockwise, \"half\" for overhead, or \"ccw\" for counterclockwise as an argument\n" printf "\n" } while getopts ":hdf:r:" opt do case $opt in h ) print_help exit 0 ;; d ) DAEMON=true ;; f ) FULLSCREEN=true if [[ $OPTARG ]] then SCREEN=$OPTARG fi ;; r ) if [[\ $OPTARG == "cw"\ || $OPTARG == "half"\ || $OPTARG == "ccw"\ ]] then ROTATION=$OPTARG else echo "Invalid rotation: $arg" 1>&2 exit 1 fi ;; : ) if [[ $OPTARG == "r" ]] then echo 'option requires an argument -- ' $OPTARG 1>&2 print_help exit 1 fi ;; \? ) print_help exit 1 ;; esac done shift $(( OPTIND -1 )) get_dev () { DEV=$(\ xsetwacom --list devices\ | grep "STYLUS"\ | cut -d$'\t' -f 2\ | tr -cd [:digit:] ) if [[ ! $DEV ]] then echo "no device found" exit 1 fi } full_tablet_size () { xsetwacom --set $1 ResetArea TB_X=$( xsetwacom --get $1 Area | cut -d ' ' -f 1) TB_Y=$( xsetwacom --get $1 Area | cut -d ' ' -f 2) TB_WIDTH=$( xsetwacom --get $1 Area | cut -d ' ' -f 3) TB_HEIGHT=$( xsetwacom --get $1 Area | cut -d ' ' -f 4) } set_rotation () { if [[ $2 ]] then xsetwacom --set $1 Rotate $2 else xsetwacom --set $1 Rotate none fi } set_output () { xsetwacom set $1 MapToOutput "${2}x${3}+${4}+${5}" } set_area () { xsetwacom set $1 area "$2" "$3"\ $( echo "$4 + $2" | bc )\ $( echo "$5 + $3" | bc ) } get_x_screen_size () { W_X="0" W_Y="0" W_WIDTH=$( xwininfo -root | grep Width | tr -dc [:digit:]) W_HEIGHT=$( xwininfo -root | grep Height | tr -dc [:digit:]) } get_screen_size () { local screen=$( xrandr -q | grep "$1 connected" | cut -d ' ' -f 3 ) if [[ ! $screen ]] then echo "couldn't find screen: $1" 1>&2 exit 1 fi if [[ $screen == "primary" ]] then local screen=$( xrandr -q | grep "$1 connected" | cut -d ' ' -f 4 ) fi IFS='x+' read -r -a array <<< "$screen" W_WIDTH="${array[0]}" W_HEIGHT="${array[1]}" W_X="${array[2]}" W_Y="${array[3]}" } get_active_window_size () { W_X=$(\ xdotool getactivewindow getwindowgeometry --shell\ | grep X\ | cut -d "=" -f2\ ) W_Y=$(\ xdotool getactivewindow getwindowgeometry --shell\ | grep Y\ | cut -d "=" -f2\ ) W_WIDTH=$(\ xdotool getactivewindow getwindowgeometry --shell\ | grep WIDTH\ | cut -d "=" -f2\ ) W_HEIGHT=$(\ xdotool getactivewindow getwindowgeometry --shell\ | grep HEIGHT\ | cut -d "=" -f2\ ) } calculate_new_tablet_size () { if [[ $1 == "cw" || $1 == "ccw" ]] then twidth=$3 theight=$2 else twidth=$2 theight=$3 fi tar=$( echo "scale=16; $twidth / $theight" | bc ) war=$( echo "scale=16; $4 / $5" | bc ) if [[ $( echo "scale=16; $tar <= $war" | bc ) -eq "1" ]] then theight=$( echo "scale=0; $twidth / $war /1" | bc ) else twidth=$( echo "scale=0; $theight * $war /1" | bc ) fi if [[ $1 == "cw" || $1 == "ccw" ]] then tmp=$twidth twidth=$theight theight=$tmp unset tmp fi TB_X=$( echo "scale=0; ($TB_WIDTH - $twidth) / 2" | bc ) TB_Y=$( echo "scale=0; ($TB_HEIGHT - $theight) / 2" | bc ) TB_WIDTH=$twidth TB_HEIGHT=$theight } main () { get_dev set_rotation "$DEV" "$ROTATION" full_tablet_size "$DEV" if [[ $FULLSCREEN ]] then if [[ $SCREEN ]] then get_screen_size "$SCREEN" else get_x_screen_size fi else get_active_window_size fi calculate_new_tablet_size "$ROTATION"\ "$TB_WIDTH" "$TB_HEIGHT"\ "$W_WIDTH" "$W_HEIGHT" set_output "$DEV" "$W_WIDTH" "$W_HEIGHT" "$W_X" "$W_Y" set_area "$DEV" "$TB_X" "$TB_Y" "$TB_WIDTH" "$TB_HEIGHT" echo "${W_WIDTH}x${W_HEIGHT}+${W_X}+${W_Y} \ ${TB_WIDTH}x${TB_HEIGHT}+${TB_X}+${TB_Y} $ROTATIONATION" } if [[ $DAEMON ]] then main xdotool search . behave %@ focus exec --sync\ $(\ echo 'xwacomcalibrate '\ $( if [[ $ROTATION ]]; then echo '-r ' $ROTATION ; fi )\ $( if [[ $FULLSCREEN ]]; then echo '-f'; fi )\ ) else main fi