Skip to content

Instantly share code, notes, and snippets.

@Deevad
Last active October 10, 2022 10:49
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save Deevad/51820854ffd5ea5cd883 to your computer and use it in GitHub Desktop.
Save Deevad/51820854ffd5ea5cd883 to your computer and use it in GitHub Desktop.
A bash script for an advanced setup of a Wacom on Linux : with a grep, automatic parsing of the Wacom identifier, of the screen, of dpi and with a precision mode ( drawing at 1:1 scale , the tablet / the screen ) . Only the button layout remain custom to the model ( Intuos 3 in this example ) and can be easily adapted with other buttons ID.
#! /bin/bash
# A bash script for an advanced setup of a Wacom on Linux :
# with a grep, automatic parsing of the Wacom identifier, of the screen, of dpi and with a precision mode
# ( drawing at 1:1 scale , the tablet / the screen ) .
# Only the button layout remain custom to the model ( Intuos 3 in this example )
# and can be easily adapted with other buttons ID.
#
# Dependencies: libwacom (xsetwacom), Bash and bc for the math, xrandr
# optional: Gnome icon, notify-send
# ( tested/created on Mint 17.2 Cinnamon, 11/2015 )
#
# Usage: Edit the script to enter the real world size of your tablet active zone (around line 20),
# Edit the script to get your button layout correctly setup ( around line 80),
# Execute the script to setup the tablet. It's a toggle:
# 1. First launch, tablet will be mapped fullscreen, with ratio correction.
# 2. Second launch, tablet will setup a precision mode.
# 3. Third launch loop to 1 , etc... a toggle.
# 4. I'm using the Linux Mint settings to attribute a keybind to launch this script.
# (the unused 'email' button on my keyboard)
# Art usage: I like to paint with fullscreen mapping (normal) mode
# I like to draw with precision mode.
# (Note: Krita does support live change of config without any observed bugs.)
#
# License: CC-0/Public-Domain/WTFPL (http://www.wtfpl.net/) license
# autor: www.peppercarrot.com
# Configuration information
# Enter here the active area of your tablet in centimeters (mesure in physical world) :
XtabletactiveareaCM=30.5
YtabletactiveareaCM=22.7
# Custom preference
# Correction scaling can enlarge a bit the precision zone.
# I saw during test a precision zone slightly larger has no impact on control quality, and might feels better.
# default=1 for real precision zone, enlarge=1.5 or reduce=0.8
# myfav: slighly-larger=1.11 with Intuos3 A4 and 96dpi 21inch 1080p workstation screen.
# larger=1.5 with Intuos4 Medium and 120dpi 15inch 1080p laptop screen.
correctionscalefactor=1
# Under this line, everything should be automatic, exept customising your buttons
# Tablet
tabletstylus=$(xsetwacom --list | grep STYLUS | cut -d ' ' -f 1-5 | sed -e 's/[[:space:]]*$//')
tableteraser=$(xsetwacom --list | grep ERASER | cut -d ' ' -f 1-5 | sed -e 's/[[:space:]]*$//')
tabletpad=$(xsetwacom --list | grep PAD | cut -d ' ' -f 1-5 | sed -e 's/[[:space:]]*$//')
xsetwacom --set "$tabletstylus" ResetArea
xsetwacom --set "$tableteraser" ResetArea
fulltabletarea=`xsetwacom get "$tabletstylus" Area | grep "[0-9]\+ [0-9]\+$" -o`
Xtabletmaxarea=`echo $fulltabletarea | grep "^[0-9]\+" -o`
Ytabletmaxarea=`echo $fulltabletarea | grep "[0-9]\+$" -o`
# Screen
Xscreenpix=$(xrandr --current | grep '*' | uniq | awk '{print $1}' | cut -d 'x' -f1)
Yscreenpix=$(xrandr --current | grep '*' | uniq | awk '{print $1}' | cut -d 'x' -f2)
screenPPI=$(xdpyinfo | grep dots | awk '{print $2}' | awk -Fx '{print $1}')
XscreenPPI=$(bc <<< "scale = 2; $Xscreenpix / $screenPPI")
YscreenPPI=$(bc <<< "scale = 2; $Yscreenpix / $screenPPI")
XscreenCM=$(bc <<< "scale = 0; $Xscreenpix * 0.0254")
YscreenCM=$(bc <<< "scale = 0; $Yscreenpix * 0.0254")
# Precise Mode + Ratio
Ytabletmaxarearatiosized=$(bc <<< "scale = 0; $Yscreenpix * $Xtabletmaxarea / $Xscreenpix")
XtabletactiveareaPIX=$(bc <<< "scale = 0; $XtabletactiveareaCM * $screenPPI / 2.54 * $correctionscalefactor")
YtabletactiveareaPIX=$(bc <<< "scale = 0; $YtabletactiveareaCM * $screenPPI / 2.54 * $correctionscalefactor")
XtabletactiveareaPIX=$(bc <<< "scale = 0; ($XtabletactiveareaPIX + 0.5) / 1")
YtabletactiveareaPIX=$(bc <<< "scale = 0; ($YtabletactiveareaPIX + 0.5) / 1")
XOffsettabletactiveareaPIX=$(bc <<< "scale = 0; ($Xscreenpix - $XtabletactiveareaPIX) / 2")
YOffsettabletactiveareaPIX=$(bc <<< "scale = 0; ($Yscreenpix - $YtabletactiveareaPIX) / 2")
# Verbose for debugging
echo "Setup script for your $tabletpad"
echo "-----------------------------------------"
echo ""
echo "Debug informations:"
echo "Tablet size (cm) :" "$XtabletactiveareaCM" x "$YtabletactiveareaCM"
echo "Screen size (px) :" "$Xscreenpix" x "$Yscreenpix"
echo "Screen size (cm) :" "$XscreenCM" x "$YscreenCM"
echo "Screen ppi :" "$screenPPI"
echo "Correction factor :" "$correctionscalefactor"
echo "Maximum tablet-Area (Wacom unit):" "$Xtabletmaxarea" x "$Ytabletmaxarea"
echo "Precision-mode area (px):" "$XtabletactiveareaPIX" x "$YtabletactiveareaPIX"
echo "Precision-mode offset (px):" "$XOffsettabletactiveareaPIX" x "$YOffsettabletactiveareaPIX"
# INTUOS 3 Large Infos:
# max area : 0 0 60960 45720
# ---------
# | | 1 |
# | 3 |---|
# | | 2 |
# |-------|
# | 8 |
# ---------
xsetwacom set "$tabletpad" Button 1 "key e" # Eraser
xsetwacom set "$tabletpad" Button 2 "key Shift_L" # Resize widget with Krita
xsetwacom set "$tabletpad" Button 3 "key Control_L" # Control color picker
xsetwacom set "$tabletpad" Button 8 "key KP_Divide" # '/' key to swap current brush preset with previous used on Krita.
xsetwacom set "$tabletstylus" RawSample 4
# Other example
# xsetwacom set "$tabletpad" Button 1 "key greater" # '>' Symbol ; I map on it a color selector, or a custom feature of Krita
# xsetwacom set "$tabletpad" Button 8 "key comma" # ',' key ; another easy key to bind an on-canvas color selector
# xsetwacom set "$tabletstylus" Button 2 "key ctrl" # A way to add Color picker on stylus.
# In case of Nvidia gfx:
xsetwacom set "$tabletstylus" MapToOutput "HEAD-0"
xsetwacom set "$tableteraser" MapToOutput "HEAD-0"
xsetwacom set "$tabletpad" MapToOutput "HEAD-0"
# Precision mode start here :
# Dual configuration
if [ -f /tmp/wacomscript-memory-tokken ]; then
# Here Precision mode; full tablet area in cm are 1:1 on a portion of the screen.
echo "Precision mode"
xsetwacom set "$tabletstylus" Area 0 0 "$Xtabletmaxarea" "$Ytabletmaxarea"
xsetwacom set "$tableteraser" Area 0 0 "$Xtabletmaxarea" "$Ytabletmaxarea"
xsetwacom set "$tabletstylus" MapToOutput "$XtabletactiveareaPIX"x"$YtabletactiveareaPIX"+"$XOffsettabletactiveareaPIX"+"$YOffsettabletactiveareaPIX"
notify-send -i /usr/share/icons/gnome/22x22/devices/input-tablet.png "Precision mode" "$XtabletactiveareaPIX x $YtabletactiveareaPIX part-of-screen"
rm /tmp/wacomscript-memory-tokken
else
# Here normal mode; tablet map to Fullscreen with ratio correction
echo "Full-screen mode with ratio correction"
xsetwacom set "$tabletstylus" Area 0 0 "$Xtabletmaxarea" "$Ytabletmaxarearatiosized"
xsetwacom set "$tableteraser" Area 0 0 "$Xtabletmaxarea" "$Ytabletmaxarearatiosized"
xsetwacom set "$tabletstylus" MapToOutput "$Xscreenpix"x"$Yscreenpix"+0+0
notify-send -i /usr/share/icons/gnome/22x22/devices/input-tablet.png "Normal mode" "full-screen"
touch /tmp/wacomscript-memory-tokken
fi
@Deevad
Copy link
Author

