Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import of Selkies JS Interposer for WebRTC to Linux Joystick support #95

Merged
merged 2 commits into from
Sep 22, 2023

Conversation

danisla
Copy link
Member

@danisla danisla commented Sep 20, 2023

Fixes #90
Fixes #55

New features

Import of Selkies JS Interposer for WebRTC to Linux Joystick support without uinput dependency

  • LD_PRELOAD syscall interposer to emulate gamepads.
  • Intercepts open() requests to /dev/input/jsX devices.
  • Interposer connects to selkies unix domain socket.
  • Interposer writes log to /tmp/selkies_js.log
  • Selkies WebRTC app sends Javascript gamepad events to socket.
  • Up to 4 simultaneous gamepads supported from WebRTC.
  • Build as debian package and installed to /usr/local/lib/selkies-js-interposer/joystick_interposer.so
  • Dev container updated to auto-load interposer.
  • Update to github workflow to build and publish image and release asset.
  • Add joystick interposer to example Dockerfile

Add turnserver to example docker image

  • Helps with initial connectivity in environments like WSL with Docker.
  • Can be overridden with env vars or cli args.

Supported Gamepads

I've tested this with apps like retroarch and it seems to work well.

Currently only Xpad like gamepads are emulated for the button and axes mapping.

I've tested with the following controllers:

  • Xbox Series X/S Controller
  • Stadia Controller
  • 8Bitdo SN30 PRO

Others will surely work just fine, especially if they have similar button layouts to an Xpad.

Please let me know if there is a gamepad that doesn't work and we can try to accommodate.

Testing

The testing branch has been built with the new joystick interposer pre-installed and added to the default LD_PRELOAD environment variable. This branch also contains the integrated turnserver to the example container, hence the new port 3478 to the docker run command.

You can test it with the example docker container like this:

Ubuntu 22.04

docker run --pull=always --name selkies -it --rm -p 8080:8080 -p 3478:3478 ghcr.io/selkies-project/selkies-gstreamer/gst-py-example:testing-ubuntu22.04

For Ubuntu 20.04:

docker run --pull=always --name selkies -it --rm -p 8080:8080 -p 3478:3478 ghcr.io/selkies-project/selkies-gstreamer/gst-py-example:testing-ubuntu20.04

Usage

  1. Connect to the web interface.
  2. Connect a gamepad to your local computer.
  3. Press any button on the gamepad to connect it to the web interface.
  4. In the remote session, run a program like jstest-gtk to verify you see the Selkies Controller
  5. Connect up to 4 total gamepads using the same method.
    Selkies Gamepad Test

The example docker image has these environment variables set:

export LD_PRELOAD=/usr/local/lib/selkies-js-interposer/joystick_interposer.so
export SDL_JOYSTICK_DEVICE=/dev/input/js0

The entrypoint script also creates fake jsX files in /dev/input like below to help programs that try to list the /dev/input directory discover the joystick devices:

sudo mkdir -p /dev/input
sudo touch /dev/input/{js0,js1,js2,js3}

Some software programs use different methods to discover linux joysticks. The LD_PRELOAD method seems to work for most direct linux applications and the SDL_JOYSTICK_DEVICE env var helps with SDL applications.

@ehfd
Copy link
Member

ehfd commented Sep 20, 2023

Wow. This actually works?...

One aspect of testing that should be done is with Wine games and applications.

@ehfd
Copy link
Member

ehfd commented Sep 20, 2023

#28 (comment)

Could this approach be expanded to allow true relative mouse cursors?

@danisla
Copy link
Member Author

danisla commented Sep 20, 2023

Wow. This actually works?...

One aspect of testing that should be done is with Wine games and applications.

If someone can help test, that would be great.

@danisla
Copy link
Member Author

danisla commented Sep 20, 2023

#28 (comment)

Could this approach be expanded to allow true relative mouse cursors?

I think the approach would be similar, yes. My plan is to investigate doing this for mouse emulation later so we can completely remove the dependency on uinput and have full support in container environments.
However, Xorg has a funny way of loading core input devices like Mice and Keyboards so it might have to be a custom X11 module or a full uinput interposer. Either way, that's a separate task from the gamepad support in this PR.

@ehfd
Copy link
Member

ehfd commented Sep 20, 2023

Good to know that the approach is similar with mouse devices.

Unfortunately, I don't have a real gamepad device at the moment and I am having a hard time with time management.

@xhejtman perhaps interested?
Or any of the community.

Copy link
Member

@ehfd ehfd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, looks okay but was just skimming. Made comments.

src/selkies_gstreamer/__main__.py Outdated Show resolved Hide resolved
src/selkies_gstreamer/webrtc_input.py Outdated Show resolved Hide resolved
- LD_PRELOAD syscall interposer to emulate gamepads.
- Intercepts open() requests to /dev/input/jsX devices.
- Interposer connects to selkies unix domain socket.
- Interposer writes log to /tmp/selkies_js.log
- Selkies WebRTC app sends Javascript gamepad events to socket.
- Up to 4 simultaneous gamepads supported from WebRTC.
- Build as debian package and installed to /usr/local/lib/selkies-js-interposer/joystick_interposer.so
- Dev container updated to auto-load interposer.
- Update to github workflow to build and publish image and release asset.
- Add joystick interposer to example Dockerfile
@danisla danisla merged commit 7b3b799 into main Sep 22, 2023
1 check passed
@ehfd
Copy link
Member

ehfd commented Sep 23, 2023

This commit is a great milestone which is a step forward from all known Linux remote desktop implementations working in containers.

@ehfd ehfd deleted the danisla/js-intercept branch April 17, 2024 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants