Monday, December 16, 2019

Configuring Wacom tablet on Debian Xorg multiple displays

Configuring wacom tablet on Linux is thankfully much easier these days than 10 years ago. However there are still some issues with figuring out aspect ratio, especially with multiple displays.  This gets more complicated when you have a mix of displays in portrait and landscape modes:
The above is my X Server configuration, by the quirk of how this configuration works, technically my overall display is 4920 pixels by 1920 pixels, with the parts in dark gray inaccessible since they're outside of the available viewports.

Wacom setup (it's mostly automatic)

The Debian wiki has a great high level overview on the status of Wacom driver and basic commands, nutshell: current Debian versions do great auto detection Wacom hardware. 

However, the one missing part is correct detection of aspect ratios and display mapping, especially with multi-display configurations.  On my system for instance, the single 8x6 tablet maps to the entire span of my display across all 3 monitors.  This creates a flattened out and distorted image when drawing.

Thankfully, the article above does provide a clue as to how this can be fixed.  The article points to the following command:
xsetwacom --set "id" MapToOutput 1920x1080+0+1024
The command is used to lock the stylus pointer to the correct screen (and aspect ratio).

The key here is the bunch of numbers at the tail end of the command.  These numbers map the tablet to a specific pixel resolution, and X and Y axis offsets from coordinates (0,0). 

Tablet ratio and screen resolution

In my case the screen I want to map the tablet to is the middle screen at 1920x1080 pixels, however that does not map exactly to my tablet which has an 8x6 ratio.  Mapping the tablet to 1920 by 1080 pixels caused it to produce stretched images:  tracing a circle with the stylus on the tablet created a flat oval on the screen. 

To fix this, I needed to map the tablet to a pixel resolution that matched the aspect ratio of the tablet.  Using the screen width as starting value, some quick math can give us the correct resolution for the tablet size:

( Screen_pixel_width / tablet width ) * tablet height = screen_pixel_height

so

( 1920px / 8 ) * 6 = 1440px

To maintain the correct aspect ratio when drawing, my tablet needs to map to a screen with a resolution of 1920x1440.  However, plugging these numbers into the xsetwacom command will map the tablet to an area larger than the screen.  This overlap will be in effect a dead zone on the tablet.   

Screen offset + multiple displays

To minimize the effect of the tablet resolution being larger than the display resolution, the tablet view-port (1920x1440) needs to be centered over the display screen (1920x1080). This can be easily accomplished by offsetting the display by half of the difference between 1440 and 1080, which equals 180 pixels.  And this is where the last two values in the xsetwacom command come into play. 

The last two values correspond to x-axis offset and y-axis offset, keeping in mind that the Cartesian coordinate origin point for X Server display is in the upper left corner of the display. 

So, our offset in this case will be +0-180, bringing it all together, to map a 8x6 Wacom tablet to a 1920x1080 screen (in a single display system), we would need the following command: 
xsetwacom --set "id" MapToPutput 1920x1440+0-180
Now, since I wanted to map the tablet to a middle display of a multi-display setup,  I had to account for the overall screen size as dictated by the layout of my other displays.  To recap, my displays are arranged as follows:


This means that my middle screen is offset in the X Server display origin by +1080+420.  Remember, the Cartesian origin (0,0) is in the top leftmost corner of this X Server display, which is also the top left corner of the first, portrait oriented screen.

To map the tablet to my middle display, all I had to do was add the x,y offsets from my X Server configuration to the calculated tablet offset values from further above (1080 + 0 = 1080, and 420 - 180 = 240), giving us:
xsetwacom --set "id" MapToPutput 1920x1440+1080+240
Providing a tablet mapping that corresponds to the following (blue rectangle):
Yes, parts of the tablet are not usable, since they are outside the boundaries of my middle display.  However I can now draw over the entire area of the middle screen, and I can retain the correct aspect ratio when drawing (no more flat circles). 

The above command needs to be applied to every Wacom device that exists on the system.  This is where the "id" value is important.  Use the following command to list Wacom devices on your system:
root@Orthanc:/etc# xsetwacom --list dev
Wacom Intuos3 6x8 Pen stylus            id: 8   type: STYLUS   
Wacom Intuos3 6x8 Pad pad               id: 9   type: PAD      
Wacom Intuos3 6x8 Pen eraser            id: 15  type: ERASER   
Wacom Intuos3 6x8 Pen cursor            id: 16  type: CURSOR   
Then, for each device, set it to the required resolution and offset, for me that's:
root@Orthanc:/etc# xsetwacom --set "8" MapToOutput 1920x1440+1080+240 root@Orthanc:/etc# xsetwacom --set "9" MapToOutput 1920x1440+1080+240
root@Orthanc:/etc# xsetwacom --set "15" MapToOutput 1920x1440+1080+240
root@Orthanc:/etc# xsetwacom --set "16" MapToOutput 1920x1440+1080+240
I'm not sure if the Pad device has to be configured as such as well, however there seems to be no ill effect to this.  For sure the Pen devices have to be set as such. 

Next steps: automating this configuration setup on system startup.