Deevad commented Nov 19, 2015

Here is a visual illustration about what precision mode does :
2015-11-19_screenshot_006

@piotr-rudnik
Copy link

Thanks! Script is really helpful for me

Copy link

ghost commented Oct 27, 2016

Hi David,

Thanks for the script, it was a very good starting point to write my own.

In your script you wrote:

tabletstylus=$(xsetwacom --list | grep STYLUS | cut -d ' ' -f 1-5 | sed -e 's/[[:space:]]*$//')

For me this didn't work because the identifier for my stylus contains six words instead of five. I wrote the following which will probably work in more cases and is a bit more clean:

tabletstylus=$(xsetwacom --list awk '/STYLUS/ {print $1}' FS=" ")

Also, I think xdpyinfo will often return an incorect DPI (= PPI) as it was in my case. I think the safest solution is to just calculate it from the physical dimensions of the screen and the resolution. The PPI for my laptop screen is about 140.6769 for example.

Another thing to note is that it's easy to make rounding mistakes with bc.

First, the scale option is only considered in the case of a division!

You wrote XscreenCM=$(bc <<< "scale = 0; $Xscreenpix * 0.0254" But because there is no division the scale option is just ignored here.

Also, rounding doesn't only happen at the end of the calculation but may also happen with subcalculations bc makes. For example:
bc <<< "scale=0;(1/2)+(1/2) results in 0, not 1.

So I think it's a bit unpredictable to write something like:
XtabletactiveareaPIX=$(bc <<< "scale = 0; $XtabletactiveareaCM * $screenPPI / 2.54 * $correctionscalefactor")

It's hard to tell how precise this calculation will be.

I would change calculations like this to:

XtabletactiveareaPIX_FLOAT=$(bc -l <<< "$XtabletactiveareaCM * $screenPPI / 2.54 * $correctionscalefactor")

The option -l means that it will calculate as precise as possible. Afther this you can round the float to an integer.
XtabletactiveareaPIX=$(bc <<< "scale=0; $XtabletactiveareaPIX_FLOAT / 1")

Again, the division is necesary for the 'scale' option not to be ignored.

Hope this will help some people and again, thanks for your work!

@trueharmony3
Copy link

trueharmony3 commented Feb 8, 2017

Please help. I have a Intuos 3 small that a long time back, i read how you can add the precision mode to the code and button map it, i did it and it worked, well trying to set it up again with a Intuos 3 larger one, and its not working on it and trying to find where i read the how to. Can not find it, and I don't remember where to go.

@Deevad
Copy link
Author

Deevad commented Sep 15, 2017

Hi, sorry for long time without reply on this thread.
I think this precision mode can be precious to keep update about it , thanks @tomvdab for the proposed fix. I'll retest asap and I'll try to come with update.

@Deevad
Copy link
Author

Deevad commented Sep 15, 2017

mm... I tested it on 'buntu 17.04. The tablet and stylus is correctly identified ; even if I use another wacom. I'm waiting for your feedback in your 2017/autumn GNU/Linux distro install

@caltrop2075
Copy link

nothing about the touch strips
default config has issues
as soon as you touch the strip the mouse goes wonky requiring a restart of the system
FYI: I am using a dual monitor system which has caused all kinds of headaches in linux

I would really like to disable the intuos3 in linux
I have virtual WinXP with the REAL drivers for the tablet & it works as it should

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment