kurikaesu / userspace-tablet-driver-daemon

Linux device drivers for non-wacom (XP-Pen, Huion, Gaomon) graphics tablets and pen displays
GNU General Public License v3.0
65 stars 16 forks source link

2308: (XP-Pen Deco Pro M), touch pad not working #41

Closed mknj closed 2 years ago

mknj commented 2 years ago

I need to change

-    if (interfaceId == 0)
+    if (interfaceId == 2)

in deco_pro_medium::attachDevice to get the round touch pad working. Otherwise uinputPointers[handle] is 0 in deco_pro::handleNonUnifiedFrameEvent() and the daemon writes binary data to std::cout.

I am using latest git source.

My device is 28bd:0904 XP-Pen 11 inch PenTablet The daemon reports Set up config for device 2308: (XP-Pen Deco Pro M)

After adapting the config to my german keyboard everything seems to work fine with the above modification.

btw: why are there two dials in the 2308 config? Do some devices transform touch pad actions to the second dial directly?

I'd like to use gestures on the touch pad in order to change i.e. the brush size. What would be the best way in order to implement such a feature? Moving the mouse cursor is not a relevant feature for me. For me events for up/down, left/right and cw/ccw would be enough.

kurikaesu commented 2 years ago

The Deco Pro series has a touch pad and a scroll-ring/dial. The touch pad can be configured to emulate a scroll-ring/dial as well by setting to either scroll or to customized.

In order for you to be able to use the touch pad to change brush size, you would need to set it to customized and then set the appropriate bindings for dial->left and dial->right.

What my driver does not recognize is "gestures" while in mouse mode as it is 100% a touchpad/mouse in that mode.

mknj commented 2 years ago

I managed to start the ui and set the touchdial to +/- (the outer dial is ctrl + +/-) However i see no + - appear in the terminal when i try the circle guestures. When i add the 29 (KEY_LEFTCTRL) the touch dial still does nothing.

"dials":{"6":{"1":{"1":[27],"3":[]},"-1":{"1":[53],"3":[]}},"8":{"1":{"1":[29,27]},"-1":{"1":[29,53]}}}
mknj commented 2 years ago

Still binary data is written to the terminal. Even with the above dials config. Is there an other section of the config file relevant?

mknj commented 2 years ago

ok, using the tag v0.1.3 touch-pad-as-mouse is working. No binary data written to stdout. However i still can not switch to dial mode.

kurikaesu commented 2 years ago

How are you executing the daemon? From the logs in the issue you posted on the GUI it says: Is the driver not running? Could not connect to it

That leads me to think that you are executing the daemon as root (maybe through sudo)? The daemon needs to be executed as your non-root user otherwise the GUI can't connect as the location of the socket file is relative to the current user. You would have to run the GUI as root if you were running the daemon as root.

The only way right now to switch to dial mode is to either get the GUI working and click the config buttons that will switch modes, or to plug your tablet into a Windows/Mac computer and use the official driver to set the touch pad to dial. Either way you do it the tablet will retain that setting when plugged into other devices so it only needs to be done once.

kurikaesu commented 2 years ago

I've created a new issue here https://github.com/kurikaesu/userspace-tablet-driver-daemon/issues/42 to track preventing a user from running the driver as root

mknj commented 2 years ago

i am not running as root. I retried now and the device selection window opened and showed the name of the tablet, but the app freezed and SEG_FAULTED after some seconds. The gui issue is not that important for me. i can edit the json directly. Sending the events to 0 (stdout) in the main branch is more of an issue.

kurikaesu commented 2 years ago

I don't see the events being shown in stdout:

https://user-images.githubusercontent.com/6769666/147299631-342df63d-fa3e-48b3-8c3c-69dde0906359.mp4

I am also on the main branch with no modifications compared to origin/github.

The Deco Pro M and S use the same code in my driver. I only own the S version

mknj commented 2 years ago

in the video i do a fresh build and run the daemon. Then i add some debug output to deco_pro.cpp and simply return instead of writing to the fd. The tablet is in mouse mode.

btw. I think it would be nice to store the mode in the config file and check/change it at every startup of the daemon. This would make configs more reproducable.

https://user-images.githubusercontent.com/4385662/147345300-5365ac76-d491-4562-a678-c27327ea960e.mp4

mknj commented 2 years ago

(the video works in chromium, but not in firefox)

kurikaesu commented 2 years ago

While I could store the mode that you've set in the configuration and apply it every time, the mode is actually stored on the device itself and is kept whenever you switch computers.

I cannot see anywhere in the code that would cause binary to be spit out into console. Every std::cout (and I only use std::cout) is accountable here: https://github.com/kurikaesu/userspace-tablet-driver-daemon/search?p=1&q=std%3A%3Acout

You are going to have to debug where that output is being sent from as it is unlikely that it is the actual driver code that is producing it. If you do find it, fix it and send me a PR if necessary

mknj commented 2 years ago

In linux stdout is an other name for the file descriptor with the number "0".

In xp_pen_unified_device::attachToInterfaceId you only allow to attach to interfaceId 2.

In deco_pro_medium::attachDevice() the pointer is not initialized when the interfaceId is !=0.

In 'deco_pro::handleNonUnifiedFrameEvent' you do uinput_send(uinputPointers[handle], .....); As nothing is stored in uinputPointers[handle], this returns 0. As a result you are calling write(0, &event, sizeof(event)) inside uinput_send, which in turn will print the event in binary form to stdout.

As you are already doing if (productHandlers[productId]->attachToInterfaceId(interface_number)) inside the vendor_handler i do not know why you are also checking the interfaceId inside attachDevice.

If i remove if(InterfaceId == ..) inside attachDevice everything works as expected. Should i do a MR removing the two if() statements?

kurikaesu commented 2 years ago

Hmmn that would not be the correct implementation either though as the pointer (track pad in mouse mode) messages only come from interface id == 0. The regular pen messages and buttons are always on interface 2. The Deco Pro is one of the tablet models that needs to be attached on two interfaces but we do not want to create two instances of pens and two instances of pointers which is why there is a second if inside the attachDevice method to make sure to only create a pen when on interface 2, and only create a pointer when on interface 0.

What needs to change is in xp_pen_unified_device, instead of only attaching to interface 2, set it to true so it attaches to all interfaces rather than just 2. This of course needs a bit of testing on the other devices once the change is done to make sure they still work. That is something I can do once you send a PR though.

kurikaesu commented 2 years ago

An alternative so that the changes only affect the deco pro tablets is to override attachToInterfaceId in deco_pro.cpp and return true for all interfaces (Or just true for interfaceId == 0 and 2). This way it doesn't affect the other XP-Pen tablets.

kurikaesu commented 2 years ago

Closing this issue as it appears to have been resolved by the merge.