H-M-H / Weylus

Use your tablet as graphic tablet/touch screen on your computer.
Other
7.08k stars 282 forks source link

Stylus and touch support on windows #17

Open H-M-H opened 4 years ago

H-M-H commented 4 years ago

Right now only the mouse can be controlled, things like pressure or touch events are not handled. I do not run windows myself and thus will most likely not implement this, but if someone else is up to the task here is what needs to be done:

Implement the InputDevice trait: https://github.com/H-M-H/Weylus/blob/master/src/input/device.rs, send_event is called on every PointerEvent sent from the browser. The PointerEvent type is defined in https://github.com/H-M-H/Weylus/blob/master/src/protocol.rs. x and y coordinates of the events are normalized to a range between 0 and 1, have a look at https://github.com/H-M-H/Weylus/blob/master/ts/lib.ts.

Once a struct that implements this trait is done (should be in its own file in https://github.com/H-M-H/Weylus/blob/master/src/input/), it has to be instantiated in https://github.com/H-M-H/Weylus/blob/master/src/websocket.rs setup.

Probably useful:

qdlmcfresh commented 3 years ago

I wanted to implement this but i cant figure out how to build weylus on windows. I installed wsl and the dependencies there but building ffmpeg and the tsc call always fail ...
So i thought ill at least share my findings. For Pens windows has an api to create a synthetic pointer device and inject pointer movements.
winapi-rs supports these apis With winapi-rs the api calls look like this:

use winapi::shared::windef::{HWND, POINT};
use winapi::um::winuser::*;
unsafe { 
    let syntheticPointerDeviceHandle = CreateSyntheticPointerDevice(PT_PEN, 1, 1)
    let mut pointerTypeInfo = POINTER_TYPE_INFO {
                type_: PT_PEN,
                u: std::mem::zeroed(),
    };
    // Fill this struct with the information from PointerEvent and call InjectSyntheticPointerInput for every PointerEvent
    *pointerTypeInfo.u.pen_info_mut() = POINTER_PEN_INFO {
                pointerInfo: POINTER_INFO {
                    pointerType: PT_PEN,
                    pointerId: event.pointer_id,
                    frameId: 0,
                    pointerFlags: POINTER_FLAG_INRANGE
                        | POINTER_FLAG_INCONTACT
                        //| POINTER_FLAG_FIRSTBUTTON
                        | POINTER_FLAG_PRIMARY,
                    sourceDevice: 0 as *mut winapi::ctypes::c_void, //maybe use syntheticPointerDeviceHandle here but works with 0
                    hwndTarget: 0 as HWND,
                    ptPixelLocation: POINT { x: x, y: y },
                    ptHimetricLocation: POINT { x: 0, y: 0 },
                    ptPixelLocationRaw: POINT { x: x, y: y },
                    ptHimetricLocationRaw: POINT { x: 0, y: 0 },
                    dwTime: 0,
                    historyCount: 1,
                    InputData: 0,
                    dwKeyStates: 0,
                    PerformanceCount: 0,
                    ButtonChangeType: POINTER_CHANGE_NONE,
                },
                penFlags: PEN_FLAG_NONE,
                penMask: PEN_MASK_PRESSURE | PEN_MASK_ROTATION | PEN_MASK_TILT_X | PEN_MASK_TILT_Y,
                pressure: event.pressure,
                rotation: 0,
                tiltX: event.tiltx,
                tiltY: event.tilty,
            };
    InjectSyntheticPointerInput(syntheticPointerDeviceHandle, &pointerTypeInfo, 1);
}
H-M-H commented 3 years ago

Awesome, thanks a lot for the effort! I think the best course of action is to somehow get Weylus building on your system as you can also properly test if everything is working fine.

I installed wsl and the dependencies there but building ffmpeg and the tsc call always fail

Yeah, sadly building on Windows, especially ffmpeg is a massive pain (needs bash for example...) and github's Windows environment is a rather special beast. As a stopgap measure you can use the build artifacts from here: https://github.com/H-M-H/Weylus/actions/runs/1499946104#artifacts. Just place the dist folder into the deps folder of Weylus, like that you don't need to build ffmpeg yourself. As for tsc: copy the lib.js file from within the www folder over into the Weylus folder and disable tsc in the build script by commenting these lines: https://github.com/H-M-H/Weylus/blob/e23d3b9133abbe7e43e27b15aecfa436158b8033/build.rs#L35-L59

This should get you building. And thanks for looking into this again!

qdlmcfresh commented 3 years ago

Ok i got it building now. Thanks

qdlmcfresh commented 3 years ago

The coordinates are way off (this is on my second screen, while weylus is capturing my primary screen) but its something weylus2

H-M-H commented 3 years ago

Awesome! Feel free to open a pull request once you want some code reviewing.

qdlmcfresh commented 3 years ago

Im currently trying to figure out multimonitor support... but autopilot only supports the primary monitor. this lib seems promising though. Getting winapi to spit out the number of connected monitors was another rabbithole šŸ˜µā€šŸ’«

H-M-H commented 2 years ago

Thanks to @qdlmcfresh's hard work we now have support for a stylus/pen and multiple monitors on Windows! I encourage everyone subscribed to this issue to give it a try and report back here: #128. The build can be found here: https://github.com/H-M-H/Weylus/suites/4497283181/artifacts/120013116

edemaine commented 2 years ago

Exciting progress! I just gave this a try, using an Android phone with stylus support (Note 8) on a Windows 10 machine, using Windows Journal, Photoshop, and my own web software on Chrome, all of which support pressure sensitivity (e.g. when using my Wacom tablet). In all cases, I'm getting the behavior of pen strokes, but as if the pressure is set to (close to) zero.

Investigating further, I ran this helpful demo (in Chrome), and I'm getting the following kind of output when pushing hard with the pen:

image

The good news is that the tilt angles look accurate — very cool! The pressure sensitivity seems to be scaled down though; at full pressure, I'm getting about 0.09 through Weylus, whereas if I run the same app on Chrome for Adnroid, I get about 0.9. Perhaps a factor of 10 somewhere?

qdlmcfresh commented 2 years ago

yes for some reason i thought its 0-100 on windows so im scaling with 100. its 0-1024 though grafik

I hope this fixes it https://github.com/H-M-H/Weylus/pull/128/commits/ebdd6ca8c4f1533f0ee0e0a4793b8fc6aa62027c

qdlmcfresh commented 2 years ago

Investigating further, I ran this helpful demo (in Chrome), and I'm getting the following kind of output when pushing hard with the pen:

This demo seems really helpful thanks :)

Pressing really hard on my Note10 now gives me this: grafik

qdlmcfresh commented 2 years ago

@edemaine this build should have working pressure

edemaine commented 2 years ago

Looks great! Here's a Note 8 controlling a Windows 10 machine running Cocreate:

image

Schischu commented 2 years ago

Hi, i just tested the latest build (https://github.com/H-M-H/Weylus/pull/128) with my Tab S 6. In principal it works, however the pen already starts drawing when 4cm away from screen and I dont really see any change in pressure. Tested in Microsoft Whiteboard app.

I also ran the demo here: https://patrickhlauke.github.io/touch/pen-tracker/ When hovering 4cm away: image When having light pressure: image When pressing as hard as possible: image

Seems to me that apps are already drawing when pressure is 0.

Am I using the wrong apps or is there a bug ? Thanks.

Schischu commented 2 years ago

If I use the test app directly on the tablet pressure goes from 0 to 1.0. -> factor 100 missing to windows. Also "buttons" is 0 as long as the pen is not touching the screen and 1 after touching the screen. -> buttons is not correctly reflected.

Schischu commented 2 years ago

@qdlmcfresh With your build here https://github.com/H-M-H/Weylus/suites/4510850264/artifacts/120521424 pressure is ok, so I guess its a regression in one of the newer commits of the pull request. However "buttons" is also wrongly mapped in that build.

qdlmcfresh commented 2 years ago

Will have a look

qdlmcfresh commented 2 years ago

@Schischu you are right about the pressure. seems like i accidentally reverted the commit that corrected pressure :face_with_spiral_eyes:

qdlmcfresh commented 2 years ago

Hi, i just tested the latest build (#128) with my Tab S 6. In principal it works, however the pen already starts drawing when 4cm away from screen and I dont really see any change in pressure. Tested in Microsoft Whiteboard app.

Its interesting that you can draw without touching. On my end i dont even receive any pointer events while hovering above the screen with my stylus. Im using a Note 10 with Chrome. I get the hovering pointer indicator on my phone screen but no events get sent to my windows device. What browser are you unsing @Schischu

edit: Just tried it with firefox on android and it seems like pen support is missing? I only get it to send mouse and touch events ... Hovering is supported there though ...

H-M-H commented 2 years ago

Yeah, Firefox on Android doesn't have pen support, I even filed an issue for that: https://bugzilla.mozilla.org/show_bug.cgi?id=1702482

Schischu commented 2 years ago

I am using Chrome on Android 11. Yep if you are 4cm away the tablet starts showing an icon of the position of the pen but only if you actually touch the screen it will start to draw/interact with the application.

qdlmcfresh commented 2 years ago

If I use the test app directly on the tablet pressure goes from 0 to 1.0. -> factor 100 missing to windows. Also "buttons" is 0 as long as the pen is not touching the screen and 1 after touching the screen. -> buttons is not correctly reflected.

I have the exact same behaviour directly on android.

https://user-images.githubusercontent.com/10837173/145392654-8e1c1244-6353-4e45-9624-7d2ba51b8ff0.mp4

https://user-images.githubusercontent.com/10837173/145394419-26ab2bc9-f797-477a-a6d9-5aae689ba220.mp4

Schischu commented 2 years ago

Here my recording with first hovering and only after a couple of seconds touching the screen. Hope this helps. https://user-images.githubusercontent.com/145518/145586742-1752f2d7-1a84-49f5-af96-89161d992981.mp4

Schischu commented 2 years ago

Quick fix for getting hover working is checking for the pressure value before setting INCONTACT. With this Windows even shows the hovering of the stylus.

        let mut pointer_flags = match event.event_type {
            PointerEventType::DOWN => {
                POINTER_FLAG_INRANGE | POINTER_FLAG_DOWN
            }
            PointerEventType::MOVE => {
                POINTER_FLAG_INRANGE | POINTER_FLAG_UPDATE
            }
            PointerEventType::UP => POINTER_FLAG_UP,
            PointerEventType::CANCEL => {
                POINTER_FLAG_INRANGE | POINTER_FLAG_UPDATE | POINTER_FLAG_CANCELED
            }
        };
        if event.is_primary {
            pointer_flags |= POINTER_FLAG_PRIMARY;
        }
        match event.pointer_type {
            PointerType::Pen => {
                unsafe {
                    let mut pointer_type_info = POINTER_TYPE_INFO {
                        type_: PT_PEN,
                        u: std::mem::zeroed(),
                    };

                    if event.pressure != 0.0 {
                        pointer_flags |= POINTER_FLAG_INCONTACT;
                    }

                    *pointer_type_info.u.penInfo_mut() = POINTER_PEN_INFO {
                        pointerInfo: POINTER_INFO {
                            pointerType: PT_PEN,

There is possibly a cleaner way of doing this as buttons is NONE if hovering, and PRIMARY if in contact. Hovering: WARN weylus::input::autopilot_device_win: Event. event=PointerEvent { event_type: MOVE, pointer_id: 2, timestamp: 6775800, is_primary: true, pointer_type: Pen, button: NONE, buttons: NONE, x: 0.2605376005172729, y: 0.6788673213624155, movement_x: 1, movement_y: 1, pressure: 0.0, tilt_x: 0, tilt_y: 18, twist: 0, width: 0.0006910911244949609, height: 0.0006910911244949609 }

Incontact: WARN weylus::input::autopilot_device_win: Event. event=PointerEvent { event_type: MOVE, pointer_id: 2, timestamp: 38949800, is_primary: true, pointer_type: Pen, button: NONE, buttons: PRIMARY, x: 0.623295259475708, y: 0.1239082072855886, movement_x: -4, movement_y: 7, pressure: 0.4495726823806762, tilt_x: 23, tilt_y: -31, twist: 0, width: 0.0, height: 0.0 }

Also gonna look into how the Button on the Pen can be used as an Eraser, like how it behaves on the Tab S6. However could be that this is not generic behavior as Samsung implemented this function before Eraser on Pens were a common functionality.

H-M-H commented 2 years ago

Yeah, better use button state to detect hovering. About buttons: The situation is somewhat complicated, some pens have a barrel button that often acts as eraser but browsers don't consider it as one, see https://github.com/H-M-H/Weylus/issues/66#issuecomment-799002061. Then there are actual eraser buttons typically located at the back of the pen, which work fine.

qdlmcfresh commented 2 years ago

https://github.com/H-M-H/Weylus/pull/128/commits/574c37ae50fa5badaad1257cdcf78f4b406e7ac2 should fix hovering. @Schischu thanks for your investigation. Sry for not answering, i had to fix my windows machine šŸ˜…

0lm commented 2 years ago

Not sure if this is the right section, but last time (a year ago maybe) I used Weylus on my Windows 10 Pc and everything worked. I was writing with my Stylus Pen in Xournal, Paint and other Apps without problems. But I put the software aside, because it had huge delays back then.

Now testing again, the Pen feature is barely working. At first try it only did extremely straight lines (couldnt write curves or other shapes, only perfect lines were possible). At 2nd try, it never wrote again. Couldnt use Pen Mode anymore to write in Programs like Xournal++ etc.

Anyone knows where the problem could be? Is it because of my Tablet Updates? Or is it because of newest Weylus Version?

qdlmcfresh commented 2 years ago

Not sure if this is the right section, but last time (a year ago maybe) I used Weylus on my Windows 10 Pc and everything worked. I was writing with my Stylus Pen in Xournal, Paint and other Apps without problems. But I put the software aside, because it had huge delays back then.

Now testing again, the Pen feature is barely working. At first try it only did extremely straight lines (couldnt write curves or other shapes, only perfect lines were possible). At 2nd try, it never wrote again. Couldnt use Pen Mode anymore to write in Programs like Xournal++ etc.

Anyone knows where the problem could be? Is it because of my Tablet Updates? Or is it because of newest Weylus Version?

Try the build linked in this comment. Stylus support for windows actively worked on. https://github.com/H-M-H/Weylus/issues/17#issuecomment-993648595

melwazir commented 1 year ago

Hello. First of all I want to thank you for an excellent project. My problem is also no pen pressure on windows 10 and iPad Pro. I tried safari and chrome. Is there a previous release that used to work?

Edit: the "build" linked to in the previous comment turned out to be a commit, and is apparently orphaned too.

Edit2: Never mind. Found this release and pen pressure is working! Thanks everyone for a truly amazing piece of software!

mson1509 commented 6 months ago

Thanks to @qdlmcfresh's hard work we now have support for a stylus/pen and multiple monitors on Windows! I encourage everyone subscribed to this issue to give it a try and report back here: #128. The build can be found here: https://github.com/H-M-H/Weylus/suites/4497283181/artifacts/120013116

Sorry i know its been a few years, but the link for the build is not working. Is there anyway I can find the build that support stylus for Windows? Thank you very much

melwazir commented 6 months ago

Check out my previous comment.

qdlmcfresh commented 6 months ago

Thanks to @qdlmcfresh's hard work we now have support for a stylus/pen and multiple monitors on Windows! I encourage everyone subscribed to this issue to give it a try and report back here: #128. The build can be found here: https://github.com/H-M-H/Weylus/suites/4497283181/artifacts/120013116

Sorry i know its been a few years, but the link for the build is not working. Is there anyway I can find the build that support stylus for Windows? Thank you very much

Yep as melwazir said already, this build should work https://github.com/kotaewing/Weylus/releases/download/V1.1/windows.zip

vpontikes commented 2 months ago

Hello! Thank you for creating such a cool project! :) I tried using the above build (with Windows 11 and iPad Pro) but pen pressure is not being detected. Is there some way this could be fixed?

qdlmcfresh commented 2 months ago

Hello! Thank you for creating such a cool project! :) I tried using the above build (with Windows 11 and iPad Pro) but pen pressure is not being detected. Is there some way this could be fixed?

I havent worked on this for 3 years since the repo is pretty much abandoned. I can definitely see if still works with my hardware sometime this week and we can work our way up from there. (Given I can even get it to build šŸ™ƒ)

Diordany commented 2 months ago

@qdlmcfresh if you decide to look into this and you're having trouble with the building process, maybe you can ask around at WeylusCommunityEdition, the repo has working builds for various platforms.

If you're using Arch I might be able to help directly.

qdlmcfresh commented 2 months ago

Well i can confirm pen pressure works for my samsung devices with the latest build of weylus community. Since i dont have any apple devices to test on im rather clueless. Maybe safari doesnt send pressure data? @vpontikes maybe you can test around a bit with this https://patrickhlauke.github.io/touch/pen-tracker/ and compare the values when you run it directly on your ipad and when you have it open on your windows machine and control it via weylus.

H-M-H commented 2 months ago

I've had a some time to work on Weylus again. A build including the changes proposed in #128 can be found here: https://github.com/H-M-H/Weylus/actions/runs/11022895787

It also includes some other changes like updated dependencies and a new library for websockets.