linuxwacom / xf86-input-wacom

X.Org driver for Wacom devices
356 stars 46 forks source link

Pen tilt issue on (non Wacom) GPD Pocket 3 #291

Closed michimussato closed 11 months ago

michimussato commented 1 year ago

Hello everybody

I'm not sure if this is the right place to find a solution, but hopefully a starting point. The main reason why I'm starting here is because I'm using the Wacom driver:

[michael@pocket3 ~] $ cat /etc/X11/xorg.conf.d/99-touchscreen.conf 
# https://wiki.archlinux.org/title/GPD_Pocket_3#Touchscreen_and_Digitizer

Section "InputClass"
  Identifier    "calibration"
  Driver        "wacom"
  MatchProduct  "GXTP7380"
  Option        "TransformationMatrix" "0 1 0 -1 0 1 0 0 1"
  Option        "Button2" "3"
EndSection

My issue: Krita does recognize a tilted pen (Microsoft Surface Pen) on the internal touch screen of a GPD Pocket 3 UMPC.

[michael@pocket3 ~] $ xinput list
⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   [...]
⎜   ↳ GXTP7380:00 27C6:0113 touch               id=10   [slave  pointer  (2)]
⎜   ↳ GXTP7380:00 27C6:0113 Stylus stylus       id=11   [slave  pointer  (2)]
⎜   ↳ GXTP7380:00 27C6:0113 Stylus eraser       id=14   [slave  pointer  (2)]
⎜   ↳ [...]

However, if i twist/turn the pen clockwise, Krita reads a counterclockwise rotation.

I went a bit through the code here (linuxwacom/xf86-input-wacom and linuxwacom/input-wacom) and found some clues about ABS_TILT_X and ABS_TILT_Y values being processed, however, I'm not a C programmer so I'm a bit lost.

Thank you for your help, Michael

whot commented 1 year ago

/me squints at the config file

So, if I read this right you are rotating the tablet by 180 degrees - but that rotation is done for x/y in the server. The tilt (handled by the driver) is still in original rotation. I think you should be able to get what you want by using Option "Rotate" "half" instead of the transformation matrix. That's handled in the driver and the tilt rotation should rotate along with that.

michimussato commented 1 year ago

Thanks @whot , I'll give that a shot. A workaround I had so far (which works for some situations, but not for all) was to configure Krita brushes indivitually like soinverting the tilt direction curve:

Screenshot from 2023-01-26 10-33-59

Your solution seem more likely to be a REAL solution. I'll get back with my results.

michimussato commented 1 year ago

Well, actually, while being at it, it seems that another bug has disappeared after yesterdays system update (or the switch from 5.14 to 5.19, not entirely sure yet)...I had the problem that when I pressed the stylus onto the screen, the was interpreted as PRESS->RELEASE->PRESS which automatically lead to double clicks. That meant that even simply moving a window by its title bar maximized it, which was very annoying. In case that bug is not really gone yet, I'll investigate further and maybe open a separate issue.

michimussato commented 1 year ago

I hope that this sheds a bit more light into this topic. The behavior shown first is the correct one, the three subsequent examples are incorrect. I was not able to solve the wrong orientation using the Krita brush tilt settings - it wouldn't address the source of the issue anyway. https://youtu.be/hFMjOWI9p0M

This is how the orientation/transformation/mapping is controlled:

### STATES (ACCORDING TO 2in1screen)
# 0
# 1 180
# 2 90 CW
# 3 270 CW

# o = camera position

# STATE 0
# --------
# |     o|
# |      |
# |      |
# --------
#
# STATE 1
# --------
# |      |
# |      |
# |o     |
# --------
#
# STATE 2
# -------------
# |o          |
# |           |
# -------------
#
# STATE 3
# -------------
# |           |
# |          o|
# -------------

# GXTP7380:00 27C6:0113 STATE0
alias set_state0_stylus="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus stylus\" \"Rotate\" \"none\""
alias set_state0_eraser="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus eraser\" \"Rotate\" \"none\""
alias set_state0_touch="xsetwacom set \"GXTP7380:00 27C6:0113 touch\" \"Rotate\" \"none\""
alias set_state0_stylus_mapping="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus stylus\" \"MapToOutput\" \"DSI1\""
alias set_state0_eraser_mapping="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus eraser\" \"MapToOutput\" \"DSI1\""
alias set_state0_touch_mapping="xsetwacom set \"GXTP7380:00 27C6:0113 touch\" \"MapToOutput\" \"DSI1\""

# GXTP7380:00 27C6:0113 STATE1
alias set_state1_stylus="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus stylus\" \"Rotate\" \"half\""
alias set_state1_eraser="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus eraser\" \"Rotate\" \"half\""
alias set_state1_touch="xsetwacom set \"GXTP7380:00 27C6:0113 touch\" \"Rotate\" \"half\""
alias set_state1_stylus_mapping="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus stylus\" \"MapToOutput\" \"DSI1\""
alias set_state1_eraser_mapping="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus eraser\" \"MapToOutput\" \"DSI1\""
alias set_state1_touch_mapping="xsetwacom set \"GXTP7380:00 27C6:0113 touch\" \"MapToOutput\" \"DSI1\""

# GXTP7380:00 27C6:0113 STATE2
alias set_state2_stylus="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus stylus\" \"Rotate\" \"cw\""
alias set_state2_eraser="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus eraser\" \"Rotate\" \"cw\""
alias set_state2_touch="xsetwacom set \"GXTP7380:00 27C6:0113 touch\" \"Rotate\" \"cw\""
alias set_state2_stylus_mapping="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus stylus\" \"MapToOutput\" \"DSI1\""
alias set_state2_eraser_mapping="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus eraser\" \"MapToOutput\" \"DSI1\""
alias set_state2_touch_mapping="xsetwacom set \"GXTP7380:00 27C6:0113 touch\" \"MapToOutput\" \"DSI1\""

# GXTP7380:00 27C6:0113 STATE3
alias set_state3_stylus="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus stylus\" \"Rotate\" \"ccw\""
alias set_state3_eraser="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus eraser\" \"Rotate\" \"ccw\""
alias set_state3_touch="xsetwacom set \"GXTP7380:00 27C6:0113 touch\" \"Rotate\" \"ccw\""
alias set_state3_stylus_mapping="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus stylus\" \"MapToOutput\" \"DSI1\""
alias set_state3_eraser_mapping="xsetwacom set \"GXTP7380:00 27C6:0113 Stylus eraser\" \"MapToOutput\" \"DSI1\""
alias set_state3_touch_mapping="xsetwacom set \"GXTP7380:00 27C6:0113 touch\" \"MapToOutput\" \"DSI1\""

Any ideas? Is it more related to https://github.com/linuxwacom/input-wacom?

whot commented 1 year ago

oh, ok, now I get it. this is a built-in tablet, so the driver doesn't (shouldn't) actually do rotation in this case. The rotation is for external tablets that are used in left-handed mode (==upside down) or in some more niche cases at 90 deg angles.

The coordinate transformation matrix is to change the device from what is normally, relative to the screen. In your case you shouldn't need it since the X server (in the randr code probably, I don't remember) rotates the input coordinates along with the display.

But that rotation doesn't apply to other axes because the X server doesn't know what the other axes mean, they're just numbered axes with magic values in them. So the server cannot rotate tilt because it doesn't know which axis is tilt, let alone what tilt is.

tbh, I'm not sure what the solution to this would be. The driver doesn't know the device is rotated. The server doesn't know it needs to be rotated. There's no API to go either way to tell the other part what's happening. API could be added but I'm not liking my chances on the amount of effort this would require... So yeah, not looking good right now, tbh.

michimussato commented 1 year ago

Thanks @whot for your thoughts. I understand that the effort required to overcome a minor issue like this one can hardly be justified - impossible for me to even grasp the depth or where to actually look for a solution. Glad I was able to show the issue a bit better for you to get the idea so that we can keep that in the back of our heads :)

Pinglinux commented 11 months ago

I guess we wait for someone knows the display and tablet to fix it.