Sunday, May 15, 2016

I recently decided to migrate from OS X to Ubuntu, and one of the most difficult (or rather easy once you figure out) things to setup is the Ugee Tablet Monitor on Ubuntu. Fortunately, the drivers for the Ugee monitor and touch screen input are already configured and makes the display and touch input drivers load automatically when the monitor is plugged in and turned on. The tricky part is getting the calibration settings correct.

Anyway, below are the steps you need to take to calibrate the Ugee.

1. Figure out what displays are available and which one corresponds to the Ugee display.

2. Figure out the input id for the touch display input. You can do this as follows:

$ xinput_calibrator --list

Device "UC-Logic 19" Tablet Monito" id=13

Where I've highlighted the important part in yellow. The id for my display is 13.

3. Just in case, jot-down the previous calibration and transformation matrix values. Replace the value 13 with your id value from step 2. You may/may not need to do this. I never did, but then had a lengthy process of trying to recover those values when I got my display into a badly calibrated state. This step also let's me explain what the calibration parameters are and what they affect.

I've highlighted the important lines to jot-down in green above. A quick explanation of each setting:

Coordinate Transformation Matrix - This is a 3x3 matrix that creates an affine transformation that warps a rectangular coordinate system to the coordinate system of the display. The transform needs to be changed to match the desktop layout/geometry if this gets updated (e.g., by dragging the display layout around in Settings->Display, changing the aspect ratio, or updating the rotation of the desktop).

Evdev Axis Calibration: This is the calibration value. The settings are written in the order:

xmin xmax ymin ymax

They control the bounds of the cursor in the x- and y- directions relative to some local coordinate system of the Ugee display. For mine, I roughly figured out that the coordinate system was something like 0 to 32210 for x and 0 to 20330 for y through trial and error. Tweaking the bounds around these values stretches the coordinate system along x and y to fit plane. If the display plane gets shifted from the touch display plane, the shift would be reflected by the lower or higher values.

Evdev Axes Swap: I haven't messed with this, but I'm speculating that a non-zero value flips the x- and y- coordinates so that the x-axis becomes the y-axis and vice versa.

5. Sync the coordinate system with the display. This step automagically populates the "Coordinate Transformation Matrix" values with the right values. Recall from step 1 that my Ugee display name is DP-1. From step 2, the Ugee input ID is 13.

$ xinput map-to-output 13DP-1

You will want to replace the 13 and DP-1 with your values. If you're curious about how this updates the coordinate transformation matrix, feel free to check it out by running the command in step 3, xinput list-props 13

6. Run the calibrator.

$ xinput_calibrator \

--device 13 \

--verbose \

--output-type xorg.conf.d

This will bring up a gray display with some targets to click on. If you run into issues like I did where tapping a target gets rejected or ignored because the tap is way out of bounds and gets clipped by the screen resolution, it means your display has gotten into a poorly calibrated state. The work around is to input a precalibrated value that is close to the Ugee's calibrated state. I had to figure out what these values were by trial and error. Anyway, you can also just use my calibrated values as well.

copy the snippet below into '/etc/X11/xorg.conf.d/99-calibration.conf' (/usr/share/X11/xorg.conf.d/ in some distro's)

Section "InputClass"

Identifier"calibration"

MatchProduct"UC-Logic 19" Tablet Monito"

Option"Calibration""-74 32085 182 20353"

Option"SwapAxes""0"

EndSection

Copy and paste the above highlighted yellow into some scratch file or text editor. If you want to restore the calibration after each reboot, we will need to create a calibration file later on. But first to finish the calibration.

7. Turn on all of the displays you turned off in step 4. I turned off DP-2, so to turn it back on:

$ xrandr --output DP-2 --auto

8. Reset the layout of your desktop. I had to rearrange the monitor layouts in Settings->Display so that the layouts are side-by-side instead of overlapping each other.

9. Update and sync the updated coordinate system by repeating step 5:

$ xinput map-to-output 13DP-1

10. By now, everything should be calibrated. Try out the stylus on the touch display. It should all work out. You may need to run the calibrator a second time if there's still an offset.

11. The remaining steps are to setup Ubuntu such that the calibration is restored on reboot. First, we need to create the file /usr/share/X11/xorg.conf.d/99-calibration.conf (or if the parent folder doesn't exist, then try creating /etc/X11/xorg.conf.d/99-calibration.conf ). The highlighted output from step 6 goes into the 99-calibration.conf file with some tweaks:

Section "InputClass"

Identifier"calibration"

MatchProduct"UC-Logic 19"

Option"Calibration""-74 32085 182 20353"

Option"SwapAxes""0"

EndSection

Notice that I've updated the value in green. This step is necessary since " would cause the string to terminate and create errors in the xorg configuration file. Since MatchProduct matches substrings, the new value works (unless you happen to have another input device that contains the string "UC-Logic 19").

12. One more final issue. After rebooting into X11, the coordinate transformation for the input gets reset to the identity matrix. This means you'll need to update the coordinate transformation with the correct value after every reboot. E.g., I could manually run : xinput map-to-output 13 DP-1
after every reboot, but I'm lazy. So, I wrote a script in ~/bin/sync_coordinate_transform.sh with the contents:

#!/bin/sh

xinput map-to-output 13 DP-1

(Actually, I made mine more generic since I worry the id values and DP values can change. I used the following script instead:

#!/bin/sh

get_tablet_input_id() {

xinput_calibrator --list | grep "UC-Logic 19" | cut -f2 -d"="

}

get_tablet_display_id() {

xrandr | grep "DP" | grep "1440x900" | cut -f1 -d" "

}

INPUT_ID="$(get_tablet_input_id)"

DISPLAY_ID="$(get_tablet_display_id)"

xinput map-to-output "${INPUT_ID}" "${DISPLAY_ID}"

And then added this script to Startup Applications:

$ gnome-session-properties

Name: Calibrate touchscreen

Command: ~/bin/sync_coordinate_transform.sh

=====================================================

That's it. Also, if you're lazy and want to try out my automated script of grabbing the display and input ids automatically and running xinput_calibrator, I did try and write one. It may/may not parse properly, but you can always tweak it. You'll still need to do the restore calibration part manually. You can name this file calibrate_touch.sh:

#!/bin/bash

get_connected_display_ids() {

xrandr | grep " connected" | cut -f1 -d" " | tr "\n" " "

}

get_tablet_display_id() {

xrandr | grep "DP" | grep "1440x900" | cut -f1 -d" "

}

get_tablet_input_id() {

xinput_calibrator --list | grep "UC-Logic 19" | cut -f2 -d"="

}

turnoff() {

id="${1}"

xrandr --output "${id}" --off

}

turnon() {

id="${1}"

xrandr --output "${id}" --auto

}

CONNECTED_IDS="$(get_connected_display_ids)"

DISPLAY_ID="$(get_tablet_display_id)"

INPUT_ID="$(get_tablet_input_id)"

# Power off other displays

for id in ${CONNECTED_IDS}; do

if [ "${id}" != "${DISPLAY_ID}" ]; then

turnoff "${id}"

fi

done

xinput map-to-output "${INPUT_ID}" "${DISPLAY_ID}"

xinput_calibrator \

--device ${INPUT_ID} \

--verbose \

--output-type xorg.conf.d \

--precalib -54 32210 137 20332

# Power on other displays

for id in ${CONNECTED_IDS}; do

if [ "${id}" != "${DISPLAY_ID}" ]; then

turnon "${id}"

fi

done

xinput map-to-output "${INPUT_ID}" "${DISPLAY_ID}"[Updated 2016-06-04]Getting Right Click to work
If you're like me and you need to remap the stylus buttons, do the following:

Create the following file /usr/share/X11/xorg.conf.d/52-tablet.conf with the following contents: