git: ec671703cada - main - games/moonlight-embedded: update to 2.6.1
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 19 Oct 2023 07:08:20 UTC
The branch main has been updated by fuz: URL: https://cgit.FreeBSD.org/ports/commit/?id=ec671703cada5b2e44de0758dc14199b2fb75596 commit ec671703cada5b2e44de0758dc14199b2fb75596 Author: Armin Zhu <lisp_25689@163.com> AuthorDate: 2023-10-16 14:59:48 +0000 Commit: Robert Clausecker <fuz@FreeBSD.org> CommitDate: 2023-10-19 07:07:28 +0000 games/moonlight-embedded: update to 2.6.1 *Security fixes: Fixed CVE-2023-42799, CVE-2023-42800, and CVE-2023-42801 From: https://github.com/moonlight-stream/moonlight-embedded/releases/tag/v2.6.1 *Optimize the experience of grabing the keyboard. Now,Exclusive grab keyboard is the default behavior.But maybe it doesn't work on the Wayland WM. Use Alt+Ctrl+Shift+Z to grab or ungrab keyboard. *Optimize the experience of using the gamepad on FreeBSD. Replace the libevdev drive gamepad with SDL to ensure maximum compatibility. The rumble on the gamepad may not work. *Update man page. Explanation for changed patch files: *patch-src_config.c: *patch-src_config.h: *patch-src_main.c: *patch-src_input_sdl.c: *patch-src_input_sdl.h: Add -nosdl option and replace the libevdev drive gamepad with SDL. *patch-src_input_evdev.c: *patch-src_input_x11.c: *patch-src_video_x11.c: Add the way to ungrab the keyboard for x11* platform. *patch-src_sdl.c: *patch-src_sdl.h: *patch-src_input_sdl.c: Add the way to ungrab the keyboard for SDL platform. PR: 274452 MFH: 2023Q4 Security: f8c2f741-6be1-11ee-b33a-a04a5edf46d9 --- games/moonlight-embedded/Makefile | 7 +- games/moonlight-embedded/distinfo | 6 +- .../moonlight-embedded/files/patch-docs_README.pod | 77 ++--- games/moonlight-embedded/files/patch-src_config.c | 28 ++ games/moonlight-embedded/files/patch-src_config.h | 10 + .../files/patch-src_input_evdev.c | 195 +++++++++++-- .../moonlight-embedded/files/patch-src_input_sdl.c | 309 +++++++++++++++++++++ .../moonlight-embedded/files/patch-src_input_sdl.h | 8 + .../moonlight-embedded/files/patch-src_input_x11.c | 185 ++++++++++++ games/moonlight-embedded/files/patch-src_main.c | 59 +++- games/moonlight-embedded/files/patch-src_sdl.c | 64 +++++ games/moonlight-embedded/files/patch-src_sdl.h | 19 ++ .../moonlight-embedded/files/patch-src_video_x11.c | 42 +++ ...d__party_moonlight-common-c_enet_CMakeLists.txt | 30 +- 14 files changed, 966 insertions(+), 73 deletions(-) diff --git a/games/moonlight-embedded/Makefile b/games/moonlight-embedded/Makefile index cb5234b0b748..62846f1b23f9 100644 --- a/games/moonlight-embedded/Makefile +++ b/games/moonlight-embedded/Makefile @@ -1,5 +1,5 @@ PORTNAME= moonlight-embedded -DISTVERSION= 2.6.0 +DISTVERSION= 2.6.1 CATEGORIES= games MASTER_SITES= https://github.com/moonlight-stream/moonlight-embedded/releases/download/v${DISTVERSION}/ @@ -34,9 +34,8 @@ NO_WRKSUBDIR= yes CFLAGS+= -DHAS_SOCKLEN_T=1 -I${LOCALBASE}/include/libepoll-shim/ LDFLAGS+= -lepoll-shim -pre-configure: - @${REINPLACE_CMD} -e 's@/etc/moonlight/moonlight.conf@${PREFIX}/etc/moonlight.conf@' \ - -e 's@moonligt@moonlight@g' \ +post-patch: + @${REINPLACE_CMD} -e 's@/usr/local@${PREFIX}@' \ ${WRKSRC}/docs/README.pod post-install: diff --git a/games/moonlight-embedded/distinfo b/games/moonlight-embedded/distinfo index 40634ce7451a..d28e65f19dbf 100644 --- a/games/moonlight-embedded/distinfo +++ b/games/moonlight-embedded/distinfo @@ -1,3 +1,3 @@ -TIMESTAMP = 1695536824 -SHA256 (moonlight-embedded-2.6.0.tar.xz) = 71c883e10c65085c82a75c9affaef5e63f43d9074df74d48039d8c9b83120df7 -SIZE (moonlight-embedded-2.6.0.tar.xz) = 324572 +TIMESTAMP = 1697067500 +SHA256 (moonlight-embedded-2.6.1.tar.xz) = 1a252e18ac637e0ad7180238fa868e04629a3d8e43232097d5ccaa3b4142fded +SIZE (moonlight-embedded-2.6.1.tar.xz) = 327632 diff --git a/games/moonlight-embedded/files/patch-docs_README.pod b/games/moonlight-embedded/files/patch-docs_README.pod index f19916d281e1..4763811ca71f 100644 --- a/games/moonlight-embedded/files/patch-docs_README.pod +++ b/games/moonlight-embedded/files/patch-docs_README.pod @@ -1,18 +1,26 @@ ---- docs/README.pod.orig 2023-09-01 23:40:56 UTC +--- docs/README.pod.orig 2023-10-11 15:50:11 UTC +++ docs/README.pod -@@ -27,6 +27,11 @@ Stream game from host to this computer. +@@ -13,7 +13,10 @@ Usage: I<moonlight> E<lt>actionE<gt> [options] [host] - List all available games and application on host. + =item B<pair> -+=item B<discover> -+ -+Discover moonlight server host.Need start avahi-daemon first. -+NOTE:It's not work under wifibox. -+ - =item B<quit> +-Pair this computer with the host. ++ Pair this computer with the host. ++ If [host] is not specified here,moonlight will auto discover host first. ++ It's need start avahi-daemon first. ++ NOTE:It's not work under wifibox. + + =item B<unpair> + +@@ -22,6 +25,7 @@ Unpair this computer with the host. + =item B<stream> - Quit the current running game or application on host. -@@ -99,9 +104,9 @@ By default, 1392 is used on LAN and 1024 on WAN. + Stream game from host to this computer. ++If [host] is not specified here,moonlight will auto discover host first. + + =item B<list> + +@@ -99,9 +103,9 @@ By default, 1392 is used on LAN and 1024 on WAN. =item B<-codec> [I<CODEC>] Select codec to use. @@ -25,7 +33,7 @@ =item B<-remote> [I<yes/no/auto>] -@@ -138,8 +143,10 @@ By default the gamecontrollerdb.txt provided by Moonli +@@ -138,8 +142,10 @@ By default the gamecontrollerdb.txt provided by Moonli =item B<-platform> [I<PLATFORM>] Select platform for audio and video output and input. @@ -37,19 +45,22 @@ =item B<-nounsupported> Don't stream if resolution is not officially supported by the server -@@ -170,11 +177,6 @@ Enable the I<INPUT> device. +@@ -170,10 +176,11 @@ Enable the I<INPUT> device. By default all available input devices are enabled. Only evdev devices /dev/input/event* are supported. -=item B<-audio> [I<DEVICE>] -- ++=item B<-nosdl> + -Use <DEVICE> as audio output device. -The default value is 'sysdefault' for ALSA and 'hdmi' for OMX on the Raspberry Pi. -- ++Use libevdev to drive game controller instead. ++SDL controller module have better compatibility for gamepad. ++So it's not recommended. + =item B<-windowed> - Display the stream in a window instead of fullscreen. -@@ -182,22 +184,48 @@ Only available when X11 or SDL platform is used. +@@ -182,22 +189,51 @@ Only available when X11 or SDL platform is used. =back @@ -74,32 +85,36 @@ If no user specified configuration file is available the configuration will be loaded from: - /etc/moonlight/moonlight.conf +- /etc/moonlight/moonlight.conf ++ /usr/local/etc/moonlight.conf -A documented example configuration file can be found at /etc/moonlight/moonlight.conf. +A documented example configuration file can be found at /usr/local/etc/moonlight.conf. --=head1 COMMENTS +=head1 KEYBOARD SHORTCUTS - - Use Ctrl+Alt+Shift+Q or Play+Back+LeftShoulder+RightShoulder to quit the streaming session. - ++ ++ Use Ctrl+Alt+Shift+Q or Play+Back+LeftShoulder+RightShoulder to quit the streaming session. ++ Use Ctrl+Alt+Shift+Z to Grab/Ungrab keyboard. ++ It may not grab the keyboard Using sdl platform under wayland. ++ +=head1 GAMEPAD + +FreeBSD supports fewer controllers.Please see hgame(4) xb360gp(4) ps4dshock(4) and FreeBSD forums... +SDL platforms have better compatibility for gamepad. + -+=head1 COMMENTS -+ -+Platform 'sdl' and 'x11' is soft decoding. -+Platform 'x11_vaapi' and 'x11_vdpau' is hard decoding. -+If you want to use GPU decoding,you must meet 3 conditions: -+ 1.Use platform 'x11_vaapi' or 'x11_vdpau'. -+ 2.Use Intel or AMD(not test) GPU driver in xorg.conf + =head1 COMMENTS + +-Use Ctrl+Alt+Shift+Q or Play+Back+LeftShoulder+RightShoulder to quit the streaming session. ++Platform 'sdl' and 'x11' is soft decoding.'x11' is deprecated. ++Platform 'x11_vaapi' and 'x11_vdpau' is hard accel decoding. ++If you want to use GPU decoding for intel gpu,you must meet 3 conditions: ++ 1.Use platform 'x11_vaapi' ++ 2.Use intel GPU driver in xorg.conf but not modesetting. + 3.Install package:libva-intel-driver/libva-intel-media-driver or libva-vdpau-driver. + + =head1 AUTHOR -Iwan Timmer E<lt>irtimmer@gmail.comE<gt> -+Thanks Iwan Timmer and every contributor! -+Armin Zhu E<lt>lisp_25689@163.comE<gt> ++ Thanks Iwan Timmer and every contributor! ++ Armin Zhu E<lt>lisp_25689@163.comE<gt>. diff --git a/games/moonlight-embedded/files/patch-src_config.c b/games/moonlight-embedded/files/patch-src_config.c new file mode 100644 index 000000000000..58b295aad0f0 --- /dev/null +++ b/games/moonlight-embedded/files/patch-src_config.c @@ -0,0 +1,28 @@ +--- src/config.c.orig 2023-10-11 15:50:11 UTC ++++ src/config.c +@@ -42,6 +42,7 @@ + #define write_config_bool(fd, key, value) fprintf(fd, "%s = %s\n", key, value ? "true":"false") + + bool inputAdded = false; ++bool isNoSdl = false; + + static struct option long_options[] = { + {"720", no_argument, NULL, 'a'}, +@@ -49,6 +50,7 @@ static struct option long_options[] = { + {"4k", no_argument, NULL, '0'}, + {"width", required_argument, NULL, 'c'}, + {"height", required_argument, NULL, 'd'}, ++ {"nosdl", no_argument, NULL, 'e'}, + {"bitrate", required_argument, NULL, 'g'}, + {"packetsize", required_argument, NULL, 'h'}, + {"app", required_argument, NULL, 'i'}, +@@ -149,6 +151,9 @@ static void parse_argument(int c, char* value, PCONFIG + break; + case 'd': + config->stream.height = atoi(value); ++ break; ++ case 'e': ++ isNoSdl = true; + break; + case 'g': + config->stream.bitrate = atoi(value); diff --git a/games/moonlight-embedded/files/patch-src_config.h b/games/moonlight-embedded/files/patch-src_config.h new file mode 100644 index 000000000000..f7b36617a241 --- /dev/null +++ b/games/moonlight-embedded/files/patch-src_config.h @@ -0,0 +1,10 @@ +--- src/config.h.orig 2023-10-11 15:50:11 UTC ++++ src/config.h +@@ -51,6 +51,7 @@ typedef struct _CONFIGURATION { + } CONFIGURATION, *PCONFIGURATION; + + extern bool inputAdded; ++extern bool isNoSdl; + + bool config_file_parse(char* filename, PCONFIGURATION config); + void config_parse(int argc, char* argv[], PCONFIGURATION config); diff --git a/games/moonlight-embedded/files/patch-src_input_evdev.c b/games/moonlight-embedded/files/patch-src_input_evdev.c index 5daa32c63111..b93c258415f6 100644 --- a/games/moonlight-embedded/files/patch-src_input_evdev.c +++ b/games/moonlight-embedded/files/patch-src_input_evdev.c @@ -1,6 +1,6 @@ ---- src/input/evdev.c.orig 2023-09-01 23:40:56 UTC +--- src/input/evdev.c.orig 2023-10-11 15:50:11 UTC +++ src/input/evdev.c -@@ -38,10 +38,12 @@ +@@ -38,10 +38,16 @@ #include <limits.h> #include <unistd.h> #include <pthread.h> @@ -9,13 +9,17 @@ #include <math.h> -#if __BYTE_ORDER == __LITTLE_ENDIAN -+bool iskeyboardgrab = true; ++extern bool isNoSdl; ++bool iskeyboardgrab = false; ++void grab_window(bool grabstat); ++static bool waitingToSwitchGrabOnModifierUp = false; ++static bool isgrabkeyrelease = false; + +#if _BYTE_ORDER == _LITTLE_ENDIAN #define int16_to_le(val) val #else #define int16_to_le(val) ((((val) >> 8) & 0x00FF) | (((val) << 8) & 0xFF00)) -@@ -66,8 +68,8 @@ struct input_device { +@@ -66,8 +72,8 @@ struct input_device { int hats_state[3][2]; int fd; char modifiers; @@ -26,7 +30,38 @@ struct timeval touchDownTime; struct timeval btnDownTime; short controllerId; -@@ -343,7 +345,7 @@ static bool evdev_handle_event(struct input_event *ev, +@@ -127,6 +133,7 @@ int evdev_gamepads = 0; + + #define ACTION_MODIFIERS (MODIFIER_SHIFT|MODIFIER_ALT|MODIFIER_CTRL) + #define QUIT_KEY KEY_Q ++#define GRAB_KEY KEY_Z + #define QUIT_BUTTONS (PLAY_FLAG|BACK_FLAG|LB_FLAG|RB_FLAG) + + static bool (*handler) (struct input_event*, struct input_device*); +@@ -139,6 +146,22 @@ static int evdev_get_map(int* map, int length, int val + return -1; + } + ++static short keystatlist[0xFF]; ++static void keyrelease(int keycode) { ++ keystatlist[keycode] = 0; ++} ++static void keypress(int keycode) { ++ keystatlist[keycode] = 1; ++} ++static void freeallkey () { ++ for (int i=0;i<0xFF;i++) { ++ if (keystatlist[i] == 1) { ++ keystatlist[i] = 0; ++ LiSendKeyboardEvent(0x80 << 8 | keyCodes[i], KEY_ACTION_UP, 0); ++ } ++ } ++} ++ + static bool evdev_init_parms(struct input_device *dev, struct input_abs_parms *parms, int code) { + int abs = evdev_get_map(dev->abs_map, ABS_MAX, code); + +@@ -343,7 +366,7 @@ static bool evdev_handle_event(struct input_event *ev, if (dev->mouseHScroll != 0) { LiSendHScrollEvent(dev->mouseHScroll); dev->mouseHScroll = 0; @@ -35,26 +70,142 @@ if (dev->gamepadModified) { if (dev->controllerId < 0) { for (int i = 0; i < MAX_GAMEPADS; i++) { -@@ -813,7 +815,7 @@ void evdev_create(const char* device, struct mapping* - if (mappings == NULL && strstr(name, "Xbox 360 Wireless Receiver") != NULL) - mappings = xwc_mapping; +@@ -398,15 +421,41 @@ static bool evdev_handle_event(struct input_event *ev, + } + + // After the quit key combo is pressed, quit once all keys are raised +- if ((dev->modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && +- ev->code == QUIT_KEY && ev->value != 0) { +- waitingToExitOnModifiersUp = true; +- return true; +- } else if (waitingToExitOnModifiersUp && dev->modifiers == 0) ++ if ((dev->modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && ev->value != 0) { ++ if (ev->code == QUIT_KEY) { ++ waitingToExitOnModifiersUp = true; ++ return true; ++ } else if (ev->code == GRAB_KEY && iskeyboardgrab) { ++ waitingToSwitchGrabOnModifierUp = true; ++ return true; ++ } ++ } ++ if (waitingToSwitchGrabOnModifierUp) { ++ if (ev->code == GRAB_KEY && ev->value == 0) { ++ isgrabkeyrelease = true; ++ if (dev->modifiers != 0) ++ return true; ++ } ++ if (dev->modifiers == 0 && isgrabkeyrelease) { ++ waitingToSwitchGrabOnModifierUp = false; ++ isgrabkeyrelease = false; ++ freeallkey(); ++ grab_window(!iskeyboardgrab); ++ return true; ++ } ++ } else if (waitingToExitOnModifiersUp && dev->modifiers == 0) { ++ freeallkey(); ++ grab_window(false); + return false; ++ } -- bool is_keyboard = libevdev_has_event_code(evdev, EV_KEY, KEY_Q); -+ bool is_keyboard = libevdev_has_event_code(evdev, EV_KEY, KEY_Q) && libevdev_get_id_version(evdev) < 500; - bool is_mouse = libevdev_has_event_type(evdev, EV_REL) || libevdev_has_event_code(evdev, EV_KEY, BTN_LEFT); - bool is_touchscreen = libevdev_has_event_code(evdev, EV_KEY, BTN_TOUCH); ++ if (ev->value) ++ keypress(ev->code); ++ else ++ keyrelease(ev->code); + short code = 0x80 << 8 | keyCodes[ev->code]; + LiSendKeyboardEvent(code, ev->value?KEY_ACTION_DOWN:KEY_ACTION_UP, dev->modifiers); ++ + } else { + int mouseCode = 0; + int gamepadCode = 0; +@@ -749,8 +798,10 @@ static int evdev_handle(int fd) { + struct input_event ev; + while ((rc = libevdev_next_event(devices[i].dev, LIBEVDEV_READ_FLAG_NORMAL, &ev)) >= 0) { + if (rc == LIBEVDEV_READ_STATUS_SYNC) +- fprintf(stderr, "Error: cannot keep up\n"); ++ fprintf(stderr, "Error:%s(%d) cannot keep up\n", libevdev_get_name(devices[i].dev), i); + else if (rc == LIBEVDEV_READ_STATUS_SUCCESS) { ++ if (!iskeyboardgrab) ++ break; + if (!handler(&ev, &devices[i])) + return LOOP_RETURN; + } +@@ -840,7 +891,28 @@ void evdev_create(const char* device, struct mapping* + libevdev_has_event_code(evdev, EV_ABS, ABS_WHEEL) || + libevdev_has_event_code(evdev, EV_ABS, ABS_GAS) || + libevdev_has_event_code(evdev, EV_ABS, ABS_BRAKE)); ++ bool is_acpibutton = ++ is_keyboard && ++ (strcmp(libevdev_get_name(evdev), "Sleep Button") == 0 || ++ strcmp(libevdev_get_name(evdev), "Power Button") == 0); ++ bool is_likekeyboard = ++ is_keyboard && ++ (libevdev_get_id_version(evdev) > 1000 || ++ libevdev_get_id_bustype(evdev) <= 3); -@@ -1055,8 +1057,12 @@ void evdev_start() { ++ // In some cases,acpibutton can be mistaken for a keyboard and freeze the keyboard when tring grab. ++ if (is_acpibutton) { ++ if (verbose) ++ printf("Do Not grab acpibutton: %s\n", libevdev_get_name(evdev)); ++ is_keyboard = false; ++ } ++ // In some cases,tring grab "Logitech USB Receiver Keyboard" will freeze the keyboard. ++ if (is_likekeyboard) { ++ if (verbose) ++ printf("Do Not grab likekeyboard: %s,version: %d,bustype: %d\n", libevdev_get_name(evdev), libevdev_get_id_version(evdev), libevdev_get_id_bustype(evdev)); ++ is_keyboard = false; ++ } ++ + if (is_accelerometer) { + if (verbose) + printf("Ignoring accelerometer: %s\n", name); +@@ -850,6 +922,13 @@ void evdev_create(const char* device, struct mapping* + } + + if (is_gamepad) { ++ if (!isNoSdl) { ++ if (verbose) ++ printf("Gamepad %s ignored,use sdl instead.\n", name); ++ libevdev_free(evdev); ++ close(fd); ++ return; ++ } + evdev_gamepads++; + + if (mappings == NULL) { +@@ -1054,11 +1133,7 @@ void evdev_start() { + // code looks for. For this reason, we wait to grab until // we're ready to take input events. Ctrl+C works up until // this point. - for (int i = 0; i < numDevices; i++) { +- for (int i = 0; i < numDevices; i++) { - if ((devices[i].is_keyboard || devices[i].is_mouse || devices[i].is_touchscreen) && ioctl(devices[i].fd, EVIOCGRAB, 1) < 0) { -+ if ((devices[i].is_mouse || devices[i].is_touchscreen) && ioctl(devices[i].fd, EVIOCGRAB, 1) < 0) { - fprintf(stderr, "EVIOCGRAB failed with error %d\n", errno); -+ } -+ if (devices[i].is_keyboard && libevdev_get_id_bustype(devices[i].dev) > 3) { -+ if (ioctl(devices[i].fd, EVIOCGRAB, 1) < 0) -+ fprintf(stderr, "EVIOCGRAB failed with error %d\n", errno); - } - } +- fprintf(stderr, "EVIOCGRAB failed with error %d\n", errno); +- } +- } ++ grab_window(true); + // Any new input devices detected after this point will be grabbed immediately + grabbingDevices = true; +@@ -1111,4 +1186,23 @@ void evdev_rumble(unsigned short controller_id, unsign + event.value = 1; + write(device->fd, (const void*) &event, sizeof(event)); + device->haptic_effect_id = effect.id; ++} ++ ++void grab_window(bool grabstat) { ++ if (grabstat != iskeyboardgrab) { ++ int grabnum; ++ if (iskeyboardgrab) { ++ grabnum = 0; ++ iskeyboardgrab = false; ++ } else { ++ grabnum = 1; ++ iskeyboardgrab = true; ++ } ++ for (int i = 0; i < numDevices; i++) { ++ if (devices[i].is_keyboard || devices[i].is_mouse || devices[i].is_touchscreen) { ++ if (ioctl(devices[i].fd, EVIOCGRAB, grabnum) < 0) ++ fprintf(stderr, "EVIOCGRAB failed with error %d\n", errno); ++ } ++ } ++ } + } diff --git a/games/moonlight-embedded/files/patch-src_input_sdl.c b/games/moonlight-embedded/files/patch-src_input_sdl.c new file mode 100644 index 000000000000..6b6278d8109e --- /dev/null +++ b/games/moonlight-embedded/files/patch-src_input_sdl.c @@ -0,0 +1,309 @@ +--- src/input/sdl.c.orig 2023-10-08 02:12:37 UTC ++++ src/input/sdl.c +@@ -19,15 +19,23 @@ + + #include "sdl.h" + #include "../sdl.h" ++#include "../loop.h" + ++#include <poll.h> ++#include <fcntl.h> ++#include <unistd.h> + #include <Limelight.h> + + #define ACTION_MODIFIERS (MODIFIER_SHIFT|MODIFIER_ALT|MODIFIER_CTRL) + #define QUIT_KEY SDLK_q + #define QUIT_BUTTONS (PLAY_FLAG|BACK_FLAG|LB_FLAG|RB_FLAG) + #define FULLSCREEN_KEY SDLK_f +-#define UNGRAB_KEY SDLK_z ++#define UNGRAB_MOUSE_KEY SDLK_m ++#define UNGRAB_WINDOW_KEY SDLK_z + ++static bool isx11sdlcall = false; ++static int x11_sdl_event_handle(int fd); ++ + static const int SDL_TO_LI_BUTTON_MAP[] = { + A_FLAG, B_FLAG, X_FLAG, Y_FLAG, + BACK_FLAG, SPECIAL_FLAG, PLAY_FLAG, +@@ -51,6 +59,8 @@ typedef struct _GAMEPAD_STATE { + int haptic_effect_id; + #endif + short id; ++ int fd; ++ bool fdadded; + bool initialized; + } GAMEPAD_STATE, *PGAMEPAD_STATE; + +@@ -62,6 +72,22 @@ static GAMEPAD_STATE gamepads[MAX_GAMEPADS]; + static int keyboard_modifiers; + static int activeGamepadMask = 0; + ++static short keystatlist[0xFF]; ++static void keyrelease(int keycode) { ++ keystatlist[keycode] = 0; ++} ++static void keypress(int keycode) { ++ keystatlist[keycode] = 1; ++} ++static void freeallkey () { ++ for (int i=0;i<0xFF;i++) { ++ if (keystatlist[i] == 1) { ++ keystatlist[i] = 0; ++ LiSendKeyboardEvent(0x80 << 8 | i, KEY_ACTION_UP, 0); ++ } ++ } ++} ++ + int sdl_gamepads = 0; + + static void send_controller_arrival(PGAMEPAD_STATE state) { +@@ -142,12 +168,22 @@ static PGAMEPAD_STATE get_gamepad(SDL_JoystickID sdl_i + } + + static void add_gamepad(int joystick_index) { ++ int fd; + SDL_GameController* controller = SDL_GameControllerOpen(joystick_index); + if (!controller) { + fprintf(stderr, "Could not open gamecontroller %i: %s\n", joystick_index, SDL_GetError()); + return; + } +- ++ if (isx11sdlcall) { ++ char* controllerpath = SDL_GameControllerPath(controller); ++ fd = open(controllerpath, O_RDWR|O_NONBLOCK); ++ if (fd == -1) { ++ close(fd); ++ fprintf(stderr, "Could not open gamecontroller from path: %s\n", controllerpath); ++ return; ++ } ++ } ++ + SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller); + SDL_JoystickID joystick_id = SDL_JoystickInstanceID(joystick); + +@@ -166,10 +202,15 @@ static void add_gamepad(int joystick_index) { + // Create a new gamepad state + state = get_gamepad(joystick_id, true); + state->controller = controller; ++ if (isx11sdlcall) { ++ state->fd = fd; ++ loop_add_fd(state->fd, &x11_sdl_event_handle, POLLIN); ++ state->fdadded = true; ++ } + + #if !SDL_VERSION_ATLEAST(2, 0, 9) + state->haptic = SDL_HapticOpenFromJoystick(joystick); +- if (haptic && (SDL_HapticQuery(state->haptic) & SDL_HAPTIC_LEFTRIGHT) == 0) { ++ if (state->haptic && (SDL_HapticQuery(state->haptic) & SDL_HAPTIC_LEFTRIGHT) == 0) { + SDL_HapticClose(state->haptic); + state->haptic = NULL; + } +@@ -182,6 +223,11 @@ static void add_gamepad(int joystick_index) { + sdl_gamepads++; + } + ++static void x11_add_gamepad(int joystick_index) { ++ isx11sdlcall = true; ++ add_gamepad(joystick_index); ++} ++ + static void remove_gamepad(SDL_JoystickID sdl_id) { + for (int i = 0;i<MAX_GAMEPADS;i++) { + if (gamepads[i].initialized && gamepads[i].sdl_id == sdl_id) { +@@ -208,6 +254,20 @@ static void remove_gamepad(SDL_JoystickID sdl_id) { + } + } + ++static void x11_remove_gamepad(SDL_JoystickID sdl_id) { ++ for (int i=0;i<MAX_GAMEPADS;i++) { ++ if (gamepads[i].initialized && gamepads[i].sdl_id == sdl_id) { ++ if (gamepads[i].fdadded) { ++ loop_remove_fd(gamepads[i].fd); ++ gamepads[i].fdadded = false; ++ close(gamepads[i].fd); ++ } ++ remove_gamepad(gamepads[i].sdl_id); ++ return; ++ } ++ } ++} ++ + void sdlinput_init(char* mappings) { + memset(gamepads, 0, sizeof(gamepads)); + +@@ -317,15 +377,28 @@ int sdlinput_handle_event(SDL_Window* window, SDL_Even + keyboard_modifiers &= ~modifier; + } + +- LiSendKeyboardEvent(0x80 << 8 | button, event->type==SDL_KEYDOWN?KEY_ACTION_DOWN:KEY_ACTION_UP, keyboard_modifiers); +- + // Quit the stream if all the required quit keys are down +- if ((keyboard_modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && event->key.keysym.sym == QUIT_KEY && event->type==SDL_KEYUP) ++ if ((keyboard_modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && event->key.keysym.sym == QUIT_KEY && event->type==SDL_KEYUP) { ++ freeallkey(); + return SDL_QUIT_APPLICATION; +- else if ((keyboard_modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && event->key.keysym.sym == FULLSCREEN_KEY && event->type==SDL_KEYUP) ++ } else if ((keyboard_modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && event->key.keysym.sym == FULLSCREEN_KEY && event->type==SDL_KEYUP) { ++ freeallkey(); + return SDL_TOGGLE_FULLSCREEN; +- else if ((keyboard_modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && event->key.keysym.sym == UNGRAB_KEY && event->type==SDL_KEYUP) ++ } else if ((keyboard_modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && event->key.keysym.sym == UNGRAB_MOUSE_KEY && event->type==SDL_KEYUP) { ++ freeallkey(); + return SDL_GetRelativeMouseMode() ? SDL_MOUSE_UNGRAB : SDL_MOUSE_GRAB; ++ } else if ((keyboard_modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && event->key.keysym.sym == UNGRAB_WINDOW_KEY && event->type==SDL_KEYUP) { ++ freeallkey(); ++ return iskeyboardgrab ? SDL_WINDOW_UNGRAB : SDL_WINDOW_GRAB; ++ } ++ ++ if (event->type==SDL_KEYDOWN) ++ keypress(button); ++ else ++ keyrelease(button); ++ ++ ++ LiSendKeyboardEvent(0x80 << 8 | button, event->type==SDL_KEYDOWN?KEY_ACTION_DOWN:KEY_ACTION_UP, keyboard_modifiers); + break; + case SDL_FINGERDOWN: + case SDL_FINGERMOTION: +@@ -524,4 +597,139 @@ void sdlinput_set_controller_led(unsigned short contro + #if SDL_VERSION_ATLEAST(2, 0, 14) + SDL_GameControllerSetLED(state->controller, r, g, b); + #endif +-} +\ No newline at end of file ++} ++ ++static int x11_sdlinput_handle_event(SDL_Event* event) { ++ int button = 0; ++ unsigned char touchEventType; ++ PGAMEPAD_STATE gamepad; ++ switch (event->type) { ++ case SDL_CONTROLLERAXISMOTION: ++ gamepad = get_gamepad(event->caxis.which, false); ++ if (!gamepad) ++ return SDL_NOTHING; ++ switch (event->caxis.axis) { ++ case SDL_CONTROLLER_AXIS_LEFTX: ++ gamepad->leftStickX = event->caxis.value; ++ break; ++ case SDL_CONTROLLER_AXIS_LEFTY: ++ gamepad->leftStickY = -SDL_max(event->caxis.value, (short)-32767); ++ break; ++ case SDL_CONTROLLER_AXIS_RIGHTX: ++ gamepad->rightStickX = event->caxis.value; ++ break; ++ case SDL_CONTROLLER_AXIS_RIGHTY: ++ gamepad->rightStickY = -SDL_max(event->caxis.value, (short)-32767); ++ break; ++ case SDL_CONTROLLER_AXIS_TRIGGERLEFT: ++ gamepad->leftTrigger = (unsigned char)(event->caxis.value * 255UL / 32767); ++ break; ++ case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: ++ gamepad->rightTrigger = (unsigned char)(event->caxis.value * 255UL / 32767); ++ break; ++ default: ++ return SDL_NOTHING; ++ } ++ LiSendMultiControllerEvent(gamepad->id, activeGamepadMask, gamepad->buttons, gamepad->leftTrigger, gamepad->rightTrigger, gamepad->leftStickX, gamepad->leftStickY, gamepad->rightStickX, gamepad->rightStickY); ++ break; ++ case SDL_CONTROLLERBUTTONDOWN: ++ case SDL_CONTROLLERBUTTONUP: ++ gamepad = get_gamepad(event->cbutton.which, false); ++ if (!gamepad) ++ return SDL_NOTHING; ++ if (event->cbutton.button >= SDL_arraysize(SDL_TO_LI_BUTTON_MAP)) ++ return SDL_NOTHING; ++ ++ if (event->type == SDL_CONTROLLERBUTTONDOWN) ++ gamepad->buttons |= SDL_TO_LI_BUTTON_MAP[event->cbutton.button]; ++ else ++ gamepad->buttons &= ~SDL_TO_LI_BUTTON_MAP[event->cbutton.button]; ++ ++ if ((gamepad->buttons & QUIT_BUTTONS) == QUIT_BUTTONS) ++ return SDL_QUIT_APPLICATION; ++ ++ LiSendMultiControllerEvent(gamepad->id, activeGamepadMask, gamepad->buttons, gamepad->leftTrigger, gamepad->rightTrigger, gamepad->leftStickX, gamepad->leftStickY, gamepad->rightStickX, gamepad->rightStickY); ++ break; ++ case SDL_CONTROLLERDEVICEADDED: ++ x11_add_gamepad(event->cdevice.which); ++ break; ++ case SDL_CONTROLLERDEVICEREMOVED: ++ x11_remove_gamepad(event->cdevice.which); ++ break; ++#if SDL_VERSION_ATLEAST(2, 0, 14) ++ case SDL_CONTROLLERSENSORUPDATE: ++ gamepad = get_gamepad(event->csensor.which, false); ++ if (!gamepad) ++ return SDL_NOTHING; ++ switch (event->csensor.sensor) { ++ case SDL_SENSOR_ACCEL: ++ LiSendControllerMotionEvent(gamepad->id, LI_MOTION_TYPE_ACCEL, event->csensor.data[0], event->csensor.data[1], event->csensor.data[2]); ++ break; ++ case SDL_SENSOR_GYRO: ++ // Convert rad/s to deg/s ++ LiSendControllerMotionEvent(gamepad->id, LI_MOTION_TYPE_GYRO, ++ event->csensor.data[0] * 57.2957795f, ++ event->csensor.data[1] * 57.2957795f, ++ event->csensor.data[2] * 57.2957795f); ++ break; ++ } ++ break; ++ case SDL_CONTROLLERTOUCHPADDOWN: ++ case SDL_CONTROLLERTOUCHPADUP: ++ case SDL_CONTROLLERTOUCHPADMOTION: ++ gamepad = get_gamepad(event->ctouchpad.which, false); ++ if (!gamepad) ++ return SDL_NOTHING; ++ switch (event->type) { ++ case SDL_CONTROLLERTOUCHPADDOWN: ++ touchEventType = LI_TOUCH_EVENT_DOWN; ++ break; ++ case SDL_CONTROLLERTOUCHPADUP: ++ touchEventType = LI_TOUCH_EVENT_UP; ++ break; ++ case SDL_CONTROLLERTOUCHPADMOTION: ++ touchEventType = LI_TOUCH_EVENT_MOVE; ++ break; ++ default: ++ return SDL_NOTHING; ++ } ++ LiSendControllerTouchEvent(gamepad->id, touchEventType, event->ctouchpad.finger, ++ event->ctouchpad.x, event->ctouchpad.y, event->ctouchpad.pressure); ++ break; ++#endif ++ } ++ ++ return SDL_NOTHING; ++} ++ ++static int x11_sdl_event_handle(int fd) { ++ SDL_Event event; ++ for (int i=0;i<MAX_GAMEPADS;i++) { ++ if (gamepads[i].fd == fd) { ++ int rc; ++ while (SDL_PollEvent(&event)) { ++ rc = x11_sdlinput_handle_event(&event); ++ if (rc == SDL_QUIT_APPLICATION) ++ return LOOP_RETURN; ++ } ++ } ++ } ++ return LOOP_OK; ++} ++ ++void x11_sdl_init(char* mappings) { ++ isx11sdlcall = true; ++ sdlinput_init(mappings); ++} ++ ++void x11_sdl_stop() { ++ for (int i=0;i<MAX_GAMEPADS;i++) { ++ if (gamepads[i].initialized && gamepads[i].fdadded) { ++ loop_remove_fd(gamepads[i].fd); ++ gamepads[i].fdadded = false; ++ close(gamepads[i].fd); ++ remove_gamepad(gamepads[i].sdl_id); ++ } ++ } ++ SDL_Quit(); ++} diff --git a/games/moonlight-embedded/files/patch-src_input_sdl.h b/games/moonlight-embedded/files/patch-src_input_sdl.h new file mode 100644 index 000000000000..5ccc7cf8b321 --- /dev/null +++ b/games/moonlight-embedded/files/patch-src_input_sdl.h @@ -0,0 +1,8 @@ +--- src/input/sdl.h.orig 2023-10-11 15:50:11 UTC ++++ src/input/sdl.h +@@ -105,3 +105,5 @@ void sdlinput_rumble(unsigned short controller_id, uns + void sdlinput_rumble_triggers(unsigned short controller_id, unsigned short left_trigger, unsigned short right_trigger); + void sdlinput_set_motion_event_state(unsigned short controller_id, unsigned char motion_type, unsigned short report_rate_hz); + void sdlinput_set_controller_led(unsigned short controller_id, unsigned char r, unsigned char g, unsigned char b); ++void x11_sdl_init(char* mappings); ++void x11_sdl_stop(); diff --git a/games/moonlight-embedded/files/patch-src_input_x11.c b/games/moonlight-embedded/files/patch-src_input_x11.c new file mode 100644 index 000000000000..582b15b405cd --- /dev/null +++ b/games/moonlight-embedded/files/patch-src_input_x11.c @@ -0,0 +1,185 @@ +--- src/input/x11.c.orig 2023-10-08 02:12:37 UTC ++++ src/input/x11.c +@@ -33,6 +33,8 @@ + + #define ACTION_MODIFIERS (MODIFIER_SHIFT|MODIFIER_ALT|MODIFIER_CTRL) + #define QUIT_KEY 0x18 /* KEY_Q */ ++#define GRAB_KEY 0x34 /* KEY_Z */ ++#define TAB_KEY 0x17 /* KEY_Tab */ + + static Display *display; + static Window window; +@@ -46,6 +48,35 @@ static const char data[1] = {0}; + static Cursor cursor; + static bool grabbed = True; + ++static bool isgrabkeyrelease = false; ++static bool waitingToSwitchGrabOnModifierUp = false; ++static bool waitingToExitOnModifiersUp = false; ++extern bool iskeyboardgrab; ++extern void grab_window(bool grabstat); ++ ++static short keystatlist[0xFF]; ++static void keyrelease(int keycode) { ++ keystatlist[keycode] = 0; ++} ++static void keypress(int keycode) { ++ keystatlist[keycode] = 1; ++} ++static void freeallkey () { ++ for (int i=0;i<0xFF;i++) { ++ if (keystatlist[i] == 1) { ++ keystatlist[i] = 0; ++ LiSendKeyboardEvent(0x80 << 8 | keyCodes[i - 8], KEY_ACTION_UP, 0); ++ } ++ } ++} ++static void clearallkey () { ++ for (int i=0;i<0xFF;i++) { ++ if (keystatlist[i] == 1) { ++ keystatlist[i] = 0; ++ } ++ } ++} ++ + static int x11_handler(int fd) { + XEvent event; + int button = 0; +@@ -54,18 +85,24 @@ static int x11_handler(int fd) { + while (XPending(display)) { + XNextEvent(display, &event); + switch (event.type) { ++ case FocusIn: ++ case FocusOut: ++ if (event.type == FocusIn) { ++ clearallkey(); ++ keyboard_modifiers = 0; ++ grabbed = true; ++ } else { ++ if (iskeyboardgrab) ++ break; ++ freeallkey(); ++ keyboard_modifiers = 0; ++ grabbed = false; ++ } ++ XDefineCursor(display, window, grabbed ? cursor : 0); ++ break; + case KeyPress: + case KeyRelease: + if (event.xkey.keycode >= 8 && event.xkey.keycode < (sizeof(keyCodes)/sizeof(keyCodes[0]) + 8)) { +- if ((keyboard_modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && event.type == KeyRelease) { +- if (event.xkey.keycode == QUIT_KEY) +- return LOOP_RETURN; +- else { +- grabbed = !grabbed; +- XDefineCursor(display, window, grabbed ? cursor : 0); +- } +- } +- + int modifier = 0; + switch (event.xkey.keycode) { + case 0x32: +@@ -89,8 +126,58 @@ static int x11_handler(int fd) { + keyboard_modifiers &= ~modifier; + } + ++ if ((keyboard_modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && event.type == KeyPress) { ++ if (event.xkey.keycode == QUIT_KEY) { ++ waitingToExitOnModifiersUp = true; ++ break; ++ } else if (event.xkey.keycode == GRAB_KEY) { ++ if (event.type == KeyPress) { ++ waitingToSwitchGrabOnModifierUp = true; ++ break; ++ } ++ } ++ } ++ if (waitingToSwitchGrabOnModifierUp) { ++ if (event.xkey.keycode == GRAB_KEY && event.type == KeyRelease) { ++ isgrabkeyrelease = true; ++ if (keyboard_modifiers != 0) ++ break; ++ } ++ if (keyboard_modifiers == 0 && isgrabkeyrelease) { ++ waitingToSwitchGrabOnModifierUp = false; ++ isgrabkeyrelease = false; ++ XDefineCursor(display, window, cursor); ++ freeallkey(); ++ grab_window(true); ++ break; ++ } ++ } else if (waitingToExitOnModifiersUp) { ++ if (event.xkey.keycode == QUIT_KEY) { ++ if (keyboard_modifiers != 0) ++ break; ++ } ++ if (keyboard_modifiers == 0) { ++ freeallkey(); ++ waitingToExitOnModifiersUp = false; ++ return LOOP_RETURN; ++ } ++ } ++ if (event.xkey.keycode == TAB_KEY && keyboard_modifiers == MODIFIER_ALT) { ++ freeallkey(); ++ keyboard_modifiers = 0; ++ break; ++ } ++ if (event.xkey.keycode == 0x40 || event.xkey.keycode == 0x6c) ++ break; ++ ++ if (event.type == KeyPress) ++ keypress(event.xkey.keycode); ++ else ++ keyrelease(event.xkey.keycode); ++ + short code = 0x80 << 8 | keyCodes[event.xkey.keycode - 8]; +- LiSendKeyboardEvent(code, event.type == KeyPress ? KEY_ACTION_DOWN : KEY_ACTION_UP, keyboard_modifiers); ++ if (!iskeyboardgrab) ++ LiSendKeyboardEvent(code, event.type == KeyPress ? KEY_ACTION_DOWN : KEY_ACTION_UP, keyboard_modifiers); + } + break; + case ButtonPress: +@@ -106,16 +193,20 @@ static int x11_handler(int fd) { *** 318 LINES SKIPPED ***